nx-config2
Version:
Next-generation configuration management for Node.js - Zero dependencies, TypeScript-first, production-ready
350 lines • 12 kB
TypeScript
/**
* nxconfig - Next-generation configuration management for Node.js
*
* Smart multi-config support with merge strategies and named configs
*
* @license MIT
* @version 2.0.0
*/
import { EventEmitter } from 'events';
import { RemoteJsonConfig } from 'nx-remote-json';
export type ConfigSource = string | object | {
filePath: string;
};
export type MergeStrategy = 'deep' | 'shallow' | 'override' | 'append';
export interface ParseConfigOptions {
strict?: boolean;
verbose?: boolean;
filePath?: string;
encoding?: BufferEncoding;
dotenvPath?: string;
defaults?: Record<string, any>;
transform?: Record<string, (value: string) => any>;
prefix?: string;
suffix?: string;
descriptions?: Record<string, string>;
createDirectories?: boolean;
commandLineArgs?: boolean;
envSeparator?: string;
heuristicJsonParsing?: boolean;
lenientJson?: boolean;
enableSharedEnv?: boolean;
sharedEnvRequired?: boolean;
warnOnFallback?: boolean | 'error';
}
export interface MultiConfigOptions extends ParseConfigOptions {
sources: ConfigSource[];
mergeStrategy?: MergeStrategy;
keepSeparate?: boolean;
names?: string[];
extends?: string;
priority?: 'first' | 'last';
}
export interface ParseConfigResult<T = any> {
config: T;
resolvedVars: string[];
warnings: string[];
errors: string[];
documentation?: string;
}
export interface MultiConfigResult<T = any> {
config: T;
configs: Record<string, any>;
resolvedVars: string[];
warnings: string[];
errors: string[];
documentation?: string;
}
export interface VerificationResult {
validated: boolean;
missing: string[];
empty: string[];
present: string[];
}
export interface InitConfigOptions extends ParseConfigOptions {
requiredVars?: string[];
validateOnInit?: boolean;
throwOnMissing?: boolean;
schema?: Record<string, SchemaDefinition>;
generateDocs?: boolean;
docsPath?: string;
overrides?: Record<string, any>;
stores?: ConfigStore[];
onResolved?: (config: any) => any;
}
export interface InitConfigResult<T = any> {
config: T;
validation: VerificationResult;
resolvedVars: string[];
warnings: string[];
documentation?: string | undefined;
}
export interface RemoteConfigOptions extends Omit<InitConfigOptions, 'stores'> {
remoteJsonConfig: RemoteJsonConfig;
mode: string;
jsonRouter: string;
jsonKey: string;
}
export interface SchemaDefinition {
type: 'string' | 'number' | 'boolean' | 'json' | 'array' | 'url' | 'email' | 'port' | 'bigint' | 'regex' | 'duration' | 'timestamp' | 'ipaddress' | 'nat' | 'int' | 'bytes';
required?: boolean;
default?: any;
enum?: any[];
min?: number;
max?: number;
pattern?: RegExp;
transform?: (value: string) => any;
description?: string;
doc?: string;
isDirectory?: boolean;
isFile?: boolean;
sensitive?: boolean;
nullable?: boolean;
arg?: string;
env?: string;
format?: string | ((value: any) => boolean);
}
export interface ConfigStore {
name: string;
type: 'literal' | 'file' | 'memory' | 'env' | 'argv';
data?: any;
filePath?: string;
secure?: boolean;
secret?: string;
}
export interface WatchConfigOptions {
interval?: number;
onChange?: (newConfig: any) => void;
onError?: (error: Error) => void;
}
export interface ConfigHierarchy {
set(key: string, value: any): void;
get(key: string): any;
has(key: string): boolean;
reset(key: string): void;
load(data: any): void;
save(callback?: (err?: Error) => void): void;
merge(data: any): void;
}
export declare class ConfigParseError extends Error {
variableName?: string | undefined;
path?: string | undefined;
filePath?: string | undefined;
constructor(message: string, variableName?: string | undefined, path?: string | undefined, filePath?: string | undefined);
}
export declare class ConfigValidationError extends Error {
missingVars: string[];
emptyVars: string[];
constructor(message: string, missingVars: string[], emptyVars: string[]);
}
export declare class ConfigFileError extends Error {
filePath: string;
originalError?: Error | undefined;
constructor(message: string, filePath: string, originalError?: Error | undefined);
}
export declare class ConfigSchemaError extends Error {
field: string;
expectedType: string;
constructor(message: string, field: string, expectedType: string);
}
export declare class ConfigMergeError extends Error {
sources: string[];
constructor(message: string, sources: string[]);
}
export interface EnvVariableInfo {
varName: string;
length: number;
synthesizedValue: string;
}
export declare function getEnvVariables(envPath?: string): EnvVariableInfo[];
export declare function extractEnvTokens(config: any): string[];
export declare function maskSecrets(config: any, path?: string, schema?: Record<string, SchemaDefinition>): any;
export declare function validateRequiredEnvVars(variableNames: string[]): VerificationResult;
declare function deepMerge(target: any, ...sources: any[]): any;
declare function shallowMerge(target: any, ...sources: any[]): any;
declare function mergeConfigs(configs: any[], strategy?: MergeStrategy): any;
declare function loadDotenv(dotenvPath?: string, enableSharedEnv?: boolean, verbose?: boolean): Record<string, string>;
export declare function generateDocumentation(_config: any, resolvedVars: string[], descriptions?: Record<string, string>, schema?: Record<string, SchemaDefinition>): string;
export declare class ConfigurationHierarchy implements ConfigHierarchy {
private stores;
private data;
constructor();
set(key: string, value: any, separator?: string): void;
get(key: string, separator?: string): any;
has(key: string, separator?: string): boolean;
reset(key: string, separator?: string): void;
load(data: any): void;
merge(data: any): void;
save(callback?: (err?: Error) => void): void;
toObject(): any;
toString(): string;
}
export declare function parseConfig<T = any>(config: ConfigSource, options?: ParseConfigOptions): ParseConfigResult<T>;
export declare function parseMultiConfig<T = any>(options: MultiConfigOptions): MultiConfigResult<T>;
export declare function verify(variableNames: string[]): VerificationResult;
export declare function initConfig<T = any>(config: ConfigSource, options?: InitConfigOptions): InitConfigResult<T>;
/**
* Initialize configuration from a remote JSON source using nx-remote-json.
*
* This function fetches configuration from a remote backend (disk, S3, or MongoDB)
* and then processes it through the standard initConfig pipeline.
*
* @param options Configuration options including remote JSON client config
* @returns Initialized configuration result
*
* @example
* ```typescript
* const result = await remoteConfig({
* remoteJsonConfig: {
* disk: {
* rootLocation: "/data/configs",
* mapping: [{ jsonRouter: "app", folder: "app-configs" }]
* }
* },
* mode: "disk",
* jsonRouter: "app",
* jsonKey: "production"
* });
* ```
*
* @example
* ```typescript
* // Using environment variables for route and key
* const result = await remoteConfig({
* remoteJsonConfig: {
* storage: {
* region: "us-east-1",
* endpoint: "https://s3.amazonaws.com",
* bucket: "my-bucket",
* accessKey: "ACCESS_KEY",
* secretKey: "SECRET_KEY",
* mapping: [{ jsonRouter: "config", folder: "configs" }]
* }
* },
* mode: "storage",
* jsonRouter: "ENV.CONFIG_ROUTER", // Resolved from process.env.CONFIG_ROUTER
* jsonKey: "ENV.CONFIG_KEY" // Resolved from process.env.CONFIG_KEY
* });
* ```
*/
export declare function remoteConfig<T = any>(options: RemoteConfigOptions): Promise<InitConfigResult<T>>;
export declare function createConfig<T = any>(schema: Record<string, SchemaDefinition>): {
get: (key: string) => any;
has: (key: string) => boolean;
getProperties: () => T;
validate: () => void;
toString: () => string;
};
export interface AutoLoadConfigOptions extends ParseConfigOptions {
dotenvPath?: string;
includeAllEnvVars?: boolean;
beautify?: boolean;
}
/**
* Automatically load configuration from environment variables.
*
* Uses a default config map with common patterns, then automatically
* adds any additional environment variables as camelCase properties at the root.
*
* @param options Configuration options
* @returns Parsed configuration object with all env vars
*/
export declare function autoLoadConfig<T = any>(options?: AutoLoadConfigOptions): T;
/**
* Shared .env file information
*/
export interface SharedEnvInfo {
localFile: string;
sharedFiles: Array<{
path: string;
name?: string;
required: boolean;
exists: boolean;
variableCount: number;
}>;
totalVariables: number;
variablesBySource: Record<string, string[]>;
}
/**
* Variable source information
*/
export interface VariableSource {
value: string;
source: string;
priority: number;
overridden: boolean;
}
/**
* Get information about shared .env files
*/
export declare function inspectSharedEnvFiles(dotenvPath?: string): SharedEnvInfo;
/**
* Track which file provides each variable (useful for debugging)
*/
export declare function getVariableSourceMap(dotenvPath?: string): Record<string, VariableSource>;
export interface ConfigWatcher extends EventEmitter {
stop(): void;
on(event: 'change', listener: (newConfig: any) => void): this;
on(event: 'error', listener: (error: Error) => void): this;
once(event: 'change', listener: (newConfig: any) => void): this;
once(event: 'error', listener: (error: Error) => void): this;
emit(event: 'change', newConfig: any): boolean;
emit(event: 'error', error: Error): boolean;
}
/**
* Watch a configuration source for changes and emit events when changes occur.
*
* @param configSource - Configuration source to watch (file path or object)
* @param options - Watch configuration options
* @returns ConfigWatcher instance with EventEmitter interface
*
* @example
* ```typescript
* const watcher = watchConfig('./config.json', {
* interval: 1000,
* onChange: (newConfig) => console.log('Config changed:', newConfig)
* });
*
* // Using event emitter
* watcher.on('change', (newConfig) => {
* console.log('Config updated:', newConfig);
* });
*
* watcher.on('error', (error) => {
* console.error('Watch error:', error);
* });
*
* // Stop watching
* watcher.stop();
* ```
*/
export declare function watchConfig(configSource: ConfigSource, options?: WatchConfigOptions): ConfigWatcher;
declare const _default: {
parseConfig: typeof parseConfig;
verify: typeof verify;
initConfig: typeof initConfig;
remoteConfig: typeof remoteConfig;
parseMultiConfig: typeof parseMultiConfig;
watchConfig: typeof watchConfig;
createConfig: typeof createConfig;
autoLoadConfig: typeof autoLoadConfig;
extractEnvTokens: typeof extractEnvTokens;
maskSecrets: typeof maskSecrets;
validateRequiredEnvVars: typeof validateRequiredEnvVars;
loadDotenv: typeof loadDotenv;
generateDocumentation: typeof generateDocumentation;
getEnvVariables: typeof getEnvVariables;
inspectSharedEnvFiles: typeof inspectSharedEnvFiles;
getVariableSourceMap: typeof getVariableSourceMap;
deepMerge: typeof deepMerge;
shallowMerge: typeof shallowMerge;
mergeConfigs: typeof mergeConfigs;
ConfigurationHierarchy: typeof ConfigurationHierarchy;
ConfigParseError: typeof ConfigParseError;
ConfigValidationError: typeof ConfigValidationError;
ConfigFileError: typeof ConfigFileError;
ConfigSchemaError: typeof ConfigSchemaError;
ConfigMergeError: typeof ConfigMergeError;
};
export default _default;
//# sourceMappingURL=index.backup.d.ts.map