All checks were successful
- 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
79 lines
2.7 KiB
JavaScript
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;
|