UNPKG

@qlover/env-loader

Version:

A package for managing environment variables

1,510 lines (1,503 loc) 42.6 kB
/** * Represents a log event in the logging system * * This class encapsulates all information about a single log event, * including the log level, message arguments, timestamp, logger name, * and optional typed context data. * * Core features: * - Automatic timestamp generation * - Type-safe context support * - Flexible argument handling * - Logger identification * * @typeParam Ctx - Type of the context value, defaults to unknown * * @example Basic usage * ```typescript * const event = new LogEvent( * 'info', * ['Application started'], * 'app' * ); * // event.timestamp is automatically set * console.log(event); * ``` * * @example With context * ```typescript * interface RequestContext { * requestId: string; * userId: string; * path: string; * } * * const event = new LogEvent<RequestContext>( * 'info', * ['Request processed', { duration: 150 }], * 'http', * new LogContext({ * requestId: 'req-123', * userId: 'user-456', * path: '/api/users' * }) * ); * ``` * * @example Error event * ```typescript * const error = new Error('Database connection failed'); * const event = new LogEvent( * 'error', * [ * 'Failed to connect to database', * { * error: error.message, * stack: error.stack, * code: 'DB_CONN_ERROR' * } * ], * 'database' * ); * ``` * * @example Performance monitoring * ```typescript * interface PerformanceContext { * operation: string; * startTime: number; * endTime: number; * metadata: Record<string, unknown>; * } * * const event = new LogEvent<PerformanceContext>( * 'debug', * ['Operation completed'], * 'performance', * new LogContext({ * operation: 'data-processing', * startTime: 1679395845000, * endTime: 1679395846000, * metadata: { * itemsProcessed: 1000, * batchSize: 100, * cacheHits: 850 * } * }) * ); * ``` */ declare class LogEvent<Ctx = unknown> { /** * Log level indicating the severity or importance * * Common values: * - 'fatal': System is unusable * - 'error': Error conditions * - 'warn': Warning conditions * - 'info': Informational messages * - 'debug': Debug-level messages * - 'trace': Trace-level messages * * @example * ```typescript * new LogEvent('error', ['Database connection failed'], 'db'); * ``` */ level: string; /** * Array of log message arguments * * The first argument is typically the main message string, * followed by optional data objects, error instances, or * other relevant information. * * @example * ```typescript * // Simple message * new LogEvent('info', ['User logged in'], 'auth'); * * // Message with data * new LogEvent('info', [ * 'User logged in', * { userId: 123, role: 'admin' } * ], 'auth'); * * // Error with details * new LogEvent('error', [ * 'Operation failed', * new Error('Invalid input'), * { operation: 'validate', input: data } * ], 'validator'); * ``` */ args: unknown[]; /** * Name of the logger that created this event * * Used to identify the source or category of the log event. * This can be a module name, service name, or any other * identifier that helps categorize log events. * * @example * ```typescript * // Module-based names * new LogEvent('info', ['Starting'], 'auth.service'); * new LogEvent('debug', ['Cache miss'], 'data.cache'); * * // Component-based names * new LogEvent('info', ['Render complete'], 'ui.dashboard'); * new LogEvent('error', ['API error'], 'api.users'); * ``` */ loggerName: string; /** * Optional typed context data for the log event * * Provides additional structured data that can be used by * formatters and handlers. The context type is controlled * by the Ctx type parameter. * * @example * ```typescript * // Request context * interface RequestContext { * requestId: string; * path: string; * method: string; * } * * new LogEvent<RequestContext>( * 'info', * ['Request received'], * 'http', * new LogContext({ * requestId: 'req-123', * path: '/api/users', * method: 'GET' * }) * ); * * // Performance context * interface PerfContext { * duration: number; * memoryUsage: number; * } * * new LogEvent<PerfContext>( * 'debug', * ['Operation completed'], * 'perf', * new LogContext({ * duration: 150, * memoryUsage: process.memoryUsage().heapUsed * }) * ); * ``` */ context?: Ctx | undefined; /** * Timestamp when the log event was created * * Automatically set to the current time in milliseconds since the Unix epoch * when the event is constructed. This ensures accurate timing information * for each log entry. * * @example * ```typescript * const event = new LogEvent('info', ['message'], 'app'); * console.log(new Date(event.timestamp).toISOString()); * // Output: "2024-03-21T14:30:45.123Z" * ``` */ timestamp: number; constructor( /** * Log level indicating the severity or importance * * Common values: * - 'fatal': System is unusable * - 'error': Error conditions * - 'warn': Warning conditions * - 'info': Informational messages * - 'debug': Debug-level messages * - 'trace': Trace-level messages * * @example * ```typescript * new LogEvent('error', ['Database connection failed'], 'db'); * ``` */ level: string, /** * Array of log message arguments * * The first argument is typically the main message string, * followed by optional data objects, error instances, or * other relevant information. * * @example * ```typescript * // Simple message * new LogEvent('info', ['User logged in'], 'auth'); * * // Message with data * new LogEvent('info', [ * 'User logged in', * { userId: 123, role: 'admin' } * ], 'auth'); * * // Error with details * new LogEvent('error', [ * 'Operation failed', * new Error('Invalid input'), * { operation: 'validate', input: data } * ], 'validator'); * ``` */ args: unknown[], /** * Name of the logger that created this event * * Used to identify the source or category of the log event. * This can be a module name, service name, or any other * identifier that helps categorize log events. * * @example * ```typescript * // Module-based names * new LogEvent('info', ['Starting'], 'auth.service'); * new LogEvent('debug', ['Cache miss'], 'data.cache'); * * // Component-based names * new LogEvent('info', ['Render complete'], 'ui.dashboard'); * new LogEvent('error', ['API error'], 'api.users'); * ``` */ loggerName: string, /** * Optional typed context data for the log event * * Provides additional structured data that can be used by * formatters and handlers. The context type is controlled * by the Ctx type parameter. * * @example * ```typescript * // Request context * interface RequestContext { * requestId: string; * path: string; * method: string; * } * * new LogEvent<RequestContext>( * 'info', * ['Request received'], * 'http', * new LogContext({ * requestId: 'req-123', * path: '/api/users', * method: 'GET' * }) * ); * * // Performance context * interface PerfContext { * duration: number; * memoryUsage: number; * } * * new LogEvent<PerfContext>( * 'debug', * ['Operation completed'], * 'perf', * new LogContext({ * duration: 150, * memoryUsage: process.memoryUsage().heapUsed * }) * ); * ``` */ context?: Ctx | undefined); } /** * Interface for log event formatters * * Formatters are responsible for converting log events into specific output * formats. They can transform the event data into strings, objects, or arrays * suitable for the target output medium. * * Core responsibilities: * - Format log events into desired output format * - Support type-safe context handling * - Maintain consistent formatting across log entries * - Handle different log levels appropriately * * @typeParam Ctx - Type of the context value, defaults to unknown * * @example Basic string formatter * ```typescript * class SimpleFormatter implements FormatterInterface { * format(event: LogEvent): string[] { * const timestamp = new Date(event.timestamp).toISOString(); * const level = event.level.toUpperCase(); * const message = event.args.join(' '); * * return [`[${timestamp}] ${level}: ${message}`]; * } * } * ``` * * @example JSON formatter * ```typescript * class JSONFormatter implements FormatterInterface { * format(event: LogEvent): string { * return JSON.stringify({ * timestamp: event.timestamp, * level: event.level, * message: event.args[0], * data: event.args.slice(1), * context: event.context?.value * }); * } * } * ``` * * @example Type-safe context formatter * ```typescript * interface RequestContext { * requestId: string; * userId?: string; * path: string; * method: string; * } * * class RequestFormatter implements FormatterInterface<RequestContext> { * format(event: LogEvent<RequestContext>): string[] { * const ctx = event.context?.value; * const prefix = ctx * ? `[${ctx.method} ${ctx.path}] [${ctx.requestId}]` * : ''; * * return [ * prefix, * event.level.toUpperCase(), * ...event.args * ]; * } * } * ``` * * @example Colored console formatter * ```typescript * class ColoredFormatter implements FormatterInterface { * private colors = { * error: '\x1b[31m', // Red * warn: '\x1b[33m', // Yellow * info: '\x1b[36m', // Cyan * debug: '\x1b[90m', // Gray * reset: '\x1b[0m' // Reset * }; * * format(event: LogEvent): unknown[] { * const color = this.colors[event.level] || this.colors.reset; * const timestamp = new Date(event.timestamp).toISOString(); * * return [ * `${color}[${timestamp}] ${event.level.toUpperCase()}:${this.colors.reset}`, * ...event.args * ]; * } * } * ``` */ interface FormatterInterface<Ctx = unknown> { /** * Formats a log event into the desired output format * * This method transforms a log event into a format suitable for output. * The return value can be: * - A single value (string, object, etc.) * - An array of values (for handlers that support multiple arguments) * * Implementation considerations: * - Handle all log levels consistently * - Process context data appropriately * - Maintain type safety with generic context * - Consider performance for high-volume logging * * @param event - The log event to format * @returns Formatted output as a single value or array of values * * @example String output * ```typescript * format(event: LogEvent): string { * const { timestamp, level, args } = event; * return `[${new Date(timestamp).toISOString()}] ${ * level.toUpperCase() * }: ${args.join(' ')}`; * } * ``` * * @example Array output for console * ```typescript * format(event: LogEvent): unknown[] { * const prefix = `[${event.level.toUpperCase()}]`; * return [prefix, ...event.args]; * } * ``` * * @example Structured output * ```typescript * format(event: LogEvent): object { * return { * '@timestamp': event.timestamp, * level: event.level, * message: event.args[0], * metadata: { * args: event.args.slice(1), * context: event.context?.value * } * }; * } * ``` * * @example Type-safe context handling * ```typescript * interface UserContext { * userId: string; * sessionId: string; * } * * format(event: LogEvent<UserContext>): object { * const ctx = event.context?.value; * return { * timestamp: event.timestamp, * level: event.level, * message: event.args[0], * user: ctx ? { * id: ctx.userId, * session: ctx.sessionId * } : undefined * }; * } * ``` */ format(event: LogEvent<Ctx>): unknown | unknown[]; } /** * Interface for log event handlers (appenders) * * Handlers are responsible for processing and outputting log events to * various destinations (console, file, network, etc.). They can optionally * use formatters to customize the output format. * * Core responsibilities: * - Process log events * - Output logs to specific destinations * - Support optional formatting * - Handle different log levels * * @example Basic console handler * ```typescript * class ConsoleHandler implements HandlerInterface { * private formatter: FormatterInterface | null = null; * * append(event: LogEvent): void { * const args = this.formatter * ? this.formatter.format(event) * : event.args; * * console.log(...args); * } * * setFormatter(formatter: FormatterInterface): void { * this.formatter = formatter; * } * } * ``` * * @example File handler with rotation * ```typescript * class RotatingFileHandler implements HandlerInterface { * constructor( * private filename: string, * private maxSize: number = 10 * 1024 * 1024 * ) {} * * append(event: LogEvent): void { * const message = this.formatter * ? this.formatter.format(event) * : event.args.join(' '); * * if (this.shouldRotate()) { * this.rotate(); * } * fs.appendFileSync(this.filename, message + '\n'); * } * * setFormatter(formatter: FormatterInterface): void { * this.formatter = formatter; * } * * private shouldRotate(): boolean { * return fs.statSync(this.filename).size > this.maxSize; * } * * private rotate(): void { * const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); * fs.renameSync( * this.filename, * `${this.filename}.${timestamp}.backup` * ); * } * } * ``` * * @example Network handler with buffering * ```typescript * class NetworkHandler implements HandlerInterface { * private buffer: LogEvent[] = []; * private timer: NodeJS.Timer | null = null; * * constructor( * private endpoint: string, * private batchSize: number = 100, * private flushInterval: number = 5000 * ) { * this.startTimer(); * } * * append(event: LogEvent): void { * this.buffer.push(event); * if (this.buffer.length >= this.batchSize) { * this.flush(); * } * } * * setFormatter(formatter: FormatterInterface): void { * this.formatter = formatter; * } * * private async flush(): Promise<void> { * if (this.buffer.length === 0) return; * * const events = this.buffer.map(event => ({ * level: event.level, * message: this.formatter * ? this.formatter.format(event) * : event.args.join(' '), * timestamp: event.timestamp * })); * * try { * await fetch(this.endpoint, { * method: 'POST', * body: JSON.stringify(events) * }); * this.buffer = []; * } catch (error) { * console.error('Failed to send logs:', error); * } * } * * private startTimer(): void { * this.timer = setInterval(() => this.flush(), this.flushInterval); * } * } * ``` */ interface HandlerInterface<Ctx = unknown> { /** * Processes and outputs a log event * * This method is called by the logger for each log event that needs * to be processed. The handler can format the event using its formatter * (if set) and output it to its destination. * * Implementation considerations: * - Handle all log levels appropriately * - Apply formatting if a formatter is set * - Handle errors gracefully * - Consider performance implications * * @param event - The log event to process and output * * @example Basic implementation * ```typescript * append(event: LogEvent): void { * const output = this.formatter * ? this.formatter.format(event) * : event.args; * * console.log(...output); * } * ``` * * @example Advanced implementation with error handling * ```typescript * append(event: LogEvent): void { * try { * // Format the event * const formatted = this.formatter * ? this.formatter.format(event) * : event.args; * * // Add timestamp and level * const output = [ * new Date(event.timestamp).toISOString(), * event.level.toUpperCase(), * ...formatted * ]; * * // Write to file * fs.appendFileSync(this.filename, output.join(' ') + '\n'); * } catch (error) { * console.error('Failed to append log:', error); * // Optionally write to fallback location * fs.appendFileSync( * 'error.log', * `Failed to write log: ${error.message}\n` * ); * } * } * ``` * * @example Asynchronous implementation * ```typescript * async append(event: LogEvent): Promise<void> { * // Format the event * const message = this.formatter * ? this.formatter.format(event) * : event.args.join(' '); * * // Prepare log entry * const entry = { * timestamp: event.timestamp, * level: event.level, * message, * metadata: event.context?.value * }; * * try { * // Send to logging service * await fetch('https://logging.example.com/ingest', { * method: 'POST', * headers: { 'Content-Type': 'application/json' }, * body: JSON.stringify(entry) * }); * } catch (error) { * // Handle failure * console.error('Failed to send log:', error); * // Add to retry queue * this.retryQueue.push(entry); * } * } * ``` */ append(event: LogEvent<Ctx>): void; /** * Sets or updates the formatter for this handler * * The formatter is responsible for converting log events into * the desired output format. This method allows changing the * formatter at runtime. * * Implementation considerations: * - Handle null formatters gracefully * - Consider thread safety in async environments * - Clean up old formatter resources if necessary * * @param formatter - The formatter instance to use * * @example Basic implementation * ```typescript * setFormatter(formatter: FormatterInterface): void { * this.formatter = formatter; * } * ``` * * @example Implementation with cleanup * ```typescript * setFormatter(formatter: FormatterInterface): void { * if (this.formatter && 'dispose' in this.formatter) { * // Clean up old formatter resources * this.formatter.dispose(); * } * this.formatter = formatter; * } * ``` * * @example Thread-safe implementation * ```typescript * setFormatter(formatter: FormatterInterface): void { * // Ensure atomic formatter update * this.lock.acquire(); * try { * const oldFormatter = this.formatter; * this.formatter = formatter; * * // Flush any pending logs with old formatter * if (oldFormatter) { * this.flushBuffer(oldFormatter); * } * } finally { * this.lock.release(); * } * } * ``` */ setFormatter(formatter: FormatterInterface): void; } /** * Type-safe container for log event context data * * This class provides a generic wrapper for additional context data * that can be attached to log events. It ensures type safety through * its generic type parameter and provides a consistent structure for * context handling. * * Core features: * - Generic type support * - Optional value handling * - Immutable context data * - Type-safe access * * @typeParam Value - Type of the context value * * @example Basic usage * ```typescript * // Simple context * const context = new LogContext({ userId: 123 }); * logger.info('User action', context); * ``` * * @example Type-safe context * ```typescript * interface RequestContext { * requestId: string; * path: string; * method: string; * userId?: string; * } * * const context = new LogContext<RequestContext>({ * requestId: 'req-123', * path: '/api/users', * method: 'GET' * }); * * logger.info('Request received', context); * ``` * * @example Optional context * ```typescript * // Empty context * const emptyContext = new LogContext(); * * // Context with undefined value * const context = new LogContext<string | undefined>(undefined); * * // Context with null value * const nullContext = new LogContext<string | null>(null); * ``` * * @example Complex context * ```typescript * interface PerformanceContext { * operation: string; * metrics: { * duration: number; * memory: { * before: number; * after: number; * }; * cpu: { * user: number; * system: number; * }; * }; * metadata: Record<string, unknown>; * } * * const context = new LogContext<PerformanceContext>({ * operation: 'data-processing', * metrics: { * duration: 1500, * memory: { * before: 100000, * after: 150000 * }, * cpu: { * user: 80, * system: 20 * } * }, * metadata: { * batchSize: 1000, * compression: true, * priority: 'high' * } * }); * * logger.debug('Operation metrics', context); * ``` * * @example Context in formatters * ```typescript * class DetailedFormatter implements FormatterInterface<RequestContext> { * format(event: LogEvent<RequestContext>): string[] { * const ctx = event.context?.value; * if (ctx) { * return [ * `[${ctx.method} ${ctx.path}]`, * `[${ctx.requestId}]`, * ...event.args * ]; * } * return event.args; * } * } * ``` */ declare class LogContext<Value> { /** * The context value that will be attached to log events * * This value is typed according to the Value type parameter * and can be accessed safely through optional chaining. */ value?: Value | undefined; /** * Creates a new LogContext instance * * @param value - Optional context value of type Value * * The value parameter is marked as optional to support: * - Empty contexts (no value provided) * - Explicitly undefined values * - Nullable types (Value | null) * * The value is stored as a public property to allow: * - Direct access in formatters and handlers * - Type-safe value extraction * - Optional chaining support * * @example Basic construction * ```typescript * // With value * const context = new LogContext({ userId: 123 }); * console.log(context.value?.userId); // 123 * * // Empty context * const empty = new LogContext(); * console.log(empty.value); // undefined * ``` * * @example Type-safe construction * ```typescript * interface UserContext { * id: number; * name: string; * role?: string; * } * * const context = new LogContext<UserContext>({ * id: 123, * name: 'John', * role: 'admin' // Optional property * }); * * // Type-safe access * const userId = context.value?.id; // number | undefined * const role = context.value?.role; // string | undefined * ``` * * @example Nullable context * ```typescript * type NullableContext = { * sessionId: string; * } | null; * * // With value * const active = new LogContext<NullableContext>({ * sessionId: 'sess-123' * }); * * // With null * const inactive = new LogContext<NullableContext>(null); * * // Type-safe null handling * console.log(active.value?.sessionId); // 'sess-123' * console.log(inactive.value?.sessionId); // undefined * ``` * * @example Context in logging * ```typescript * interface RequestContext { * path: string; * method: string; * duration: number; * } * * const context = new LogContext<RequestContext>({ * path: '/api/users', * method: 'GET', * duration: 150 * }); * * // Using context in log messages * logger.info('Request completed', context); * * // Accessing context in formatters * class RequestFormatter implements FormatterInterface<RequestContext> { * format(event: LogEvent<RequestContext>): string[] { * const ctx = event.context?.value; * return [ * ctx ? `${ctx.method} ${ctx.path} (${ctx.duration}ms)` : 'Unknown', * ...event.args * ]; * } * } * ``` */ constructor( /** * The context value that will be attached to log events * * This value is typed according to the Value type parameter * and can be accessed safely through optional chaining. */ value?: Value | undefined); } /** * Core interface for logger implementations * * This interface defines the standard contract for logger implementations, * providing methods for different log levels, handler management, and * context creation. * * Core functionality: * - Standard log level methods (fatal, error, warn, info, debug, trace) * - Handler (appender) management * - Context creation for structured logging * - Type-safe logging with generic context support * * @example Basic usage * ```typescript * class MyLogger implements LoggerInterface { * info(...args: unknown[]): void { * console.log('[INFO]', ...args); * } * // ... implement other methods * } * * const logger = new MyLogger(); * logger.info('Application started'); * ``` * * @example With handlers and context * ```typescript * class AdvancedLogger implements LoggerInterface { * private handlers: HandlerInterface[] = []; * * addAppender(handler: HandlerInterface): void { * this.handlers.push(handler); * } * * info(...args: unknown[]): void { * const event = { * level: 'info', * args, * timestamp: Date.now() * }; * * this.handlers.forEach(handler => handler.append(event)); * } * * context<T>(value?: T): LogContext<T> { * return new LogContext(value); * } * // ... implement other methods * } * * const logger = new AdvancedLogger(); * logger.addAppender(new ConsoleHandler()); * logger.info('User logged in', logger.context({ userId: 123 })); * ``` * * @example Type-safe context usage * ```typescript * interface UserContext { * userId: number; * username: string; * role: string; * } * * const logger: LoggerInterface = new Logger(); * * // Type-safe context * logger.info('User action', logger.context<UserContext>({ * userId: 123, * username: 'john_doe', * role: 'admin' * })); * ``` */ interface LoggerInterface<Ctx = unknown> { /** * General purpose logging method (alias for info) * * @param args - Message content followed by optional context * * @example * ```typescript * logger.log('Application started'); * logger.log('User action', { userId: 123 }); * logger.log('Process completed', logger.context({ duration: 1500 })); * ``` */ log(...args: unknown[]): void; /** * Logs a critical error that causes application termination * * Use for severe errors that: * - Cause immediate application shutdown * - Require immediate administrator attention * - Indicate system is unusable * * @param args - Message content followed by optional context * * @example * ```typescript * logger.fatal('Database connection permanently lost'); * logger.fatal('Out of memory', { memoryUsage: process.memoryUsage() }); * logger.fatal('System crash', logger.context({ * error: new Error('Unrecoverable error'), * state: 'corrupted' * })); * ``` */ fatal(...args: unknown[]): void; /** * Logs an error condition that doesn't cause termination * * Use for errors that: * - Prevent normal operation but allow recovery * - Require administrator attention * - Need to be tracked for troubleshooting * * @param args - Message content followed by optional context * * @example * ```typescript * logger.error('Failed to process payment'); * logger.error('API request failed', { status: 500, path: '/api/users' }); * logger.error('Database query error', logger.context({ * query: 'SELECT * FROM users', * error: new Error('Connection timeout') * })); * ``` */ error(...args: unknown[]): void; /** * Logs a warning condition that might cause issues * * Use for situations that: * - Are unusual but not errors * - Might cause problems in the future * - Indicate deprecated feature usage * * @param args - Message content followed by optional context * * @example * ```typescript * logger.warn('High memory usage detected'); * logger.warn('Deprecated API used', { api: 'oldMethod', alternative: 'newMethod' }); * logger.warn('Cache miss rate high', logger.context({ * rate: '85%', * threshold: '75%' * })); * ``` */ warn(...args: unknown[]): void; /** * Logs normal but significant events * * Use for events that: * - Mark major application state changes * - Track business process completion * - Record user actions * * @param args - Message content followed by optional context * * @example * ```typescript * logger.info('Application started on port 3000'); * logger.info('User logged in', { userId: 123, role: 'admin' }); * logger.info('Order processed', logger.context({ * orderId: 'ORD-123', * amount: 99.99, * currency: 'USD' * })); * ``` */ info(...args: unknown[]): void; /** * Logs detailed information for debugging * * Use for information that: * - Helps diagnose problems * - Shows detailed flow of execution * - Exposes internal state * * @param args - Message content followed by optional context * * @example * ```typescript * logger.debug('Processing request payload'); * logger.debug('Cache state', { size: 1024, entries: 50 }); * logger.debug('Query execution plan', logger.context({ * sql: 'SELECT * FROM users WHERE role = ?', * params: ['admin'], * executionTime: 150 * })); * ``` */ debug(...args: unknown[]): void; /** * Logs the most detailed level of information * * Use for information that: * - Shows step-by-step execution flow * - Includes method entry/exit points * - Contains variable state changes * * @param args - Message content followed by optional context * * @example * ```typescript * logger.trace('Entering method processUser'); * logger.trace('Variable state', { counter: 5, buffer: [1,2,3] }); * logger.trace('Method execution', logger.context({ * method: 'processUser', * args: { id: 123 }, * stack: new Error().stack * })); * ``` */ trace(...args: unknown[]): void; /** * Adds a new handler (appender) to the logger * * Handlers are responsible for processing and outputting log events. * Multiple handlers can be added to send logs to different destinations * or format them differently. * * @param appender - The handler instance to add * * @example Basic console handler * ```typescript * const logger = new Logger(); * logger.addAppender(new ConsoleHandler()); * ``` * * @example Multiple handlers * ```typescript * const logger = new Logger(); * * // Console output for development * logger.addAppender(new ConsoleHandler( * new TimestampFormatter({ locale: 'en-US' }) * )); * * // File output for errors * logger.addAppender(new FileHandler('./logs/errors.log', { * level: 'error', * formatter: new JSONFormatter() * })); * * // Metrics collection * logger.addAppender(new MetricsHandler({ * service: 'user-api', * endpoint: 'https://metrics.example.com' * })); * ``` * * @example Conditional handlers * ```typescript * const logger = new Logger(); * * // Development handlers * if (process.env.NODE_ENV === 'development') { * logger.addAppender(new ConsoleHandler( * new PrettyFormatter({ colors: true }) * )); * logger.addAppender(new FileHandler('./logs/dev.log')); * } * * // Production handlers * if (process.env.NODE_ENV === 'production') { * logger.addAppender(new CloudWatchHandler({ * region: 'us-east-1', * logGroupName: '/aws/api' * })); * logger.addAppender(new AlertHandler({ * level: 'error', * webhook: 'https://alerts.example.com' * })); * } * ``` */ addAppender(appender: HandlerInterface<Ctx>): void; /** * Creates a new LogContext instance for structured logging * * Context objects allow adding structured data to log messages * in a type-safe way. They can be used to add metadata, * performance metrics, error details, or any other relevant * information to log entries. * * @since 0.1.0 * @param value - Optional value to be stored in the context * @returns A new LogContext instance with the provided value * * @example Basic context usage * ```typescript * logger.info('User logged in', logger.context({ * userId: 123, * role: 'admin', * loginTime: new Date() * })); * ``` * * @example Type-safe context * ```typescript * interface RequestContext { * method: string; * path: string; * duration: number; * statusCode: number; * } * * logger.info('Request completed', logger.context<RequestContext>({ * method: 'GET', * path: '/api/users', * duration: 150, * statusCode: 200 * })); * ``` * * @example Error context * ```typescript * try { * await processOrder(orderId); * } catch (error) { * logger.error('Order processing failed', logger.context({ * orderId, * error: error instanceof Error ? error.message : String(error), * stack: error instanceof Error ? error.stack : undefined * })); * } * ``` * * @example Performance monitoring * ```typescript * const startTime = Date.now(); * try { * const result = await heavyOperation(); * logger.info('Operation completed', logger.context({ * duration: Date.now() - startTime, * resultSize: result.length, * memoryUsage: process.memoryUsage() * })); * } catch (error) { * logger.error('Operation failed', logger.context({ * duration: Date.now() - startTime, * error, * memoryUsage: process.memoryUsage() * })); * } * ``` */ context<Value>(value?: Value): LogContext<Value>; } /** * Environment configuration options interface * @interface * @description * Significance: Defines initialization parameters for Env class * Core idea: Configure environment variable management * Main function: Type-safe environment configuration * Main purpose: Initialize environment handler * Example: * ```typescript * const options: EnvOptions = { * rootPath: '/path/to/project', * logger: new Logger() * }; * ``` */ interface EnvOptions { /** Root path for environment files */ rootPath: string; /** Logger instance */ logger?: LoggerInterface | typeof console; } /** * Environment loading options interface * @interface * @description * Significance: Defines options for loading environment variables * Core idea: Control environment file loading behavior * Main function: Configure environment loading process * Main purpose: Customize environment loading * Example: * ```typescript * const loadOptions: LoadOptions = { * preloadList: ['.env', '.env.local'], * rootPath: '/custom/path' * }; * ``` */ interface LoadOptions { /** List of environment files to load */ preloadList: string[]; /** Optional root path override */ rootPath?: string; } /** * Environment variable management class * @class * @description * Significance: Manages environment variables and .env files * Core idea: Centralize environment variable operations * Main function: Load and manage environment variables * Main purpose: Provide consistent environment variable access * Example: * ```typescript * const env = new Env({ * rootPath: process.cwd(), * logger: new Logger() * }); * env.load({ preloadList: ['.env'] }); * ``` */ declare class Env { private options; /** * Creates an Env instance * @param options - Environment configuration options * @description * Significance: Initializes environment management * Core idea: Setup environment configuration * Main function: Create environment handler * Main purpose: Prepare for environment operations * Example: * ```typescript * const env = new Env({ * rootPath: './project', * logger: new Logger() * }); * ``` */ constructor(options: EnvOptions); get rootPath(): string; get logger(): LoggerInterface | typeof console | undefined; /** * from current directory to root directory, search and load .env file * @param {object} options * @param {string} [options.cwd] start search directory, default is process.cwd() * @param {string[]} [options.preloadList] search file name list, default is ['.env.local', '.env'] * @param {Logger} [options.logger] logger * @param {number} [options.maxDepth=5] maximum search depth * @returns {Env} environment variable loader instance */ static searchEnv({ cwd, preloadList, logger, maxDepth }?: { cwd?: string; preloadList?: string[]; logger?: LoggerInterface; maxDepth?: number; }): Env; /** * Load environment variables from files * @param options - Load configuration options * @returns void * @description * Significance: Loads environment variables from files * Core idea: Sequential environment file loading * Main function: Process and load environment files * Main purpose: Initialize environment variables * Example: * ```typescript * env.load({ * preloadList: ['.env.local', '.env'], * rootPath: './config' * }); * ``` */ load(options?: LoadOptions): void; /** * Remove environment variable * @param variable - Environment variable name * @returns void * @description * Significance: Removes specific environment variable * Core idea: Safe environment variable deletion * Main function: Delete environment variable * Main purpose: Clean up environment state * Example: * ```typescript * env.remove('API_KEY'); * ``` */ remove(variable: string): void; /** * Get environment variable value * @param variable - Environment variable name * @returns Environment variable value or undefined * @description * Significance: Retrieves environment variable value * Core idea: Safe environment variable access * Main function: Get environment variable * Main purpose: Access environment state * Example: * ```typescript * const apiKey = env.get('API_KEY'); * ``` */ get(variable: string): string | undefined; /** * Set environment variable * @param variable - Environment variable name * @param value - Value to set * @returns void * @description * Significance: Sets environment variable value * Core idea: Safe environment variable modification * Main function: Update environment variable * Main purpose: Modify environment state * Example: * ```typescript * env.set('DEBUG', 'true'); * ``` */ set(variable: string, value: string): void; /** * Get and remove environment variable * @param variable - Environment variable name * @returns Environment variable value or undefined * @description * Significance: Retrieves and removes environment variable * Core idea: Atomic get and delete operation * Main function: Access and clean up variable * Main purpose: One-time environment variable access * Example: * ```typescript * const tempKey = env.getDestroy('TEMP_API_KEY'); * ``` */ getDestroy(variable: string): string | undefined; } export { Env };