import { MemoizeOptions } from '../flow-control/index.ts'; import type { PathLeaves, PathValue } from '../types.ts'; /** * Coerces string values in an object to their appropriate types. * Converts "true"/"false" to booleans, numeric strings to numbers, etc. * Recursively processes nested objects. * * IMPORTANT: This function mutates the input object in place. * * INTENTION: This is a best-effort coercion based on common string patterns. * It does not handle all edge cases and should be used with caution. The goal * is to convert typical string representations of booleans and numbers to their * actual types, while leaving other strings unchanged. * * USE CASE: Parsing environment variables or other flatmap configuration objects. * * @param obj The object whose values should be coerced (mutated in place). * @param opts Optional configuration options * @param opts.parseUnits Optional flag to parse unit values like '5m', '10mb'. Default is false. * @param opts.skipConversion Optional function to skip conversion for specific keys. Default is to convert all keys. * * @example * const config = { * debug: 'true', * port: '3000', * nested: { * enabled: 'false', * retries: '5' * } * }; * * castValuesToTypes(config); * * console.log(config); * // { * // debug: true, * // port: 3000, * // nested: { * // enabled: false, * // retries: 5 * // } * // } * * @example * const config = { * timeout: '5m', * maxUploadSize: '10mb', * debug: 'true' * }; * * castValuesToTypes(config, { parseUnits: true }); * * console.log(config); * // { * // timeout: 300000, // 5 minutes in milliseconds * // maxUploadSize: 10485760, // 10 megabytes in bytes * // debug: true * // } * * @example * const config = { * apiKey: '12345', * port: '3000' * }; * * // Skip conversion for apiKey (keep it as string) * castValuesToTypes(config, { * skipConversion: (key) => key.toLowerCase().includes('key') * }); * * console.log(config); * // { * // apiKey: '12345', // Kept as string * // port: 3000 // Converted to number * // } */ export declare const castValuesToTypes: (obj: object, opts?: { parseUnits?: boolean; skipConversion?: ((key: string, value: unknown) => boolean) | undefined; }) => void; export type MakeNestedConfigOpts = { filter?: (key: string, value: string) => boolean; skipConversion?: (key: string, value: unknown) => boolean; separator?: string; stripPrefix?: string | number; forceAllCapToLower?: boolean; parseUnits?: boolean; memoizeOpts?: false | MemoizeOptions; }; /** * Loads the flatmap variables and returns a config object. * Coerces values to the correct types based on guessing from * the value itself. For example, if the value is "true", it will be * converted to a boolean true, if it's "123", it will be converted * to a number 123, etc. * * @param flatConfig The flatmap configuration object (e.g. process.env) * @param opts Optional options object * @param opts.filter Optional filter function to include/exclude specific keys. Default is to include all keys. * @param opts.forceAllCapToLower Optional flag to force all-caps keys to lowercase. Default is true. * @param opts.separator Optional string to use as a separator for nested keys. Default is "_" * @param opts.stripPrefix Optional prefix to strip from keys. Can be a string (e.g., "APP_") or number of characters (e.g., 4). Default is undefined (no stripping). * @param opts.parseUnits Optional flag to parse unit values like '5m', '10mb'. Default is false. * @param opts.skipConversion Optional function to skip conversion for specific keys. Default is to convert all keys. * @param opts.memoizeOpts Optional memoization options for caching the config. Default is false (no memoization). * * @returns The full configuration object. * * @example * // Assuming process.env contains: * // { * // APP_DB_HOST: 'localhost', * // APP_DB_PORT: '5432', * // APP_DEBUG: 'true', * // APP_FEATURE_X_ENABLED: 'false' * // APP_WORKER_EMAILS_maxRunsPerMin: '100' * // APP_WORKER_EMAILS_networkTimeoutMs: '100' * // } * * const config = makeNestedConfig(process.env, { * filter: (key) => key.startsWith('APP_'), * stripPrefix: 'APP_', // Strip the APP_ prefix from all keys * forceAllCapToLower: true, * separator: '_', * memoizeOpts: { ttl: 60000 } // Cache for 60 seconds * }); * * console.log(config()); * // { * // db: { * // host: 'localhost', * // port: 5432 * // }, * // debug: true, * // feature: { * // x: { * // enabled: false * // } * // }, * // worker: { * // emails: { * // maxRunsPerMin: 100, * // networkTimeoutMs: 100 * // } * // } * // } * * @example * // Using a custom separator * // Assuming process.env contains: * // { * // APP_DB__HOST: 'localhost', * // APP_DB__PORT: '5432', * // APP_DEBUG: 'true', * // APP_FEATURE__X_ENABLED: 'false', * // APP_WORKER__EMAILS__maxRunsPerMin: '100' * // APP_WORKER__EMAILS__networkTimeoutMs: '100' * // } * const config = makeNestedConfig(process.env, { * filter: (key) => key.startsWith('APP_'), * stripPrefix: 'APP_', // Strip the APP_ prefix * forceAllCapToLower: true, * separator: '__' * }); * * console.log(config()); * // { * // db: { * // host: 'localhost', * // port: 5432 * // }, * // debug: true, * // feature: { * // x_enabled: false * // }, * // worker: { * // emails: { * // maxRunsPerMin: 100, * // networkTimeoutMs: 100 * // } * // } * // } * * @example * * // Not forcing all-caps to lowercase * // Assuming process.env contains: * // { * // APP_DB_HOST: 'localhost', * // APP_DB_PORT: '5432', * // APP_DEBUG: 'true', * // APP_FEATURE_X_ENABLED: 'false' * // APP_WORKER_EMAILS_maxRunsPerMin: '100' * // APP_WORKER_EMAILS_networkTimeoutMs: '100' * // } * * const config = makeNestedConfig(process.env, { * filter: (key) => key.startsWith('APP_'), * stripPrefix: 'APP_', // Strip the APP_ prefix * forceAllCapToLower: false, * separator: '_' * }); * * console.log(config()); * // { * // DB: { * // HOST: 'localhost', * // PORT: 5432 * // }, * // DEBUG: true, * // FEATURE: { * // X_ENABLED: false * // }, * // WORKER: { * // EMAILS: { * // maxRunsPerMin: 100, * // networkTimeoutMs: 100 * // } * // } * // } * * @example * // Using parseUnits to convert time and byte values * // Assuming process.env contains: * // { * // APP_SESSION_TIMEOUT: '15m', * // APP_CACHE_TTL: '1hour', * // APP_MAX_UPLOAD_SIZE: '10mb', * // APP_DISK_QUOTA: '100gb' * // } * * const config = makeNestedConfig(process.env, { * filter: (key) => key.startsWith('APP_'), * stripPrefix: 'APP_', * parseUnits: true // Enable unit parsing * }); * * console.log(config()); * // { * // session: { * // timeout: 900000 // 15 minutes in milliseconds * // }, * // cache: { * // ttl: 3600000 // 1 hour in milliseconds * // }, * // max: { * // upload: { * // size: 10485760 // 10 megabytes in bytes * // } * // }, * // disk: { * // quota: 107374182400 // 100 gigabytes in bytes * // } * // } * * @example * // Using skipConversion to keep certain values as strings * // Assuming process.env contains: * // { * // APP_API_KEY: '12345', * // APP_SECRET_TOKEN: '67890', * // APP_PORT: '3000', * // APP_DEBUG: 'true' * // } * * const config = makeNestedConfig(process.env, { * filter: (key) => key.startsWith('APP_'), * stripPrefix: 'APP_', * skipConversion: (key) => key.toLowerCase().includes('key') || key.toLowerCase().includes('token') * }); * * console.log(config()); * // { * // api: { * // key: '12345' // Kept as string * // }, * // secret: { * // token: '67890' // Kept as string * // }, * // port: 3000, // Converted to number * // debug: true // Converted to boolean * // } * */ export declare const makeNestedConfig: , F = Record>(_flatConfig: F, opts?: MakeNestedConfigOpts) => { allConfigs: () => C; getConfig:

, D extends PathValue>(path: P, defaultValue?: D) => PathValue; };