import type { Duration } from "dayjs/plugin/duration"; import type { Modify } from "@homarr/common/types"; import type { Integration, IntegrationSecret } from "@homarr/db/schema"; import type { IntegrationKind } from "@homarr/definitions"; import { createIntegrationOptionsChannel } from "@homarr/redis"; import { createCachedRequestHandler } from "./cached-request-handler"; type IntegrationOfKind = Omit & { kind: TKind; decryptedSecrets: Modify, { value: string }>[]; externalUrl: string | null; }; interface Options> { queryKey: string; requestAsync: (integration: IntegrationOfKind, input: TInput) => Promise; cacheDuration: Duration; cacheDurationForInput?: (input: TInput) => Duration | undefined; } export const createCachedIntegrationRequestHandler = < TData, TKind extends IntegrationKind, TInput extends Record, >( options: Options, ) => { return { handler: (integration: IntegrationOfKind, itemOptions: TInput) => createCachedRequestHandler({ queryKey: options.queryKey, requestAsync: async (input: { options: TInput; integration: IntegrationOfKind }) => { return await options.requestAsync(input.integration, input.options); }, cacheDuration: options.cacheDurationForInput?.(itemOptions) ?? options.cacheDuration, createRedisChannel(input, handlerOptions) { return createIntegrationOptionsChannel(input.integration.id, handlerOptions.queryKey, input.options); }, }).handler({ options: itemOptions, integration }), }; };