import type { Modify } from "@homarr/common/types"; import type { Integration, IntegrationSecret } from "@homarr/db/schema"; import type { IntegrationKind } from "@homarr/definitions"; import { createRequestHandler } from "./request-handler"; type IntegrationOfKind = Omit & { kind: TKind; decryptedSecrets: Modify, { value: string }>[]; externalUrl: string | null; }; interface Options> { requestAsync: (integration: IntegrationOfKind, input: TInput) => Promise; cacheTtlMs?: number; fallbackToStaleOnError?: boolean; } export const createIntegrationRequestHandler = < TData, TKind extends IntegrationKind, TInput extends Record, >( options: Options, ) => { const integrationMap = new Map>(); const inner = createRequestHandler({ requestAsync: async (input) => { const integration = integrationMap.get(input.integrationId); if (!integration) { throw new Error(`Integration ${input.integrationId} not found in cache`); } return options.requestAsync(integration, input.options); }, cacheTtlMs: options.cacheTtlMs, fallbackToStaleOnError: options.fallbackToStaleOnError, }); return { invalidateCache: inner.invalidateCache, handler: (integration: IntegrationOfKind, itemOptions: TInput) => { integrationMap.set(integration.id, integration); return inner.handler({ integrationId: integration.id, options: itemOptions }); }, }; };