export function cascadeConfigurationLists()

in apps/firelens-stability/lib/utils/config-utils.ts [20:92]


export function cascadeConfigurationLists(configs: IGenericConfig[]) {
    /* Treat config lists differently */
    /* Merge each list and override same named entries */

    /* Find config lists */
    const configLists = configs.map(config =>
        Object.entries(config?.config ?? [])
        .filter(([k, _]) => k.startsWith("lists."))
    );

    /* Mutate configLists into entries - overrides are last */
    const entries = configLists.map(
        list => list.map(([k,v]) => {
            return {
                "listName": k,
                "items": v
            }
        }
    )).flat();

    /* Build merged lists abstract structure */
    const mergedListsAbstract: {[listName: string]: {[itemName: string]: any}} = {};
    entries.forEach(entry => {
        entry.items.forEach(item => {
            /* In most javascript implementations, order is preserved, duplicates are not */
            mergedListsAbstract[entry.listName] = mergedListsAbstract[entry.listName] ?? [];
            mergedListsAbstract[entry.listName][item.name ?? "null"] = item; /* preserve unnamed with random name */
        });
    });

    /* Rebuild merged lists */
    const mergedEntries = Object.entries(mergedListsAbstract).map(([listName,items]) => {
        const itemsList = Object.entries(items).map(([name, item]) => item);
        
        /* Stable sort lists by order */
        const sortedItemsList = itemsList.sort((a, b) => a?.order ?? 1 - b?.order ?? 1)
        return [
            listName, sortedItemsList
        ]
    })
    const mergedLists = Object.fromEntries(mergedEntries);

    /* Cascade the configuration objects */
    let cascadedConfig: IGenericConfig = {} as IGenericConfig;
    configs.forEach(config => {
        cascadedConfig = {
            config: {
                ...(cascadedConfig?.config ?? {}),
                ...config.config,
            },
            definitions: {
                ...(cascadedConfig?.definitions ?? {}),
                ...config.definitions,
            },
            managed: {
                ...(cascadedConfig?.managed ?? {}),
                ...config.managed,
            }
        };
    });

    /* Add merged lists to config object */
    cascadedConfig = {
        config: {
            ...(cascadedConfig?.config ?? {}),
            ...mergedLists,
        },
        definitions: cascadedConfig.definitions,
        managed: cascadedConfig.managed,
    }

    return cascadedConfig;
}