/* eslint-disable @typescript-eslint/no-explicit-any */ import stableStringify from 'fast-json-stable-stringify'; import { LookUpRefSpec, LookUpSpec } from '../schema/WebApiSchema.js'; import { PluginContext } from '../types/PluginContext.js'; import { SqupContext } from '../types/SqupContext.js'; import { CallApi } from './ApiFetcher.js'; import { RenderObject, referenceData } from './Render.js'; export async function CallLookUp ( pluginContext: PluginContext, squpContext: SqupContext, lookUpRef: LookUpRefSpec, replacements: Record = {} ) { const lookUp: LookUpSpec | undefined = pluginContext.lookUps.get(lookUpRef.lookUp); if (!lookUp) { throw new Error(`LookUp ${lookUpRef.lookUp} not found for lookUp reference ${lookUpRef.name}`); } const args: Record = {}; for (const arg of lookUpRef.args ?? []) { if ( typeof arg.arg === 'string') { if (arg.arg.match(/^\{{4}.+\}{4}$/u)) { args[arg.name] = RenderObject(arg.arg, pluginContext, replacements); } else { args[arg.name] = referenceData(arg.arg, pluginContext, replacements); } } else { args[arg.name] = arg.arg; } } // Lookups can only use replacements that are unchanging for this call or encoded into the key below const replacementsForLookup = { timeframe: replacements.timeframe, dataSourceConfig: replacements.dataSourceConfig, args }; // Generate stable key const key = stableStringify({ name: lookUp.name, args }); const cachedData = pluginContext.lookUpCache.get(key); if (cachedData) { // Already loaded return cachedData; } // Get data let object; if (lookUp.api) { const { response, data } = await CallApi( pluginContext, lookUp.api, { complete: false, recordCount: 0 }, squpContext, replacementsForLookup ); object = data; } squpContext.log.debug(`Handling lookUp results: '${JSON.stringify(lookUp.result)}', object='${JSON.stringify(object)}'`); let result: any = RenderObject(lookUp.result.path, pluginContext, { ...replacementsForLookup, object }); if (result && lookUp.result.groupBy) { if (!Array.isArray(result)) { throw new Error(`groupBy ${lookUp.result.groupBy} specified but didn't receive an array`); } const groupBy = lookUp.result.groupBy ?? ''; result = result.reduce( (acc, val) => acc.set(typeof val === 'object' && val ? val[groupBy] : '', val), new Map() ); } squpContext.log.debug(`LookUp result: '${JSON.stringify(result)}'`); // Save data in cache pluginContext.lookUpCache.set(key, result); return result; }