Files
sofarr/server/clients/ArrRetriever.js
Gronod 6e199925aa
All checks were successful
Build and Push Docker Image / build (push) Successful in 20s
CI / Security audit (push) Successful in 1m18s
CI / Tests & coverage (push) Successful in 1m14s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 54s
refactor: make PALDRA match PDCA style exactly - remove redundant instanceConfig parameter and convert to pure singleton
- Remove instanceConfig parameter from all retriever methods (getTags, getQueue, getHistory)
- Retriever instances now use this.url, this.apiKey, this.id instead of passed parameter
- Convert ArrRetrieverRegistry from class with convenience functions to pure singleton object
- Export singleton instance directly instead of class + convenience functions
- Update poller.js and historyFetcher.js to call methods on singleton directly
- All 261 tests pass with zero behavior changes
2026-05-19 14:51:22 +01:00

79 lines
2.7 KiB
JavaScript

// Copyright (c) 2026 Gordon Bolton. MIT License.
/**
* Abstract base class for all *arr data retrievers.
* Defines the common interface that all retrievers must implement.
* This pluggable layer enables future retrieval strategies (e.g., webhook listeners)
* to push normalized data directly into the existing cache and SSE system
* without touching the poller logic.
*/
class ArrRetriever {
/**
* @param {Object} instanceConfig - Configuration for this retriever instance
* @param {string} instanceConfig.id - Unique identifier for this instance
* @param {string} instanceConfig.name - Display name for this instance
* @param {string} instanceConfig.url - Base URL for the *arr API
* @param {string} instanceConfig.apiKey - API key for authentication
*/
constructor(instanceConfig) {
if (this.constructor === ArrRetriever) {
throw new Error('ArrRetriever is an abstract class and cannot be instantiated directly');
}
this.id = instanceConfig.id;
this.name = instanceConfig.name;
this.url = instanceConfig.url;
this.apiKey = instanceConfig.apiKey;
}
/**
* Get the retriever type identifier (e.g., 'sonarr', 'radarr')
* @returns {string} The retriever type
*/
getRetrieverType() {
throw new Error('getRetrieverType() must be implemented by subclass');
}
/**
* Get the unique instance ID
* @returns {string} The instance ID
*/
getInstanceId() {
return this.id;
}
/**
* Get tags from this *arr instance
* @returns {Promise<Array>} Array of tag objects
*/
async getTags() {
throw new Error('getTags() must be implemented by subclass');
}
/**
* Get queue from this *arr instance
* @returns {Promise<Object>} Queue object with records array
*/
async getQueue() {
throw new Error('getQueue() must be implemented by subclass');
}
/**
* Get history from this *arr instance
* @param {Object} options - Optional parameters for history fetch
* @param {number} [options.pageSize] - Number of records to fetch
* @param {string} [options.sortKey] - Field to sort by
* @param {string} [options.sortDir] - Sort direction ('ascending' or 'descending')
* @param {boolean} [options.includeSeries] - Include series data (Sonarr)
* @param {boolean} [options.includeEpisode] - Include episode data (Sonarr)
* @param {boolean} [options.includeMovie] - Include movie data (Radarr)
* @param {string} [options.startDate] - ISO date string for filtering
* @returns {Promise<Object>} History object with records array
*/
async getHistory(options = {}) {
throw new Error('getHistory() must be implemented by subclass');
}
}
module.exports = ArrRetriever;