@vritti/api-sdk 0.4.3 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/auth.cjs +58 -17
  2. package/dist/auth.cjs.map +1 -1
  3. package/dist/auth.d.cts +1 -1
  4. package/dist/auth.d.ts +1 -1
  5. package/dist/auth.js +58 -17
  6. package/dist/auth.js.map +1 -1
  7. package/dist/cache.cjs +51 -17
  8. package/dist/cache.cjs.map +1 -1
  9. package/dist/cache.js +51 -17
  10. package/dist/cache.js.map +1 -1
  11. package/dist/catalog-resolver.d.cts +2 -2
  12. package/dist/catalog-resolver.d.ts +2 -2
  13. package/dist/{code-pattern-BP4zkNtT.d.cts → code-pattern-DMlbIwwn.d.cts} +3 -3
  14. package/dist/{code-pattern-BP4zkNtT.d.ts → code-pattern-DMlbIwwn.d.ts} +3 -3
  15. package/dist/data-table.cjs +154 -48
  16. package/dist/data-table.cjs.map +1 -1
  17. package/dist/data-table.js +154 -48
  18. package/dist/data-table.js.map +1 -1
  19. package/dist/database.cjs +101 -31
  20. package/dist/database.cjs.map +1 -1
  21. package/dist/database.js +101 -31
  22. package/dist/database.js.map +1 -1
  23. package/dist/decorators.cjs +1 -1
  24. package/dist/decorators.cjs.map +1 -1
  25. package/dist/decorators.d.cts +2 -2
  26. package/dist/decorators.d.ts +2 -2
  27. package/dist/decorators.js +1 -1
  28. package/dist/decorators.js.map +1 -1
  29. package/dist/drizzle-pg-core.cjs +1 -1
  30. package/dist/drizzle-pg-core.cjs.map +1 -1
  31. package/dist/drizzle-pg-core.d.cts +1 -1
  32. package/dist/drizzle-pg-core.d.ts +1 -1
  33. package/dist/drizzle-pg-core.js +1 -1
  34. package/dist/drizzle-pg-core.js.map +1 -1
  35. package/dist/email.cjs +22 -6
  36. package/dist/email.cjs.map +1 -1
  37. package/dist/email.js +22 -6
  38. package/dist/email.js.map +1 -1
  39. package/dist/files.cjs +1 -1
  40. package/dist/files.cjs.map +1 -1
  41. package/dist/files.d.cts +3 -3
  42. package/dist/files.d.ts +3 -3
  43. package/dist/files.js +1 -1
  44. package/dist/files.js.map +1 -1
  45. package/dist/filters.cjs +18 -4
  46. package/dist/filters.cjs.map +1 -1
  47. package/dist/filters.js +18 -4
  48. package/dist/filters.js.map +1 -1
  49. package/dist/index.d.cts +1 -1
  50. package/dist/index.d.ts +1 -1
  51. package/dist/license.d.cts +1 -1
  52. package/dist/license.d.ts +1 -1
  53. package/dist/logger.cjs +49 -15
  54. package/dist/logger.cjs.map +1 -1
  55. package/dist/logger.js +49 -15
  56. package/dist/logger.js.map +1 -1
  57. package/dist/nats.cjs +51 -19
  58. package/dist/nats.cjs.map +1 -1
  59. package/dist/nats.js +50 -18
  60. package/dist/nats.js.map +1 -1
  61. package/dist/root.cjs +44 -12
  62. package/dist/root.cjs.map +1 -1
  63. package/dist/root.js +44 -12
  64. package/dist/root.js.map +1 -1
  65. package/dist/{types-BQY0Aa1p.d.cts → types-VDKSjje5.d.cts} +1 -1
  66. package/dist/{types-BQY0Aa1p.d.ts → types-VDKSjje5.d.ts} +1 -1
  67. package/package.json +38 -38
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/logger/interceptors/http-logger.interceptor.ts","../src/exceptions/conflict.exception.ts","../src/exceptions/base-field.exception.ts","../src/filters/pg-error.translator.ts","../src/logger/services/logger.service.ts","../src/logger/utils/index.ts","../src/logger/logger.module.ts","../src/logger/middleware/correlation-id.middleware.ts"],"sourcesContent":["import { type CallHandler, type ExecutionContext, Injectable, type NestInterceptor, Optional } from '@nestjs/common';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport type { Observable } from 'rxjs';\nimport { catchError, tap } from 'rxjs/operators';\nimport { findPgError } from '../../filters/pg-error.translator';\nimport { LoggerService } from '../services/logger.service';\nimport type { HttpLoggerOptions, LogMetadata } from '../types';\nimport { getCorrelationContext } from '../utils';\n\n@Injectable()\nexport class HttpLoggerInterceptor implements NestInterceptor {\n private readonly enableRequestLog: boolean;\n private readonly enableResponseLog: boolean;\n private readonly slowRequestThreshold: number;\n\n constructor(\n private readonly logger: LoggerService,\n @Optional() options?: HttpLoggerOptions,\n ) {\n this.enableRequestLog = options?.enableRequestLog ?? true;\n this.enableResponseLog = options?.enableResponseLog ?? true;\n this.slowRequestThreshold = options?.slowRequestThreshold ?? 3000; // 3 seconds\n }\n\n intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {\n if (context.getType() !== 'http') {\n return next.handle();\n }\n\n const httpContext = context.switchToHttp();\n const request = httpContext.getRequest<FastifyRequest>();\n const response = httpContext.getResponse<FastifyReply>();\n\n const startTime = Date.now();\n\n // Log incoming request\n if (this.enableRequestLog) {\n this.logRequest(request);\n }\n\n // Process request and log response/errors\n return next.handle().pipe(\n tap(() => {\n if (this.enableResponseLog) {\n const duration = Date.now() - startTime;\n this.logResponse(request, response, duration);\n }\n }),\n catchError((error) => {\n const duration = Date.now() - startTime;\n this.logError(request, response, duration, error);\n throw error;\n }),\n );\n }\n\n private logRequest(request: FastifyRequest): void {\n try {\n const correlationContext = getCorrelationContext();\n const metadata: LogMetadata = {\n type: 'http_request',\n method: request.method,\n url: request.url,\n correlationId: correlationContext?.correlationId,\n ip: request.ip,\n userAgent: request.headers['user-agent'],\n };\n\n this.logger.logWithMetadata('log', `Incoming ${request.method} ${request.url}`, metadata);\n } catch (error) {\n this.logger.error('Failed to log HTTP request', (error as Error).stack);\n }\n }\n\n private logResponse(request: FastifyRequest, response: FastifyReply, duration: number): void {\n try {\n const correlationContext = getCorrelationContext();\n const statusCode = response.statusCode;\n\n // Determine log level based on status code\n const logLevel = statusCode >= 500 ? 'error' : statusCode >= 400 ? 'warn' : 'log';\n\n const metadata: LogMetadata = {\n type: 'http_response',\n method: request.method,\n url: request.url,\n statusCode,\n duration,\n correlationId: correlationContext?.correlationId,\n };\n\n // Flag slow requests\n if (duration > this.slowRequestThreshold) {\n metadata.slowRequest = true;\n }\n\n const message = metadata.slowRequest\n ? `SLOW ${request.method} ${request.url} ${statusCode} - ${duration}ms`\n : `${request.method} ${request.url} ${statusCode} - ${duration}ms`;\n\n this.logger.logWithMetadata(logLevel, message, metadata);\n } catch (error) {\n this.logger.error('Failed to log HTTP response', (error as Error).stack);\n }\n }\n\n private logError(request: FastifyRequest, response: FastifyReply, duration: number, error: unknown): void {\n try {\n const correlationContext = getCorrelationContext();\n const err = error as {\n name?: string;\n message?: string;\n detail?: string;\n status?: number;\n statusCode?: number;\n stack?: string;\n response?: unknown;\n };\n const statusCode = err.status ?? err.statusCode ?? response.statusCode ?? 500;\n // Drizzle wraps pg errors in DrizzleQueryError whose `.message` is only the failed query — unwrap the real reason from `.cause`.\n const pgCause = findPgError(error);\n let errorMessage = err.message || err.detail || 'Unknown error';\n if (pgCause?.message && pgCause.message !== err.message) {\n errorMessage = `${errorMessage} — cause: ${pgCause.message}${pgCause.code ? ` [${pgCause.code}]` : ''}`;\n }\n\n const metadata: LogMetadata = {\n type: 'http_error',\n method: request.method,\n url: request.url,\n statusCode,\n duration,\n correlationId: correlationContext?.correlationId,\n errorName: err.name || 'Error',\n errorMessage,\n };\n\n // Attach the structured pg cause so log sinks capture SQLSTATE, constraint, table, etc.\n if (pgCause) {\n metadata.pgError = pgCause;\n }\n\n if (err.stack) {\n metadata.trace = err.stack;\n }\n\n if (err.response) {\n metadata.errorDetails = err.response;\n }\n\n const message = `ERROR ${request.method} ${request.url} ${statusCode} - ${errorMessage}`;\n this.logger.logWithMetadata('error', message, metadata);\n } catch (loggingError) {\n this.logger.error('Failed to log HTTP error', (loggingError as Error).stack);\n }\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ConflictException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Conflict', HttpStatus.CONFLICT);\n }\n}\n","import { HttpException, HttpStatus } from '@nestjs/common';\nimport type { FieldError } from '../types/error-response.types';\n\n// Re-export FieldError for backwards compatibility\nexport type { FieldError } from '../types/error-response.types';\n\nexport interface ProblemOptions {\n type?: string;\n label?: string;\n detail?: string;\n errors?: FieldError[];\n}\n\nexport abstract class HttpProblemException extends HttpException {\n constructor(detailOrOptions: string | ProblemOptions, httpStatus: HttpStatus) {\n const options = typeof detailOrOptions === 'string' ? { detail: detailOrOptions } : detailOrOptions;\n\n super(\n {\n type: options.type ?? 'about:blank',\n label: options.label,\n detail: options.detail,\n errors: options.errors ?? [],\n },\n httpStatus,\n );\n }\n}\n","import { ConflictException } from '../exceptions/conflict.exception';\n\nconst PG_UNIQUE_VIOLATION = '23505';\n\nexport type PgErrorShape = {\n code?: string;\n message?: string;\n constraint?: string;\n table?: string;\n schema?: string;\n column?: string;\n detail?: string;\n hint?: string;\n};\n\n// Returns a ConflictException for a Postgres unique-violation error, otherwise undefined.\nexport function tryTranslatePgError(error: unknown): ConflictException | undefined {\n const pgError = findPgError(error);\n if (!pgError) return undefined;\n const { code, constraint, table, detail } = pgError;\n if (code !== PG_UNIQUE_VIOLATION) return undefined;\n return new ConflictException({\n label: 'Duplicate Entry',\n detail: detail?.trim() || 'A record with these values already exists.',\n errors: [],\n ...(constraint || table ? { meta: { constraint, table } } : {}),\n });\n}\n\n// Walks up to N levels of `.cause` looking for a pg-shaped error (has SQLSTATE `code`), capping depth.\nexport function findPgError(error: unknown, depth = 0): PgErrorShape | undefined {\n if (!error || typeof error !== 'object' || depth > 5) return undefined;\n const candidate = error as PgErrorShape & { cause?: unknown };\n if (typeof candidate.code === 'string') return candidate;\n return findPgError(candidate.cause, depth + 1);\n}\n","import { Injectable, type Logger, type LoggerService as NestLoggerService, Optional } from '@nestjs/common';\nimport { createLogger, format, type LoggerOptions, transports, type Logger as WinstonLogger } from 'winston';\nimport DailyRotateFile from 'winston-daily-rotate-file';\nimport type { LoggerModuleOptions, LogLevel, LogMetadata } from '../types';\nimport { getCorrelationContext } from '../utils';\n\nexport type LogMessage = string | Error | object;\n\n@Injectable()\nexport class LoggerService implements NestLoggerService {\n private readonly activeLogger: NestLoggerService | WinstonLogger;\n private readonly options: LoggerModuleOptions;\n private context?: string;\n\n constructor(\n @Optional() options: LoggerModuleOptions = {},\n @Optional() private readonly defaultLogger?: Logger,\n ) {\n this.options = options;\n const provider = options.provider ?? 'winston';\n\n if (provider === 'default') {\n if (!this.defaultLogger) {\n throw new Error('LoggerService: Default Logger not provided');\n }\n this.activeLogger = this.defaultLogger;\n } else {\n this.activeLogger = this.createWinstonLogger(options);\n }\n }\n\n // Creates a Winston logger instance with inline transports and format configuration\n private createWinstonLogger(opts: LoggerModuleOptions): WinstonLogger {\n const level = opts.level ?? 'debug';\n const logFormat = opts.format ?? 'text';\n\n // Base formatters — Winston merges metadata into the info object, so all properties are already at the top level.\n const baseFormatters = [format.timestamp({ format: 'YYYY-MM-DDTHH:mm:ss.SSSZ' }), format.errors({ stack: true })];\n\n // Console transport\n const consoleTransport =\n logFormat === 'json'\n ? new transports.Console({\n level,\n format: format.combine(...baseFormatters, format.json()),\n })\n : new transports.Console({\n level,\n format: format.combine(\n ...baseFormatters,\n format.printf((info) => {\n const { timestamp, level, message, context, correlationId, trace } = info;\n const parts = [\n timestamp,\n level.toUpperCase().padEnd(7),\n correlationId ? `[${correlationId.toString().slice(-6)}]` : '',\n context ? `[${context}]` : '',\n message,\n ].filter(Boolean);\n let output = parts.join(' ');\n\n // Append stack trace on new line if present\n if (trace) {\n output += `\\n${trace}`;\n }\n\n return output;\n }),\n format.colorize({ all: true }),\n ),\n });\n\n const winstonTransports: (InstanceType<typeof transports.Console> | DailyRotateFile)[] = [consoleTransport];\n\n // File transports\n if (opts.enableFileLogger) {\n const filePath = opts.filePath ?? './logs';\n const maxFiles = opts.maxFiles ?? '14d';\n\n winstonTransports.push(\n new DailyRotateFile({\n level,\n filename: `${filePath}/%DATE%-combined.log`,\n datePattern: 'YYYY-MM-DD',\n maxSize: '20m',\n maxFiles,\n format: format.combine(format.timestamp(), format.json()),\n }),\n new DailyRotateFile({\n level: 'error',\n filename: `${filePath}/%DATE%-error.log`,\n datePattern: 'YYYY-MM-DD',\n maxSize: '20m',\n maxFiles,\n format: format.combine(format.timestamp(), format.json()),\n }),\n );\n }\n\n const config: LoggerOptions = {\n level,\n transports: winstonTransports,\n exitOnError: false,\n };\n\n if (opts.defaultMeta || opts.appName) {\n config.defaultMeta = {\n ...opts.defaultMeta,\n appName: opts.appName,\n environment: opts.environment,\n };\n }\n\n return createLogger(config);\n }\n\n // NestJS LoggerService interface methods\n log(message: LogMessage, context?: string): void {\n this._log('log', message, context);\n }\n\n error(message: LogMessage, trace?: string, context?: string): void {\n this._log('error', message, context, trace);\n }\n\n warn(message: LogMessage, context?: string): void {\n this._log('warn', message, context);\n }\n\n debug(message: LogMessage, context?: string): void {\n this._log('debug', message, context);\n }\n\n verbose(message: LogMessage, context?: string): void {\n this._log('verbose', message, context);\n }\n\n setContext(context: string): void {\n this.context = context;\n }\n\n // Dispatches a log entry to either the Winston or NestJS logger implementation\n private _log(level: LogLevel, message: LogMessage, context?: string, trace?: string): void {\n const ctx = context ?? this.context;\n\n // Check if Winston logger by duck typing\n if ('format' in this.activeLogger && 'transports' in this.activeLogger) {\n // Winston logger path\n const winstonLogger = this.activeLogger as WinstonLogger;\n const winstonLevel = level === 'log' ? 'info' : level;\n const formattedMessage = this.formatMessage(message);\n const metadata = this.enrichMetadata({}, ctx, trace);\n // Winston merges all properties into the info object when using object syntax\n winstonLogger.log({ level: winstonLevel, message: formattedMessage, ...metadata });\n } else {\n // NestJS logger path\n const nestLogger = this.activeLogger as Logger;\n if (level === 'error' && trace) {\n ctx ? nestLogger.error(message, trace, ctx) : nestLogger.error(message, trace);\n } else if (level === 'log') {\n ctx ? nestLogger.log(message, ctx) : nestLogger.log(message);\n } else if (level === 'warn') {\n ctx ? nestLogger.warn(message, ctx) : nestLogger.warn(message);\n } else if (level === 'debug' && nestLogger.debug) {\n ctx ? nestLogger.debug(message, ctx) : nestLogger.debug(message);\n } else if (level === 'verbose' && nestLogger.verbose) {\n ctx ? nestLogger.verbose(message, ctx) : nestLogger.verbose(message);\n }\n }\n }\n\n // Logs a message with custom metadata fields (Winston only)\n logWithMetadata(level: LogLevel, message: LogMessage, metadata?: LogMetadata, context?: string): void {\n const ctx = context ?? this.context;\n\n // Check if Winston logger by duck typing\n if ('format' in this.activeLogger && 'transports' in this.activeLogger) {\n const winstonLogger = this.activeLogger as WinstonLogger;\n const winstonLevel = level === 'log' ? 'info' : level;\n // Winston merges all properties into the info object when using object syntax\n winstonLogger.log({ level: winstonLevel, message: this.formatMessage(message), ...metadata });\n } else {\n // Fallback for default logger\n const messageWithMeta = metadata ? `${message} ${JSON.stringify(metadata)}` : message;\n this[level](messageWithMeta, ctx);\n }\n }\n\n private formatMessage(message: LogMessage): string {\n if (message instanceof Error) return message.message;\n if (typeof message === 'object' && message !== null) {\n try {\n return JSON.stringify(message);\n } catch {\n return String(message);\n }\n }\n return String(message);\n }\n\n // Enriches metadata with correlation context from AsyncLocalStorage\n private enrichMetadata(metadata: LogMetadata = {}, context?: string, trace?: string): LogMetadata {\n const enriched: LogMetadata = { ...metadata };\n\n if (context) enriched.context = context;\n\n const correlationContext = getCorrelationContext();\n if (correlationContext) {\n if (correlationContext.correlationId) enriched.correlationId = correlationContext.correlationId;\n for (const [key, value] of Object.entries(correlationContext)) {\n if (key !== 'correlationId') {\n enriched[key] = value;\n }\n }\n }\n\n if (trace) enriched.trace = trace;\n\n return enriched;\n }\n\n child(context: string): LoggerService {\n const childLogger = new LoggerService(this.options, this.defaultLogger);\n childLogger.setContext(context);\n return childLogger;\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport { randomUUID } from 'node:crypto';\nimport type { FastifyReply } from 'fastify';\nimport type { CorrelationContext } from '../types';\n\n// Async Context Management (AsyncLocalStorage)\n\nexport const correlationStorage = new AsyncLocalStorage<CorrelationContext>();\n\n// Returns the current correlation context from AsyncLocalStorage\nexport function getCorrelationContext(): CorrelationContext | undefined {\n return correlationStorage.getStore();\n}\n\n// Runs a callback within the given correlation context\nexport function runWithCorrelationContext<T>(context: CorrelationContext, callback: () => T): T {\n return correlationStorage.run(context, callback);\n}\n\n// Updates the current correlation context with new values\nexport function updateCorrelationContext(updates: Partial<CorrelationContext>): void {\n const context = correlationStorage.getStore();\n if (context) {\n Object.assign(context, updates);\n }\n}\n\n// Correlation ID Management\n\nexport const DEFAULT_CORRELATION_HEADER = 'x-correlation-id';\n\n// Generates a new UUID v4 correlation ID for the current request\nexport function generateCorrelationId(): string {\n return randomUUID();\n}\n\n// Adds the correlation ID to Fastify response headers\nexport function addCorrelationIdToResponse(\n reply: FastifyReply,\n correlationId: string,\n headerName: string = DEFAULT_CORRELATION_HEADER,\n): void {\n if (typeof reply.header === 'function') {\n reply.header(headerName, correlationId);\n } else if (reply.raw && typeof reply.raw.setHeader === 'function') {\n reply.raw.setHeader(headerName, correlationId);\n }\n}\n","import {\n type DynamicModule,\n Global,\n Logger,\n type MiddlewareConsumer,\n Module,\n type NestModule,\n type Provider,\n} from '@nestjs/common';\nimport { HttpLoggerInterceptor } from './interceptors/http-logger.interceptor';\nimport { CorrelationIdMiddleware } from './middleware/correlation-id.middleware';\nimport { LoggerService } from './services/logger.service';\nimport type { LoggerModuleAsyncOptions, LoggerModuleOptions, LoggerOptionsFactory } from './types';\n\n// Constants (inline from constants.ts)\n\nexport const LOGGER_MODULE_OPTIONS = Symbol('LOGGER_MODULE_OPTIONS');\n\nconst DEFAULT_LOGGER_OPTIONS = {\n provider: 'winston' as const,\n enableCorrelationId: true,\n enableHttpLogger: true,\n filePath: './logs',\n maxFiles: '14d',\n} as const;\n\n// Environment Presets (replaces process.env auto-detection)\n\nconst ENVIRONMENT_PRESETS: Record<string, Partial<LoggerModuleOptions>> = {\n development: {\n provider: 'winston',\n level: 'debug',\n format: 'text',\n enableFileLogger: false,\n enableCorrelationId: true,\n enableHttpLogger: true,\n httpLogger: {\n enableRequestLog: true,\n enableResponseLog: true,\n slowRequestThreshold: 1000, // 1 second - lower threshold for dev\n },\n },\n\n staging: {\n provider: 'winston',\n level: 'log',\n format: 'json',\n enableFileLogger: true,\n enableCorrelationId: true,\n enableHttpLogger: true,\n httpLogger: {\n enableRequestLog: true,\n enableResponseLog: true,\n slowRequestThreshold: 3000, // 3 seconds\n },\n },\n\n production: {\n provider: 'winston',\n level: 'warn',\n format: 'json',\n enableFileLogger: true,\n enableCorrelationId: true,\n enableHttpLogger: true,\n httpLogger: {\n enableRequestLog: false, // Reduce noise in production\n enableResponseLog: true,\n slowRequestThreshold: 5000, // 5 seconds - higher threshold for prod\n },\n },\n\n test: {\n provider: 'winston',\n level: 'error',\n format: 'json',\n enableFileLogger: false,\n enableCorrelationId: false,\n enableHttpLogger: false,\n },\n} as const;\n\n// Configuration Merging (uses presets instead of process.env)\n\n// Merges user-provided options with default and environment preset values\nfunction mergeWithDefaults(options: LoggerModuleOptions = {}): LoggerModuleOptions {\n // Select preset based on explicit environment option (defaults to development)\n const preset = options.environment\n ? (ENVIRONMENT_PRESETS[options.environment] ?? ENVIRONMENT_PRESETS.development)\n : ENVIRONMENT_PRESETS.development;\n\n // Filter out undefined values from user options to avoid overriding preset defaults\n const filteredOptions = Object.fromEntries(Object.entries(options).filter(([_, value]) => value !== undefined));\n\n // Handle nested httpLogger object - merge with preset httpLogger if both exist\n if (filteredOptions.httpLogger && preset?.httpLogger) {\n filteredOptions.httpLogger = {\n ...preset.httpLogger,\n ...Object.fromEntries(Object.entries(filteredOptions.httpLogger).filter(([_, value]) => value !== undefined)),\n };\n }\n\n // Merge: base defaults < preset < user options (with undefined values removed)\n const merged = {\n ...DEFAULT_LOGGER_OPTIONS,\n ...preset,\n ...filteredOptions,\n };\n\n return merged;\n}\n\n// Provider Factories (inline from logging.providers.ts)\n\n// Creates the default NestJS Logger provider with optional log level configuration\nfunction createDefaultLoggerProvider(options: LoggerModuleOptions): Provider {\n return {\n provide: Logger,\n useFactory: () => {\n const logger = new Logger();\n\n // Set log levels if specified and method exists\n if (options.level) {\n const levels = getLevelsUpTo(options.level);\n (logger as { setLogLevels?: (levels: NestLogLevel[]) => void }).setLogLevels?.(levels);\n }\n\n return logger;\n },\n };\n}\n\n// Builds all logger providers for the module based on merged configuration\nfunction createLoggerProviders(options: LoggerModuleOptions = {}): Provider[] {\n // Merge user options with preset defaults\n const mergedOptions = mergeWithDefaults(options);\n\n // Base providers (always included)\n const providers: Provider[] = [\n // Options provider\n {\n provide: LOGGER_MODULE_OPTIONS,\n useValue: mergedOptions,\n },\n ];\n\n // Default logger provider (only if using default provider)\n if (mergedOptions.provider === 'default') {\n providers.push(createDefaultLoggerProvider(mergedOptions));\n }\n\n // Unified LoggerService facade (always included)\n providers.push({\n provide: LoggerService,\n useFactory: (opts: LoggerModuleOptions, defaultLogger?: Logger) => {\n return new LoggerService(opts, defaultLogger);\n },\n inject: [LOGGER_MODULE_OPTIONS, { token: Logger, optional: true }],\n });\n\n // Correlation ID middleware\n providers.push({\n provide: CorrelationIdMiddleware,\n useFactory: () => {\n return new CorrelationIdMiddleware({\n includeInResponse: true,\n responseHeader: 'x-correlation-id',\n });\n },\n });\n\n // HTTP logger interceptor\n providers.push({\n provide: HttpLoggerInterceptor,\n useFactory: (logger: LoggerService, opts: LoggerModuleOptions) => {\n // Use detailed httpLogger config if provided, otherwise fall back to simple enableHttpLogger\n const httpLoggerOptions = opts.httpLogger ?? {\n enableRequestLog: opts.enableHttpLogger,\n enableResponseLog: opts.enableHttpLogger,\n };\n return new HttpLoggerInterceptor(logger, httpLoggerOptions);\n },\n inject: [LoggerService, LOGGER_MODULE_OPTIONS],\n });\n\n return providers;\n}\n\ntype NestLogLevel = 'error' | 'warn' | 'log' | 'debug' | 'verbose';\n\n// Returns all NestJS log levels up to and including the specified level\nfunction getLevelsUpTo(level: string): NestLogLevel[] {\n const allLevels: NestLogLevel[] = ['error', 'warn', 'log', 'debug', 'verbose'];\n\n // Check if level is a valid NestLogLevel\n const isValidLevel = (l: string): l is NestLogLevel => allLevels.includes(l as NestLogLevel);\n\n if (!isValidLevel(level)) {\n return ['error', 'warn', 'log'];\n }\n\n const levelIndex = allLevels.indexOf(level);\n return allLevels.slice(0, levelIndex + 1);\n}\n\n@Global()\n@Module({})\nexport class LoggerModule implements NestModule {\n // Configures the logger module with static options and environment preset\n static forRoot(options: LoggerModuleOptions = {}): DynamicModule {\n const providers = createLoggerProviders(options);\n\n return {\n module: LoggerModule,\n providers,\n exports: [LoggerService, CorrelationIdMiddleware, HttpLoggerInterceptor, LOGGER_MODULE_OPTIONS],\n };\n }\n\n // Configures the logger module with async options (useFactory, useClass, useExisting)\n static forRootAsync<T extends unknown[] = unknown[]>(options: LoggerModuleAsyncOptions<T>): DynamicModule {\n const asyncProviders = LoggerModule.createAsyncProviders(options as LoggerModuleAsyncOptions<unknown[]>);\n\n return {\n module: LoggerModule,\n imports: options.imports || [],\n providers: [\n ...asyncProviders,\n // Default logger provider\n {\n provide: Logger,\n useFactory: (opts: LoggerModuleOptions) => {\n if (opts.provider === 'default') {\n const logger = new Logger();\n if (opts.level) {\n const levels = getLevelsUpTo(opts.level);\n (logger as { setLogLevels?: (levels: NestLogLevel[]) => void }).setLogLevels?.(levels);\n }\n return logger;\n }\n return null;\n },\n inject: [LOGGER_MODULE_OPTIONS],\n },\n // Unified logger service\n {\n provide: LoggerService,\n useFactory: (opts: LoggerModuleOptions, defaultLogger?: Logger) => {\n return new LoggerService(opts, defaultLogger);\n },\n inject: [LOGGER_MODULE_OPTIONS, { token: Logger, optional: true }],\n },\n // Correlation ID middleware\n {\n provide: CorrelationIdMiddleware,\n useFactory: () => {\n return new CorrelationIdMiddleware({\n includeInResponse: true,\n responseHeader: 'x-correlation-id',\n });\n },\n },\n // HTTP logger interceptor\n {\n provide: HttpLoggerInterceptor,\n useFactory: (logger: LoggerService, opts: LoggerModuleOptions) => {\n // Use detailed httpLogger config if provided, otherwise fall back to simple enableHttpLogger\n const httpLoggerOptions = opts.httpLogger ?? {\n enableRequestLog: opts.enableHttpLogger,\n enableResponseLog: opts.enableHttpLogger,\n };\n return new HttpLoggerInterceptor(logger, httpLoggerOptions);\n },\n inject: [LoggerService, LOGGER_MODULE_OPTIONS],\n },\n ],\n exports: [LoggerService, CorrelationIdMiddleware, HttpLoggerInterceptor, LOGGER_MODULE_OPTIONS],\n };\n }\n\n // Middleware registration is handled globally in main.ts via Fastify hooks\n configure(_consumer: MiddlewareConsumer): void {\n // Middleware is registered globally in main.ts via Fastify's addHook('onRequest') to avoid DI issues with the constructor.\n }\n\n // Creates async providers for dynamic module configuration\n private static createAsyncProviders(options: LoggerModuleAsyncOptions<unknown[]>): Provider[] {\n if (options.useFactory) {\n return [LoggerModule.createAsyncOptionsProvider(options)];\n }\n\n const providers: Provider[] = [LoggerModule.createAsyncOptionsProvider(options)];\n\n if (options.useClass) {\n providers.push({\n provide: options.useClass,\n useClass: options.useClass,\n });\n }\n\n return providers;\n }\n\n // Creates the DI provider that resolves and merges async logger options\n private static createAsyncOptionsProvider(options: LoggerModuleAsyncOptions<unknown[]>): Provider {\n if (options.useFactory) {\n return {\n provide: LOGGER_MODULE_OPTIONS,\n useFactory: async (...args: unknown[]) => {\n const userOptions = await options.useFactory?.(...args);\n return mergeWithDefaults(userOptions);\n },\n inject: options.inject || [],\n };\n }\n\n if (options.useClass) {\n return {\n provide: LOGGER_MODULE_OPTIONS,\n useFactory: async (optionsFactory: LoggerOptionsFactory) => {\n const userOptions = await optionsFactory.createLoggerOptions();\n return mergeWithDefaults(userOptions);\n },\n inject: [options.useClass],\n };\n }\n\n if (options.useExisting) {\n return {\n provide: LOGGER_MODULE_OPTIONS,\n useFactory: async (optionsFactory: LoggerOptionsFactory) => {\n const userOptions = await optionsFactory.createLoggerOptions();\n return mergeWithDefaults(userOptions);\n },\n inject: [options.useExisting],\n };\n }\n\n throw new Error('LoggerModule.forRootAsync() requires one of: useFactory, useClass, or useExisting');\n }\n}\n","import { Injectable, type NestMiddleware } from '@nestjs/common';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport {\n addCorrelationIdToResponse,\n correlationStorage,\n DEFAULT_CORRELATION_HEADER,\n generateCorrelationId,\n runWithCorrelationContext,\n} from '../utils';\n\nexport interface CorrelationIdMiddlewareOptions {\n includeInResponse?: boolean;\n responseHeader?: string;\n}\n\n@Injectable()\nexport class CorrelationIdMiddleware implements NestMiddleware {\n private readonly includeInResponse: boolean;\n private readonly responseHeader: string;\n\n constructor(options: CorrelationIdMiddlewareOptions = {}) {\n this.includeInResponse = options.includeInResponse ?? true;\n this.responseHeader = options.responseHeader ?? DEFAULT_CORRELATION_HEADER;\n }\n\n // Generates and stores a correlation ID for the incoming request\n use(_req: FastifyRequest, reply: FastifyReply, next: () => void): void {\n // Generate new correlation ID for this request\n const correlationId = generateCorrelationId();\n\n // Add to response headers if enabled\n if (this.includeInResponse) {\n addCorrelationIdToResponse(reply, correlationId, this.responseHeader);\n }\n\n // Run the rest of the request in AsyncLocalStorage context\n runWithCorrelationContext({ correlationId }, () => {\n next();\n });\n }\n\n // Fastify onRequest hook that initializes correlation context in AsyncLocalStorage\n async onRequest(_req: FastifyRequest, reply: FastifyReply): Promise<void> {\n // Generate new correlation ID for this request\n const correlationId = generateCorrelationId();\n\n // Add to response headers if enabled\n if (this.includeInResponse) {\n addCorrelationIdToResponse(reply, correlationId, this.responseHeader);\n }\n\n // Store in AsyncLocalStorage — no runWithCorrelationContext wrap needed, Fastify's async context tracking handles it.\n const store = correlationStorage.getStore();\n if (!store) {\n // Initialize new store\n correlationStorage.enterWith({ correlationId });\n }\n }\n}\n"],"mappings":";;;;AAAA,SAAkDA,cAAAA,aAAkCC,YAAAA,iBAAgB;AAGpG,SAASC,YAAYC,WAAW;;;ACHhC,SAASC,kBAAkB;;;ACA3B,SAASC,qBAAiC;;;AC8BnC,SAASC,YAAYC,OAAgBC,QAAQ,GAAC;AACnD,MAAI,CAACD,SAAS,OAAOA,UAAU,YAAYC,QAAQ,EAAG,QAAOC;AAC7D,QAAMC,YAAYH;AAClB,MAAI,OAAOG,UAAUC,SAAS,SAAU,QAAOD;AAC/C,SAAOJ,YAAYI,UAAUE,OAAOJ,QAAQ,CAAA;AAC9C;AALgBF;;;AC9BhB,SAASO,YAAkEC,gBAAgB;AAC3F,SAASC,cAAcC,QAA4BC,kBAAgD;AACnG,OAAOC,qBAAqB;;;ACF5B,SAASC,yBAAyB;AAClC,SAASC,kBAAkB;AAMpB,IAAMC,qBAAqB,IAAIC,kBAAAA;AAG/B,SAASC,wBAAAA;AACd,SAAOF,mBAAmBG,SAAQ;AACpC;AAFgBD;AAKT,SAASE,0BAA6BC,SAA6BC,UAAiB;AACzF,SAAON,mBAAmBO,IAAIF,SAASC,QAAAA;AACzC;AAFgBF;AAKT,SAASI,yBAAyBC,SAAoC;AAC3E,QAAMJ,UAAUL,mBAAmBG,SAAQ;AAC3C,MAAIE,SAAS;AACXK,WAAOC,OAAON,SAASI,OAAAA;EACzB;AACF;AALgBD;AAST,IAAMI,6BAA6B;AAGnC,SAASC,wBAAAA;AACd,SAAOC,WAAAA;AACT;AAFgBD;AAKT,SAASE,2BACdC,OACAC,eACAC,aAAqBN,4BAA0B;AAE/C,MAAI,OAAOI,MAAMG,WAAW,YAAY;AACtCH,UAAMG,OAAOD,YAAYD,aAAAA;EAC3B,WAAWD,MAAMI,OAAO,OAAOJ,MAAMI,IAAIC,cAAc,YAAY;AACjEL,UAAMI,IAAIC,UAAUH,YAAYD,aAAAA;EAClC;AACF;AAVgBF;;;;;;;;;;;;;;;;;;;;AD5BT,IAAMO,gBAAN,MAAMA,eAAAA;SAAAA;;;;EACMC;EACAC;EACTC;EAER,YACcD,UAA+B,CAAC,GACfE,eAC7B;SAD6BA,gBAAAA;AAE7B,SAAKF,UAAUA;AACf,UAAMG,WAAWH,QAAQG,YAAY;AAErC,QAAIA,aAAa,WAAW;AAC1B,UAAI,CAAC,KAAKD,eAAe;AACvB,cAAM,IAAIE,MAAM,4CAAA;MAClB;AACA,WAAKL,eAAe,KAAKG;IAC3B,OAAO;AACL,WAAKH,eAAe,KAAKM,oBAAoBL,OAAAA;IAC/C;EACF;;EAGQK,oBAAoBC,MAA0C;AACpE,UAAMC,QAAQD,KAAKC,SAAS;AAC5B,UAAMC,YAAYF,KAAKG,UAAU;AAGjC,UAAMC,iBAAiB;MAACD,OAAOE,UAAU;QAAEF,QAAQ;MAA2B,CAAA;MAAIA,OAAOG,OAAO;QAAEC,OAAO;MAAK,CAAA;;AAG9G,UAAMC,mBACJN,cAAc,SACV,IAAIO,WAAWC,QAAQ;MACrBT;MACAE,QAAQA,OAAOQ,QAAO,GAAIP,gBAAgBD,OAAOS,KAAI,CAAA;IACvD,CAAA,IACA,IAAIH,WAAWC,QAAQ;MACrBT;MACAE,QAAQA,OAAOQ,QAAO,GACjBP,gBACHD,OAAOU,OAAO,CAACC,SAAAA;AACb,cAAM,EAAET,WAAWJ,OAAAA,QAAOc,SAASpB,SAASqB,eAAeC,MAAK,IAAKH;AACrE,cAAMI,QAAQ;UACZb;UACAJ,OAAMkB,YAAW,EAAGC,OAAO,CAAA;UAC3BJ,gBAAgB,IAAIA,cAAcK,SAAQ,EAAGC,MAAM,EAAC,CAAA,MAAQ;UAC5D3B,UAAU,IAAIA,OAAAA,MAAa;UAC3BoB;UACAQ,OAAOC,OAAAA;AACT,YAAIC,SAASP,MAAMQ,KAAK,GAAA;AAGxB,YAAIT,OAAO;AACTQ,oBAAU;EAAKR,KAAAA;QACjB;AAEA,eAAOQ;MACT,CAAA,GACAtB,OAAOwB,SAAS;QAAEC,KAAK;MAAK,CAAA,CAAA;IAEhC,CAAA;AAEN,UAAMC,oBAAmF;MAACrB;;AAG1F,QAAIR,KAAK8B,kBAAkB;AACzB,YAAMC,WAAW/B,KAAK+B,YAAY;AAClC,YAAMC,WAAWhC,KAAKgC,YAAY;AAElCH,wBAAkBI,KAChB,IAAIC,gBAAgB;QAClBjC;QACAkC,UAAU,GAAGJ,QAAAA;QACbK,aAAa;QACbC,SAAS;QACTL;QACA7B,QAAQA,OAAOQ,QAAQR,OAAOE,UAAS,GAAIF,OAAOS,KAAI,CAAA;MACxD,CAAA,GACA,IAAIsB,gBAAgB;QAClBjC,OAAO;QACPkC,UAAU,GAAGJ,QAAAA;QACbK,aAAa;QACbC,SAAS;QACTL;QACA7B,QAAQA,OAAOQ,QAAQR,OAAOE,UAAS,GAAIF,OAAOS,KAAI,CAAA;MACxD,CAAA,CAAA;IAEJ;AAEA,UAAM0B,SAAwB;MAC5BrC;MACAQ,YAAYoB;MACZU,aAAa;IACf;AAEA,QAAIvC,KAAKwC,eAAexC,KAAKyC,SAAS;AACpCH,aAAOE,cAAc;QACnB,GAAGxC,KAAKwC;QACRC,SAASzC,KAAKyC;QACdC,aAAa1C,KAAK0C;MACpB;IACF;AAEA,WAAOC,aAAaL,MAAAA;EACtB;;EAGAM,IAAI7B,SAAqBpB,SAAwB;AAC/C,SAAKkD,KAAK,OAAO9B,SAASpB,OAAAA;EAC5B;EAEAmD,MAAM/B,SAAqBE,OAAgBtB,SAAwB;AACjE,SAAKkD,KAAK,SAAS9B,SAASpB,SAASsB,KAAAA;EACvC;EAEA8B,KAAKhC,SAAqBpB,SAAwB;AAChD,SAAKkD,KAAK,QAAQ9B,SAASpB,OAAAA;EAC7B;EAEAqD,MAAMjC,SAAqBpB,SAAwB;AACjD,SAAKkD,KAAK,SAAS9B,SAASpB,OAAAA;EAC9B;EAEAsD,QAAQlC,SAAqBpB,SAAwB;AACnD,SAAKkD,KAAK,WAAW9B,SAASpB,OAAAA;EAChC;EAEAuD,WAAWvD,SAAuB;AAChC,SAAKA,UAAUA;EACjB;;EAGQkD,KAAK5C,OAAiBc,SAAqBpB,SAAkBsB,OAAsB;AACzF,UAAMkC,MAAMxD,WAAW,KAAKA;AAG5B,QAAI,YAAY,KAAKF,gBAAgB,gBAAgB,KAAKA,cAAc;AAEtE,YAAM2D,gBAAgB,KAAK3D;AAC3B,YAAM4D,eAAepD,UAAU,QAAQ,SAASA;AAChD,YAAMqD,mBAAmB,KAAKC,cAAcxC,OAAAA;AAC5C,YAAMyC,WAAW,KAAKC,eAAe,CAAC,GAAGN,KAAKlC,KAAAA;AAE9CmC,oBAAcR,IAAI;QAAE3C,OAAOoD;QAActC,SAASuC;QAAkB,GAAGE;MAAS,CAAA;IAClF,OAAO;AAEL,YAAME,aAAa,KAAKjE;AACxB,UAAIQ,UAAU,WAAWgB,OAAO;AAC9BkC,cAAMO,WAAWZ,MAAM/B,SAASE,OAAOkC,GAAAA,IAAOO,WAAWZ,MAAM/B,SAASE,KAAAA;MAC1E,WAAWhB,UAAU,OAAO;AAC1BkD,cAAMO,WAAWd,IAAI7B,SAASoC,GAAAA,IAAOO,WAAWd,IAAI7B,OAAAA;MACtD,WAAWd,UAAU,QAAQ;AAC3BkD,cAAMO,WAAWX,KAAKhC,SAASoC,GAAAA,IAAOO,WAAWX,KAAKhC,OAAAA;MACxD,WAAWd,UAAU,WAAWyD,WAAWV,OAAO;AAChDG,cAAMO,WAAWV,MAAMjC,SAASoC,GAAAA,IAAOO,WAAWV,MAAMjC,OAAAA;MAC1D,WAAWd,UAAU,aAAayD,WAAWT,SAAS;AACpDE,cAAMO,WAAWT,QAAQlC,SAASoC,GAAAA,IAAOO,WAAWT,QAAQlC,OAAAA;MAC9D;IACF;EACF;;EAGA4C,gBAAgB1D,OAAiBc,SAAqByC,UAAwB7D,SAAwB;AACpG,UAAMwD,MAAMxD,WAAW,KAAKA;AAG5B,QAAI,YAAY,KAAKF,gBAAgB,gBAAgB,KAAKA,cAAc;AACtE,YAAM2D,gBAAgB,KAAK3D;AAC3B,YAAM4D,eAAepD,UAAU,QAAQ,SAASA;AAEhDmD,oBAAcR,IAAI;QAAE3C,OAAOoD;QAActC,SAAS,KAAKwC,cAAcxC,OAAAA;QAAU,GAAGyC;MAAS,CAAA;IAC7F,OAAO;AAEL,YAAMI,kBAAkBJ,WAAW,GAAGzC,OAAAA,IAAW8C,KAAKC,UAAUN,QAAAA,CAAAA,KAAczC;AAC9E,WAAKd,KAAAA,EAAO2D,iBAAiBT,GAAAA;IAC/B;EACF;EAEQI,cAAcxC,SAA6B;AACjD,QAAIA,mBAAmBjB,MAAO,QAAOiB,QAAQA;AAC7C,QAAI,OAAOA,YAAY,YAAYA,YAAY,MAAM;AACnD,UAAI;AACF,eAAO8C,KAAKC,UAAU/C,OAAAA;MACxB,QAAQ;AACN,eAAOgD,OAAOhD,OAAAA;MAChB;IACF;AACA,WAAOgD,OAAOhD,OAAAA;EAChB;;EAGQ0C,eAAeD,WAAwB,CAAC,GAAG7D,SAAkBsB,OAA6B;AAChG,UAAM+C,WAAwB;MAAE,GAAGR;IAAS;AAE5C,QAAI7D,QAASqE,UAASrE,UAAUA;AAEhC,UAAMsE,qBAAqBC,sBAAAA;AAC3B,QAAID,oBAAoB;AACtB,UAAIA,mBAAmBjD,cAAegD,UAAShD,gBAAgBiD,mBAAmBjD;AAClF,iBAAW,CAACmD,KAAKC,KAAAA,KAAUC,OAAOC,QAAQL,kBAAAA,GAAqB;AAC7D,YAAIE,QAAQ,iBAAiB;AAC3BH,mBAASG,GAAAA,IAAOC;QAClB;MACF;IACF;AAEA,QAAInD,MAAO+C,UAAS/C,QAAQA;AAE5B,WAAO+C;EACT;EAEAO,MAAM5E,SAAgC;AACpC,UAAM6E,cAAc,IAAIhF,eAAc,KAAKE,SAAS,KAAKE,aAAa;AACtE4E,gBAAYtB,WAAWvD,OAAAA;AACvB,WAAO6E;EACT;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AJxNO,IAAMC,wBAAN,MAAMA;SAAAA;;;;EACMC;EACAC;EACAC;EAEjB,YACmBC,QACLC,SACZ;SAFiBD,SAAAA;AAGjB,SAAKH,mBAAmBI,SAASJ,oBAAoB;AACrD,SAAKC,oBAAoBG,SAASH,qBAAqB;AACvD,SAAKC,uBAAuBE,SAASF,wBAAwB;EAC/D;EAEAG,UAAUC,SAA2BC,MAAwC;AAC3E,QAAID,QAAQE,QAAO,MAAO,QAAQ;AAChC,aAAOD,KAAKE,OAAM;IACpB;AAEA,UAAMC,cAAcJ,QAAQK,aAAY;AACxC,UAAMC,UAAUF,YAAYG,WAAU;AACtC,UAAMC,WAAWJ,YAAYK,YAAW;AAExC,UAAMC,YAAYC,KAAKC,IAAG;AAG1B,QAAI,KAAKlB,kBAAkB;AACzB,WAAKmB,WAAWP,OAAAA;IAClB;AAGA,WAAOL,KAAKE,OAAM,EAAGW,KACnBC,IAAI,MAAA;AACF,UAAI,KAAKpB,mBAAmB;AAC1B,cAAMqB,WAAWL,KAAKC,IAAG,IAAKF;AAC9B,aAAKO,YAAYX,SAASE,UAAUQ,QAAAA;MACtC;IACF,CAAA,GACAE,WAAW,CAACC,UAAAA;AACV,YAAMH,WAAWL,KAAKC,IAAG,IAAKF;AAC9B,WAAKU,SAASd,SAASE,UAAUQ,UAAUG,KAAAA;AAC3C,YAAMA;IACR,CAAA,CAAA;EAEJ;EAEQN,WAAWP,SAA+B;AAChD,QAAI;AACF,YAAMe,qBAAqBC,sBAAAA;AAC3B,YAAMC,WAAwB;QAC5BC,MAAM;QACNC,QAAQnB,QAAQmB;QAChBC,KAAKpB,QAAQoB;QACbC,eAAeN,oBAAoBM;QACnCC,IAAItB,QAAQsB;QACZC,WAAWvB,QAAQwB,QAAQ,YAAA;MAC7B;AAEA,WAAKjC,OAAOkC,gBAAgB,OAAO,YAAYzB,QAAQmB,MAAM,IAAInB,QAAQoB,GAAG,IAAIH,QAAAA;IAClF,SAASJ,OAAO;AACd,WAAKtB,OAAOsB,MAAM,8BAA+BA,MAAgBa,KAAK;IACxE;EACF;EAEQf,YAAYX,SAAyBE,UAAwBQ,UAAwB;AAC3F,QAAI;AACF,YAAMK,qBAAqBC,sBAAAA;AAC3B,YAAMW,aAAazB,SAASyB;AAG5B,YAAMC,WAAWD,cAAc,MAAM,UAAUA,cAAc,MAAM,SAAS;AAE5E,YAAMV,WAAwB;QAC5BC,MAAM;QACNC,QAAQnB,QAAQmB;QAChBC,KAAKpB,QAAQoB;QACbO;QACAjB;QACAW,eAAeN,oBAAoBM;MACrC;AAGA,UAAIX,WAAW,KAAKpB,sBAAsB;AACxC2B,iBAASY,cAAc;MACzB;AAEA,YAAMC,UAAUb,SAASY,cACrB,QAAQ7B,QAAQmB,MAAM,IAAInB,QAAQoB,GAAG,IAAIO,UAAAA,MAAgBjB,QAAAA,OACzD,GAAGV,QAAQmB,MAAM,IAAInB,QAAQoB,GAAG,IAAIO,UAAAA,MAAgBjB,QAAAA;AAExD,WAAKnB,OAAOkC,gBAAgBG,UAAUE,SAASb,QAAAA;IACjD,SAASJ,OAAO;AACd,WAAKtB,OAAOsB,MAAM,+BAAgCA,MAAgBa,KAAK;IACzE;EACF;EAEQZ,SAASd,SAAyBE,UAAwBQ,UAAkBG,OAAsB;AACxG,QAAI;AACF,YAAME,qBAAqBC,sBAAAA;AAC3B,YAAMe,MAAMlB;AASZ,YAAMc,aAAaI,IAAIC,UAAUD,IAAIJ,cAAczB,SAASyB,cAAc;AAE1E,YAAMM,UAAUC,YAAYrB,KAAAA;AAC5B,UAAIsB,eAAeJ,IAAID,WAAWC,IAAIK,UAAU;AAChD,UAAIH,SAASH,WAAWG,QAAQH,YAAYC,IAAID,SAAS;AACvDK,uBAAe,GAAGA,YAAAA,kBAAyBF,QAAQH,OAAO,GAAGG,QAAQI,OAAO,KAAKJ,QAAQI,IAAI,MAAM,EAAA;MACrG;AAEA,YAAMpB,WAAwB;QAC5BC,MAAM;QACNC,QAAQnB,QAAQmB;QAChBC,KAAKpB,QAAQoB;QACbO;QACAjB;QACAW,eAAeN,oBAAoBM;QACnCiB,WAAWP,IAAIQ,QAAQ;QACvBJ;MACF;AAGA,UAAIF,SAAS;AACXhB,iBAASuB,UAAUP;MACrB;AAEA,UAAIF,IAAIL,OAAO;AACbT,iBAASwB,QAAQV,IAAIL;MACvB;AAEA,UAAIK,IAAI7B,UAAU;AAChBe,iBAASyB,eAAeX,IAAI7B;MAC9B;AAEA,YAAM4B,UAAU,SAAS9B,QAAQmB,MAAM,IAAInB,QAAQoB,GAAG,IAAIO,UAAAA,MAAgBQ,YAAAA;AAC1E,WAAK5C,OAAOkC,gBAAgB,SAASK,SAASb,QAAAA;IAChD,SAAS0B,cAAc;AACrB,WAAKpD,OAAOsB,MAAM,4BAA6B8B,aAAuBjB,KAAK;IAC7E;EACF;AACF;;;;;;;;;;;;AM5JA,SAEEkB,QACAC,UAAAA,SAEAC,cAGK;;;ACRP,SAASC,cAAAA,mBAAuC;;;;;;;;;;;;AAgBzC,IAAMC,0BAAN,MAAMA;SAAAA;;;EACMC;EACAC;EAEjB,YAAYC,UAA0C,CAAC,GAAG;AACxD,SAAKF,oBAAoBE,QAAQF,qBAAqB;AACtD,SAAKC,iBAAiBC,QAAQD,kBAAkBE;EAClD;;EAGAC,IAAIC,MAAsBC,OAAqBC,MAAwB;AAErE,UAAMC,gBAAgBC,sBAAAA;AAGtB,QAAI,KAAKT,mBAAmB;AAC1BU,iCAA2BJ,OAAOE,eAAe,KAAKP,cAAc;IACtE;AAGAU,8BAA0B;MAAEH;IAAc,GAAG,MAAA;AAC3CD,WAAAA;IACF,CAAA;EACF;;EAGA,MAAMK,UAAUP,MAAsBC,OAAoC;AAExE,UAAME,gBAAgBC,sBAAAA;AAGtB,QAAI,KAAKT,mBAAmB;AAC1BU,iCAA2BJ,OAAOE,eAAe,KAAKP,cAAc;IACtE;AAGA,UAAMY,QAAQC,mBAAmBC,SAAQ;AACzC,QAAI,CAACF,OAAO;AAEVC,yBAAmBE,UAAU;QAAER;MAAc,CAAA;IAC/C;EACF;AACF;;;;;;;;;;;;;;;;;AD1CO,IAAMS,wBAAwBC,OAAO,uBAAA;AAE5C,IAAMC,yBAAyB;EAC7BC,UAAU;EACVC,qBAAqB;EACrBC,kBAAkB;EAClBC,UAAU;EACVC,UAAU;AACZ;AAIA,IAAMC,sBAAoE;EACxEC,aAAa;IACXN,UAAU;IACVO,OAAO;IACPC,QAAQ;IACRC,kBAAkB;IAClBR,qBAAqB;IACrBC,kBAAkB;IAClBQ,YAAY;MACVC,kBAAkB;MAClBC,mBAAmB;MACnBC,sBAAsB;IACxB;EACF;EAEAC,SAAS;IACPd,UAAU;IACVO,OAAO;IACPC,QAAQ;IACRC,kBAAkB;IAClBR,qBAAqB;IACrBC,kBAAkB;IAClBQ,YAAY;MACVC,kBAAkB;MAClBC,mBAAmB;MACnBC,sBAAsB;IACxB;EACF;EAEAE,YAAY;IACVf,UAAU;IACVO,OAAO;IACPC,QAAQ;IACRC,kBAAkB;IAClBR,qBAAqB;IACrBC,kBAAkB;IAClBQ,YAAY;MACVC,kBAAkB;MAClBC,mBAAmB;MACnBC,sBAAsB;IACxB;EACF;EAEAG,MAAM;IACJhB,UAAU;IACVO,OAAO;IACPC,QAAQ;IACRC,kBAAkB;IAClBR,qBAAqB;IACrBC,kBAAkB;EACpB;AACF;AAKA,SAASe,kBAAkBC,UAA+B,CAAC,GAAC;AAE1D,QAAMC,SAASD,QAAQE,cAClBf,oBAAoBa,QAAQE,WAAW,KAAKf,oBAAoBC,cACjED,oBAAoBC;AAGxB,QAAMe,kBAAkBC,OAAOC,YAAYD,OAAOE,QAAQN,OAAAA,EAASO,OAAO,CAAC,CAACC,GAAGC,KAAAA,MAAWA,UAAUC,MAAAA,CAAAA;AAGpG,MAAIP,gBAAgBX,cAAcS,QAAQT,YAAY;AACpDW,oBAAgBX,aAAa;MAC3B,GAAGS,OAAOT;MACV,GAAGY,OAAOC,YAAYD,OAAOE,QAAQH,gBAAgBX,UAAU,EAAEe,OAAO,CAAC,CAACC,GAAGC,KAAAA,MAAWA,UAAUC,MAAAA,CAAAA;IACpG;EACF;AAGA,QAAMC,SAAS;IACb,GAAG9B;IACH,GAAGoB;IACH,GAAGE;EACL;AAEA,SAAOQ;AACT;AAzBSZ;AA8BT,SAASa,4BAA4BZ,SAA4B;AAC/D,SAAO;IACLa,SAASC;IACTC,YAAY,6BAAA;AACV,YAAMC,SAAS,IAAIF,QAAAA;AAGnB,UAAId,QAAQX,OAAO;AACjB,cAAM4B,SAASC,cAAclB,QAAQX,KAAK;AACzC2B,eAA+DG,eAAeF,MAAAA;MACjF;AAEA,aAAOD;IACT,GAVY;EAWd;AACF;AAfSJ;AAkBT,SAASQ,sBAAsBpB,UAA+B,CAAC,GAAC;AAE9D,QAAMqB,gBAAgBtB,kBAAkBC,OAAAA;AAGxC,QAAMsB,YAAwB;;IAE5B;MACET,SAASlC;MACT4C,UAAUF;IACZ;;AAIF,MAAIA,cAAcvC,aAAa,WAAW;AACxCwC,cAAUE,KAAKZ,4BAA4BS,aAAAA,CAAAA;EAC7C;AAGAC,YAAUE,KAAK;IACbX,SAASY;IACTV,YAAY,wBAACW,MAA2BC,kBAAAA;AACtC,aAAO,IAAIF,cAAcC,MAAMC,aAAAA;IACjC,GAFY;IAGZC,QAAQ;MAACjD;MAAuB;QAAEkD,OAAOf;QAAQgB,UAAU;MAAK;;EAClE,CAAA;AAGAR,YAAUE,KAAK;IACbX,SAASkB;IACThB,YAAY,6BAAA;AACV,aAAO,IAAIgB,wBAAwB;QACjCC,mBAAmB;QACnBC,gBAAgB;MAClB,CAAA;IACF,GALY;EAMd,CAAA;AAGAX,YAAUE,KAAK;IACbX,SAASqB;IACTnB,YAAY,wBAACC,QAAuBU,SAAAA;AAElC,YAAMS,oBAAoBT,KAAKlC,cAAc;QAC3CC,kBAAkBiC,KAAK1C;QACvBU,mBAAmBgC,KAAK1C;MAC1B;AACA,aAAO,IAAIkD,sBAAsBlB,QAAQmB,iBAAAA;IAC3C,GAPY;IAQZP,QAAQ;MAACH;MAAe9C;;EAC1B,CAAA;AAEA,SAAO2C;AACT;AArDSF;AA0DT,SAASF,cAAc7B,OAAa;AAClC,QAAM+C,YAA4B;IAAC;IAAS;IAAQ;IAAO;IAAS;;AAGpE,QAAMC,eAAe,wBAACC,MAAiCF,UAAUG,SAASD,CAAAA,GAArD;AAErB,MAAI,CAACD,aAAahD,KAAAA,GAAQ;AACxB,WAAO;MAAC;MAAS;MAAQ;;EAC3B;AAEA,QAAMmD,aAAaJ,UAAUK,QAAQpD,KAAAA;AACrC,SAAO+C,UAAUM,MAAM,GAAGF,aAAa,CAAA;AACzC;AAZStB;AAgBF,IAAMyB,eAAN,MAAMA,cAAAA;SAAAA;;;;EAEX,OAAOC,QAAQ5C,UAA+B,CAAC,GAAkB;AAC/D,UAAMsB,YAAYF,sBAAsBpB,OAAAA;AAExC,WAAO;MACL6C,QAAQF;MACRrB;MACAwB,SAAS;QAACrB;QAAeM;QAAyBG;QAAuBvD;;IAC3E;EACF;;EAGA,OAAOoE,aAA8C/C,SAAqD;AACxG,UAAMgD,iBAAiBL,cAAaM,qBAAqBjD,OAAAA;AAEzD,WAAO;MACL6C,QAAQF;MACRO,SAASlD,QAAQkD,WAAW,CAAA;MAC5B5B,WAAW;WACN0B;;QAEH;UACEnC,SAASC;UACTC,YAAY,wBAACW,SAAAA;AACX,gBAAIA,KAAK5C,aAAa,WAAW;AAC/B,oBAAMkC,SAAS,IAAIF,QAAAA;AACnB,kBAAIY,KAAKrC,OAAO;AACd,sBAAM4B,SAASC,cAAcQ,KAAKrC,KAAK;AACtC2B,uBAA+DG,eAAeF,MAAAA;cACjF;AACA,qBAAOD;YACT;AACA,mBAAO;UACT,GAVY;UAWZY,QAAQ;YAACjD;;QACX;;QAEA;UACEkC,SAASY;UACTV,YAAY,wBAACW,MAA2BC,kBAAAA;AACtC,mBAAO,IAAIF,cAAcC,MAAMC,aAAAA;UACjC,GAFY;UAGZC,QAAQ;YAACjD;YAAuB;cAAEkD,OAAOf;cAAQgB,UAAU;YAAK;;QAClE;;QAEA;UACEjB,SAASkB;UACThB,YAAY,6BAAA;AACV,mBAAO,IAAIgB,wBAAwB;cACjCC,mBAAmB;cACnBC,gBAAgB;YAClB,CAAA;UACF,GALY;QAMd;;QAEA;UACEpB,SAASqB;UACTnB,YAAY,wBAACC,QAAuBU,SAAAA;AAElC,kBAAMS,oBAAoBT,KAAKlC,cAAc;cAC3CC,kBAAkBiC,KAAK1C;cACvBU,mBAAmBgC,KAAK1C;YAC1B;AACA,mBAAO,IAAIkD,sBAAsBlB,QAAQmB,iBAAAA;UAC3C,GAPY;UAQZP,QAAQ;YAACH;YAAe9C;;QAC1B;;MAEFmE,SAAS;QAACrB;QAAeM;QAAyBG;QAAuBvD;;IAC3E;EACF;;EAGAwE,UAAUC,WAAqC;EAE/C;;EAGA,OAAeH,qBAAqBjD,SAA0D;AAC5F,QAAIA,QAAQe,YAAY;AACtB,aAAO;QAAC4B,cAAaU,2BAA2BrD,OAAAA;;IAClD;AAEA,UAAMsB,YAAwB;MAACqB,cAAaU,2BAA2BrD,OAAAA;;AAEvE,QAAIA,QAAQsD,UAAU;AACpBhC,gBAAUE,KAAK;QACbX,SAASb,QAAQsD;QACjBA,UAAUtD,QAAQsD;MACpB,CAAA;IACF;AAEA,WAAOhC;EACT;;EAGA,OAAe+B,2BAA2BrD,SAAwD;AAChG,QAAIA,QAAQe,YAAY;AACtB,aAAO;QACLF,SAASlC;QACToC,YAAY,iCAAUwC,SAAAA;AACpB,gBAAMC,cAAc,MAAMxD,QAAQe,aAAU,GAAMwC,IAAAA;AAClD,iBAAOxD,kBAAkByD,WAAAA;QAC3B,GAHY;QAIZ5B,QAAQ5B,QAAQ4B,UAAU,CAAA;MAC5B;IACF;AAEA,QAAI5B,QAAQsD,UAAU;AACpB,aAAO;QACLzC,SAASlC;QACToC,YAAY,8BAAO0C,mBAAAA;AACjB,gBAAMD,cAAc,MAAMC,eAAeC,oBAAmB;AAC5D,iBAAO3D,kBAAkByD,WAAAA;QAC3B,GAHY;QAIZ5B,QAAQ;UAAC5B,QAAQsD;;MACnB;IACF;AAEA,QAAItD,QAAQ2D,aAAa;AACvB,aAAO;QACL9C,SAASlC;QACToC,YAAY,8BAAO0C,mBAAAA;AACjB,gBAAMD,cAAc,MAAMC,eAAeC,oBAAmB;AAC5D,iBAAO3D,kBAAkByD,WAAAA;QAC3B,GAHY;QAIZ5B,QAAQ;UAAC5B,QAAQ2D;;MACnB;IACF;AAEA,UAAM,IAAIC,MAAM,mFAAA;EAClB;AACF;;;;;","names":["Injectable","Optional","catchError","tap","HttpStatus","HttpException","findPgError","error","depth","undefined","candidate","code","cause","Injectable","Optional","createLogger","format","transports","DailyRotateFile","AsyncLocalStorage","randomUUID","correlationStorage","AsyncLocalStorage","getCorrelationContext","getStore","runWithCorrelationContext","context","callback","run","updateCorrelationContext","updates","Object","assign","DEFAULT_CORRELATION_HEADER","generateCorrelationId","randomUUID","addCorrelationIdToResponse","reply","correlationId","headerName","header","raw","setHeader","LoggerService","activeLogger","options","context","defaultLogger","provider","Error","createWinstonLogger","opts","level","logFormat","format","baseFormatters","timestamp","errors","stack","consoleTransport","transports","Console","combine","json","printf","info","message","correlationId","trace","parts","toUpperCase","padEnd","toString","slice","filter","Boolean","output","join","colorize","all","winstonTransports","enableFileLogger","filePath","maxFiles","push","DailyRotateFile","filename","datePattern","maxSize","config","exitOnError","defaultMeta","appName","environment","createLogger","log","_log","error","warn","debug","verbose","setContext","ctx","winstonLogger","winstonLevel","formattedMessage","formatMessage","metadata","enrichMetadata","nestLogger","logWithMetadata","messageWithMeta","JSON","stringify","String","enriched","correlationContext","getCorrelationContext","key","value","Object","entries","child","childLogger","HttpLoggerInterceptor","enableRequestLog","enableResponseLog","slowRequestThreshold","logger","options","intercept","context","next","getType","handle","httpContext","switchToHttp","request","getRequest","response","getResponse","startTime","Date","now","logRequest","pipe","tap","duration","logResponse","catchError","error","logError","correlationContext","getCorrelationContext","metadata","type","method","url","correlationId","ip","userAgent","headers","logWithMetadata","stack","statusCode","logLevel","slowRequest","message","err","status","pgCause","findPgError","errorMessage","detail","code","errorName","name","pgError","trace","errorDetails","loggingError","Global","Logger","Module","Injectable","CorrelationIdMiddleware","includeInResponse","responseHeader","options","DEFAULT_CORRELATION_HEADER","use","_req","reply","next","correlationId","generateCorrelationId","addCorrelationIdToResponse","runWithCorrelationContext","onRequest","store","correlationStorage","getStore","enterWith","LOGGER_MODULE_OPTIONS","Symbol","DEFAULT_LOGGER_OPTIONS","provider","enableCorrelationId","enableHttpLogger","filePath","maxFiles","ENVIRONMENT_PRESETS","development","level","format","enableFileLogger","httpLogger","enableRequestLog","enableResponseLog","slowRequestThreshold","staging","production","test","mergeWithDefaults","options","preset","environment","filteredOptions","Object","fromEntries","entries","filter","_","value","undefined","merged","createDefaultLoggerProvider","provide","Logger","useFactory","logger","levels","getLevelsUpTo","setLogLevels","createLoggerProviders","mergedOptions","providers","useValue","push","LoggerService","opts","defaultLogger","inject","token","optional","CorrelationIdMiddleware","includeInResponse","responseHeader","HttpLoggerInterceptor","httpLoggerOptions","allLevels","isValidLevel","l","includes","levelIndex","indexOf","slice","LoggerModule","forRoot","module","exports","forRootAsync","asyncProviders","createAsyncProviders","imports","configure","_consumer","createAsyncOptionsProvider","useClass","args","userOptions","optionsFactory","createLoggerOptions","useExisting","Error"]}
1
+ {"version":3,"sources":["../src/logger/interceptors/http-logger.interceptor.ts","../src/exceptions/conflict.exception.ts","../src/exceptions/base-field.exception.ts","../src/filters/pg-error.translator.ts","../src/logger/services/logger.service.ts","../src/logger/utils/index.ts","../src/logger/logger.module.ts","../src/logger/middleware/correlation-id.middleware.ts"],"sourcesContent":["import { type CallHandler, type ExecutionContext, Injectable, type NestInterceptor, Optional } from '@nestjs/common';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport type { Observable } from 'rxjs';\nimport { catchError, tap } from 'rxjs/operators';\nimport { findPgError } from '../../filters/pg-error.translator';\nimport { LoggerService } from '../services/logger.service';\nimport type { HttpLoggerOptions, LogMetadata } from '../types';\nimport { getCorrelationContext } from '../utils';\n\n@Injectable()\nexport class HttpLoggerInterceptor implements NestInterceptor {\n private readonly enableRequestLog: boolean;\n private readonly enableResponseLog: boolean;\n private readonly slowRequestThreshold: number;\n\n constructor(\n private readonly logger: LoggerService,\n @Optional() options?: HttpLoggerOptions,\n ) {\n this.enableRequestLog = options?.enableRequestLog ?? true;\n this.enableResponseLog = options?.enableResponseLog ?? true;\n this.slowRequestThreshold = options?.slowRequestThreshold ?? 3000; // 3 seconds\n }\n\n intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {\n if (context.getType() !== 'http') {\n return next.handle();\n }\n\n const httpContext = context.switchToHttp();\n const request = httpContext.getRequest<FastifyRequest>();\n const response = httpContext.getResponse<FastifyReply>();\n\n const startTime = Date.now();\n\n // Log incoming request\n if (this.enableRequestLog) {\n this.logRequest(request);\n }\n\n // Process request and log response/errors\n return next.handle().pipe(\n tap(() => {\n if (this.enableResponseLog) {\n const duration = Date.now() - startTime;\n this.logResponse(request, response, duration);\n }\n }),\n catchError((error) => {\n const duration = Date.now() - startTime;\n this.logError(request, response, duration, error);\n throw error;\n }),\n );\n }\n\n private logRequest(request: FastifyRequest): void {\n try {\n const correlationContext = getCorrelationContext();\n const metadata: LogMetadata = {\n type: 'http_request',\n method: request.method,\n url: request.url,\n correlationId: correlationContext?.correlationId,\n ip: request.ip,\n userAgent: request.headers['user-agent'],\n };\n\n this.logger.logWithMetadata('log', `Incoming ${request.method} ${request.url}`, metadata);\n } catch (error) {\n this.logger.error('Failed to log HTTP request', (error as Error).stack);\n }\n }\n\n private logResponse(request: FastifyRequest, response: FastifyReply, duration: number): void {\n try {\n const correlationContext = getCorrelationContext();\n const statusCode = response.statusCode;\n\n // Determine log level based on status code\n const logLevel = statusCode >= 500 ? 'error' : statusCode >= 400 ? 'warn' : 'log';\n\n const metadata: LogMetadata = {\n type: 'http_response',\n method: request.method,\n url: request.url,\n statusCode,\n duration,\n correlationId: correlationContext?.correlationId,\n };\n\n // Flag slow requests\n if (duration > this.slowRequestThreshold) {\n metadata.slowRequest = true;\n }\n\n const message = metadata.slowRequest\n ? `SLOW ${request.method} ${request.url} ${statusCode} - ${duration}ms`\n : `${request.method} ${request.url} ${statusCode} - ${duration}ms`;\n\n this.logger.logWithMetadata(logLevel, message, metadata);\n } catch (error) {\n this.logger.error('Failed to log HTTP response', (error as Error).stack);\n }\n }\n\n private logError(request: FastifyRequest, response: FastifyReply, duration: number, error: unknown): void {\n try {\n const correlationContext = getCorrelationContext();\n const err = error as {\n name?: string;\n message?: string;\n detail?: string;\n status?: number;\n statusCode?: number;\n stack?: string;\n response?: unknown;\n };\n const statusCode = err.status ?? err.statusCode ?? response.statusCode ?? 500;\n // Drizzle wraps pg errors in DrizzleQueryError whose `.message` is only the failed query — unwrap the real reason from `.cause`.\n const pgCause = findPgError(error);\n let errorMessage = err.message || err.detail || 'Unknown error';\n if (pgCause?.message && pgCause.message !== err.message) {\n errorMessage = `${errorMessage} — cause: ${pgCause.message}${pgCause.code ? ` [${pgCause.code}]` : ''}`;\n }\n\n const metadata: LogMetadata = {\n type: 'http_error',\n method: request.method,\n url: request.url,\n statusCode,\n duration,\n correlationId: correlationContext?.correlationId,\n errorName: err.name || 'Error',\n errorMessage,\n };\n\n // Attach the structured pg cause so log sinks capture SQLSTATE, constraint, table, etc.\n if (pgCause) {\n metadata.pgError = pgCause;\n }\n\n if (err.stack) {\n metadata.trace = err.stack;\n }\n\n if (err.response) {\n metadata.errorDetails = err.response;\n }\n\n const message = `ERROR ${request.method} ${request.url} ${statusCode} - ${errorMessage}`;\n this.logger.logWithMetadata('error', message, metadata);\n } catch (loggingError) {\n this.logger.error('Failed to log HTTP error', (loggingError as Error).stack);\n }\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ConflictException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Conflict', HttpStatus.CONFLICT);\n }\n}\n","import { HttpException, HttpStatus } from '@nestjs/common';\nimport type { FieldError } from '../types/error-response.types';\n\n// Re-export FieldError for backwards compatibility\nexport type { FieldError } from '../types/error-response.types';\n\nexport interface ProblemOptions {\n type?: string;\n label?: string;\n detail?: string;\n errors?: FieldError[];\n}\n\nexport abstract class HttpProblemException extends HttpException {\n constructor(detailOrOptions: string | ProblemOptions, httpStatus: HttpStatus) {\n const options = typeof detailOrOptions === 'string' ? { detail: detailOrOptions } : detailOrOptions;\n\n super(\n {\n type: options.type ?? 'about:blank',\n label: options.label,\n detail: options.detail,\n errors: options.errors ?? [],\n },\n httpStatus,\n );\n }\n}\n","import { ConflictException } from '../exceptions/conflict.exception';\n\nconst PG_UNIQUE_VIOLATION = '23505';\n\nexport type PgErrorShape = {\n code?: string;\n message?: string;\n constraint?: string;\n table?: string;\n schema?: string;\n column?: string;\n detail?: string;\n hint?: string;\n};\n\n// Returns a ConflictException for a Postgres unique-violation error, otherwise undefined.\nexport function tryTranslatePgError(error: unknown): ConflictException | undefined {\n const pgError = findPgError(error);\n if (!pgError) return undefined;\n const { code, constraint, table, detail } = pgError;\n if (code !== PG_UNIQUE_VIOLATION) return undefined;\n return new ConflictException({\n label: 'Duplicate Entry',\n detail: detail?.trim() || 'A record with these values already exists.',\n errors: [],\n ...(constraint || table ? { meta: { constraint, table } } : {}),\n });\n}\n\n// Walks up to N levels of `.cause` looking for a pg-shaped error (has SQLSTATE `code`), capping depth.\nexport function findPgError(error: unknown, depth = 0): PgErrorShape | undefined {\n if (!error || typeof error !== 'object' || depth > 5) return undefined;\n const candidate = error as PgErrorShape & { cause?: unknown };\n if (typeof candidate.code === 'string') return candidate;\n return findPgError(candidate.cause, depth + 1);\n}\n","import { Injectable, type Logger, type LoggerService as NestLoggerService, Optional } from '@nestjs/common';\nimport { createLogger, format, type LoggerOptions, transports, type Logger as WinstonLogger } from 'winston';\nimport DailyRotateFile from 'winston-daily-rotate-file';\nimport type { LoggerModuleOptions, LogLevel, LogMetadata } from '../types';\nimport { getCorrelationContext } from '../utils';\n\nexport type LogMessage = string | Error | object;\n\n@Injectable()\nexport class LoggerService implements NestLoggerService {\n private readonly activeLogger: NestLoggerService | WinstonLogger;\n private readonly options: LoggerModuleOptions;\n private context?: string;\n\n constructor(\n @Optional() options: LoggerModuleOptions = {},\n @Optional() private readonly defaultLogger?: Logger,\n ) {\n this.options = options;\n const provider = options.provider ?? 'winston';\n\n if (provider === 'default') {\n if (!this.defaultLogger) {\n throw new Error('LoggerService: Default Logger not provided');\n }\n this.activeLogger = this.defaultLogger;\n } else {\n this.activeLogger = this.createWinstonLogger(options);\n }\n }\n\n // Creates a Winston logger instance with inline transports and format configuration\n private createWinstonLogger(opts: LoggerModuleOptions): WinstonLogger {\n const level = opts.level ?? 'debug';\n const logFormat = opts.format ?? 'text';\n\n // Base formatters — Winston merges metadata into the info object, so all properties are already at the top level.\n const baseFormatters = [format.timestamp({ format: 'YYYY-MM-DDTHH:mm:ss.SSSZ' }), format.errors({ stack: true })];\n\n // Console transport\n const consoleTransport =\n logFormat === 'json'\n ? new transports.Console({\n level,\n format: format.combine(...baseFormatters, format.json()),\n })\n : new transports.Console({\n level,\n format: format.combine(\n ...baseFormatters,\n format.printf((info) => {\n const { timestamp, level, message, context, correlationId, trace } = info;\n const parts = [\n timestamp,\n level.toUpperCase().padEnd(7),\n correlationId ? `[${correlationId.toString().slice(-6)}]` : '',\n context ? `[${context}]` : '',\n message,\n ].filter(Boolean);\n let output = parts.join(' ');\n\n // Append stack trace on new line if present\n if (trace) {\n output += `\\n${trace}`;\n }\n\n return output;\n }),\n format.colorize({ all: true }),\n ),\n });\n\n const winstonTransports: (InstanceType<typeof transports.Console> | DailyRotateFile)[] = [consoleTransport];\n\n // File transports\n if (opts.enableFileLogger) {\n const filePath = opts.filePath ?? './logs';\n const maxFiles = opts.maxFiles ?? '14d';\n\n winstonTransports.push(\n new DailyRotateFile({\n level,\n filename: `${filePath}/%DATE%-combined.log`,\n datePattern: 'YYYY-MM-DD',\n maxSize: '20m',\n maxFiles,\n format: format.combine(format.timestamp(), format.json()),\n }),\n new DailyRotateFile({\n level: 'error',\n filename: `${filePath}/%DATE%-error.log`,\n datePattern: 'YYYY-MM-DD',\n maxSize: '20m',\n maxFiles,\n format: format.combine(format.timestamp(), format.json()),\n }),\n );\n }\n\n const config: LoggerOptions = {\n level,\n transports: winstonTransports,\n exitOnError: false,\n };\n\n if (opts.defaultMeta || opts.appName) {\n config.defaultMeta = {\n ...opts.defaultMeta,\n appName: opts.appName,\n environment: opts.environment,\n };\n }\n\n return createLogger(config);\n }\n\n // NestJS LoggerService interface methods\n log(message: LogMessage, context?: string): void {\n this._log('log', message, context);\n }\n\n error(message: LogMessage, trace?: string, context?: string): void {\n this._log('error', message, context, trace);\n }\n\n warn(message: LogMessage, context?: string): void {\n this._log('warn', message, context);\n }\n\n debug(message: LogMessage, context?: string): void {\n this._log('debug', message, context);\n }\n\n verbose(message: LogMessage, context?: string): void {\n this._log('verbose', message, context);\n }\n\n setContext(context: string): void {\n this.context = context;\n }\n\n // Dispatches a log entry to either the Winston or NestJS logger implementation\n private _log(level: LogLevel, message: LogMessage, context?: string, trace?: string): void {\n const ctx = context ?? this.context;\n\n // Check if Winston logger by duck typing\n if ('format' in this.activeLogger && 'transports' in this.activeLogger) {\n // Winston logger path\n const winstonLogger = this.activeLogger as WinstonLogger;\n const winstonLevel = level === 'log' ? 'info' : level;\n const formattedMessage = this.formatMessage(message);\n const metadata = this.enrichMetadata({}, ctx, trace);\n // Winston merges all properties into the info object when using object syntax\n winstonLogger.log({ level: winstonLevel, message: formattedMessage, ...metadata });\n } else {\n // NestJS logger path\n const nestLogger = this.activeLogger as Logger;\n if (level === 'error' && trace) {\n ctx ? nestLogger.error(message, trace, ctx) : nestLogger.error(message, trace);\n } else if (level === 'log') {\n ctx ? nestLogger.log(message, ctx) : nestLogger.log(message);\n } else if (level === 'warn') {\n ctx ? nestLogger.warn(message, ctx) : nestLogger.warn(message);\n } else if (level === 'debug' && nestLogger.debug) {\n ctx ? nestLogger.debug(message, ctx) : nestLogger.debug(message);\n } else if (level === 'verbose' && nestLogger.verbose) {\n ctx ? nestLogger.verbose(message, ctx) : nestLogger.verbose(message);\n }\n }\n }\n\n // Logs a message with custom metadata fields (Winston only)\n logWithMetadata(level: LogLevel, message: LogMessage, metadata?: LogMetadata, context?: string): void {\n const ctx = context ?? this.context;\n\n // Check if Winston logger by duck typing\n if ('format' in this.activeLogger && 'transports' in this.activeLogger) {\n const winstonLogger = this.activeLogger as WinstonLogger;\n const winstonLevel = level === 'log' ? 'info' : level;\n // Winston merges all properties into the info object when using object syntax\n winstonLogger.log({ level: winstonLevel, message: this.formatMessage(message), ...metadata });\n } else {\n // Fallback for default logger\n const messageWithMeta = metadata ? `${message} ${JSON.stringify(metadata)}` : message;\n this[level](messageWithMeta, ctx);\n }\n }\n\n private formatMessage(message: LogMessage): string {\n if (message instanceof Error) return message.message;\n if (typeof message === 'object' && message !== null) {\n try {\n return JSON.stringify(message);\n } catch {\n return String(message);\n }\n }\n return String(message);\n }\n\n // Enriches metadata with correlation context from AsyncLocalStorage\n private enrichMetadata(metadata: LogMetadata = {}, context?: string, trace?: string): LogMetadata {\n const enriched: LogMetadata = { ...metadata };\n\n if (context) enriched.context = context;\n\n const correlationContext = getCorrelationContext();\n if (correlationContext) {\n if (correlationContext.correlationId) enriched.correlationId = correlationContext.correlationId;\n for (const [key, value] of Object.entries(correlationContext)) {\n if (key !== 'correlationId') {\n enriched[key] = value;\n }\n }\n }\n\n if (trace) enriched.trace = trace;\n\n return enriched;\n }\n\n child(context: string): LoggerService {\n const childLogger = new LoggerService(this.options, this.defaultLogger);\n childLogger.setContext(context);\n return childLogger;\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport { randomUUID } from 'node:crypto';\nimport type { FastifyReply } from 'fastify';\nimport type { CorrelationContext } from '../types';\n\n// Async Context Management (AsyncLocalStorage)\n\nexport const correlationStorage = new AsyncLocalStorage<CorrelationContext>();\n\n// Returns the current correlation context from AsyncLocalStorage\nexport function getCorrelationContext(): CorrelationContext | undefined {\n return correlationStorage.getStore();\n}\n\n// Runs a callback within the given correlation context\nexport function runWithCorrelationContext<T>(context: CorrelationContext, callback: () => T): T {\n return correlationStorage.run(context, callback);\n}\n\n// Updates the current correlation context with new values\nexport function updateCorrelationContext(updates: Partial<CorrelationContext>): void {\n const context = correlationStorage.getStore();\n if (context) {\n Object.assign(context, updates);\n }\n}\n\n// Correlation ID Management\n\nexport const DEFAULT_CORRELATION_HEADER = 'x-correlation-id';\n\n// Generates a new UUID v4 correlation ID for the current request\nexport function generateCorrelationId(): string {\n return randomUUID();\n}\n\n// Adds the correlation ID to Fastify response headers\nexport function addCorrelationIdToResponse(\n reply: FastifyReply,\n correlationId: string,\n headerName: string = DEFAULT_CORRELATION_HEADER,\n): void {\n if (typeof reply.header === 'function') {\n reply.header(headerName, correlationId);\n } else if (reply.raw && typeof reply.raw.setHeader === 'function') {\n reply.raw.setHeader(headerName, correlationId);\n }\n}\n","import {\n type DynamicModule,\n Global,\n Logger,\n type MiddlewareConsumer,\n Module,\n type NestModule,\n type Provider,\n} from '@nestjs/common';\nimport { HttpLoggerInterceptor } from './interceptors/http-logger.interceptor';\nimport { CorrelationIdMiddleware } from './middleware/correlation-id.middleware';\nimport { LoggerService } from './services/logger.service';\nimport type { LoggerModuleAsyncOptions, LoggerModuleOptions, LoggerOptionsFactory } from './types';\n\n// Constants (inline from constants.ts)\n\nexport const LOGGER_MODULE_OPTIONS = Symbol('LOGGER_MODULE_OPTIONS');\n\nconst DEFAULT_LOGGER_OPTIONS = {\n provider: 'winston' as const,\n enableCorrelationId: true,\n enableHttpLogger: true,\n filePath: './logs',\n maxFiles: '14d',\n} as const;\n\n// Environment Presets (replaces process.env auto-detection)\n\nconst ENVIRONMENT_PRESETS: Record<string, Partial<LoggerModuleOptions>> = {\n development: {\n provider: 'winston',\n level: 'debug',\n format: 'text',\n enableFileLogger: false,\n enableCorrelationId: true,\n enableHttpLogger: true,\n httpLogger: {\n enableRequestLog: true,\n enableResponseLog: true,\n slowRequestThreshold: 1000, // 1 second - lower threshold for dev\n },\n },\n\n staging: {\n provider: 'winston',\n level: 'log',\n format: 'json',\n enableFileLogger: true,\n enableCorrelationId: true,\n enableHttpLogger: true,\n httpLogger: {\n enableRequestLog: true,\n enableResponseLog: true,\n slowRequestThreshold: 3000, // 3 seconds\n },\n },\n\n production: {\n provider: 'winston',\n level: 'warn',\n format: 'json',\n enableFileLogger: true,\n enableCorrelationId: true,\n enableHttpLogger: true,\n httpLogger: {\n enableRequestLog: false, // Reduce noise in production\n enableResponseLog: true,\n slowRequestThreshold: 5000, // 5 seconds - higher threshold for prod\n },\n },\n\n test: {\n provider: 'winston',\n level: 'error',\n format: 'json',\n enableFileLogger: false,\n enableCorrelationId: false,\n enableHttpLogger: false,\n },\n} as const;\n\n// Configuration Merging (uses presets instead of process.env)\n\n// Merges user-provided options with default and environment preset values\nfunction mergeWithDefaults(options: LoggerModuleOptions = {}): LoggerModuleOptions {\n // Select preset based on explicit environment option (defaults to development)\n const preset = options.environment\n ? (ENVIRONMENT_PRESETS[options.environment] ?? ENVIRONMENT_PRESETS.development)\n : ENVIRONMENT_PRESETS.development;\n\n // Filter out undefined values from user options to avoid overriding preset defaults\n const filteredOptions = Object.fromEntries(Object.entries(options).filter(([_, value]) => value !== undefined));\n\n // Handle nested httpLogger object - merge with preset httpLogger if both exist\n if (filteredOptions.httpLogger && preset?.httpLogger) {\n filteredOptions.httpLogger = {\n ...preset.httpLogger,\n ...Object.fromEntries(Object.entries(filteredOptions.httpLogger).filter(([_, value]) => value !== undefined)),\n };\n }\n\n // Merge: base defaults < preset < user options (with undefined values removed)\n const merged = {\n ...DEFAULT_LOGGER_OPTIONS,\n ...preset,\n ...filteredOptions,\n };\n\n return merged;\n}\n\n// Provider Factories (inline from logging.providers.ts)\n\n// Creates the default NestJS Logger provider with optional log level configuration\nfunction createDefaultLoggerProvider(options: LoggerModuleOptions): Provider {\n return {\n provide: Logger,\n useFactory: () => {\n const logger = new Logger();\n\n // Set log levels if specified and method exists\n if (options.level) {\n const levels = getLevelsUpTo(options.level);\n (logger as { setLogLevels?: (levels: NestLogLevel[]) => void }).setLogLevels?.(levels);\n }\n\n return logger;\n },\n };\n}\n\n// Builds all logger providers for the module based on merged configuration\nfunction createLoggerProviders(options: LoggerModuleOptions = {}): Provider[] {\n // Merge user options with preset defaults\n const mergedOptions = mergeWithDefaults(options);\n\n // Base providers (always included)\n const providers: Provider[] = [\n // Options provider\n {\n provide: LOGGER_MODULE_OPTIONS,\n useValue: mergedOptions,\n },\n ];\n\n // Default logger provider (only if using default provider)\n if (mergedOptions.provider === 'default') {\n providers.push(createDefaultLoggerProvider(mergedOptions));\n }\n\n // Unified LoggerService facade (always included)\n providers.push({\n provide: LoggerService,\n useFactory: (opts: LoggerModuleOptions, defaultLogger?: Logger) => {\n return new LoggerService(opts, defaultLogger);\n },\n inject: [LOGGER_MODULE_OPTIONS, { token: Logger, optional: true }],\n });\n\n // Correlation ID middleware\n providers.push({\n provide: CorrelationIdMiddleware,\n useFactory: () => {\n return new CorrelationIdMiddleware({\n includeInResponse: true,\n responseHeader: 'x-correlation-id',\n });\n },\n });\n\n // HTTP logger interceptor\n providers.push({\n provide: HttpLoggerInterceptor,\n useFactory: (logger: LoggerService, opts: LoggerModuleOptions) => {\n // Use detailed httpLogger config if provided, otherwise fall back to simple enableHttpLogger\n const httpLoggerOptions = opts.httpLogger ?? {\n enableRequestLog: opts.enableHttpLogger,\n enableResponseLog: opts.enableHttpLogger,\n };\n return new HttpLoggerInterceptor(logger, httpLoggerOptions);\n },\n inject: [LoggerService, LOGGER_MODULE_OPTIONS],\n });\n\n return providers;\n}\n\ntype NestLogLevel = 'error' | 'warn' | 'log' | 'debug' | 'verbose';\n\n// Returns all NestJS log levels up to and including the specified level\nfunction getLevelsUpTo(level: string): NestLogLevel[] {\n const allLevels: NestLogLevel[] = ['error', 'warn', 'log', 'debug', 'verbose'];\n\n // Check if level is a valid NestLogLevel\n const isValidLevel = (l: string): l is NestLogLevel => allLevels.includes(l as NestLogLevel);\n\n if (!isValidLevel(level)) {\n return ['error', 'warn', 'log'];\n }\n\n const levelIndex = allLevels.indexOf(level);\n return allLevels.slice(0, levelIndex + 1);\n}\n\n@Global()\n@Module({})\nexport class LoggerModule implements NestModule {\n // Configures the logger module with static options and environment preset\n static forRoot(options: LoggerModuleOptions = {}): DynamicModule {\n const providers = createLoggerProviders(options);\n\n return {\n module: LoggerModule,\n providers,\n exports: [LoggerService, CorrelationIdMiddleware, HttpLoggerInterceptor, LOGGER_MODULE_OPTIONS],\n };\n }\n\n // Configures the logger module with async options (useFactory, useClass, useExisting)\n static forRootAsync<T extends unknown[] = unknown[]>(options: LoggerModuleAsyncOptions<T>): DynamicModule {\n const asyncProviders = LoggerModule.createAsyncProviders(options as LoggerModuleAsyncOptions<unknown[]>);\n\n return {\n module: LoggerModule,\n imports: options.imports || [],\n providers: [\n ...asyncProviders,\n // Default logger provider\n {\n provide: Logger,\n useFactory: (opts: LoggerModuleOptions) => {\n if (opts.provider === 'default') {\n const logger = new Logger();\n if (opts.level) {\n const levels = getLevelsUpTo(opts.level);\n (logger as { setLogLevels?: (levels: NestLogLevel[]) => void }).setLogLevels?.(levels);\n }\n return logger;\n }\n return null;\n },\n inject: [LOGGER_MODULE_OPTIONS],\n },\n // Unified logger service\n {\n provide: LoggerService,\n useFactory: (opts: LoggerModuleOptions, defaultLogger?: Logger) => {\n return new LoggerService(opts, defaultLogger);\n },\n inject: [LOGGER_MODULE_OPTIONS, { token: Logger, optional: true }],\n },\n // Correlation ID middleware\n {\n provide: CorrelationIdMiddleware,\n useFactory: () => {\n return new CorrelationIdMiddleware({\n includeInResponse: true,\n responseHeader: 'x-correlation-id',\n });\n },\n },\n // HTTP logger interceptor\n {\n provide: HttpLoggerInterceptor,\n useFactory: (logger: LoggerService, opts: LoggerModuleOptions) => {\n // Use detailed httpLogger config if provided, otherwise fall back to simple enableHttpLogger\n const httpLoggerOptions = opts.httpLogger ?? {\n enableRequestLog: opts.enableHttpLogger,\n enableResponseLog: opts.enableHttpLogger,\n };\n return new HttpLoggerInterceptor(logger, httpLoggerOptions);\n },\n inject: [LoggerService, LOGGER_MODULE_OPTIONS],\n },\n ],\n exports: [LoggerService, CorrelationIdMiddleware, HttpLoggerInterceptor, LOGGER_MODULE_OPTIONS],\n };\n }\n\n // Middleware registration is handled globally in main.ts via Fastify hooks\n configure(_consumer: MiddlewareConsumer): void {\n // Middleware is registered globally in main.ts via Fastify's addHook('onRequest') to avoid DI issues with the constructor.\n }\n\n // Creates async providers for dynamic module configuration\n private static createAsyncProviders(options: LoggerModuleAsyncOptions<unknown[]>): Provider[] {\n if (options.useFactory) {\n return [LoggerModule.createAsyncOptionsProvider(options)];\n }\n\n const providers: Provider[] = [LoggerModule.createAsyncOptionsProvider(options)];\n\n if (options.useClass) {\n providers.push({\n provide: options.useClass,\n useClass: options.useClass,\n });\n }\n\n return providers;\n }\n\n // Creates the DI provider that resolves and merges async logger options\n private static createAsyncOptionsProvider(options: LoggerModuleAsyncOptions<unknown[]>): Provider {\n if (options.useFactory) {\n return {\n provide: LOGGER_MODULE_OPTIONS,\n useFactory: async (...args: unknown[]) => {\n const userOptions = await options.useFactory?.(...args);\n return mergeWithDefaults(userOptions);\n },\n inject: options.inject || [],\n };\n }\n\n if (options.useClass) {\n return {\n provide: LOGGER_MODULE_OPTIONS,\n useFactory: async (optionsFactory: LoggerOptionsFactory) => {\n const userOptions = await optionsFactory.createLoggerOptions();\n return mergeWithDefaults(userOptions);\n },\n inject: [options.useClass],\n };\n }\n\n if (options.useExisting) {\n return {\n provide: LOGGER_MODULE_OPTIONS,\n useFactory: async (optionsFactory: LoggerOptionsFactory) => {\n const userOptions = await optionsFactory.createLoggerOptions();\n return mergeWithDefaults(userOptions);\n },\n inject: [options.useExisting],\n };\n }\n\n throw new Error('LoggerModule.forRootAsync() requires one of: useFactory, useClass, or useExisting');\n }\n}\n","import { Injectable, type NestMiddleware } from '@nestjs/common';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport {\n addCorrelationIdToResponse,\n correlationStorage,\n DEFAULT_CORRELATION_HEADER,\n generateCorrelationId,\n runWithCorrelationContext,\n} from '../utils';\n\nexport interface CorrelationIdMiddlewareOptions {\n includeInResponse?: boolean;\n responseHeader?: string;\n}\n\n@Injectable()\nexport class CorrelationIdMiddleware implements NestMiddleware {\n private readonly includeInResponse: boolean;\n private readonly responseHeader: string;\n\n constructor(options: CorrelationIdMiddlewareOptions = {}) {\n this.includeInResponse = options.includeInResponse ?? true;\n this.responseHeader = options.responseHeader ?? DEFAULT_CORRELATION_HEADER;\n }\n\n // Generates and stores a correlation ID for the incoming request\n use(_req: FastifyRequest, reply: FastifyReply, next: () => void): void {\n // Generate new correlation ID for this request\n const correlationId = generateCorrelationId();\n\n // Add to response headers if enabled\n if (this.includeInResponse) {\n addCorrelationIdToResponse(reply, correlationId, this.responseHeader);\n }\n\n // Run the rest of the request in AsyncLocalStorage context\n runWithCorrelationContext({ correlationId }, () => {\n next();\n });\n }\n\n // Fastify onRequest hook that initializes correlation context in AsyncLocalStorage\n async onRequest(_req: FastifyRequest, reply: FastifyReply): Promise<void> {\n // Generate new correlation ID for this request\n const correlationId = generateCorrelationId();\n\n // Add to response headers if enabled\n if (this.includeInResponse) {\n addCorrelationIdToResponse(reply, correlationId, this.responseHeader);\n }\n\n // Store in AsyncLocalStorage — no runWithCorrelationContext wrap needed, Fastify's async context tracking handles it.\n const store = correlationStorage.getStore();\n if (!store) {\n // Initialize new store\n correlationStorage.enterWith({ correlationId });\n }\n }\n}\n"],"mappings":"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","names":["Injectable","Optional","catchError","tap","HttpStatus","HttpException","findPgError","error","depth","undefined","candidate","code","cause","Injectable","Optional","createLogger","format","transports","DailyRotateFile","AsyncLocalStorage","randomUUID","correlationStorage","AsyncLocalStorage","getCorrelationContext","getStore","runWithCorrelationContext","context","callback","run","updateCorrelationContext","updates","Object","assign","DEFAULT_CORRELATION_HEADER","generateCorrelationId","randomUUID","addCorrelationIdToResponse","reply","correlationId","headerName","header","raw","setHeader","LoggerService","activeLogger","options","context","defaultLogger","provider","Error","createWinstonLogger","opts","level","logFormat","format","baseFormatters","timestamp","errors","stack","consoleTransport","transports","Console","combine","json","printf","info","message","correlationId","trace","parts","toUpperCase","padEnd","toString","slice","filter","Boolean","output","join","colorize","all","winstonTransports","enableFileLogger","filePath","maxFiles","push","DailyRotateFile","filename","datePattern","maxSize","config","exitOnError","defaultMeta","appName","environment","createLogger","log","_log","error","warn","debug","verbose","setContext","ctx","winstonLogger","winstonLevel","formattedMessage","formatMessage","metadata","enrichMetadata","nestLogger","logWithMetadata","messageWithMeta","JSON","stringify","String","enriched","correlationContext","getCorrelationContext","key","value","Object","entries","child","childLogger","HttpLoggerInterceptor","enableRequestLog","enableResponseLog","slowRequestThreshold","logger","options","intercept","context","next","getType","handle","httpContext","switchToHttp","request","getRequest","response","getResponse","startTime","Date","now","logRequest","pipe","tap","duration","logResponse","catchError","error","logError","correlationContext","getCorrelationContext","metadata","type","method","url","correlationId","ip","userAgent","headers","logWithMetadata","stack","statusCode","logLevel","slowRequest","message","err","status","pgCause","findPgError","errorMessage","detail","code","errorName","name","pgError","trace","errorDetails","loggingError","Global","Logger","Module","Injectable","CorrelationIdMiddleware","includeInResponse","responseHeader","options","DEFAULT_CORRELATION_HEADER","use","_req","reply","next","correlationId","generateCorrelationId","addCorrelationIdToResponse","runWithCorrelationContext","onRequest","store","correlationStorage","getStore","enterWith","LOGGER_MODULE_OPTIONS","Symbol","DEFAULT_LOGGER_OPTIONS","provider","enableCorrelationId","enableHttpLogger","filePath","maxFiles","ENVIRONMENT_PRESETS","development","level","format","enableFileLogger","httpLogger","enableRequestLog","enableResponseLog","slowRequestThreshold","staging","production","test","mergeWithDefaults","options","preset","environment","filteredOptions","Object","fromEntries","entries","filter","_","value","undefined","merged","createDefaultLoggerProvider","provide","Logger","useFactory","logger","levels","getLevelsUpTo","setLogLevels","createLoggerProviders","mergedOptions","providers","useValue","push","LoggerService","opts","defaultLogger","inject","token","optional","CorrelationIdMiddleware","includeInResponse","responseHeader","HttpLoggerInterceptor","httpLoggerOptions","allLevels","isValidLevel","l","includes","levelIndex","indexOf","slice","LoggerModule","forRoot","module","exports","forRootAsync","asyncProviders","createAsyncProviders","imports","configure","_consumer","createAsyncOptionsProvider","useClass","args","userOptions","optionsFactory","createLoggerOptions","useExisting","Error"]}
package/dist/nats.cjs CHANGED
@@ -101,8 +101,15 @@ __name(findPgError, "findPgError");
101
101
  // src/filters/rpc-problem-exception.filter.ts
102
102
  function _ts_decorate(decorators, target, key, desc) {
103
103
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
104
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
105
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
104
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
105
+ r = Reflect.decorate(decorators, target, key, desc);
106
+ } else {
107
+ for (var i = decorators.length - 1; i >= 0; i--) {
108
+ if (d = decorators[i]) {
109
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
110
+ }
111
+ }
112
+ }
106
113
  return c > 3 && r && Object.defineProperty(target, key, r), r;
107
114
  }
108
115
  __name(_ts_decorate, "_ts_decorate");
@@ -238,14 +245,14 @@ var import_config = require("@nestjs/config");
238
245
  var import_microservices4 = require("@nestjs/microservices");
239
246
 
240
247
  // src/nats/constants.ts
241
- var NATS_MODULE_OPTIONS = Symbol("NATS_MODULE_OPTIONS");
242
- var NATS_CONTEXT_RESOLVER = Symbol("NATS_CONTEXT_RESOLVER");
248
+ var NATS_MODULE_OPTIONS = /* @__PURE__ */ Symbol("NATS_MODULE_OPTIONS");
249
+ var NATS_CONTEXT_RESOLVER = /* @__PURE__ */ Symbol("NATS_CONTEXT_RESOLVER");
243
250
 
244
251
  // src/nats/nats-client.service.ts
245
252
  var import_common5 = require("@nestjs/common");
246
253
  var import_core = require("@nestjs/core");
247
254
  var import_microservices2 = require("@nestjs/microservices");
248
- var import_nats = require("nats");
255
+ var import_transport_node = require("@nats-io/transport-node");
249
256
 
250
257
  // src/context/resolve-request.ts
251
258
  function resolveInjectedRequest(injected) {
@@ -260,13 +267,22 @@ __name(resolveInjectedRequest, "resolveInjectedRequest");
260
267
  // src/nats/nats-client.service.ts
261
268
  function _ts_decorate2(decorators, target, key, desc) {
262
269
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
263
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
264
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
270
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
271
+ r = Reflect.decorate(decorators, target, key, desc);
272
+ } else {
273
+ for (var i = decorators.length - 1; i >= 0; i--) {
274
+ if (d = decorators[i]) {
275
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
276
+ }
277
+ }
278
+ }
265
279
  return c > 3 && r && Object.defineProperty(target, key, r), r;
266
280
  }
267
281
  __name(_ts_decorate2, "_ts_decorate");
268
- function _ts_metadata(k, v) {
269
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
282
+ function _ts_metadata(metadataKey, metadataValue) {
283
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
284
+ return Reflect.metadata(metadataKey, metadataValue);
285
+ }
270
286
  }
271
287
  __name(_ts_metadata, "_ts_metadata");
272
288
  function _ts_param(paramIndex, decorator) {
@@ -275,7 +291,7 @@ function _ts_param(paramIndex, decorator) {
275
291
  };
276
292
  }
277
293
  __name(_ts_param, "_ts_param");
278
- var NATS_CLIENTS = Symbol("NATS_CLIENTS");
294
+ var NATS_CLIENTS = /* @__PURE__ */ Symbol("NATS_CLIENTS");
279
295
  var NatsClientService = class {
280
296
  static {
281
297
  __name(this, "NatsClientService");
@@ -330,7 +346,7 @@ NatsClientService = _ts_decorate2([
330
346
  ])
331
347
  ], NatsClientService);
332
348
  function contextToHeaders(ctx) {
333
- const hdrs = (0, import_nats.headers)();
349
+ const hdrs = (0, import_transport_node.headers)();
334
350
  for (const [field, key] of Object.entries(NATS_HEADER_KEYS)) {
335
351
  if (ctx[field]) hdrs.set(key, ctx[field]);
336
352
  }
@@ -343,13 +359,22 @@ var import_common6 = require("@nestjs/common");
343
359
  var import_microservices3 = require("@nestjs/microservices");
344
360
  function _ts_decorate3(decorators, target, key, desc) {
345
361
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
346
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
347
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
362
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
363
+ r = Reflect.decorate(decorators, target, key, desc);
364
+ } else {
365
+ for (var i = decorators.length - 1; i >= 0; i--) {
366
+ if (d = decorators[i]) {
367
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
368
+ }
369
+ }
370
+ }
348
371
  return c > 3 && r && Object.defineProperty(target, key, r), r;
349
372
  }
350
373
  __name(_ts_decorate3, "_ts_decorate");
351
- function _ts_metadata2(k, v) {
352
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
374
+ function _ts_metadata2(metadataKey, metadataValue) {
375
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
376
+ return Reflect.metadata(metadataKey, metadataValue);
377
+ }
353
378
  }
354
379
  __name(_ts_metadata2, "_ts_metadata");
355
380
  function _ts_param2(paramIndex, decorator) {
@@ -358,7 +383,7 @@ function _ts_param2(paramIndex, decorator) {
358
383
  };
359
384
  }
360
385
  __name(_ts_param2, "_ts_param");
361
- var NATS_MS_CLIENTS = Symbol("NATS_MS_CLIENTS");
386
+ var NATS_MS_CLIENTS = /* @__PURE__ */ Symbol("NATS_MS_CLIENTS");
362
387
  var NatsMicroserviceClientService = class {
363
388
  static {
364
389
  __name(this, "NatsMicroserviceClientService");
@@ -399,12 +424,19 @@ NatsMicroserviceClientService = _ts_decorate3([
399
424
  // src/nats/nats-client.module.ts
400
425
  function _ts_decorate4(decorators, target, key, desc) {
401
426
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
402
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
403
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
427
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
428
+ r = Reflect.decorate(decorators, target, key, desc);
429
+ } else {
430
+ for (var i = decorators.length - 1; i >= 0; i--) {
431
+ if (d = decorators[i]) {
432
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
433
+ }
434
+ }
435
+ }
404
436
  return c > 3 && r && Object.defineProperty(target, key, r), r;
405
437
  }
406
438
  __name(_ts_decorate4, "_ts_decorate");
407
- var NATS_MS_OPTIONS = Symbol("NATS_MS_OPTIONS");
439
+ var NATS_MS_OPTIONS = /* @__PURE__ */ Symbol("NATS_MS_OPTIONS");
408
440
  var NatsClientModule = class _NatsClientModule {
409
441
  static {
410
442
  __name(this, "NatsClientModule");
package/dist/nats.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/nats.ts","../src/filters/rpc-problem-exception.filter.ts","../src/exceptions/conflict.exception.ts","../src/exceptions/base-field.exception.ts","../src/filters/pg-error.translator.ts","../src/nats/decorators/nats-headers.decorator.ts","../src/nats/nats-context.ts","../src/nats/nats-client.module.ts","../src/nats/constants.ts","../src/nats/nats-client.service.ts","../src/context/resolve-request.ts","../src/nats/nats-microservice-client.service.ts"],"sourcesContent":["// NATS + microservice exports — kept out of the main barrel so non-NATS consumers never load @nestjs/microservices\n\n// RPC exception filter (microservice side) — moved out of the main filters barrel\nexport { RpcProblemExceptionFilter } from './filters/rpc-problem-exception.filter';\nexport { RpcSiteCurrencyCode, RpcSiteId, RpcNatsHeaders } from './nats/decorators/nats-headers.decorator';\nexport type {\n ContextResolverFn,\n NatsHeaders,\n NatsMicroserviceModuleAsyncOptions,\n NatsRootModuleAsyncOptions,\n NatsServiceConfig,\n} from './nats/index';\nexport { NatsClientModule } from './nats/nats-client.module';\nexport { NatsClientService } from './nats/nats-client.service';\nexport { NATS_HEADER_KEYS, parseNatsHeaders } from './nats/nats-context';\nexport { NatsMicroserviceClientService } from './nats/nats-microservice-client.service';\n","import { type ArgumentsHost, Catch, type HttpException, HttpStatus, Logger } from '@nestjs/common';\nimport { RpcException } from '@nestjs/microservices';\nimport { type Observable, throwError } from 'rxjs';\nimport { tryTranslatePgError } from './pg-error.translator';\n\ninterface FieldError {\n field: string;\n message: string;\n}\n\ninterface ProblemPayload {\n type: string;\n label?: string;\n detail: string;\n message: string;\n errors: FieldError[];\n status: number;\n statusCode: number;\n}\n\n@Catch()\nexport class RpcProblemExceptionFilter {\n private readonly logger = new Logger(RpcProblemExceptionFilter.name);\n\n catch(exception: unknown, _host: ArgumentsHost): Observable<never> {\n // Translate raw Postgres errors into a ConflictException before the rest of the filter handles them.\n const translatedPgError = tryTranslatePgError(exception);\n if (translatedPgError) exception = translatedPgError;\n\n if (exception instanceof RpcException) {\n return throwError(() => exception.getError());\n }\n\n if (this.isHttpException(exception)) {\n const status = exception.getStatus();\n const response = exception.getResponse();\n const payload = this.toProblemPayload(response, status);\n // Log 4xx/5xx so the microservice terminal shows what actually failed (previously silent)\n const log = status >= HttpStatus.INTERNAL_SERVER_ERROR ? this.logger.error : this.logger.warn;\n log.call(this.logger, `RPC ${status}: ${payload.detail}`);\n return throwError(() => payload);\n }\n\n if (exception instanceof Error) {\n const cause = (exception as { cause?: unknown }).cause;\n const causeMessage = cause instanceof Error ? cause.message : undefined;\n const causeStack = cause instanceof Error ? cause.stack : undefined;\n this.logger.error(causeMessage ?? exception.message, causeStack ?? exception.stack);\n if (cause && cause !== exception) {\n this.logger.error(`Wrapped by: ${exception.message}`);\n }\n return throwError(() =>\n this.toProblemPayload(\n {\n type: 'about:blank',\n detail: causeMessage ?? exception.message,\n errors: [],\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n ),\n );\n }\n\n this.logger.error(`Unhandled non-error exception: ${JSON.stringify(exception)}`);\n return throwError(() =>\n this.toProblemPayload(\n {\n type: 'about:blank',\n detail: 'An unexpected error occurred',\n errors: [],\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n ),\n );\n }\n\n private toProblemPayload(response: unknown, status: number): ProblemPayload {\n if (typeof response === 'string') {\n return {\n type: 'about:blank',\n detail: response,\n message: response,\n errors: [],\n status,\n statusCode: status,\n };\n }\n\n const obj = (response ?? {}) as Record<string, unknown>;\n // Prefer RFC 9457 `detail`, then Nest/@nestjs-common's `message` (string or class-validator array),\n // so exceptions thrown as `@nestjs/common` errors still surface their real message across NATS.\n const detail =\n typeof obj.detail === 'string'\n ? obj.detail\n : typeof obj.message === 'string'\n ? obj.message\n : Array.isArray(obj.message)\n ? obj.message.join(', ')\n : 'Request failed';\n return {\n type: typeof obj.type === 'string' ? obj.type : 'about:blank',\n label: typeof obj.label === 'string' ? obj.label : undefined,\n detail,\n message: detail,\n errors: Array.isArray(obj.errors) ? (obj.errors as FieldError[]) : [],\n status,\n statusCode: status,\n };\n }\n\n private isHttpException(error: unknown): error is HttpException {\n return (\n error instanceof Error &&\n typeof (error as { getStatus?: unknown }).getStatus === 'function' &&\n typeof (error as { getResponse?: unknown }).getResponse === 'function'\n );\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ConflictException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Conflict', HttpStatus.CONFLICT);\n }\n}\n","import { HttpException, HttpStatus } from '@nestjs/common';\nimport type { FieldError } from '../types/error-response.types';\n\n// Re-export FieldError for backwards compatibility\nexport type { FieldError } from '../types/error-response.types';\n\nexport interface ProblemOptions {\n type?: string;\n label?: string;\n detail?: string;\n errors?: FieldError[];\n}\n\nexport abstract class HttpProblemException extends HttpException {\n constructor(detailOrOptions: string | ProblemOptions, httpStatus: HttpStatus) {\n const options = typeof detailOrOptions === 'string' ? { detail: detailOrOptions } : detailOrOptions;\n\n super(\n {\n type: options.type ?? 'about:blank',\n label: options.label,\n detail: options.detail,\n errors: options.errors ?? [],\n },\n httpStatus,\n );\n }\n}\n","import { ConflictException } from '../exceptions/conflict.exception';\n\nconst PG_UNIQUE_VIOLATION = '23505';\n\nexport type PgErrorShape = {\n code?: string;\n message?: string;\n constraint?: string;\n table?: string;\n schema?: string;\n column?: string;\n detail?: string;\n hint?: string;\n};\n\n// Returns a ConflictException for a Postgres unique-violation error, otherwise undefined.\nexport function tryTranslatePgError(error: unknown): ConflictException | undefined {\n const pgError = findPgError(error);\n if (!pgError) return undefined;\n const { code, constraint, table, detail } = pgError;\n if (code !== PG_UNIQUE_VIOLATION) return undefined;\n return new ConflictException({\n label: 'Duplicate Entry',\n detail: detail?.trim() || 'A record with these values already exists.',\n errors: [],\n ...(constraint || table ? { meta: { constraint, table } } : {}),\n });\n}\n\n// Walks up to N levels of `.cause` looking for a pg-shaped error (has SQLSTATE `code`), capping depth.\nexport function findPgError(error: unknown, depth = 0): PgErrorShape | undefined {\n if (!error || typeof error !== 'object' || depth > 5) return undefined;\n const candidate = error as PgErrorShape & { cause?: unknown };\n if (typeof candidate.code === 'string') return candidate;\n return findPgError(candidate.cause, depth + 1);\n}\n","import { createParamDecorator, type ExecutionContext, InternalServerErrorException } from '@nestjs/common';\nimport { NatsContext } from '@nestjs/microservices';\nimport { parseNatsHeaders } from '../nats-context';\n\n// Extracts parsed NatsContext from NATS message headers\nexport const RpcNatsHeaders = createParamDecorator((_data: unknown, ctx: ExecutionContext) => {\n const rpcCtx = ctx.switchToRpc().getContext<NatsContext>();\n return parseNatsHeaders(rpcCtx.getHeaders());\n});\n\n// Extracts siteId from NATS headers — throws if missing or empty\nexport const RpcSiteId = createParamDecorator((_data: unknown, ctx: ExecutionContext): string => {\n const rpcCtx = ctx.switchToRpc().getContext<NatsContext>();\n const headers = parseNatsHeaders(rpcCtx.getHeaders());\n if (!headers?.siteId) throw new InternalServerErrorException('Missing siteId in NATS headers.');\n return headers.siteId;\n});\n\n// Extracts siteCurrencyCode from NATS headers — throws if missing or empty\nexport const RpcSiteCurrencyCode = createParamDecorator((_data: unknown, ctx: ExecutionContext): string => {\n const rpcCtx = ctx.switchToRpc().getContext<NatsContext>();\n const headers = parseNatsHeaders(rpcCtx.getHeaders());\n if (!headers?.siteCurrencyCode) throw new InternalServerErrorException('Missing siteCurrencyCode in NATS headers.');\n return headers.siteCurrencyCode;\n});\n","export interface NatsHeaders {\n orgId: string;\n userId: string;\n siteId: string;\n legalEntityId: string;\n siteGroupId: string;\n siteTimezone: string;\n siteCurrencyCode: string;\n}\n\n// The single source of truth for context transport, both directions. Adding a field means\n// adding one entry here plus one on NatsHeaders — encode and parse both pick it up.\nexport const NATS_HEADER_KEYS = {\n orgId: 'x-org-id',\n userId: 'x-user-id',\n siteId: 'x-site-id',\n legalEntityId: 'x-le-id',\n siteGroupId: 'x-sg-id',\n siteTimezone: 'x-site-timezone',\n siteCurrencyCode: 'x-site-currency-code',\n} as const satisfies Record<keyof NatsHeaders, string>;\n\n// Applied when a header is absent, so a missing optional field lands on the same value the\n// producing side would have sent for \"not set\"\nconst HEADER_FALLBACKS: Partial<Record<keyof NatsHeaders, string>> = {\n siteTimezone: 'UTC',\n};\n\n// Reads a header value from either a plain object or a NATS MsgHdrsImpl\nfunction getHeader(headers: unknown, key: string): string | undefined {\n if (!headers) return undefined;\n // MsgHdrsImpl uses .get(), plain objects use bracket access\n if (typeof (headers as { get?: unknown }).get === 'function') {\n const val = (headers as { get(key: string): string[] }).get(key);\n return Array.isArray(val) ? val[0] : (val as string | undefined);\n }\n return (headers as Record<string, string>)[key];\n}\n\n/**\n * Parses NATS message headers into a NatsHeaders object.\n *\n * Only `orgId` is required. It is what scopes every row the receiving service will read, so\n * without it there is no safe way to run — the caller returns null and the interceptor decides.\n *\n * `userId` is deliberately NOT required. A control-plane call has no user behind it, and an\n * earlier version rejected the whole context when it was blank — which meant the receiving\n * service skipped RLS entirely, ran with `app.org_id` unset, and matched no rows. Losing the\n * tenant because there was no user is a far worse failure than an empty acting principal.\n */\nexport function parseNatsHeaders(headers: unknown): NatsHeaders | null {\n if (!headers) return null;\n\n const orgId = getHeader(headers, NATS_HEADER_KEYS.orgId);\n if (!orgId) return null;\n\n const parsed = {} as NatsHeaders;\n for (const [field, key] of Object.entries(NATS_HEADER_KEYS) as [keyof NatsHeaders, string][]) {\n parsed[field] = getHeader(headers, key) || HEADER_FALLBACKS[field] || '';\n }\n return parsed;\n}\n","import { type DynamicModule, Global, Logger, Module, type OnModuleDestroy, type Provider } from '@nestjs/common';\nimport { ConfigModule, ConfigService } from '@nestjs/config';\nimport type { ClientProxy } from '@nestjs/microservices';\nimport { ClientProxyFactory, Transport } from '@nestjs/microservices';\nimport { NATS_CONTEXT_RESOLVER, NATS_MODULE_OPTIONS } from './constants';\nimport type {\n NatsMicroserviceModuleAsyncOptions,\n NatsModuleBaseOptions,\n NatsRootModuleAsyncOptions,\n NatsRootModuleOptions,\n} from './nats-client.interfaces';\nimport { NATS_CLIENTS, NatsClientService } from './nats-client.service';\nimport { NATS_MS_CLIENTS, NatsMicroserviceClientService } from './nats-microservice-client.service';\n\nconst NATS_MS_OPTIONS = Symbol('NATS_MS_OPTIONS');\n\n@Global()\n@Module({})\nexport class NatsClientModule implements OnModuleDestroy {\n private static readonly logger = new Logger(NatsClientModule.name);\n private static allClients: ClientProxy[] = [];\n\n async onModuleDestroy() {\n await Promise.all(NatsClientModule.allClients.map((c) => c.close()));\n NatsClientModule.allClients = [];\n }\n\n // Builds a Map of named NATS ClientProxy instances\n private static buildClients(options: NatsModuleBaseOptions, natsUrl: string): Map<string, ClientProxy> {\n const clients = new Map<string, ClientProxy>();\n\n for (const svc of options.services) {\n const proxy = ClientProxyFactory.create({\n transport: Transport.NATS,\n options: { servers: [natsUrl] },\n });\n clients.set(svc.name, proxy);\n NatsClientModule.allClients.push(proxy);\n NatsClientModule.logger.log(`Registered NATS client: ${svc.name} → ${natsUrl}`);\n }\n\n return clients;\n }\n\n // Gateway mode — request-scoped, resolves context from the request via callback\n static forRoot(asyncOptions: NatsRootModuleAsyncOptions): DynamicModule {\n const optionsProvider: Provider = {\n provide: NATS_MODULE_OPTIONS,\n useFactory: asyncOptions.useFactory,\n inject: asyncOptions.inject || [],\n };\n\n const resolverProvider: Provider = {\n provide: NATS_CONTEXT_RESOLVER,\n useFactory: (options: NatsRootModuleOptions) => options.contextResolver,\n inject: [NATS_MODULE_OPTIONS],\n };\n\n const clientsProvider: Provider = {\n provide: NATS_CLIENTS,\n useFactory: (options: NatsRootModuleOptions, config: ConfigService): Map<string, ClientProxy> => {\n const natsUrl = options.natsUrl ?? config.get<string>('NATS_URL', 'nats://localhost:4222');\n return NatsClientModule.buildClients(options, natsUrl);\n },\n inject: [NATS_MODULE_OPTIONS, ConfigService],\n };\n\n return {\n module: NatsClientModule,\n imports: [ConfigModule, ...(asyncOptions.imports ?? [])],\n providers: [optionsProvider, resolverProvider, clientsProvider, NatsClientService],\n exports: [NatsClientService],\n };\n }\n\n // Microservice mode — singleton, forwards context from incoming NATS payload\n static forMicroservice(asyncOptions: NatsMicroserviceModuleAsyncOptions): DynamicModule {\n const optionsProvider: Provider = {\n provide: NATS_MS_OPTIONS,\n useFactory: asyncOptions.useFactory,\n inject: asyncOptions.inject || [],\n };\n\n const clientsProvider: Provider = {\n provide: NATS_MS_CLIENTS,\n useFactory: (options: NatsModuleBaseOptions, config: ConfigService): Map<string, ClientProxy> => {\n const natsUrl = options.natsUrl ?? config.get<string>('NATS_URL', 'nats://localhost:4222');\n return NatsClientModule.buildClients(options, natsUrl);\n },\n inject: [NATS_MS_OPTIONS, ConfigService],\n };\n\n return {\n module: NatsClientModule,\n imports: [ConfigModule, ...(asyncOptions.imports ?? [])],\n providers: [optionsProvider, clientsProvider, NatsMicroserviceClientService],\n exports: [NatsMicroserviceClientService],\n };\n }\n}\n","export const NATS_MODULE_OPTIONS = Symbol('NATS_MODULE_OPTIONS');\nexport const NATS_CONTEXT_RESOLVER = Symbol('NATS_CONTEXT_RESOLVER');\n","// Pulls the fastify module augmentation into this entry's dts graph — tsup builds each entry in isolation\nimport '../types/fastify-augmentation';\nimport { Inject, Injectable, Scope } from '@nestjs/common';\nimport { REQUEST } from '@nestjs/core';\nimport type { ClientProxy } from '@nestjs/microservices';\nimport { NatsRecordBuilder } from '@nestjs/microservices';\nimport type { FastifyRequest } from 'fastify';\nimport { headers as natsHeaders } from 'nats';\nimport { resolveInjectedRequest } from '../context/resolve-request';\nimport { NATS_CONTEXT_RESOLVER } from './constants';\nimport type { ContextResolverFn } from './nats-client.interfaces';\nimport { NATS_HEADER_KEYS, type NatsHeaders } from './nats-context';\n\nexport const NATS_CLIENTS = Symbol('NATS_CLIENTS');\n\n@Injectable({ scope: Scope.REQUEST })\nexport class NatsClientService {\n private cachedContext: NatsHeaders | null = null;\n\n constructor(\n @Inject(REQUEST) private readonly injectedRequest: FastifyRequest,\n @Inject(NATS_CONTEXT_RESOLVER) private readonly contextResolver: ContextResolverFn,\n @Inject(NATS_CLIENTS) private readonly clients: Map<string, ClientProxy>,\n ) {}\n\n // Unwraps the GraphQL { req, reply } context wrapper so auth is visible across both transports\n private get request(): FastifyRequest {\n return resolveInjectedRequest(this.injectedRequest);\n }\n\n // Sends a message to a named microservice with NatsHeaders as NATS headers\n async send<T>(service: string, cmd: string, data?: object): Promise<T> {\n const client = this.clients.get(service);\n if (!client) {\n throw new Error(\n `NATS service \"${service}\" is not registered. Available: [${[...this.clients.keys()].join(', ')}]`,\n );\n }\n\n if (!this.cachedContext) {\n // The resolver takes the whole request rather than one auth field: which caller kinds\n // exist, and what each contributes, is the consuming server's model — this side only\n // knows that something has to produce headers.\n const context = await this.contextResolver(this.request);\n if (!context) {\n throw new Error('No auth context on request — is the auth guard active for this route?');\n }\n this.cachedContext = context;\n }\n\n const headers = contextToHeaders(this.cachedContext);\n const record = new NatsRecordBuilder(data ?? {}).setHeaders(headers).build();\n\n return client.send<T>({ cmd }, record).toPromise() as Promise<T>;\n }\n}\n\n// Converts NatsHeaders to a NATS MsgHdrs object for NATS transport.\n//\n// Driven by the key map rather than a field-per-line, so a new context field travels the\n// moment it is added to NATS_HEADER_KEYS. Empty values are omitted — parseNatsHeaders applies\n// the same defaults on the way back, so sending a blank would just restate them.\nfunction contextToHeaders(ctx: NatsHeaders): import('nats').MsgHdrs {\n const hdrs = natsHeaders();\n for (const [field, key] of Object.entries(NATS_HEADER_KEYS) as [keyof NatsHeaders, string][]) {\n if (ctx[field]) hdrs.set(key, ctx[field]);\n }\n return hdrs;\n}\n","import type { FastifyRequest } from 'fastify';\n\n// Unwraps the @Inject(REQUEST) value to the real Fastify request (GraphQL injects a { req, reply } context).\nexport function resolveInjectedRequest(injected: FastifyRequest): FastifyRequest {\n const candidate = injected as unknown as { headers?: unknown; req?: FastifyRequest };\n if (candidate && candidate.headers === undefined && candidate.req) {\n return candidate.req;\n }\n return injected;\n}\n","import { Inject, Injectable } from '@nestjs/common';\nimport type { ClientProxy } from '@nestjs/microservices';\nimport { NatsRecordBuilder } from '@nestjs/microservices';\nimport { NATS_HEADER_KEYS, type NatsHeaders } from './nats-context';\n\nexport const NATS_MS_CLIENTS = Symbol('NATS_MS_CLIENTS');\n\n@Injectable()\nexport class NatsMicroserviceClientService {\n constructor(@Inject(NATS_MS_CLIENTS) private readonly clients: Map<string, ClientProxy>) {}\n\n // Forwards a message to another microservice with NatsHeaders\n async send<T>(service: string, cmd: string, natsHeaders: NatsHeaders, data?: object): Promise<T> {\n const client = this.clients.get(service);\n if (!client) {\n throw new Error(\n `NATS service \"${service}\" is not registered. Available: [${[...this.clients.keys()].join(', ')}]`,\n );\n }\n\n const headers: Record<string, string> = {\n [NATS_HEADER_KEYS.orgId]: natsHeaders.orgId,\n [NATS_HEADER_KEYS.userId]: natsHeaders.userId,\n [NATS_HEADER_KEYS.siteId]: natsHeaders.siteId,\n [NATS_HEADER_KEYS.siteTimezone]: natsHeaders.siteTimezone,\n };\n\n const record = new NatsRecordBuilder(data ?? {}).setHeaders(headers).build();\n return client.send<T>({ cmd }, record).toPromise() as Promise<T>;\n }\n}\n"],"mappings":"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","names":["import_common","import_common","HttpProblemException","HttpException","detailOrOptions","httpStatus","options","detail","type","label","errors","ConflictException","HttpProblemException","detailOrOptions","HttpStatus","CONFLICT","PG_UNIQUE_VIOLATION","tryTranslatePgError","error","pgError","findPgError","undefined","code","constraint","table","detail","ConflictException","label","trim","errors","meta","depth","candidate","cause","RpcProblemExceptionFilter","logger","Logger","name","catch","exception","_host","translatedPgError","tryTranslatePgError","RpcException","throwError","getError","isHttpException","status","getStatus","response","getResponse","payload","toProblemPayload","log","HttpStatus","INTERNAL_SERVER_ERROR","error","warn","call","detail","Error","cause","causeMessage","message","undefined","causeStack","stack","type","errors","JSON","stringify","statusCode","obj","Array","isArray","join","label","import_common","NATS_HEADER_KEYS","orgId","userId","siteId","legalEntityId","siteGroupId","siteTimezone","siteCurrencyCode","HEADER_FALLBACKS","getHeader","headers","key","undefined","get","val","Array","isArray","parseNatsHeaders","parsed","field","Object","entries","RpcNatsHeaders","createParamDecorator","_data","ctx","rpcCtx","switchToRpc","getContext","parseNatsHeaders","getHeaders","RpcSiteId","headers","siteId","InternalServerErrorException","RpcSiteCurrencyCode","siteCurrencyCode","import_common","import_microservices","NATS_MODULE_OPTIONS","Symbol","NATS_CONTEXT_RESOLVER","import_common","import_microservices","resolveInjectedRequest","injected","candidate","headers","undefined","req","NATS_CLIENTS","Symbol","NatsClientService","cachedContext","injectedRequest","contextResolver","clients","request","resolveInjectedRequest","send","service","cmd","data","client","get","Error","keys","join","context","headers","contextToHeaders","record","NatsRecordBuilder","setHeaders","build","toPromise","scope","Scope","REQUEST","ctx","hdrs","natsHeaders","field","key","Object","entries","NATS_HEADER_KEYS","set","import_common","import_microservices","NATS_MS_CLIENTS","Symbol","NatsMicroserviceClientService","clients","send","service","cmd","natsHeaders","data","client","get","Error","keys","join","headers","NATS_HEADER_KEYS","orgId","userId","siteId","siteTimezone","record","NatsRecordBuilder","setHeaders","build","toPromise","NATS_MS_OPTIONS","Symbol","NatsClientModule","logger","Logger","name","allClients","onModuleDestroy","Promise","all","map","c","close","buildClients","options","natsUrl","clients","Map","svc","services","proxy","ClientProxyFactory","create","transport","Transport","NATS","servers","set","push","log","forRoot","asyncOptions","optionsProvider","provide","NATS_MODULE_OPTIONS","useFactory","inject","resolverProvider","NATS_CONTEXT_RESOLVER","contextResolver","clientsProvider","NATS_CLIENTS","config","get","ConfigService","module","imports","ConfigModule","providers","NatsClientService","exports","forMicroservice","NATS_MS_CLIENTS","NatsMicroserviceClientService"]}
1
+ {"version":3,"sources":["../src/nats.ts","../src/filters/rpc-problem-exception.filter.ts","../src/exceptions/conflict.exception.ts","../src/exceptions/base-field.exception.ts","../src/filters/pg-error.translator.ts","../src/nats/decorators/nats-headers.decorator.ts","../src/nats/nats-context.ts","../src/nats/nats-client.module.ts","../src/nats/constants.ts","../src/nats/nats-client.service.ts","../src/context/resolve-request.ts","../src/nats/nats-microservice-client.service.ts"],"sourcesContent":["// NATS + microservice exports — kept out of the main barrel so non-NATS consumers never load @nestjs/microservices\n\n// RPC exception filter (microservice side) — moved out of the main filters barrel\nexport { RpcProblemExceptionFilter } from './filters/rpc-problem-exception.filter';\nexport { RpcSiteCurrencyCode, RpcSiteId, RpcNatsHeaders } from './nats/decorators/nats-headers.decorator';\nexport type {\n ContextResolverFn,\n NatsHeaders,\n NatsMicroserviceModuleAsyncOptions,\n NatsRootModuleAsyncOptions,\n NatsServiceConfig,\n} from './nats/index';\nexport { NatsClientModule } from './nats/nats-client.module';\nexport { NatsClientService } from './nats/nats-client.service';\nexport { NATS_HEADER_KEYS, parseNatsHeaders } from './nats/nats-context';\nexport { NatsMicroserviceClientService } from './nats/nats-microservice-client.service';\n","import { type ArgumentsHost, Catch, type HttpException, HttpStatus, Logger } from '@nestjs/common';\nimport { RpcException } from '@nestjs/microservices';\nimport { type Observable, throwError } from 'rxjs';\nimport { tryTranslatePgError } from './pg-error.translator';\n\ninterface FieldError {\n field: string;\n message: string;\n}\n\ninterface ProblemPayload {\n type: string;\n label?: string;\n detail: string;\n message: string;\n errors: FieldError[];\n status: number;\n statusCode: number;\n}\n\n@Catch()\nexport class RpcProblemExceptionFilter {\n private readonly logger = new Logger(RpcProblemExceptionFilter.name);\n\n catch(exception: unknown, _host: ArgumentsHost): Observable<never> {\n // Translate raw Postgres errors into a ConflictException before the rest of the filter handles them.\n const translatedPgError = tryTranslatePgError(exception);\n if (translatedPgError) exception = translatedPgError;\n\n if (exception instanceof RpcException) {\n return throwError(() => exception.getError());\n }\n\n if (this.isHttpException(exception)) {\n const status = exception.getStatus();\n const response = exception.getResponse();\n const payload = this.toProblemPayload(response, status);\n // Log 4xx/5xx so the microservice terminal shows what actually failed (previously silent)\n const log = status >= HttpStatus.INTERNAL_SERVER_ERROR ? this.logger.error : this.logger.warn;\n log.call(this.logger, `RPC ${status}: ${payload.detail}`);\n return throwError(() => payload);\n }\n\n if (exception instanceof Error) {\n const cause = (exception as { cause?: unknown }).cause;\n const causeMessage = cause instanceof Error ? cause.message : undefined;\n const causeStack = cause instanceof Error ? cause.stack : undefined;\n this.logger.error(causeMessage ?? exception.message, causeStack ?? exception.stack);\n if (cause && cause !== exception) {\n this.logger.error(`Wrapped by: ${exception.message}`);\n }\n return throwError(() =>\n this.toProblemPayload(\n {\n type: 'about:blank',\n detail: causeMessage ?? exception.message,\n errors: [],\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n ),\n );\n }\n\n this.logger.error(`Unhandled non-error exception: ${JSON.stringify(exception)}`);\n return throwError(() =>\n this.toProblemPayload(\n {\n type: 'about:blank',\n detail: 'An unexpected error occurred',\n errors: [],\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n ),\n );\n }\n\n private toProblemPayload(response: unknown, status: number): ProblemPayload {\n if (typeof response === 'string') {\n return {\n type: 'about:blank',\n detail: response,\n message: response,\n errors: [],\n status,\n statusCode: status,\n };\n }\n\n const obj = (response ?? {}) as Record<string, unknown>;\n // Prefer RFC 9457 `detail`, then Nest/@nestjs-common's `message` (string or class-validator array),\n // so exceptions thrown as `@nestjs/common` errors still surface their real message across NATS.\n const detail =\n typeof obj.detail === 'string'\n ? obj.detail\n : typeof obj.message === 'string'\n ? obj.message\n : Array.isArray(obj.message)\n ? obj.message.join(', ')\n : 'Request failed';\n return {\n type: typeof obj.type === 'string' ? obj.type : 'about:blank',\n label: typeof obj.label === 'string' ? obj.label : undefined,\n detail,\n message: detail,\n errors: Array.isArray(obj.errors) ? (obj.errors as FieldError[]) : [],\n status,\n statusCode: status,\n };\n }\n\n private isHttpException(error: unknown): error is HttpException {\n return (\n error instanceof Error &&\n typeof (error as { getStatus?: unknown }).getStatus === 'function' &&\n typeof (error as { getResponse?: unknown }).getResponse === 'function'\n );\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ConflictException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Conflict', HttpStatus.CONFLICT);\n }\n}\n","import { HttpException, HttpStatus } from '@nestjs/common';\nimport type { FieldError } from '../types/error-response.types';\n\n// Re-export FieldError for backwards compatibility\nexport type { FieldError } from '../types/error-response.types';\n\nexport interface ProblemOptions {\n type?: string;\n label?: string;\n detail?: string;\n errors?: FieldError[];\n}\n\nexport abstract class HttpProblemException extends HttpException {\n constructor(detailOrOptions: string | ProblemOptions, httpStatus: HttpStatus) {\n const options = typeof detailOrOptions === 'string' ? { detail: detailOrOptions } : detailOrOptions;\n\n super(\n {\n type: options.type ?? 'about:blank',\n label: options.label,\n detail: options.detail,\n errors: options.errors ?? [],\n },\n httpStatus,\n );\n }\n}\n","import { ConflictException } from '../exceptions/conflict.exception';\n\nconst PG_UNIQUE_VIOLATION = '23505';\n\nexport type PgErrorShape = {\n code?: string;\n message?: string;\n constraint?: string;\n table?: string;\n schema?: string;\n column?: string;\n detail?: string;\n hint?: string;\n};\n\n// Returns a ConflictException for a Postgres unique-violation error, otherwise undefined.\nexport function tryTranslatePgError(error: unknown): ConflictException | undefined {\n const pgError = findPgError(error);\n if (!pgError) return undefined;\n const { code, constraint, table, detail } = pgError;\n if (code !== PG_UNIQUE_VIOLATION) return undefined;\n return new ConflictException({\n label: 'Duplicate Entry',\n detail: detail?.trim() || 'A record with these values already exists.',\n errors: [],\n ...(constraint || table ? { meta: { constraint, table } } : {}),\n });\n}\n\n// Walks up to N levels of `.cause` looking for a pg-shaped error (has SQLSTATE `code`), capping depth.\nexport function findPgError(error: unknown, depth = 0): PgErrorShape | undefined {\n if (!error || typeof error !== 'object' || depth > 5) return undefined;\n const candidate = error as PgErrorShape & { cause?: unknown };\n if (typeof candidate.code === 'string') return candidate;\n return findPgError(candidate.cause, depth + 1);\n}\n","import { createParamDecorator, type ExecutionContext, InternalServerErrorException } from '@nestjs/common';\nimport { NatsContext } from '@nestjs/microservices';\nimport { parseNatsHeaders } from '../nats-context';\n\n// Extracts parsed NatsContext from NATS message headers\nexport const RpcNatsHeaders = createParamDecorator((_data: unknown, ctx: ExecutionContext) => {\n const rpcCtx = ctx.switchToRpc().getContext<NatsContext>();\n return parseNatsHeaders(rpcCtx.getHeaders());\n});\n\n// Extracts siteId from NATS headers — throws if missing or empty\nexport const RpcSiteId = createParamDecorator((_data: unknown, ctx: ExecutionContext): string => {\n const rpcCtx = ctx.switchToRpc().getContext<NatsContext>();\n const headers = parseNatsHeaders(rpcCtx.getHeaders());\n if (!headers?.siteId) throw new InternalServerErrorException('Missing siteId in NATS headers.');\n return headers.siteId;\n});\n\n// Extracts siteCurrencyCode from NATS headers — throws if missing or empty\nexport const RpcSiteCurrencyCode = createParamDecorator((_data: unknown, ctx: ExecutionContext): string => {\n const rpcCtx = ctx.switchToRpc().getContext<NatsContext>();\n const headers = parseNatsHeaders(rpcCtx.getHeaders());\n if (!headers?.siteCurrencyCode) throw new InternalServerErrorException('Missing siteCurrencyCode in NATS headers.');\n return headers.siteCurrencyCode;\n});\n","export interface NatsHeaders {\n orgId: string;\n userId: string;\n siteId: string;\n legalEntityId: string;\n siteGroupId: string;\n siteTimezone: string;\n siteCurrencyCode: string;\n}\n\n// The single source of truth for context transport, both directions. Adding a field means\n// adding one entry here plus one on NatsHeaders — encode and parse both pick it up.\nexport const NATS_HEADER_KEYS = {\n orgId: 'x-org-id',\n userId: 'x-user-id',\n siteId: 'x-site-id',\n legalEntityId: 'x-le-id',\n siteGroupId: 'x-sg-id',\n siteTimezone: 'x-site-timezone',\n siteCurrencyCode: 'x-site-currency-code',\n} as const satisfies Record<keyof NatsHeaders, string>;\n\n// Applied when a header is absent, so a missing optional field lands on the same value the\n// producing side would have sent for \"not set\"\nconst HEADER_FALLBACKS: Partial<Record<keyof NatsHeaders, string>> = {\n siteTimezone: 'UTC',\n};\n\n// Reads a header value from either a plain object or a NATS MsgHdrsImpl\nfunction getHeader(headers: unknown, key: string): string | undefined {\n if (!headers) return undefined;\n // MsgHdrsImpl uses .get(), plain objects use bracket access\n if (typeof (headers as { get?: unknown }).get === 'function') {\n const val = (headers as { get(key: string): string[] }).get(key);\n return Array.isArray(val) ? val[0] : (val as string | undefined);\n }\n return (headers as Record<string, string>)[key];\n}\n\n/**\n * Parses NATS message headers into a NatsHeaders object.\n *\n * Only `orgId` is required. It is what scopes every row the receiving service will read, so\n * without it there is no safe way to run — the caller returns null and the interceptor decides.\n *\n * `userId` is deliberately NOT required. A control-plane call has no user behind it, and an\n * earlier version rejected the whole context when it was blank — which meant the receiving\n * service skipped RLS entirely, ran with `app.org_id` unset, and matched no rows. Losing the\n * tenant because there was no user is a far worse failure than an empty acting principal.\n */\nexport function parseNatsHeaders(headers: unknown): NatsHeaders | null {\n if (!headers) return null;\n\n const orgId = getHeader(headers, NATS_HEADER_KEYS.orgId);\n if (!orgId) return null;\n\n const parsed = {} as NatsHeaders;\n for (const [field, key] of Object.entries(NATS_HEADER_KEYS) as [keyof NatsHeaders, string][]) {\n parsed[field] = getHeader(headers, key) || HEADER_FALLBACKS[field] || '';\n }\n return parsed;\n}\n","import { type DynamicModule, Global, Logger, Module, type OnModuleDestroy, type Provider } from '@nestjs/common';\nimport { ConfigModule, ConfigService } from '@nestjs/config';\nimport type { ClientProxy } from '@nestjs/microservices';\nimport { ClientProxyFactory, Transport } from '@nestjs/microservices';\nimport { NATS_CONTEXT_RESOLVER, NATS_MODULE_OPTIONS } from './constants';\nimport type {\n NatsMicroserviceModuleAsyncOptions,\n NatsModuleBaseOptions,\n NatsRootModuleAsyncOptions,\n NatsRootModuleOptions,\n} from './nats-client.interfaces';\nimport { NATS_CLIENTS, NatsClientService } from './nats-client.service';\nimport { NATS_MS_CLIENTS, NatsMicroserviceClientService } from './nats-microservice-client.service';\n\nconst NATS_MS_OPTIONS = Symbol('NATS_MS_OPTIONS');\n\n@Global()\n@Module({})\nexport class NatsClientModule implements OnModuleDestroy {\n private static readonly logger = new Logger(NatsClientModule.name);\n private static allClients: ClientProxy[] = [];\n\n async onModuleDestroy() {\n await Promise.all(NatsClientModule.allClients.map((c) => c.close()));\n NatsClientModule.allClients = [];\n }\n\n // Builds a Map of named NATS ClientProxy instances\n private static buildClients(options: NatsModuleBaseOptions, natsUrl: string): Map<string, ClientProxy> {\n const clients = new Map<string, ClientProxy>();\n\n for (const svc of options.services) {\n const proxy = ClientProxyFactory.create({\n transport: Transport.NATS,\n options: { servers: [natsUrl] },\n });\n clients.set(svc.name, proxy);\n NatsClientModule.allClients.push(proxy);\n NatsClientModule.logger.log(`Registered NATS client: ${svc.name} → ${natsUrl}`);\n }\n\n return clients;\n }\n\n // Gateway mode — request-scoped, resolves context from the request via callback\n static forRoot(asyncOptions: NatsRootModuleAsyncOptions): DynamicModule {\n const optionsProvider: Provider = {\n provide: NATS_MODULE_OPTIONS,\n useFactory: asyncOptions.useFactory,\n inject: asyncOptions.inject || [],\n };\n\n const resolverProvider: Provider = {\n provide: NATS_CONTEXT_RESOLVER,\n useFactory: (options: NatsRootModuleOptions) => options.contextResolver,\n inject: [NATS_MODULE_OPTIONS],\n };\n\n const clientsProvider: Provider = {\n provide: NATS_CLIENTS,\n useFactory: (options: NatsRootModuleOptions, config: ConfigService): Map<string, ClientProxy> => {\n const natsUrl = options.natsUrl ?? config.get<string>('NATS_URL', 'nats://localhost:4222');\n return NatsClientModule.buildClients(options, natsUrl);\n },\n inject: [NATS_MODULE_OPTIONS, ConfigService],\n };\n\n return {\n module: NatsClientModule,\n imports: [ConfigModule, ...(asyncOptions.imports ?? [])],\n providers: [optionsProvider, resolverProvider, clientsProvider, NatsClientService],\n exports: [NatsClientService],\n };\n }\n\n // Microservice mode — singleton, forwards context from incoming NATS payload\n static forMicroservice(asyncOptions: NatsMicroserviceModuleAsyncOptions): DynamicModule {\n const optionsProvider: Provider = {\n provide: NATS_MS_OPTIONS,\n useFactory: asyncOptions.useFactory,\n inject: asyncOptions.inject || [],\n };\n\n const clientsProvider: Provider = {\n provide: NATS_MS_CLIENTS,\n useFactory: (options: NatsModuleBaseOptions, config: ConfigService): Map<string, ClientProxy> => {\n const natsUrl = options.natsUrl ?? config.get<string>('NATS_URL', 'nats://localhost:4222');\n return NatsClientModule.buildClients(options, natsUrl);\n },\n inject: [NATS_MS_OPTIONS, ConfigService],\n };\n\n return {\n module: NatsClientModule,\n imports: [ConfigModule, ...(asyncOptions.imports ?? [])],\n providers: [optionsProvider, clientsProvider, NatsMicroserviceClientService],\n exports: [NatsMicroserviceClientService],\n };\n }\n}\n","export const NATS_MODULE_OPTIONS = Symbol('NATS_MODULE_OPTIONS');\nexport const NATS_CONTEXT_RESOLVER = Symbol('NATS_CONTEXT_RESOLVER');\n","// Pulls the fastify module augmentation into this entry's dts graph — tsup builds each entry in isolation\nimport '../types/fastify-augmentation';\nimport { Inject, Injectable, Scope } from '@nestjs/common';\nimport { REQUEST } from '@nestjs/core';\nimport type { ClientProxy } from '@nestjs/microservices';\nimport { NatsRecordBuilder } from '@nestjs/microservices';\nimport type { FastifyRequest } from 'fastify';\nimport { headers as natsHeaders } from '@nats-io/transport-node';\nimport { resolveInjectedRequest } from '../context/resolve-request';\nimport { NATS_CONTEXT_RESOLVER } from './constants';\nimport type { ContextResolverFn } from './nats-client.interfaces';\nimport { NATS_HEADER_KEYS, type NatsHeaders } from './nats-context';\n\nexport const NATS_CLIENTS = Symbol('NATS_CLIENTS');\n\n@Injectable({ scope: Scope.REQUEST })\nexport class NatsClientService {\n private cachedContext: NatsHeaders | null = null;\n\n constructor(\n @Inject(REQUEST) private readonly injectedRequest: FastifyRequest,\n @Inject(NATS_CONTEXT_RESOLVER) private readonly contextResolver: ContextResolverFn,\n @Inject(NATS_CLIENTS) private readonly clients: Map<string, ClientProxy>,\n ) {}\n\n // Unwraps the GraphQL { req, reply } context wrapper so auth is visible across both transports\n private get request(): FastifyRequest {\n return resolveInjectedRequest(this.injectedRequest);\n }\n\n // Sends a message to a named microservice with NatsHeaders as NATS headers\n async send<T>(service: string, cmd: string, data?: object): Promise<T> {\n const client = this.clients.get(service);\n if (!client) {\n throw new Error(\n `NATS service \"${service}\" is not registered. Available: [${[...this.clients.keys()].join(', ')}]`,\n );\n }\n\n if (!this.cachedContext) {\n // The resolver takes the whole request rather than one auth field: which caller kinds\n // exist, and what each contributes, is the consuming server's model — this side only\n // knows that something has to produce headers.\n const context = await this.contextResolver(this.request);\n if (!context) {\n throw new Error('No auth context on request — is the auth guard active for this route?');\n }\n this.cachedContext = context;\n }\n\n const headers = contextToHeaders(this.cachedContext);\n const record = new NatsRecordBuilder(data ?? {}).setHeaders(headers).build();\n\n return client.send<T>({ cmd }, record).toPromise() as Promise<T>;\n }\n}\n\n// Converts NatsHeaders to a NATS MsgHdrs object for NATS transport.\n//\n// Driven by the key map rather than a field-per-line, so a new context field travels the\n// moment it is added to NATS_HEADER_KEYS. Empty values are omitted — parseNatsHeaders applies\n// the same defaults on the way back, so sending a blank would just restate them.\nfunction contextToHeaders(ctx: NatsHeaders): import('@nats-io/transport-node').MsgHdrs {\n const hdrs = natsHeaders();\n for (const [field, key] of Object.entries(NATS_HEADER_KEYS) as [keyof NatsHeaders, string][]) {\n if (ctx[field]) hdrs.set(key, ctx[field]);\n }\n return hdrs;\n}\n","import type { FastifyRequest } from 'fastify';\n\n// Unwraps the @Inject(REQUEST) value to the real Fastify request (GraphQL injects a { req, reply } context).\nexport function resolveInjectedRequest(injected: FastifyRequest): FastifyRequest {\n const candidate = injected as unknown as { headers?: unknown; req?: FastifyRequest };\n if (candidate && candidate.headers === undefined && candidate.req) {\n return candidate.req;\n }\n return injected;\n}\n","import { Inject, Injectable } from '@nestjs/common';\nimport type { ClientProxy } from '@nestjs/microservices';\nimport { NatsRecordBuilder } from '@nestjs/microservices';\nimport { NATS_HEADER_KEYS, type NatsHeaders } from './nats-context';\n\nexport const NATS_MS_CLIENTS = Symbol('NATS_MS_CLIENTS');\n\n@Injectable()\nexport class NatsMicroserviceClientService {\n constructor(@Inject(NATS_MS_CLIENTS) private readonly clients: Map<string, ClientProxy>) {}\n\n // Forwards a message to another microservice with NatsHeaders\n async send<T>(service: string, cmd: string, natsHeaders: NatsHeaders, data?: object): Promise<T> {\n const client = this.clients.get(service);\n if (!client) {\n throw new Error(\n `NATS service \"${service}\" is not registered. Available: [${[...this.clients.keys()].join(', ')}]`,\n );\n }\n\n const headers: Record<string, string> = {\n [NATS_HEADER_KEYS.orgId]: natsHeaders.orgId,\n [NATS_HEADER_KEYS.userId]: natsHeaders.userId,\n [NATS_HEADER_KEYS.siteId]: natsHeaders.siteId,\n [NATS_HEADER_KEYS.siteTimezone]: natsHeaders.siteTimezone,\n };\n\n const record = new NatsRecordBuilder(data ?? {}).setHeaders(headers).build();\n return client.send<T>({ cmd }, record).toPromise() as Promise<T>;\n }\n}\n"],"mappings":"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","names":["import_common","import_common","HttpProblemException","HttpException","detailOrOptions","httpStatus","options","detail","type","label","errors","ConflictException","HttpProblemException","detailOrOptions","HttpStatus","CONFLICT","PG_UNIQUE_VIOLATION","tryTranslatePgError","error","pgError","findPgError","undefined","code","constraint","table","detail","ConflictException","label","trim","errors","meta","depth","candidate","cause","RpcProblemExceptionFilter","logger","Logger","name","catch","exception","_host","translatedPgError","tryTranslatePgError","RpcException","throwError","getError","isHttpException","status","getStatus","response","getResponse","payload","toProblemPayload","log","HttpStatus","INTERNAL_SERVER_ERROR","error","warn","call","detail","Error","cause","causeMessage","message","undefined","causeStack","stack","type","errors","JSON","stringify","statusCode","obj","Array","isArray","join","label","import_common","NATS_HEADER_KEYS","orgId","userId","siteId","legalEntityId","siteGroupId","siteTimezone","siteCurrencyCode","HEADER_FALLBACKS","getHeader","headers","key","undefined","get","val","Array","isArray","parseNatsHeaders","parsed","field","Object","entries","RpcNatsHeaders","createParamDecorator","_data","ctx","rpcCtx","switchToRpc","getContext","parseNatsHeaders","getHeaders","RpcSiteId","headers","siteId","InternalServerErrorException","RpcSiteCurrencyCode","siteCurrencyCode","import_common","import_microservices","NATS_MODULE_OPTIONS","Symbol","NATS_CONTEXT_RESOLVER","import_common","import_microservices","resolveInjectedRequest","injected","candidate","headers","undefined","req","NATS_CLIENTS","Symbol","NatsClientService","cachedContext","injectedRequest","contextResolver","clients","request","resolveInjectedRequest","send","service","cmd","data","client","get","Error","keys","join","context","headers","contextToHeaders","record","NatsRecordBuilder","setHeaders","build","toPromise","scope","Scope","REQUEST","ctx","hdrs","natsHeaders","field","key","Object","entries","NATS_HEADER_KEYS","set","import_common","import_microservices","NATS_MS_CLIENTS","Symbol","NatsMicroserviceClientService","clients","send","service","cmd","natsHeaders","data","client","get","Error","keys","join","headers","NATS_HEADER_KEYS","orgId","userId","siteId","siteTimezone","record","NatsRecordBuilder","setHeaders","build","toPromise","NATS_MS_OPTIONS","Symbol","NatsClientModule","logger","Logger","name","allClients","onModuleDestroy","Promise","all","map","c","close","buildClients","options","natsUrl","clients","Map","svc","services","proxy","ClientProxyFactory","create","transport","Transport","NATS","servers","set","push","log","forRoot","asyncOptions","optionsProvider","provide","NATS_MODULE_OPTIONS","useFactory","inject","resolverProvider","NATS_CONTEXT_RESOLVER","contextResolver","clientsProvider","NATS_CLIENTS","config","get","ConfigService","module","imports","ConfigModule","providers","NatsClientService","exports","forMicroservice","NATS_MS_CLIENTS","NatsMicroserviceClientService"]}