/** * Typed env-coercion + JSON-layering toolkit shared by every adapter config * loader. Each adapter previously hand-rolled near-identical * readBoolean/readInteger/normalizeOptionalString/set* helpers plus a * `layerJsonOntoEnv` merge; these helpers collapse that boilerplate while * keeping each adapter's own typed error via an injected error factory, so * fail-closed messages stay under the adapter's control. */ import type { SettingsJson } from "./types.js"; /** * Builds an adapter-specific typed error. Callers bind the error code so a * single helper can raise `invalid_config`, `missing_required_config`, etc. */ export type ConfigErrorFactory = (message: string, details?: Record) => Error; /** Trim a raw value and treat empty strings as absent. */ export declare function normalizeOptionalString(value: string | undefined): string | undefined; /** Read a string with a default when unset/blank. */ export declare function readString(raw: string | undefined, defaultValue: string): string; /** * Read a required string, raising the caller's typed error when absent. The * `${name} is required.` message is passed to the factory (callers that build * their own message can ignore it); `{ env: name }` is always in the details. */ export declare function readRequired(raw: string | undefined, name: string, onMissing: ConfigErrorFactory): string; /** Split a comma-separated value into trimmed, non-empty entries. */ export declare function readCsv(raw: string | undefined): string[]; /** Coerce "true"/"false" to a boolean, raising the caller's error otherwise. */ export declare function readBoolean(raw: string | undefined, name: string, defaultValue: boolean, onInvalid: ConfigErrorFactory): boolean; /** Coerce a non-negative integer within optional bounds. */ export declare function readInteger(raw: string | undefined, name: string, defaultValue: number, onInvalid: ConfigErrorFactory, bounds?: { readonly min: number; readonly max: number; }): number; /** Coerce a value to one of a closed set of string choices. */ export declare function readChoice(raw: string | undefined, name: string, choices: readonly T[], defaultValue: T, onInvalid: ConfigErrorFactory): T; /** Narrow an unknown JSON value to a plain record (never null/array). */ export declare function readRecord(value: unknown): Record; /** How a JSON value is encoded into the string env layer. */ export type EnvEncodeKind = "string" | "boolean" | "integer" | "csv"; export interface JsonEnvMapping { readonly env: string; readonly value: unknown; readonly kind?: EnvEncodeKind; } /** * One config field in an adapter's exported field registry: the JSON→env * layering facts (id + env + kind) plus the metadata provenance/secret surfaces * need. The registry is the single source of truth — the adapter's layer * function and the app's config view both derive from it, so the two can never * drift apart. */ export interface JsonEnvFieldSpec { /** Stable dotted field id mirroring the JSON path, e.g. `channel.botToken`. */ readonly id: string; readonly env: string; readonly kind?: EnvEncodeKind; /** True for credential fields: views redact the value and flag JSON placement. */ readonly secret?: boolean; /** Extract the field's raw value from the channel's JSON section. */ readonly fromJson: (section: Record) => unknown; } /** Build the {@link layerJsonOntoEnv} mappings from a field registry. */ export declare function fieldSpecMappings(section: Record, fields: readonly JsonEnvFieldSpec[]): readonly JsonEnvMapping[]; /** * Encode a JSON value exactly the way {@link layerJsonOntoEnv} would * (`undefined` = absent or wrong type, i.e. the loader would fall through to * the real env or the default). Exposed so provenance views resolve a field's * source with the loader's own semantics. */ export declare function encodeJsonEnvValue(value: unknown, kind?: EnvEncodeKind): string | undefined; /** * Encode a JSON config section into the string env shape, then overlay the real * process env so explicit env vars always win over JSON defaults. This replaces * each adapter's bespoke `layerJsonOntoEnv` + `set*` helpers. */ export declare function layerJsonOntoEnv(env: Record, mappings: readonly JsonEnvMapping[]): Record; /** Read a named object section from a settings JSON document. */ export declare function readJsonSection(json: SettingsJson, key: string): Record; /** * Canonical redacted-secret marker for adapter `redactConfig` helpers, so * each adapter stops inlining its own `{ present, redacted: true }` shape. This * is the diagnostics/redaction shape (distinct from the field-group-driven * {@link import("./redact.js").RedactedSecret} consumed by operator surfaces). */ export interface RedactedSecretValue { readonly present: boolean; readonly redacted: true; } /** Build a {@link RedactedSecretValue} from a (possibly absent) secret string. */ export declare function redactedSecret(value: string | undefined): RedactedSecretValue; //# sourceMappingURL=config-loader.d.ts.map