1Branch0Tags
GL
glucryptosync: align production template with local master
2518e512 days ago3Commits
typescript
import { z } from "zod"; const CONFIG_ENV = "OPENTOOL_PUBLIC_IMPORTANT_DATES_ROUNDUP_CONFIG"; const TEMPLATE_CONFIG_ENV_VAR = CONFIG_ENV; const TEMPLATE_CONFIG_VERSION = 2; const baseConfigSchema = z .object({ configVersion: z.number().int().optional(), title: z.string().min(1).max(120).optional(), daysAhead: z.number().int().min(1).max(180).optional(), limit: z.number().int().min(1).max(50).optional(), category: z.string().min(1).max(80).optional(), series: z.array(z.string().min(1)).max(20).optional(), summaryModel: z.string().min(1).optional(), summaryMaxEvents: z.number().int().min(1).max(8).optional(), }) .strict(); export const requestOverrideSchema = baseConfigSchema.partial(); export type ImportantDatesRoundupConfig = { configVersion: number; title: string; daysAhead: number; limit: number; category?: string; series?: string[]; summaryModel?: string; summaryMaxEvents: number; }; const TEMPLATE_CONFIG_DEFAULTS: ImportantDatesRoundupConfig = { configVersion: TEMPLATE_CONFIG_VERSION, title: "Important Upcoming Dates", daysAhead: 14, limit: 10, category: "macro", summaryMaxEvents: 5, }; const TEMPLATE_CONFIG_SCHEMA = { type: "object", properties: { configVersion: { type: "number", title: "Config version", description: "Internal version for roundup defaults.", readOnly: true, "x-hidden": true, }, title: { type: "string", title: "Title", description: "Display title used in the roundup payload.", }, daysAhead: { type: "number", title: "Days ahead", description: "How many days ahead to query for upcoming releases.", }, limit: { type: "number", title: "Limit", description: "Max number of upcoming releases returned.", }, category: { type: "string", title: "Category", description: "Optional gateway category filter, for example macro.", }, series: { type: "array", title: "Series", description: "Optional release series filters, for example CPI or FOMC.", items: { type: "string" }, }, summaryModel: { type: "string", title: "Summary model", description: "Optional model override used for roundup summarization.", }, summaryMaxEvents: { type: "number", title: "Summary max events", description: "Max number of events surfaced in the top summary.", }, }, }; function parseJson(raw: string | null): unknown | null { if (!raw) return null; try { return JSON.parse(raw) as unknown; } catch { return null; } } function pickDefined<T extends Record<string, unknown>>(value: T): Partial<T> { return Object.fromEntries( Object.entries(value).filter(([, entry]) => entry !== undefined), ) as Partial<T>; } function normalizeStringArray(value?: string[]) { if (!value || value.length === 0) return undefined; const normalized = Array.from( new Set(value.map((entry) => entry.trim()).filter(Boolean)), ); return normalized.length > 0 ? normalized : undefined; } export function resolveRuntimeConfig( overrides?: z.infer<typeof requestOverrideSchema>, ): ImportantDatesRoundupConfig { const envConfig = parseJson(process.env[CONFIG_ENV] ?? null); const parsed = baseConfigSchema.safeParse( envConfig ?? TEMPLATE_CONFIG_DEFAULTS, ); const base = parsed.success ? parsed.data : TEMPLATE_CONFIG_DEFAULTS; const merged = { ...base, ...pickDefined((overrides ?? {}) as Record<string, unknown>), }; return { configVersion: TEMPLATE_CONFIG_VERSION, title: merged.title ?? TEMPLATE_CONFIG_DEFAULTS.title, daysAhead: merged.daysAhead ?? TEMPLATE_CONFIG_DEFAULTS.daysAhead, limit: merged.limit ?? TEMPLATE_CONFIG_DEFAULTS.limit, category: typeof merged.category === "string" && merged.category.trim().length > 0 ? merged.category.trim() : TEMPLATE_CONFIG_DEFAULTS.category, series: normalizeStringArray(merged.series), summaryModel: merged.summaryModel, summaryMaxEvents: merged.summaryMaxEvents ?? TEMPLATE_CONFIG_DEFAULTS.summaryMaxEvents, }; } export const IMPORTANT_DATES_ROUNDUP_TEMPLATE_CONFIG = { version: TEMPLATE_CONFIG_VERSION, schema: TEMPLATE_CONFIG_SCHEMA, defaults: TEMPLATE_CONFIG_DEFAULTS, envVar: TEMPLATE_CONFIG_ENV_VAR, };