diff --git a/config/config.json.example b/config/config.json.example index 857b30e5..2a84030d 100644 --- a/config/config.json.example +++ b/config/config.json.example @@ -2,18 +2,16 @@ "debugMode": false, "disableWeb": false, "sourceDefaults": { - "options": { - "logPayload": false, - "logFilterFailure": "warn", - "logPlayerState": false, - "scrobbleThresholds": { - "duration": 30, - "percent": 50 - }, - "maxPollRetries": 1, - "maxRequestRetries": 1, - "retryMultiplier": 1.5 - } + "logPayload": false, + "logFilterFailure": "warn", + "logPlayerState": false, + "scrobbleThresholds": { + "duration": 30, + "percent": 50 + }, + "maxPollRetries": 1, + "maxRequestRetries": 1, + "retryMultiplier": 1.5 }, "clientDefaults": { "maxRequestRetries": 1, diff --git a/docsite/docs/configuration/kitchensink.md b/docsite/docs/configuration/kitchensink.md index fad0d7d3..2168a6cb 100644 --- a/docsite/docs/configuration/kitchensink.md +++ b/docsite/docs/configuration/kitchensink.md @@ -42,6 +42,8 @@ Using just one config file located at `CONFIG_DIR/config.json`: "data": { "clientId": "foxxSpotifyAppId", "clientSecret": "foxxSpotifyAppSecret", + }, + "options": { "maxRequestRetries": 2, // override default max retries because spotify can...spotty } }, diff --git a/src/backend/common/infrastructure/Atomic.ts b/src/backend/common/infrastructure/Atomic.ts index e27dfffe..e3f8405a 100644 --- a/src/backend/common/infrastructure/Atomic.ts +++ b/src/backend/common/infrastructure/Atomic.ts @@ -195,3 +195,5 @@ export interface MdnsDeviceInfo { } export type AbstractApiOptions = Record & { logger: Logger } + +export type keyOmit = T & { [P in U]?: never } diff --git a/src/backend/common/infrastructure/config/aioConfig.ts b/src/backend/common/infrastructure/config/aioConfig.ts index 03a8b1ef..a19f587f 100644 --- a/src/backend/common/infrastructure/config/aioConfig.ts +++ b/src/backend/common/infrastructure/config/aioConfig.ts @@ -2,17 +2,13 @@ import { LogOptions } from "@foxxmd/logging"; import { ClientAIOConfig } from "./client/clients.js"; import { RequestRetryOptions } from "./common.js"; import { WebhookConfig } from "./health/webhooks.js"; -import { CommonSourceOptions, ScrobbleThresholds, SourceRetryOptions } from "./source/index.js"; +import { CommonSourceOptions, SourceRetryOptions } from "./source/index.js"; import { SourceAIOConfig } from "./source/sources.js"; -export interface SourceDefaults extends SourceRetryOptions { - /** - * Set thresholds for when multi-scrobbler should consider a tracked play to be "scrobbable". If both duration and percent are defined then if either condition is met the track is scrobbled. - * */ - scrobbleThresholds?: ScrobbleThresholds - options?: CommonSourceOptions +export interface SourceDefaults extends CommonSourceOptions { } + export interface AIOConfig { sourceDefaults?: SourceDefaults clientDefaults?: RequestRetryOptions diff --git a/src/backend/common/infrastructure/config/common.ts b/src/backend/common/infrastructure/config/common.ts index fe4de683..ba77f086 100644 --- a/src/backend/common/infrastructure/config/common.ts +++ b/src/backend/common/infrastructure/config/common.ts @@ -1,3 +1,5 @@ +import { keyOmit } from "../Atomic.js"; + export interface CommonConfig { name?: string data?: CommonData @@ -10,10 +12,7 @@ export interface CommonConfig { enable?: boolean } -export interface CommonData { - [key: string]: any - options?: Record -} +export type CommonData = keyOmit<{ [key: string]: any }, "options"> export interface RequestRetryOptions { /** diff --git a/src/backend/common/infrastructure/config/source/jellyfin.ts b/src/backend/common/infrastructure/config/source/jellyfin.ts index 058bb39b..63119381 100644 --- a/src/backend/common/infrastructure/config/source/jellyfin.ts +++ b/src/backend/common/infrastructure/config/source/jellyfin.ts @@ -17,33 +17,6 @@ export interface JellyData extends CommonSourceData { * @examples [["MyServerName1"]] * */ servers?: string | string[] - - /** - * Additional options for jellyfin logging and tuning - * */ - options?: { - /** - * Log raw Jellyfin webhook payload to debug - * - * @default false - * @examples [false] - * */ - logPayload?: boolean - - /** - * How MS should log when a Jellyfin event fails a defined filter (users/servers) - * - * * `false` => do not log - * * `debug` => log to DEBUG level - * * `warn` => log to WARN level (default) - * - * Hint: This is useful if you are sure this source is setup correctly and you have multiple other Jellyfin sources. Set to `debug` or `false` to reduce log noise. - * - * @default warn - * @examples ["warn"] - * */ - logFilterFailure?: false | 'debug' | 'warn' - } } export interface JellySourceConfig extends CommonSourceConfig { diff --git a/src/backend/common/infrastructure/config/source/plex.ts b/src/backend/common/infrastructure/config/source/plex.ts index 59840fc8..c3c64cb5 100644 --- a/src/backend/common/infrastructure/config/source/plex.ts +++ b/src/backend/common/infrastructure/config/source/plex.ts @@ -25,26 +25,6 @@ export interface PlexSourceData extends CommonSourceData { * @examples [["MyServerName"]] * */ servers?: string | string[] - - /** - * Additional options for Plex/Tautulli logging and tuning - * */ - options?: { - - /** - * How MS should log when a Plex/Tautulli event fails a defined filter (users/servers) - * - * * `false` => do not log - * * `debug` => log to DEBUG level - * * `warn` => log to WARN level (default) - * - * Hint: This is useful if you are sure this source is setup correctly and you have multiple other Plex/Tautulli sources. Set to `debug` or `false` to reduce log noise. - * - * @default warn - * @examples ["warn"] - * */ - logFilterFailure?: false | 'debug' | 'warn' - } } export interface PlexSourceConfig extends CommonSourceConfig { diff --git a/src/backend/common/infrastructure/config/source/webscrobbler.ts b/src/backend/common/infrastructure/config/source/webscrobbler.ts index b30a330a..f7574d31 100644 --- a/src/backend/common/infrastructure/config/source/webscrobbler.ts +++ b/src/backend/common/infrastructure/config/source/webscrobbler.ts @@ -32,31 +32,6 @@ export interface WebScrobblerData extends CommonSourceData { * @examples [["mixcloud","soundcloud","bandcamp"]] * */ whitelist?: string | string[] - - /** - * Additional options for WebScrobbler logging and tuning - * */ - options?: { - /** - * Log raw WebScrobbler webhook payload to debug - * - * @default false - * @examples [false] - * */ - logPayload?: boolean - - /** - * How MS should log when a WebScrobbler event fails a defined filter - * - * * `false` => do not log - * * `debug` => log to DEBUG level - * * `warn` => log to WARN level (default) - * - * @default warn - * @examples ["warn"] - * */ - logFilterFailure?: false | 'debug' | 'warn' - } } export interface WebScrobblerSourceConfig extends CommonSourceConfig { diff --git a/src/backend/sources/JellyfinSource.ts b/src/backend/sources/JellyfinSource.ts index a7cb7e3d..ac8f5300 100644 --- a/src/backend/sources/JellyfinSource.ts +++ b/src/backend/sources/JellyfinSource.ts @@ -38,13 +38,13 @@ export default class JellyfinSource extends MemorySource { super('jellyfin', name, config, internal, emitter); const { data: { - users, - servers, + users, + servers, + } = {}, options: { - logFilterFailure = (parseBool(process.env.DEBUG_MODE) ? 'debug' : 'warn') - } = {} + logFilterFailure = (parseBool(process.env.DEBUG_MODE) ? 'debug' : 'warn') } = {} - } = config; + } = this.config; if(logFilterFailure !== false && !['debug', 'warn'].includes(logFilterFailure)) { this.logger.warn(`logFilterFailure value of '${logFilterFailure.toString()}' is NOT VALID. Logging will not occur if filters fail. You should fix this.`); @@ -185,10 +185,8 @@ export default class JellyfinSource extends MemorySource { protected logFilterFailure = (str: string, meta?: any) => { const { - data: { - options: { - logFilterFailure = (parseBool(process.env.DEBUG_MODE) ? 'debug' : 'warn') - } = {} + options: { + logFilterFailure = (parseBool(process.env.DEBUG_MODE) ? 'debug' : 'warn') } = {} } = this.config; diff --git a/src/backend/sources/PlexSource.ts b/src/backend/sources/PlexSource.ts index 703caddc..6d411a34 100644 --- a/src/backend/sources/PlexSource.ts +++ b/src/backend/sources/PlexSource.ts @@ -28,11 +28,11 @@ export default class PlexSource extends AbstractSource { user = [], libraries = [], servers = [], - options: { - logFilterFailure = 'warn' - } = {} } = {}, - } = config + options: { + logFilterFailure = 'warn' + } = {} + } = this.config if(logFilterFailure !== false && !['debug', 'warn'].includes(logFilterFailure)) { this.logger.warn(`logFilterFailure value of '${logFilterFailure.toString()}' is NOT VALID. Logging will not occur if filters fail. You should fix this.`); @@ -134,10 +134,8 @@ export default class PlexSource extends AbstractSource { protected logFilterFailure = (str: string, meta?: any) => { const { - data: { - options: { - logFilterFailure = 'warn' - } = {} + options: { + logFilterFailure = 'warn' } = {} } = this.config; diff --git a/src/backend/sources/ScrobbleSources.ts b/src/backend/sources/ScrobbleSources.ts index 8ef0aaec..f6be2105 100644 --- a/src/backend/sources/ScrobbleSources.ts +++ b/src/backend/sources/ScrobbleSources.ts @@ -470,11 +470,9 @@ export default class ScrobbleSources { this.logger.warn(`${type} (${name}) source was disabled by config`); return; } - + // add defaults - const {options: defaultOptions = {}, ...restDefaults} = defaults; - const data = {...defaults, ...d}; - const compositeConfig: SourceConfig = {...clientConfig, data, options: {...defaultOptions, ...clientOptions}}; + const compositeConfig: SourceConfig = {...clientConfig, data: d, options: {...defaults, ...clientOptions}}; this.logger.debug(`(${name}) Constructing ${type} source`); let newSource: AbstractSource;