Skip to content

Commit

Permalink
fix: correct customFormatDefinition loading from top level
Browse files Browse the repository at this point in the history
  • Loading branch information
BlackDark committed Jan 10, 2025
1 parent aa685e9 commit f841617
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 37 deletions.
10 changes: 5 additions & 5 deletions src/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ describe("mergeConfigsAndTemplates", () => {
base_url: "http://sonarr:8989",
};

const result = await mergeConfigsAndTemplates(inputConfig, "SONARR");
const result = await mergeConfigsAndTemplates({}, inputConfig, "SONARR");

expect(result.config.custom_formats.length).toBe(3);
expect(result.config.quality_profiles.length).toBe(3);
Expand Down Expand Up @@ -197,7 +197,7 @@ describe("mergeConfigsAndTemplates", () => {
base_url: "http://sonarr:8989",
};

const result = await mergeConfigsAndTemplates(inputConfig, "SONARR");
const result = await mergeConfigsAndTemplates({}, inputConfig, "SONARR");

expect(result.config.custom_formats.length).toBe(0);
expect(result.config.quality_profiles.length).toBe(0);
Expand Down Expand Up @@ -236,7 +236,7 @@ describe("mergeConfigsAndTemplates", () => {
base_url: "http://sonarr:8989",
};

const result = await mergeConfigsAndTemplates(inputConfig, "SONARR");
const result = await mergeConfigsAndTemplates({}, inputConfig, "SONARR");

expect(result.config.custom_formats.length).toBe(2);
expect(result.config.quality_profiles.length).toBe(1);
Expand Down Expand Up @@ -282,13 +282,13 @@ describe("mergeConfigsAndTemplates", () => {
base_url: "http://sonarr:8989",
};

const result = await mergeConfigsAndTemplates(inputConfig, "SONARR");
const result = await mergeConfigsAndTemplates({}, inputConfig, "SONARR");

expect(result.config.custom_formats.length).toBe(0);
expect(result.config.quality_profiles.length).toBe(0);
});

test("should throw error for invalid input configuration", async () => {
await expect(mergeConfigsAndTemplates(null as any, "SONARR")).rejects.toThrow();
await expect(mergeConfigsAndTemplates({}, null as any, "SONARR")).rejects.toThrow();
});
});
55 changes: 35 additions & 20 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,12 @@ export const validateConfig = (input: InputConfigInstance): MergedConfigInstance
/**
* Load data from trash, recyclarr, custom configs and merge.
* Afterwards do sanitize and check against required configuration.
* @param value
* @param instanceConfig
* @param arrType
*/
export const mergeConfigsAndTemplates = async (
value: InputConfigArrInstance,
globalConfig: InputConfigSchema,
instanceConfig: InputConfigArrInstance,
arrType: ArrType,
): Promise<{ config: MergedConfigInstance }> => {
const localTemplateMap = loadLocalRecyclarrTemplate(arrType);
Expand All @@ -198,8 +199,8 @@ export const mergeConfigsAndTemplates = async (
};

// HINT: we assume customFormatDefinitions only exist in RECYCLARR
if (value.include) {
const mappedIncludes = value.include.reduce<{ recyclarr: InputConfigIncludeItem[]; trash: InputConfigIncludeItem[] }>(
if (instanceConfig.include) {
const mappedIncludes = instanceConfig.include.reduce<{ recyclarr: InputConfigIncludeItem[]; trash: InputConfigIncludeItem[] }>(
(previous, current) => {
switch (current.source) {
case "TRASH":
Expand All @@ -218,7 +219,7 @@ export const mergeConfigsAndTemplates = async (
);

logger.info(
`Found ${value.include.length} templates to include. Mapped to [recyclarr]=${mappedIncludes.recyclarr.length}, [trash]=${mappedIncludes.trash.length} ...`,
`Found ${instanceConfig.include.length} templates to include. Mapped to [recyclarr]=${mappedIncludes.recyclarr.length}, [trash]=${mappedIncludes.trash.length} ...`,
);

mappedIncludes.recyclarr.forEach((e) => {
Expand Down Expand Up @@ -287,41 +288,55 @@ export const mergeConfigsAndTemplates = async (
}

// Config values overwrite template values
if (value.custom_formats) {
mergedTemplates.custom_formats.push(...value.custom_formats);
if (instanceConfig.custom_formats) {
mergedTemplates.custom_formats.push(...instanceConfig.custom_formats);
}

if (value.quality_profiles) {
mergedTemplates.quality_profiles.push(...value.quality_profiles);
if (instanceConfig.quality_profiles) {
mergedTemplates.quality_profiles.push(...instanceConfig.quality_profiles);
}

if (value.media_management) {
mergedTemplates.media_management = { ...mergedTemplates.media_management, ...value.media_management };
if (instanceConfig.media_management) {
mergedTemplates.media_management = { ...mergedTemplates.media_management, ...instanceConfig.media_management };
}

if (value.media_naming) {
if (instanceConfig.media_naming) {
mergedTemplates.media_naming_api = {
...mergedTemplates.media_naming_api,
...(await mapConfigMediaNamingToApi(arrType, value.media_naming)),
...(await mapConfigMediaNamingToApi(arrType, instanceConfig.media_naming)),
};
}

if (value.media_naming_api) {
mergedTemplates.media_naming_api = { ...mergedTemplates.media_naming_api, ...value.media_naming_api };
if (instanceConfig.media_naming_api) {
mergedTemplates.media_naming_api = { ...mergedTemplates.media_naming_api, ...instanceConfig.media_naming_api };
}

if (value.quality_definition) {
mergedTemplates.quality_definition = { ...mergedTemplates.quality_definition, ...value.quality_definition };
if (instanceConfig.quality_definition) {
mergedTemplates.quality_definition = { ...mergedTemplates.quality_definition, ...instanceConfig.quality_definition };
}

if (value.customFormatDefinitions) {
if (Array.isArray(value.customFormatDefinitions)) {
mergedTemplates.customFormatDefinitions = [...(mergedTemplates.customFormatDefinitions || []), ...value.customFormatDefinitions];
if (globalConfig.customFormatDefinitions) {
if (Array.isArray(globalConfig.customFormatDefinitions)) {
mergedTemplates.customFormatDefinitions = [
...(mergedTemplates.customFormatDefinitions || []),
...globalConfig.customFormatDefinitions,
];
} else {
logger.warn(`CustomFormatDefinitions in config file must be an array. Ignoring.`);
}
}

if (instanceConfig.customFormatDefinitions) {
if (Array.isArray(instanceConfig.customFormatDefinitions)) {
mergedTemplates.customFormatDefinitions = [
...(mergedTemplates.customFormatDefinitions || []),
...instanceConfig.customFormatDefinitions,
];
} else {
logger.warn(`CustomFormatDefinitions in instance config file must be an array. Ignoring.`);
}
}

const recyclarrProfilesMerged = mergedTemplates.quality_profiles.reduce<Map<string, ConfigQualityProfile>>((p, c) => {
const profile = p.get(c.name);

Expand Down
24 changes: 12 additions & 12 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import { calculateQualityProfilesDiff, loadQualityProfilesFromServer } from "./q
import { cloneRecyclarrTemplateRepo } from "./recyclarr-importer";
import { cloneTrashRepo, loadQualityDefinitionFromTrash } from "./trash-guide";
import { ArrType } from "./types/common.types";
import { InputConfigArrInstance } from "./types/config.types";
import { InputConfigArrInstance, InputConfigSchema } from "./types/config.types";
import { TrashQualityDefintion } from "./types/trashguide.types";

const pipeline = async (value: InputConfigArrInstance, arrType: ArrType) => {
const pipeline = async (globalConfig: InputConfigSchema, instanceConfig: InputConfigArrInstance, arrType: ArrType) => {
const api = getUnifiedClient();

const { config } = await mergeConfigsAndTemplates(value, arrType);
const { config } = await mergeConfigsAndTemplates(globalConfig, instanceConfig, arrType);

const idsToManage = calculateCFsToManage(config);
logger.debug(Array.from(idsToManage), `CustomFormats to manage`);
Expand Down Expand Up @@ -157,14 +157,14 @@ const run = async () => {
logger.info("DryRun: Running in dry-run mode!");
}

const applicationConfig = getConfig();
const globalConfig = getConfig();

await cloneRecyclarrTemplateRepo();
await cloneTrashRepo();

// TODO currently this has to be run sequentially because of the centrally configured api

const sonarrConfig = applicationConfig.sonarr;
const sonarrConfig = globalConfig.sonarr;

if (sonarrConfig == null || Array.isArray(sonarrConfig) || typeof sonarrConfig !== "object" || Object.keys(sonarrConfig).length <= 0) {
logHeading(`No Sonarr instances defined.`);
Expand All @@ -174,12 +174,12 @@ const run = async () => {
for (const [instanceName, instance] of Object.entries(sonarrConfig)) {
logger.info(`Processing Sonarr Instance: ${instanceName}`);
await configureApi("SONARR", instance.base_url, instance.api_key);
await pipeline(instance, "SONARR");
await pipeline(globalConfig, instance, "SONARR");
unsetApi();
}
}

const radarrConfig = applicationConfig.radarr;
const radarrConfig = globalConfig.radarr;

if (radarrConfig == null || Array.isArray(radarrConfig) || typeof radarrConfig !== "object" || Object.keys(radarrConfig).length <= 0) {
logHeading(`No Radarr instances defined.`);
Expand All @@ -189,12 +189,12 @@ const run = async () => {
for (const [instanceName, instance] of Object.entries(radarrConfig)) {
logger.info(`Processing Radarr Instance: ${instanceName}`);
await configureApi("RADARR", instance.base_url, instance.api_key);
await pipeline(instance, "RADARR");
await pipeline(globalConfig, instance, "RADARR");
unsetApi();
}
}

const whisparrConfig = applicationConfig.whisparr;
const whisparrConfig = globalConfig.whisparr;

if (
whisparrConfig == null ||
Expand All @@ -209,12 +209,12 @@ const run = async () => {
for (const [instanceName, instance] of Object.entries(whisparrConfig)) {
logger.info(`Processing Whisparr Instance: ${instanceName}`);
await configureApi("WHISPARR", instance.base_url, instance.api_key);
await pipeline(instance, "WHISPARR");
await pipeline(globalConfig, instance, "WHISPARR");
unsetApi();
}
}

const readarrConfig = applicationConfig.readarr;
const readarrConfig = globalConfig.readarr;

if (
readarrConfig == null ||
Expand All @@ -229,7 +229,7 @@ const run = async () => {
for (const [instanceName, instance] of Object.entries(readarrConfig)) {
logger.info(`Processing Readarr Instance: ${instanceName}`);
await configureApi("READARR", instance.base_url, instance.api_key);
await pipeline(instance, "READARR");
await pipeline(globalConfig, instance, "READARR");
unsetApi();
}
}
Expand Down

0 comments on commit f841617

Please sign in to comment.