import { assertSafeConfigNames, getBuildConfig } from "../contracts/env.js"; import { validateRuntimeConfig } from "./runtime-config-schema.js"; export class BootConfigError extends Error { /** * @param {string} code * @param {{ buildId: string, configSchemaVersion?: string, releaseId?: string }} safe */ constructor(code, safe) { super("Runtime configuration could not be loaded"); this.name = "BootConfigError"; this.kind = "BOOT_CONFIG_FAILURE"; this.code = code; this.safe = Object.freeze({ kind: this.kind, code, buildId: safe.buildId, configSchemaVersion: safe.configSchemaVersion, releaseId: safe.releaseId, supportReference: `${safe.buildId}:${code}`, }); } } /** * @param {{ * fetcher?: typeof fetch, * buildConfig?: ReturnType, * now?: () => number * }} [options] */ export async function loadRuntimeConfig(options = {}) { const fetcher = options.fetcher ?? fetch; const buildConfig = options.buildConfig ?? getBuildConfig(); const now = options.now ?? performance.now.bind(performance); const startedAt = now(); let response; try { response = await fetcher(buildConfig.runtimeConfigUrl, { cache: "no-store", headers: { Accept: "application/json" }, }); } catch { throw new BootConfigError("CONFIG_FETCH_FAILED", { buildId: buildConfig.buildId, }); } if (!response.ok) { throw new BootConfigError("CONFIG_HTTP_FAILED", { buildId: buildConfig.buildId, }); } let rawConfig; try { rawConfig = await response.json(); } catch { throw new BootConfigError("CONFIG_JSON_INVALID", { buildId: buildConfig.buildId, }); } if (!rawConfig || typeof rawConfig !== "object" || Array.isArray(rawConfig)) { throw new BootConfigError("CONFIG_SHAPE_INVALID", { buildId: buildConfig.buildId, }); } try { assertSafeConfigNames(rawConfig); } catch { throw new BootConfigError("CONFIG_SECRET_NAME_REJECTED", { buildId: buildConfig.buildId, }); } const validated = validateRuntimeConfig(rawConfig); if (!validated.success) { throw new BootConfigError("CONFIG_SCHEMA_INVALID", { buildId: buildConfig.buildId, configSchemaVersion: typeof rawConfig.CONFIG_SCHEMA_VERSION === "string" ? rawConfig.CONFIG_SCHEMA_VERSION : undefined, releaseId: typeof rawConfig.RELEASE_ID === "string" ? rawConfig.RELEASE_ID : undefined, }); } if (validated.data.BUILD_ID && validated.data.BUILD_ID !== buildConfig.buildId) { throw new BootConfigError("CONFIG_BUILD_MISMATCH", { buildId: buildConfig.buildId, configSchemaVersion: validated.data.CONFIG_SCHEMA_VERSION, releaseId: validated.data.RELEASE_ID, }); } return Object.freeze({ config: validated.data, build: buildConfig, validationDurationMs: now() - startedAt, }); }