UNPKG

zod-config

Version:

Load configuration variables from multiple sources with flexible adapters, ensuring type safety with Zod.

126 lines (123 loc) 3.21 kB
import * as z3 from 'zod/v3'; import * as z from 'zod/v4/core'; type SchemaConfig = z3.AnyZodObject | z.$ZodType<Record<string, unknown>>; type ZodV4Output<T> = T extends z.$ZodType<any> ? z.infer<T> : never; type InferredDataConfig<S extends SchemaConfig> = S extends z3.ZodType<infer T> ? T : ZodV4Output<S>; type InferredErrorConfig<S extends SchemaConfig> = S extends z3.ZodType<infer T> ? z3.ZodError<T> : S extends z.$ZodType<infer U> ? z.$ZodError<U> : never; type BaseAdapter = { /** * Name of the adapter */ name: string; /** * Separator to use for creating nested objects from flat keys (e.g., "." or "_") * When provided, keys like "database.host" or "database_host" will be converted to { database: { host: value } } * Only top-level keys get split, nested keys are not affected. */ nestingSeparator?: string; } & SharedConfigOptions; /** * Adapter type */ type Adapter<D extends SchemaConfig = SchemaConfig> = BaseAdapter & { /** * Read the config */ read: () => Promise<InferredDataConfig<D>>; }; /** * Synchronous adapter type */ type SyncAdapter<D extends SchemaConfig = SchemaConfig> = BaseAdapter & { /** * Read the config */ read: () => InferredDataConfig<D>; }; type BaseConfig<S extends SchemaConfig = SchemaConfig> = { /** * Schema to validate the config against */ schema: S; /** * Function to call on success */ onSuccess?: (data: InferredDataConfig<S>) => void; /** * Function to call on error */ onError?: (error: InferredErrorConfig<S>) => void; /** * Logger to use */ logger?: Logger; } & SharedConfigOptions; /** * Config type */ type Config<S extends SchemaConfig = SchemaConfig> = BaseConfig<S> & { /** * Adapters to use */ adapters?: Array<Adapter | SyncAdapter> | Adapter | SyncAdapter; }; /** * Synchronous config type */ type SyncConfig<S extends SchemaConfig = SchemaConfig> = BaseConfig<S> & { /** * Adapters to use */ adapters?: Array<SyncAdapter> | SyncAdapter; }; /** * Logger type */ type Logger = { /** * Log a warning */ warn: (message: string) => void; }; /** * Base adapter props */ type BaseAdapterProps = { /** * Regular expression to match keys to be processed. */ regex?: RegExp; } & SharedConfigOptions; /** * Shared config options between global config and adapter config */ type SharedConfigOptions = { /** * Whether to suppress errors */ silent?: boolean; /** * How to handle casing differences. */ keyMatching?: KeyMatching; /** * Function to transform key-value pairs before processing. * If the function returns false, the key-value pair will be dropped. */ transform?: Transform; }; /** * Transform type */ type Transform = (obj: { key: string; value: unknown; }) => { key: string; value: unknown; } | false; /** * Key matching type */ type KeyMatching = "lenient" | "strict"; export { Adapter as A, BaseAdapterProps as B, Config as C, InferredDataConfig as I, Logger as L, SchemaConfig as S, SyncConfig as a, SyncAdapter as b };