@vritti/api-sdk 0.3.3 → 0.3.5
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.
- package/dist/auth.cjs +942 -0
- package/dist/auth.cjs.map +1 -0
- package/dist/auth.d.cts +95 -0
- package/dist/auth.d.ts +95 -0
- package/dist/auth.js +884 -0
- package/dist/auth.js.map +1 -0
- package/dist/cache.cjs +182 -14
- package/dist/cache.cjs.map +1 -1
- package/dist/cache.d.cts +48 -4
- package/dist/cache.d.ts +48 -4
- package/dist/cache.js +177 -12
- package/dist/cache.js.map +1 -1
- package/dist/catalog-resolver.cjs +226 -51
- package/dist/catalog-resolver.cjs.map +1 -1
- package/dist/catalog-resolver.d.cts +41 -19
- package/dist/catalog-resolver.d.ts +41 -19
- package/dist/catalog-resolver.js +212 -46
- package/dist/catalog-resolver.js.map +1 -1
- package/dist/code-pattern-BP4zkNtT.d.cts +12 -0
- package/dist/code-pattern-BP4zkNtT.d.ts +12 -0
- package/dist/context.cjs +93 -0
- package/dist/context.cjs.map +1 -0
- package/dist/context.d.cts +19 -0
- package/dist/context.d.ts +19 -0
- package/dist/context.js +64 -0
- package/dist/context.js.map +1 -0
- package/dist/countries.cjs +1559 -0
- package/dist/countries.cjs.map +1 -0
- package/dist/countries.d.cts +13 -0
- package/dist/countries.d.ts +13 -0
- package/dist/countries.js +1532 -0
- package/dist/countries.js.map +1 -0
- package/dist/data-table.cjs +1280 -0
- package/dist/data-table.cjs.map +1 -0
- package/dist/data-table.d.cts +123 -0
- package/dist/data-table.d.ts +123 -0
- package/dist/data-table.js +1260 -0
- package/dist/data-table.js.map +1 -0
- package/dist/database.cjs +1510 -0
- package/dist/database.cjs.map +1 -0
- package/dist/database.d.cts +287 -0
- package/dist/database.d.ts +287 -0
- package/dist/database.js +1469 -0
- package/dist/database.js.map +1 -0
- package/dist/decimal.d.cts +0 -1
- package/dist/decimal.d.ts +0 -1
- package/dist/decorators.cjs +1817 -0
- package/dist/decorators.cjs.map +1 -0
- package/dist/decorators.d.cts +24 -0
- package/dist/decorators.d.ts +24 -0
- package/dist/decorators.js +1780 -0
- package/dist/decorators.js.map +1 -0
- package/dist/drizzle-pg-core.cjs +25 -0
- package/dist/drizzle-pg-core.cjs.map +1 -1
- package/dist/drizzle-pg-core.d.cts +7 -0
- package/dist/drizzle-pg-core.d.ts +7 -0
- package/dist/drizzle-pg-core.js +22 -0
- package/dist/drizzle-pg-core.js.map +1 -1
- package/dist/exceptions.cjs +301 -0
- package/dist/exceptions.cjs.map +1 -0
- package/dist/exceptions.d.cts +90 -0
- package/dist/exceptions.d.ts +90 -0
- package/dist/exceptions.js +257 -0
- package/dist/exceptions.js.map +1 -0
- package/dist/filter.types-PuARU9XD.d.cts +50 -0
- package/dist/filter.types-PuARU9XD.d.ts +50 -0
- package/dist/filters.cjs +407 -0
- package/dist/filters.cjs.map +1 -0
- package/dist/filters.d.cts +55 -0
- package/dist/filters.d.ts +55 -0
- package/dist/filters.js +377 -0
- package/dist/filters.js.map +1 -0
- package/dist/index.cjs +0 -5423
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -854
- package/dist/index.d.ts +93 -854
- package/dist/index.js +0 -5301
- package/dist/index.js.map +1 -1
- package/dist/is-country.decorator-CcNwSSr5.d.cts +5 -0
- package/dist/is-country.decorator-CcNwSSr5.d.ts +5 -0
- package/dist/license.d.cts +1 -1
- package/dist/license.d.ts +1 -1
- package/dist/lodash.cjs.map +1 -1
- package/dist/lodash.js.map +1 -1
- package/dist/logger.cjs +862 -0
- package/dist/logger.cjs.map +1 -0
- package/dist/logger.d.cts +118 -0
- package/dist/logger.d.ts +118 -0
- package/dist/logger.js +816 -0
- package/dist/logger.js.map +1 -0
- package/dist/migrate.cjs +2 -2
- package/dist/migrate.cjs.map +1 -1
- package/dist/migrate.d.cts +2 -0
- package/dist/migrate.d.ts +2 -0
- package/dist/migrate.js +2 -2
- package/dist/migrate.js.map +1 -1
- package/dist/money.cjs +18 -3
- package/dist/money.cjs.map +1 -1
- package/dist/money.d.cts +13 -13
- package/dist/money.d.ts +13 -13
- package/dist/money.js +18 -3
- package/dist/money.js.map +1 -1
- package/dist/nats.cjs +34 -35
- package/dist/nats.cjs.map +1 -1
- package/dist/nats.d.cts +14 -14
- package/dist/nats.d.ts +14 -14
- package/dist/nats.js +32 -33
- package/dist/nats.js.map +1 -1
- package/dist/root.cjs +225 -0
- package/dist/root.cjs.map +1 -0
- package/dist/root.d.cts +4 -0
- package/dist/root.d.ts +4 -0
- package/dist/root.js +200 -0
- package/dist/root.js.map +1 -0
- package/dist/{types-DQRwj5rr.d.cts → types-C9jPdQqH.d.cts} +32 -6
- package/dist/{types-DQRwj5rr.d.ts → types-C9jPdQqH.d.ts} +32 -6
- package/dist/types.cjs +19 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +17 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.cjs +273 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.cts +8 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.js +245 -0
- package/dist/utils.js.map +1 -0
- package/package.json +122 -1
- package/dist/cache.service-_SuJIcNA.d.cts +0 -20
- package/dist/cache.service-_SuJIcNA.d.ts +0 -20
- package/dist/fastify-augmentation-CQPBNS5a.d.cts +0 -105
- package/dist/fastify-augmentation-CQPBNS5a.d.ts +0 -105
|
@@ -0,0 +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":"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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/migrate.cjs
CHANGED
|
@@ -46,8 +46,8 @@ function requiredEnv(name) {
|
|
|
46
46
|
__name(requiredEnv, "requiredEnv");
|
|
47
47
|
async function runMigrationsAndGrants(options) {
|
|
48
48
|
const directUrl = requiredEnv("PRIMARY_DB_DATABASE_DIRECT_URL");
|
|
49
|
-
const dbSchema =
|
|
50
|
-
const migrationSchema =
|
|
49
|
+
const dbSchema = options.schema;
|
|
50
|
+
const migrationSchema = options.migrationSchema;
|
|
51
51
|
const appRole = requiredEnv("PRIMARY_DB_USERNAME");
|
|
52
52
|
const pool = new import_pg.Pool({
|
|
53
53
|
connectionString: directUrl,
|
package/dist/migrate.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/migrate.ts","../src/database/migrate-runner.ts"],"sourcesContent":["// Subpath entry: @vritti/api-sdk/migrate — DB migration + grants runner for release-phase one-shots.\nexport { type MigrateRunnerOptions, runMigrationsAndGrants } from './database/migrate-runner';\n","import { drizzle } from 'drizzle-orm/node-postgres';\nimport { migrate } from 'drizzle-orm/node-postgres/migrator';\nimport { Pool } from 'pg';\n\
|
|
1
|
+
{"version":3,"sources":["../src/migrate.ts","../src/database/migrate-runner.ts"],"sourcesContent":["// Subpath entry: @vritti/api-sdk/migrate — DB migration + grants runner for release-phase one-shots.\nexport { type MigrateRunnerOptions, runMigrationsAndGrants } from './database/migrate-runner';\n","import { drizzle } from 'drizzle-orm/node-postgres';\nimport { migrate } from 'drizzle-orm/node-postgres/migrator';\nimport { Pool } from 'pg';\n\nexport interface MigrateRunnerOptions {\n migrationsFolder: string;\n migrationsTable: string;\n schema: string;\n migrationSchema: string;\n}\n\n// Validates and quotes a Postgres identifier (role/schema names can't be bound as query params).\nfunction quoteIdent(name: string): string {\n if (!/^[A-Za-z_][A-Za-z0-9_$]*$/.test(name)) {\n throw new Error(`Unsafe SQL identifier: ${name}`);\n }\n return `\"${name}\"`;\n}\n\n// Reads a required environment variable or throws.\nfunction requiredEnv(name: string): string {\n const value = process.env[name];\n if (!value) {\n throw new Error(`${name} environment variable is required`);\n }\n return value;\n}\n\n// Applies Drizzle migrations as the owner, then idempotently grants the runtime app role schema access.\nexport async function runMigrationsAndGrants(options: MigrateRunnerOptions): Promise<void> {\n const directUrl = requiredEnv('PRIMARY_DB_DATABASE_DIRECT_URL');\n const dbSchema = options.schema;\n const migrationSchema = options.migrationSchema;\n const appRole = requiredEnv('PRIMARY_DB_USERNAME');\n\n // Single connection as the owner role — runs both DDL and the grants below.\n const pool = new Pool({ connectionString: directUrl, max: 1 });\n const db = drizzle({ client: pool });\n\n try {\n console.log(`[migrate] applying migrations from ${options.migrationsFolder}`);\n await migrate(db, {\n migrationsFolder: options.migrationsFolder,\n migrationsTable: options.migrationsTable,\n migrationsSchema: migrationSchema,\n });\n\n const schema = quoteIdent(dbSchema);\n const role = quoteIdent(appRole);\n console.log(`[migrate] granting ${dbSchema} privileges to ${appRole}`);\n\n // All statements are idempotent — safe on every deploy; ALTER DEFAULT PRIVILEGES auto-grants future objects.\n await pool.query(`\n GRANT USAGE ON SCHEMA ${schema} TO ${role};\n GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA ${schema} TO ${role};\n GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA ${schema} TO ${role};\n GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA ${schema} TO ${role};\n ALTER DEFAULT PRIVILEGES IN SCHEMA ${schema} GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO ${role};\n ALTER DEFAULT PRIVILEGES IN SCHEMA ${schema} GRANT USAGE, SELECT ON SEQUENCES TO ${role};\n ALTER DEFAULT PRIVILEGES IN SCHEMA ${schema} GRANT EXECUTE ON FUNCTIONS TO ${role};\n `);\n\n console.log('[migrate] done');\n } finally {\n await pool.end();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;ACAA,2BAAwB;AACxB,sBAAwB;AACxB,gBAAqB;AAUrB,SAASA,WAAWC,MAAY;AAC9B,MAAI,CAAC,4BAA4BC,KAAKD,IAAAA,GAAO;AAC3C,UAAM,IAAIE,MAAM,0BAA0BF,IAAAA,EAAM;EAClD;AACA,SAAO,IAAIA,IAAAA;AACb;AALSD;AAQT,SAASI,YAAYH,MAAY;AAC/B,QAAMI,QAAQC,QAAQC,IAAIN,IAAAA;AAC1B,MAAI,CAACI,OAAO;AACV,UAAM,IAAIF,MAAM,GAAGF,IAAAA,mCAAuC;EAC5D;AACA,SAAOI;AACT;AANSD;AAST,eAAsBI,uBAAuBC,SAA6B;AACxE,QAAMC,YAAYN,YAAY,gCAAA;AAC9B,QAAMO,WAAWF,QAAQG;AACzB,QAAMC,kBAAkBJ,QAAQI;AAChC,QAAMC,UAAUV,YAAY,qBAAA;AAG5B,QAAMW,OAAO,IAAIC,eAAK;IAAEC,kBAAkBP;IAAWQ,KAAK;EAAE,CAAA;AAC5D,QAAMC,SAAKC,8BAAQ;IAAEC,QAAQN;EAAK,CAAA;AAElC,MAAI;AACFO,YAAQC,IAAI,sCAAsCd,QAAQe,gBAAgB,EAAE;AAC5E,cAAMC,yBAAQN,IAAI;MAChBK,kBAAkBf,QAAQe;MAC1BE,iBAAiBjB,QAAQiB;MACzBC,kBAAkBd;IACpB,CAAA;AAEA,UAAMD,SAASZ,WAAWW,QAAAA;AAC1B,UAAMiB,OAAO5B,WAAWc,OAAAA;AACxBQ,YAAQC,IAAI,sBAAsBZ,QAAAA,kBAA0BG,OAAAA,EAAS;AAGrE,UAAMC,KAAKc,MAAM;8BACSjB,MAAAA,OAAagB,IAAAA;uEAC4BhB,MAAAA,OAAagB,IAAAA;wEACZhB,MAAAA,OAAagB,IAAAA;wEACbhB,MAAAA,OAAagB,IAAAA;2CAC1ChB,MAAAA,yDAA+DgB,IAAAA;2CAC/DhB,MAAAA,yDAA+DgB,IAAAA;2CAC/DhB,MAAAA,yDAA+DgB,IAAAA;KACrG;AAEDN,YAAQC,IAAI,gBAAA;EACd,UAAA;AACE,UAAMR,KAAKe,IAAG;EAChB;AACF;AArCsBtB;","names":["quoteIdent","name","test","Error","requiredEnv","value","process","env","runMigrationsAndGrants","options","directUrl","dbSchema","schema","migrationSchema","appRole","pool","Pool","connectionString","max","db","drizzle","client","console","log","migrationsFolder","migrate","migrationsTable","migrationsSchema","role","query","end"]}
|
package/dist/migrate.d.cts
CHANGED
package/dist/migrate.d.ts
CHANGED
package/dist/migrate.js
CHANGED
|
@@ -22,8 +22,8 @@ function requiredEnv(name) {
|
|
|
22
22
|
__name(requiredEnv, "requiredEnv");
|
|
23
23
|
async function runMigrationsAndGrants(options) {
|
|
24
24
|
const directUrl = requiredEnv("PRIMARY_DB_DATABASE_DIRECT_URL");
|
|
25
|
-
const dbSchema =
|
|
26
|
-
const migrationSchema =
|
|
25
|
+
const dbSchema = options.schema;
|
|
26
|
+
const migrationSchema = options.migrationSchema;
|
|
27
27
|
const appRole = requiredEnv("PRIMARY_DB_USERNAME");
|
|
28
28
|
const pool = new Pool({
|
|
29
29
|
connectionString: directUrl,
|
package/dist/migrate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/database/migrate-runner.ts"],"sourcesContent":["import { drizzle } from 'drizzle-orm/node-postgres';\nimport { migrate } from 'drizzle-orm/node-postgres/migrator';\nimport { Pool } from 'pg';\n\
|
|
1
|
+
{"version":3,"sources":["../src/database/migrate-runner.ts"],"sourcesContent":["import { drizzle } from 'drizzle-orm/node-postgres';\nimport { migrate } from 'drizzle-orm/node-postgres/migrator';\nimport { Pool } from 'pg';\n\nexport interface MigrateRunnerOptions {\n migrationsFolder: string;\n migrationsTable: string;\n schema: string;\n migrationSchema: string;\n}\n\n// Validates and quotes a Postgres identifier (role/schema names can't be bound as query params).\nfunction quoteIdent(name: string): string {\n if (!/^[A-Za-z_][A-Za-z0-9_$]*$/.test(name)) {\n throw new Error(`Unsafe SQL identifier: ${name}`);\n }\n return `\"${name}\"`;\n}\n\n// Reads a required environment variable or throws.\nfunction requiredEnv(name: string): string {\n const value = process.env[name];\n if (!value) {\n throw new Error(`${name} environment variable is required`);\n }\n return value;\n}\n\n// Applies Drizzle migrations as the owner, then idempotently grants the runtime app role schema access.\nexport async function runMigrationsAndGrants(options: MigrateRunnerOptions): Promise<void> {\n const directUrl = requiredEnv('PRIMARY_DB_DATABASE_DIRECT_URL');\n const dbSchema = options.schema;\n const migrationSchema = options.migrationSchema;\n const appRole = requiredEnv('PRIMARY_DB_USERNAME');\n\n // Single connection as the owner role — runs both DDL and the grants below.\n const pool = new Pool({ connectionString: directUrl, max: 1 });\n const db = drizzle({ client: pool });\n\n try {\n console.log(`[migrate] applying migrations from ${options.migrationsFolder}`);\n await migrate(db, {\n migrationsFolder: options.migrationsFolder,\n migrationsTable: options.migrationsTable,\n migrationsSchema: migrationSchema,\n });\n\n const schema = quoteIdent(dbSchema);\n const role = quoteIdent(appRole);\n console.log(`[migrate] granting ${dbSchema} privileges to ${appRole}`);\n\n // All statements are idempotent — safe on every deploy; ALTER DEFAULT PRIVILEGES auto-grants future objects.\n await pool.query(`\n GRANT USAGE ON SCHEMA ${schema} TO ${role};\n GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA ${schema} TO ${role};\n GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA ${schema} TO ${role};\n GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA ${schema} TO ${role};\n ALTER DEFAULT PRIVILEGES IN SCHEMA ${schema} GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO ${role};\n ALTER DEFAULT PRIVILEGES IN SCHEMA ${schema} GRANT USAGE, SELECT ON SEQUENCES TO ${role};\n ALTER DEFAULT PRIVILEGES IN SCHEMA ${schema} GRANT EXECUTE ON FUNCTIONS TO ${role};\n `);\n\n console.log('[migrate] done');\n } finally {\n await pool.end();\n }\n}\n"],"mappings":";;;;AAAA,SAASA,eAAe;AACxB,SAASC,eAAe;AACxB,SAASC,YAAY;AAUrB,SAASC,WAAWC,MAAY;AAC9B,MAAI,CAAC,4BAA4BC,KAAKD,IAAAA,GAAO;AAC3C,UAAM,IAAIE,MAAM,0BAA0BF,IAAAA,EAAM;EAClD;AACA,SAAO,IAAIA,IAAAA;AACb;AALSD;AAQT,SAASI,YAAYH,MAAY;AAC/B,QAAMI,QAAQC,QAAQC,IAAIN,IAAAA;AAC1B,MAAI,CAACI,OAAO;AACV,UAAM,IAAIF,MAAM,GAAGF,IAAAA,mCAAuC;EAC5D;AACA,SAAOI;AACT;AANSD;AAST,eAAsBI,uBAAuBC,SAA6B;AACxE,QAAMC,YAAYN,YAAY,gCAAA;AAC9B,QAAMO,WAAWF,QAAQG;AACzB,QAAMC,kBAAkBJ,QAAQI;AAChC,QAAMC,UAAUV,YAAY,qBAAA;AAG5B,QAAMW,OAAO,IAAIC,KAAK;IAAEC,kBAAkBP;IAAWQ,KAAK;EAAE,CAAA;AAC5D,QAAMC,KAAKC,QAAQ;IAAEC,QAAQN;EAAK,CAAA;AAElC,MAAI;AACFO,YAAQC,IAAI,sCAAsCd,QAAQe,gBAAgB,EAAE;AAC5E,UAAMC,QAAQN,IAAI;MAChBK,kBAAkBf,QAAQe;MAC1BE,iBAAiBjB,QAAQiB;MACzBC,kBAAkBd;IACpB,CAAA;AAEA,UAAMD,SAASZ,WAAWW,QAAAA;AAC1B,UAAMiB,OAAO5B,WAAWc,OAAAA;AACxBQ,YAAQC,IAAI,sBAAsBZ,QAAAA,kBAA0BG,OAAAA,EAAS;AAGrE,UAAMC,KAAKc,MAAM;8BACSjB,MAAAA,OAAagB,IAAAA;uEAC4BhB,MAAAA,OAAagB,IAAAA;wEACZhB,MAAAA,OAAagB,IAAAA;wEACbhB,MAAAA,OAAagB,IAAAA;2CAC1ChB,MAAAA,yDAA+DgB,IAAAA;2CAC/DhB,MAAAA,yDAA+DgB,IAAAA;2CAC/DhB,MAAAA,yDAA+DgB,IAAAA;KACrG;AAEDN,YAAQC,IAAI,gBAAA;EACd,UAAA;AACE,UAAMR,KAAKe,IAAG;EAChB;AACF;AArCsBtB;","names":["drizzle","migrate","Pool","quoteIdent","name","test","Error","requiredEnv","value","process","env","runMigrationsAndGrants","options","directUrl","dbSchema","schema","migrationSchema","appRole","pool","Pool","connectionString","max","db","drizzle","client","console","log","migrationsFolder","migrate","migrationsTable","migrationsSchema","role","query","end"]}
|
package/dist/money.cjs
CHANGED
|
@@ -293,8 +293,23 @@ var SUPPORTED_CURRENCIES = {
|
|
|
293
293
|
ZWG: import_currencies.ZWG,
|
|
294
294
|
ZWL
|
|
295
295
|
};
|
|
296
|
-
function resolveCurrency(currencyCode) {
|
|
297
|
-
|
|
296
|
+
function resolveCurrency(currencyCode, field) {
|
|
297
|
+
const currency = SUPPORTED_CURRENCIES[currencyCode];
|
|
298
|
+
if (!currency) {
|
|
299
|
+
throw new ValidationException({
|
|
300
|
+
label: "Unsupported Currency",
|
|
301
|
+
detail: `Unsupported currency: "${currencyCode}".`,
|
|
302
|
+
...field ? {
|
|
303
|
+
errors: [
|
|
304
|
+
{
|
|
305
|
+
field,
|
|
306
|
+
message: "Unsupported currency."
|
|
307
|
+
}
|
|
308
|
+
]
|
|
309
|
+
} : {}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
return currency;
|
|
298
313
|
}
|
|
299
314
|
__name(resolveCurrency, "resolveCurrency");
|
|
300
315
|
function minorToMajor(minor, currencyCode, transform) {
|
|
@@ -313,7 +328,7 @@ function minorToMajor(minor, currencyCode, transform) {
|
|
|
313
328
|
}
|
|
314
329
|
__name(minorToMajor, "minorToMajor");
|
|
315
330
|
function majorToMinor(major, currencyCode, field = "amount") {
|
|
316
|
-
const { exponent } = resolveCurrency(currencyCode);
|
|
331
|
+
const { exponent } = resolveCurrency(currencyCode, field);
|
|
317
332
|
const scale = typeof exponent === "bigint" ? Number(exponent) : exponent;
|
|
318
333
|
const trimmed = major.trim();
|
|
319
334
|
if (!/^-?\d+(\.\d+)?$/.test(trimmed)) {
|
package/dist/money.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/money/index.ts","../src/money/money.ts","../src/exceptions/validation.exception.ts","../src/exceptions/base-field.exception.ts","../src/money/currency-amount.dto.ts","../src/money/is-currency.decorator.ts","../src/money/is-currency-code.decorator.ts"],"sourcesContent":["// Money module — the ONLY entry that touches dinero.js (utilities, validators, DTO, dinero re-export)\nexport { CurrencyAmountDto } from './currency-amount.dto';\nexport { IsCurrency } from './is-currency.decorator';\nexport { IsCurrencyCode } from './is-currency-code.decorator';\nexport * from './money';\n","import { dinero, toDecimal } from 'dinero.js/bigint';\nimport {\n AED,\n AFN,\n ALL,\n AMD,\n AOA,\n ARS,\n AUD,\n AWG,\n AZN,\n BAM,\n BBD,\n BDT,\n BGN,\n BHD,\n BIF,\n BMD,\n BND,\n BOB,\n BOV,\n BRL,\n BSD,\n BTN,\n BWP,\n BYN,\n BZD,\n CAD,\n CDF,\n CHE,\n CHF,\n CHW,\n CLF,\n CLP,\n CNY,\n COP,\n COU,\n CRC,\n CUP,\n CVE,\n CZK,\n DJF,\n DKK,\n DOP,\n DZD,\n EGP,\n ERN,\n ETB,\n EUR,\n FJD,\n FKP,\n GBP,\n GEL,\n GHS,\n GIP,\n GMD,\n GNF,\n GTQ,\n GYD,\n HKD,\n HNL,\n HTG,\n HUF,\n IDR,\n ILS,\n INR,\n IQD,\n IRR,\n ISK,\n JMD,\n JOD,\n JPY,\n KES,\n KGS,\n KHR,\n KMF,\n KPW,\n KRW,\n KWD,\n KYD,\n KZT,\n LAK,\n LBP,\n LKR,\n LRD,\n LSL,\n LYD,\n MAD,\n MDL,\n MGA,\n MKD,\n MMK,\n MNT,\n MOP,\n MRU,\n MUR,\n MVR,\n MWK,\n MXN,\n MXV,\n MYR,\n MZN,\n NAD,\n NGN,\n NIO,\n NOK,\n NPR,\n NZD,\n OMR,\n PAB,\n PEN,\n PGK,\n PHP,\n PKR,\n PLN,\n PYG,\n QAR,\n RON,\n RSD,\n RUB,\n RWF,\n SAR,\n SBD,\n SCR,\n SDG,\n SEK,\n SGD,\n SHP,\n SLE,\n SOS,\n SRD,\n SSP,\n STN,\n SVC,\n SYP,\n SZL,\n THB,\n TJS,\n TMT,\n TND,\n TOP,\n TRY,\n TTD,\n TWD,\n TZS,\n UAH,\n UGX,\n USD,\n USN,\n UYI,\n UYU,\n UYW,\n UZS,\n VED,\n VES,\n VND,\n VUV,\n WST,\n XAD,\n XAF,\n XCD,\n XCG,\n XOF,\n XPF,\n YER,\n ZAR,\n ZMW,\n ZWG,\n} from 'dinero.js/bigint/currencies';\nimport { ValidationException } from '../exceptions/validation.exception';\n\nexport * from 'dinero.js/bigint';\n\nconst ANG = { code: 'ANG', base: 10n, exponent: 2n } as const;\nconst HRK = { code: 'HRK', base: 10n, exponent: 2n } as const;\nconst XAG = { code: 'XAG', base: 10n, exponent: 0n } as const;\nconst XAU = { code: 'XAU', base: 10n, exponent: 0n } as const;\nconst XDR = { code: 'XDR', base: 10n, exponent: 0n } as const;\nconst XPD = { code: 'XPD', base: 10n, exponent: 0n } as const;\nconst XPT = { code: 'XPT', base: 10n, exponent: 0n } as const;\nconst ZWL = { code: 'ZWL', base: 10n, exponent: 2n } as const;\n\nexport const SUPPORTED_CURRENCIES = {\n AED,\n AFN,\n ALL,\n AMD,\n ANG,\n AOA,\n ARS,\n AUD,\n AWG,\n AZN,\n BAM,\n BBD,\n BDT,\n BGN,\n BHD,\n BIF,\n BMD,\n BND,\n BOB,\n BOV,\n BRL,\n BSD,\n BTN,\n BWP,\n BYN,\n BZD,\n CAD,\n CDF,\n CHE,\n CHF,\n CHW,\n CLF,\n CLP,\n CNY,\n COP,\n COU,\n CRC,\n CUP,\n CVE,\n CZK,\n DJF,\n DKK,\n DOP,\n DZD,\n EGP,\n ERN,\n ETB,\n EUR,\n FJD,\n FKP,\n GBP,\n GEL,\n GHS,\n GIP,\n GMD,\n GNF,\n GTQ,\n GYD,\n HKD,\n HNL,\n HRK,\n HTG,\n HUF,\n IDR,\n ILS,\n INR,\n IQD,\n IRR,\n ISK,\n JMD,\n JOD,\n JPY,\n KES,\n KGS,\n KHR,\n KMF,\n KPW,\n KRW,\n KWD,\n KYD,\n KZT,\n LAK,\n LBP,\n LKR,\n LRD,\n LSL,\n LYD,\n MAD,\n MDL,\n MGA,\n MKD,\n MMK,\n MNT,\n MOP,\n MRU,\n MUR,\n MVR,\n MWK,\n MXN,\n MXV,\n MYR,\n MZN,\n NAD,\n NGN,\n NIO,\n NOK,\n NPR,\n NZD,\n OMR,\n PAB,\n PEN,\n PGK,\n PHP,\n PKR,\n PLN,\n PYG,\n QAR,\n RON,\n RSD,\n RUB,\n RWF,\n SAR,\n SBD,\n SCR,\n SDG,\n SEK,\n SGD,\n SHP,\n SLE,\n SOS,\n SRD,\n SSP,\n STN,\n SVC,\n SYP,\n SZL,\n THB,\n TJS,\n TMT,\n TND,\n TOP,\n TRY,\n TTD,\n TWD,\n TZS,\n UAH,\n UGX,\n USD,\n USN,\n UYI,\n UYU,\n UYW,\n UZS,\n VED,\n VES,\n VND,\n VUV,\n WST,\n XAD,\n XAF,\n XAG,\n XAU,\n XCD,\n XCG,\n XDR,\n XOF,\n XPD,\n XPF,\n XPT,\n YER,\n ZAR,\n ZMW,\n ZWG,\n ZWL,\n} as const;\n\nexport type CurrencyCode = keyof typeof SUPPORTED_CURRENCIES;\nexport type Currency = (typeof SUPPORTED_CURRENCIES)[CurrencyCode];\n\nexport type MinorToMajorTransform<TOutput> = (props: { value: string; currency: Currency }) => TOutput;\n\nexport function resolveCurrency(currencyCode: CurrencyCode): Currency {\n return SUPPORTED_CURRENCIES[currencyCode];\n}\n\nexport function minorToMajor<TOutput = string>(\n minor: bigint,\n currencyCode: CurrencyCode,\n transform?: MinorToMajorTransform<TOutput>,\n): string | TOutput {\n const currency = resolveCurrency(currencyCode);\n const amount = dinero({ amount: minor, currency });\n\n if (!transform) {\n return toDecimal(amount);\n }\n\n return toDecimal(amount, ({ value, currency: resolvedCurrency }) => transform({ value, currency: resolvedCurrency }));\n}\n\n// Throws ValidationException (HTTP 422) instead of generic Error so the\n// NestJS error filter maps it to a field-level response automatically.\n// Callers pass `field` so the validation error binds to the right form field.\nexport function majorToMinor(major: string, currencyCode: CurrencyCode, field = 'amount'): bigint {\n const { exponent } = resolveCurrency(currencyCode);\n const scale = typeof exponent === 'bigint' ? Number(exponent) : exponent;\n const trimmed = major.trim();\n\n if (!/^-?\\d+(\\.\\d+)?$/.test(trimmed)) {\n throw new ValidationException({\n detail: `Invalid amount: \"${major}\".`,\n errors: [{ field, message: 'Enter a valid number.' }],\n });\n }\n\n const isNegative = trimmed.startsWith('-');\n const unsignedValue = isNegative ? trimmed.slice(1) : trimmed;\n const [wholePart, fractionalPart = ''] = unsignedValue.split('.');\n\n if (fractionalPart.length > scale) {\n throw new ValidationException({\n detail: `Too many decimal places for ${currencyCode}. Maximum allowed is ${scale}.`,\n errors: [{ field, message: `${currencyCode} allows up to ${scale} decimal place${scale === 1 ? '' : 's'}.` }],\n });\n }\n\n const paddedFraction = fractionalPart.padEnd(scale, '0');\n const normalizedDigits = `${wholePart}${paddedFraction}`.replace(/^0+(?=\\d)/, '');\n const minor = BigInt(normalizedDigits || '0');\n\n return isNegative ? -minor : minor;\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ValidationException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Validation Failed', HttpStatus.UNPROCESSABLE_ENTITY);\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 { type CurrencyCode, minorToMajor } from './money';\n\nexport class CurrencyAmountDto {\n currency: string;\n value: string;\n\n static from(minor: bigint, currencyCode: string): CurrencyAmountDto;\n static from(minor: bigint | null | undefined, currencyCode: string): CurrencyAmountDto | null;\n static from(minor: bigint | null | undefined, currencyCode: string): CurrencyAmountDto | null {\n if (minor == null) return null;\n const dto = new CurrencyAmountDto();\n dto.currency = currencyCode;\n dto.value = minorToMajor(minor, currencyCode as CurrencyCode);\n return dto;\n }\n}\n","import { registerDecorator, type ValidationArguments, type ValidationOptions } from 'class-validator';\nimport { type CurrencyCode, majorToMinor, SUPPORTED_CURRENCIES } from './money';\n\n// Self-contained validator for `{currency, value}` payloads. Intentionally does NOT compose\n// `@ValidateNested()` + `@Type(() => CurrencyAmountDto)` — api-sdk and the consuming app each\n// load their own copy of `class-validator` (different MetadataStorage singletons), so any\n// field-level decorators registered on `CurrencyAmountDto` from inside api-sdk are invisible\n// to the consumer's validator. Doing everything here, at the consumer's call site, sidesteps\n// that and keeps the decorator usable everywhere.\n//\n// Checks performed (in order, short-circuiting):\n// 1. Value is a non-null object.\n// 2. `currency` and `value` are both strings.\n// 3. `currency` is in `SUPPORTED_CURRENCIES`.\n// 4. `majorToMinor(value, currency)` succeeds — enforces decimal precision ≤ currency exponent.\nexport function IsCurrency(validationOptions?: ValidationOptions): PropertyDecorator {\n return (target: object, propertyName: string | symbol) => {\n registerDecorator({\n name: 'isCurrency',\n target: target.constructor,\n propertyName: String(propertyName),\n options: validationOptions,\n validator: {\n validate(value: unknown): boolean {\n if (!value || typeof value !== 'object') return false;\n const { currency, value: amount } = value as Record<string, unknown>;\n if (typeof currency !== 'string' || typeof amount !== 'string') return false;\n if (!(currency in SUPPORTED_CURRENCIES)) return false;\n try {\n majorToMinor(amount, currency as CurrencyCode);\n return true;\n } catch {\n return false;\n }\n },\n defaultMessage(args: ValidationArguments): string {\n return `${args.property} must be {currency, value} where currency is a valid ISO 4217 code and value precision matches the currency exponent.`;\n },\n },\n });\n };\n}\n","import { registerDecorator, type ValidationArguments, type ValidationOptions } from 'class-validator';\nimport { SUPPORTED_CURRENCIES } from './money';\n\nexport function IsCurrencyCode(validationOptions?: ValidationOptions): PropertyDecorator {\n return (target: object, propertyName: string | symbol) => {\n registerDecorator({\n name: 'isCurrencyCode',\n target: target.constructor,\n propertyName: String(propertyName),\n options: validationOptions,\n validator: {\n validate(value: unknown): boolean {\n if (typeof value !== 'string') return false;\n return value in SUPPORTED_CURRENCIES;\n },\n defaultMessage(args: ValidationArguments): string {\n return `${args.property} must be a valid ISO 4217 currency code.`;\n },\n },\n });\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,iBAAA;SAAAA,gBAAA;;;;;;;;;8BAAAA;;;ACAA;;;;;;;AAAA,oBAAkC;AAClC,wBAuKO;;;ACxKP,IAAAC,iBAA2B;;;ACA3B,oBAA0C;AAanC,IAAeC,uBAAf,cAA4CC,4BAAAA;EAbnD,OAamDA;;;EACjD,YAAYC,iBAA0CC,YAAwB;AAC5E,UAAMC,UAAU,OAAOF,oBAAoB,WAAW;MAAEG,QAAQH;IAAgB,IAAIA;AAEpF,UACE;MACEI,MAAMF,QAAQE,QAAQ;MACtBC,OAAOH,QAAQG;MACfF,QAAQD,QAAQC;MAChBG,QAAQJ,QAAQI,UAAU,CAAA;IAC5B,GACAL,UAAAA;EAEJ;AACF;;;ADxBO,IAAMM,sBAAN,cAAkCC,qBAAAA;EAHzC,OAGyCA;;;EACvC,YAAYC,iBAA2C;AACrD,UAAMA,mBAAmB,qBAAqBC,0BAAWC,oBAAoB;EAC/E;AACF;;;ADoKA,0BAAc;AAEd,IAAMC,MAAM;EAAEC,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMC,MAAM;EAAEH,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAME,MAAM;EAAEJ,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMG,MAAM;EAAEL,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMI,MAAM;EAAEN,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMK,MAAM;EAAEP,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMM,MAAM;EAAER,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMO,MAAM;EAAET,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AAE5C,IAAMQ,uBAAuB;EAClCC;EACAC;EACAC;EACAC;EACAf;EACAgB;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAlE;EACAmE;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACApK;EACAC;EACAoK;EACAC;EACApK;EACAqK;EACApK;EACAqK;EACApK;EACAqK;EACAC;EACAC;EACAC;EACAvK;AACF;AAOO,SAASwK,gBAAgBC,cAA0B;AACxD,SAAOxK,qBAAqBwK,YAAAA;AAC9B;AAFgBD;AAIT,SAASE,aACdC,OACAF,cACAG,WAA0C;AAE1C,QAAMC,WAAWL,gBAAgBC,YAAAA;AACjC,QAAMK,aAASC,sBAAO;IAAED,QAAQH;IAAOE;EAAS,CAAA;AAEhD,MAAI,CAACD,WAAW;AACd,eAAOI,yBAAUF,MAAAA;EACnB;AAEA,aAAOE,yBAAUF,QAAQ,CAAC,EAAEG,OAAOJ,UAAUK,iBAAgB,MAAON,UAAU;IAAEK;IAAOJ,UAAUK;EAAiB,CAAA,CAAA;AACpH;AAbgBR;AAkBT,SAASS,aAAaC,OAAeX,cAA4BY,QAAQ,UAAQ;AACtF,QAAM,EAAE5L,SAAQ,IAAK+K,gBAAgBC,YAAAA;AACrC,QAAMa,QAAQ,OAAO7L,aAAa,WAAW8L,OAAO9L,QAAAA,IAAYA;AAChE,QAAM+L,UAAUJ,MAAMK,KAAI;AAE1B,MAAI,CAAC,kBAAkBC,KAAKF,OAAAA,GAAU;AACpC,UAAM,IAAIG,oBAAoB;MAC5BC,QAAQ,oBAAoBR,KAAAA;MAC5BS,QAAQ;QAAC;UAAER;UAAOS,SAAS;QAAwB;;IACrD,CAAA;EACF;AAEA,QAAMC,aAAaP,QAAQQ,WAAW,GAAA;AACtC,QAAMC,gBAAgBF,aAAaP,QAAQU,MAAM,CAAA,IAAKV;AACtD,QAAM,CAACW,WAAWC,iBAAiB,EAAE,IAAIH,cAAcI,MAAM,GAAA;AAE7D,MAAID,eAAeE,SAAShB,OAAO;AACjC,UAAM,IAAIK,oBAAoB;MAC5BC,QAAQ,+BAA+BnB,YAAAA,wBAAoCa,KAAAA;MAC3EO,QAAQ;QAAC;UAAER;UAAOS,SAAS,GAAGrB,YAAAA,iBAA6Ba,KAAAA,iBAAsBA,UAAU,IAAI,KAAK,GAAA;QAAO;;IAC7G,CAAA;EACF;AAEA,QAAMiB,iBAAiBH,eAAeI,OAAOlB,OAAO,GAAA;AACpD,QAAMmB,mBAAmB,GAAGN,SAAAA,GAAYI,cAAAA,GAAiBG,QAAQ,aAAa,EAAA;AAC9E,QAAM/B,QAAQgC,OAAOF,oBAAoB,GAAA;AAEzC,SAAOV,aAAa,CAACpB,QAAQA;AAC/B;AA5BgBQ;;;AGhYT,IAAMyB,oBAAN,MAAMA,mBAAAA;EAFb,OAEaA;;;EACXC;EACAC;EAIA,OAAOC,KAAKC,OAAkCC,cAAgD;AAC5F,QAAID,SAAS,KAAM,QAAO;AAC1B,UAAME,MAAM,IAAIN,mBAAAA;AAChBM,QAAIL,WAAWI;AACfC,QAAIJ,QAAQK,aAAaH,OAAOC,YAAAA;AAChC,WAAOC;EACT;AACF;;;ACfA,6BAAoF;AAe7E,SAASE,WAAWC,mBAAqC;AAC9D,SAAO,CAACC,QAAgBC,iBAAAA;AACtBC,kDAAkB;MAChBC,MAAM;MACNH,QAAQA,OAAO;MACfC,cAAcG,OAAOH,YAAAA;MACrBI,SAASN;MACTO,WAAW;QACTC,SAASC,OAAc;AACrB,cAAI,CAACA,SAAS,OAAOA,UAAU,SAAU,QAAO;AAChD,gBAAM,EAAEC,UAAUD,OAAOE,OAAM,IAAKF;AACpC,cAAI,OAAOC,aAAa,YAAY,OAAOC,WAAW,SAAU,QAAO;AACvE,cAAI,EAAED,YAAYE,sBAAuB,QAAO;AAChD,cAAI;AACFC,yBAAaF,QAAQD,QAAAA;AACrB,mBAAO;UACT,QAAQ;AACN,mBAAO;UACT;QACF;QACAI,eAAeC,MAAyB;AACtC,iBAAO,GAAGA,KAAKC,QAAQ;QACzB;MACF;IACF,CAAA;EACF;AACF;AA1BgBjB;;;ACfhB,IAAAkB,0BAAoF;AAG7E,SAASC,eAAeC,mBAAqC;AAClE,SAAO,CAACC,QAAgBC,iBAAAA;AACtBC,mDAAkB;MAChBC,MAAM;MACNH,QAAQA,OAAO;MACfC,cAAcG,OAAOH,YAAAA;MACrBI,SAASN;MACTO,WAAW;QACTC,SAASC,OAAc;AACrB,cAAI,OAAOA,UAAU,SAAU,QAAO;AACtC,iBAAOA,SAASC;QAClB;QACAC,eAAeC,MAAyB;AACtC,iBAAO,GAAGA,KAAKC,QAAQ;QACzB;MACF;IACF,CAAA;EACF;AACF;AAlBgBd;;;ANChB,WAAAe,gBAAc,eAJd;","names":["money_exports","import_common","HttpProblemException","HttpException","detailOrOptions","httpStatus","options","detail","type","label","errors","ValidationException","HttpProblemException","detailOrOptions","HttpStatus","UNPROCESSABLE_ENTITY","ANG","code","base","exponent","HRK","XAG","XAU","XDR","XPD","XPT","ZWL","SUPPORTED_CURRENCIES","AED","AFN","ALL","AMD","AOA","ARS","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","BMD","BND","BOB","BOV","BRL","BSD","BTN","BWP","BYN","BZD","CAD","CDF","CHE","CHF","CHW","CLF","CLP","CNY","COP","COU","CRC","CUP","CVE","CZK","DJF","DKK","DOP","DZD","EGP","ERN","ETB","EUR","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MAD","MDL","MGA","MKD","MMK","MNT","MOP","MRU","MUR","MVR","MWK","MXN","MXV","MYR","MZN","NAD","NGN","NIO","NOK","NPR","NZD","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLE","SOS","SRD","SSP","STN","SVC","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","USD","USN","UYI","UYU","UYW","UZS","VED","VES","VND","VUV","WST","XAD","XAF","XCD","XCG","XOF","XPF","YER","ZAR","ZMW","ZWG","resolveCurrency","currencyCode","minorToMajor","minor","transform","currency","amount","dinero","toDecimal","value","resolvedCurrency","majorToMinor","major","field","scale","Number","trimmed","trim","test","ValidationException","detail","errors","message","isNegative","startsWith","unsignedValue","slice","wholePart","fractionalPart","split","length","paddedFraction","padEnd","normalizedDigits","replace","BigInt","CurrencyAmountDto","currency","value","from","minor","currencyCode","dto","minorToMajor","IsCurrency","validationOptions","target","propertyName","registerDecorator","name","String","options","validator","validate","value","currency","amount","SUPPORTED_CURRENCIES","majorToMinor","defaultMessage","args","property","import_class_validator","IsCurrencyCode","validationOptions","target","propertyName","registerDecorator","name","String","options","validator","validate","value","SUPPORTED_CURRENCIES","defaultMessage","args","property","money_exports"]}
|
|
1
|
+
{"version":3,"sources":["../src/money/index.ts","../src/money/money.ts","../src/exceptions/validation.exception.ts","../src/exceptions/base-field.exception.ts","../src/money/currency-amount.dto.ts","../src/money/is-currency.decorator.ts","../src/money/is-currency-code.decorator.ts"],"sourcesContent":["// Money module — the ONLY entry that touches dinero.js (utilities, validators, DTO, dinero re-export)\nexport { CurrencyAmountDto } from './currency-amount.dto';\nexport { IsCurrency } from './is-currency.decorator';\nexport { IsCurrencyCode } from './is-currency-code.decorator';\nexport * from './money';\n","import { dinero, toDecimal } from 'dinero.js/bigint';\nimport {\n AED,\n AFN,\n ALL,\n AMD,\n AOA,\n ARS,\n AUD,\n AWG,\n AZN,\n BAM,\n BBD,\n BDT,\n BGN,\n BHD,\n BIF,\n BMD,\n BND,\n BOB,\n BOV,\n BRL,\n BSD,\n BTN,\n BWP,\n BYN,\n BZD,\n CAD,\n CDF,\n CHE,\n CHF,\n CHW,\n CLF,\n CLP,\n CNY,\n COP,\n COU,\n CRC,\n CUP,\n CVE,\n CZK,\n DJF,\n DKK,\n DOP,\n DZD,\n EGP,\n ERN,\n ETB,\n EUR,\n FJD,\n FKP,\n GBP,\n GEL,\n GHS,\n GIP,\n GMD,\n GNF,\n GTQ,\n GYD,\n HKD,\n HNL,\n HTG,\n HUF,\n IDR,\n ILS,\n INR,\n IQD,\n IRR,\n ISK,\n JMD,\n JOD,\n JPY,\n KES,\n KGS,\n KHR,\n KMF,\n KPW,\n KRW,\n KWD,\n KYD,\n KZT,\n LAK,\n LBP,\n LKR,\n LRD,\n LSL,\n LYD,\n MAD,\n MDL,\n MGA,\n MKD,\n MMK,\n MNT,\n MOP,\n MRU,\n MUR,\n MVR,\n MWK,\n MXN,\n MXV,\n MYR,\n MZN,\n NAD,\n NGN,\n NIO,\n NOK,\n NPR,\n NZD,\n OMR,\n PAB,\n PEN,\n PGK,\n PHP,\n PKR,\n PLN,\n PYG,\n QAR,\n RON,\n RSD,\n RUB,\n RWF,\n SAR,\n SBD,\n SCR,\n SDG,\n SEK,\n SGD,\n SHP,\n SLE,\n SOS,\n SRD,\n SSP,\n STN,\n SVC,\n SYP,\n SZL,\n THB,\n TJS,\n TMT,\n TND,\n TOP,\n TRY,\n TTD,\n TWD,\n TZS,\n UAH,\n UGX,\n USD,\n USN,\n UYI,\n UYU,\n UYW,\n UZS,\n VED,\n VES,\n VND,\n VUV,\n WST,\n XAD,\n XAF,\n XCD,\n XCG,\n XOF,\n XPF,\n YER,\n ZAR,\n ZMW,\n ZWG,\n} from 'dinero.js/bigint/currencies';\nimport { ValidationException } from '../exceptions/validation.exception';\n\nexport * from 'dinero.js/bigint';\n\nconst ANG = { code: 'ANG', base: 10n, exponent: 2n } as const;\nconst HRK = { code: 'HRK', base: 10n, exponent: 2n } as const;\nconst XAG = { code: 'XAG', base: 10n, exponent: 0n } as const;\nconst XAU = { code: 'XAU', base: 10n, exponent: 0n } as const;\nconst XDR = { code: 'XDR', base: 10n, exponent: 0n } as const;\nconst XPD = { code: 'XPD', base: 10n, exponent: 0n } as const;\nconst XPT = { code: 'XPT', base: 10n, exponent: 0n } as const;\nconst ZWL = { code: 'ZWL', base: 10n, exponent: 2n } as const;\n\nexport const SUPPORTED_CURRENCIES = {\n AED,\n AFN,\n ALL,\n AMD,\n ANG,\n AOA,\n ARS,\n AUD,\n AWG,\n AZN,\n BAM,\n BBD,\n BDT,\n BGN,\n BHD,\n BIF,\n BMD,\n BND,\n BOB,\n BOV,\n BRL,\n BSD,\n BTN,\n BWP,\n BYN,\n BZD,\n CAD,\n CDF,\n CHE,\n CHF,\n CHW,\n CLF,\n CLP,\n CNY,\n COP,\n COU,\n CRC,\n CUP,\n CVE,\n CZK,\n DJF,\n DKK,\n DOP,\n DZD,\n EGP,\n ERN,\n ETB,\n EUR,\n FJD,\n FKP,\n GBP,\n GEL,\n GHS,\n GIP,\n GMD,\n GNF,\n GTQ,\n GYD,\n HKD,\n HNL,\n HRK,\n HTG,\n HUF,\n IDR,\n ILS,\n INR,\n IQD,\n IRR,\n ISK,\n JMD,\n JOD,\n JPY,\n KES,\n KGS,\n KHR,\n KMF,\n KPW,\n KRW,\n KWD,\n KYD,\n KZT,\n LAK,\n LBP,\n LKR,\n LRD,\n LSL,\n LYD,\n MAD,\n MDL,\n MGA,\n MKD,\n MMK,\n MNT,\n MOP,\n MRU,\n MUR,\n MVR,\n MWK,\n MXN,\n MXV,\n MYR,\n MZN,\n NAD,\n NGN,\n NIO,\n NOK,\n NPR,\n NZD,\n OMR,\n PAB,\n PEN,\n PGK,\n PHP,\n PKR,\n PLN,\n PYG,\n QAR,\n RON,\n RSD,\n RUB,\n RWF,\n SAR,\n SBD,\n SCR,\n SDG,\n SEK,\n SGD,\n SHP,\n SLE,\n SOS,\n SRD,\n SSP,\n STN,\n SVC,\n SYP,\n SZL,\n THB,\n TJS,\n TMT,\n TND,\n TOP,\n TRY,\n TTD,\n TWD,\n TZS,\n UAH,\n UGX,\n USD,\n USN,\n UYI,\n UYU,\n UYW,\n UZS,\n VED,\n VES,\n VND,\n VUV,\n WST,\n XAD,\n XAF,\n XAG,\n XAU,\n XCD,\n XCG,\n XDR,\n XOF,\n XPD,\n XPF,\n XPT,\n YER,\n ZAR,\n ZMW,\n ZWG,\n ZWL,\n} as const;\n\nexport type CurrencyCode = keyof typeof SUPPORTED_CURRENCIES;\nexport type Currency = (typeof SUPPORTED_CURRENCIES)[CurrencyCode];\n\nexport type MinorToMajorTransform<TOutput> = (props: { value: string; currency: Currency }) => TOutput;\n\nexport function resolveCurrency(currencyCode: CurrencyCode, field?: string): Currency {\n const currency = SUPPORTED_CURRENCIES[currencyCode];\n if (!currency) {\n throw new ValidationException({\n label: 'Unsupported Currency',\n detail: `Unsupported currency: \"${currencyCode}\".`,\n ...(field ? { errors: [{ field, message: 'Unsupported currency.' }] } : {}),\n });\n }\n return currency;\n}\n\nexport function minorToMajor<TOutput = string>(\n minor: bigint,\n currencyCode: CurrencyCode,\n transform?: MinorToMajorTransform<TOutput>,\n): string | TOutput {\n const currency = resolveCurrency(currencyCode);\n const amount = dinero({ amount: minor, currency });\n\n if (!transform) {\n return toDecimal(amount);\n }\n\n return toDecimal(amount, ({ value, currency: resolvedCurrency }) => transform({ value, currency: resolvedCurrency }));\n}\n\n// Converts a major-unit string to minor-unit bigint, throwing ValidationException (422) on invalid input\nexport function majorToMinor(major: string, currencyCode: CurrencyCode, field = 'amount'): bigint {\n const { exponent } = resolveCurrency(currencyCode, field);\n const scale = typeof exponent === 'bigint' ? Number(exponent) : exponent;\n const trimmed = major.trim();\n\n if (!/^-?\\d+(\\.\\d+)?$/.test(trimmed)) {\n throw new ValidationException({\n detail: `Invalid amount: \"${major}\".`,\n errors: [{ field, message: 'Enter a valid number.' }],\n });\n }\n\n const isNegative = trimmed.startsWith('-');\n const unsignedValue = isNegative ? trimmed.slice(1) : trimmed;\n const [wholePart, fractionalPart = ''] = unsignedValue.split('.');\n\n if (fractionalPart.length > scale) {\n throw new ValidationException({\n detail: `Too many decimal places for ${currencyCode}. Maximum allowed is ${scale}.`,\n errors: [{ field, message: `${currencyCode} allows up to ${scale} decimal place${scale === 1 ? '' : 's'}.` }],\n });\n }\n\n const paddedFraction = fractionalPart.padEnd(scale, '0');\n const normalizedDigits = `${wholePart}${paddedFraction}`.replace(/^0+(?=\\d)/, '');\n const minor = BigInt(normalizedDigits || '0');\n\n return isNegative ? -minor : minor;\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ValidationException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Validation Failed', HttpStatus.UNPROCESSABLE_ENTITY);\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 { type CurrencyCode, minorToMajor } from './money';\n\nexport class CurrencyAmountDto {\n currency: CurrencyCode;\n value: string;\n\n static from(minor: bigint, currencyCode: string): CurrencyAmountDto;\n static from(minor: bigint | null | undefined, currencyCode: string): CurrencyAmountDto | null;\n static from(minor: bigint | null | undefined, currencyCode: string): CurrencyAmountDto | null {\n if (minor == null) return null;\n const dto = new CurrencyAmountDto();\n dto.currency = currencyCode as CurrencyCode;\n dto.value = minorToMajor(minor, currencyCode as CurrencyCode);\n return dto;\n }\n}\n","import { registerDecorator, type ValidationArguments, type ValidationOptions } from 'class-validator';\nimport { type CurrencyCode, majorToMinor, SUPPORTED_CURRENCIES } from './money';\n\n// Self-contained validator for {currency, value} payloads — inlines all checks (not @ValidateNested) to dodge class-validator MetadataStorage duplication across api-sdk and consumers.\nexport function IsCurrency(validationOptions?: ValidationOptions): PropertyDecorator {\n return (target: object, propertyName: string | symbol) => {\n registerDecorator({\n name: 'isCurrency',\n target: target.constructor,\n propertyName: String(propertyName),\n options: validationOptions,\n validator: {\n validate(value: unknown): boolean {\n if (!value || typeof value !== 'object') return false;\n const { currency, value: amount } = value as Record<string, unknown>;\n if (typeof currency !== 'string' || typeof amount !== 'string') return false;\n if (!(currency in SUPPORTED_CURRENCIES)) return false;\n try {\n majorToMinor(amount, currency as CurrencyCode);\n return true;\n } catch {\n return false;\n }\n },\n defaultMessage(args: ValidationArguments): string {\n return `${args.property} must be {currency, value} where currency is a valid ISO 4217 code and value precision matches the currency exponent.`;\n },\n },\n });\n };\n}\n","import { registerDecorator, type ValidationArguments, type ValidationOptions } from 'class-validator';\nimport { SUPPORTED_CURRENCIES } from './money';\n\nexport function IsCurrencyCode(validationOptions?: ValidationOptions): PropertyDecorator {\n return (target: object, propertyName: string | symbol) => {\n registerDecorator({\n name: 'isCurrencyCode',\n target: target.constructor,\n propertyName: String(propertyName),\n options: validationOptions,\n validator: {\n validate(value: unknown): boolean {\n if (typeof value !== 'string') return false;\n return value in SUPPORTED_CURRENCIES;\n },\n defaultMessage(args: ValidationArguments): string {\n return `${args.property} must be a valid ISO 4217 currency code.`;\n },\n },\n });\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,iBAAA;SAAAA,gBAAA;;;;;;;;;8BAAAA;;;ACAA;;;;;;;AAAA,oBAAkC;AAClC,wBAuKO;;;ACxKP,IAAAC,iBAA2B;;;ACA3B,oBAA0C;AAanC,IAAeC,uBAAf,cAA4CC,4BAAAA;EAbnD,OAamDA;;;EACjD,YAAYC,iBAA0CC,YAAwB;AAC5E,UAAMC,UAAU,OAAOF,oBAAoB,WAAW;MAAEG,QAAQH;IAAgB,IAAIA;AAEpF,UACE;MACEI,MAAMF,QAAQE,QAAQ;MACtBC,OAAOH,QAAQG;MACfF,QAAQD,QAAQC;MAChBG,QAAQJ,QAAQI,UAAU,CAAA;IAC5B,GACAL,UAAAA;EAEJ;AACF;;;ADxBO,IAAMM,sBAAN,cAAkCC,qBAAAA;EAHzC,OAGyCA;;;EACvC,YAAYC,iBAA2C;AACrD,UAAMA,mBAAmB,qBAAqBC,0BAAWC,oBAAoB;EAC/E;AACF;;;ADoKA,0BAAc;AAEd,IAAMC,MAAM;EAAEC,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMC,MAAM;EAAEH,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAME,MAAM;EAAEJ,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMG,MAAM;EAAEL,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMI,MAAM;EAAEN,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMK,MAAM;EAAEP,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMM,MAAM;EAAER,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMO,MAAM;EAAET,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AAE5C,IAAMQ,uBAAuB;EAClCC;EACAC;EACAC;EACAC;EACAf;EACAgB;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAlE;EACAmE;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACApK;EACAC;EACAoK;EACAC;EACApK;EACAqK;EACApK;EACAqK;EACApK;EACAqK;EACAC;EACAC;EACAC;EACAvK;AACF;AAOO,SAASwK,gBAAgBC,cAA4BC,OAAc;AACxE,QAAMC,WAAW1K,qBAAqBwK,YAAAA;AACtC,MAAI,CAACE,UAAU;AACb,UAAM,IAAIC,oBAAoB;MAC5BC,OAAO;MACPC,QAAQ,0BAA0BL,YAAAA;MAClC,GAAIC,QAAQ;QAAEK,QAAQ;UAAC;YAAEL;YAAOM,SAAS;UAAwB;;MAAG,IAAI,CAAC;IAC3E,CAAA;EACF;AACA,SAAOL;AACT;AAVgBH;AAYT,SAASS,aACdC,OACAT,cACAU,WAA0C;AAE1C,QAAMR,WAAWH,gBAAgBC,YAAAA;AACjC,QAAMW,aAASC,sBAAO;IAAED,QAAQF;IAAOP;EAAS,CAAA;AAEhD,MAAI,CAACQ,WAAW;AACd,eAAOG,yBAAUF,MAAAA;EACnB;AAEA,aAAOE,yBAAUF,QAAQ,CAAC,EAAEG,OAAOZ,UAAUa,iBAAgB,MAAOL,UAAU;IAAEI;IAAOZ,UAAUa;EAAiB,CAAA,CAAA;AACpH;AAbgBP;AAgBT,SAASQ,aAAaC,OAAejB,cAA4BC,QAAQ,UAAQ;AACtF,QAAM,EAAEjL,SAAQ,IAAK+K,gBAAgBC,cAAcC,KAAAA;AACnD,QAAMiB,QAAQ,OAAOlM,aAAa,WAAWmM,OAAOnM,QAAAA,IAAYA;AAChE,QAAMoM,UAAUH,MAAMI,KAAI;AAE1B,MAAI,CAAC,kBAAkBC,KAAKF,OAAAA,GAAU;AACpC,UAAM,IAAIjB,oBAAoB;MAC5BE,QAAQ,oBAAoBY,KAAAA;MAC5BX,QAAQ;QAAC;UAAEL;UAAOM,SAAS;QAAwB;;IACrD,CAAA;EACF;AAEA,QAAMgB,aAAaH,QAAQI,WAAW,GAAA;AACtC,QAAMC,gBAAgBF,aAAaH,QAAQM,MAAM,CAAA,IAAKN;AACtD,QAAM,CAACO,WAAWC,iBAAiB,EAAE,IAAIH,cAAcI,MAAM,GAAA;AAE7D,MAAID,eAAeE,SAASZ,OAAO;AACjC,UAAM,IAAIf,oBAAoB;MAC5BE,QAAQ,+BAA+BL,YAAAA,wBAAoCkB,KAAAA;MAC3EZ,QAAQ;QAAC;UAAEL;UAAOM,SAAS,GAAGP,YAAAA,iBAA6BkB,KAAAA,iBAAsBA,UAAU,IAAI,KAAK,GAAA;QAAO;;IAC7G,CAAA;EACF;AAEA,QAAMa,iBAAiBH,eAAeI,OAAOd,OAAO,GAAA;AACpD,QAAMe,mBAAmB,GAAGN,SAAAA,GAAYI,cAAAA,GAAiBG,QAAQ,aAAa,EAAA;AAC9E,QAAMzB,QAAQ0B,OAAOF,oBAAoB,GAAA;AAEzC,SAAOV,aAAa,CAACd,QAAQA;AAC/B;AA5BgBO;;;AGtYT,IAAMoB,oBAAN,MAAMA,mBAAAA;EAFb,OAEaA;;;EACXC;EACAC;EAIA,OAAOC,KAAKC,OAAkCC,cAAgD;AAC5F,QAAID,SAAS,KAAM,QAAO;AAC1B,UAAME,MAAM,IAAIN,mBAAAA;AAChBM,QAAIL,WAAWI;AACfC,QAAIJ,QAAQK,aAAaH,OAAOC,YAAAA;AAChC,WAAOC;EACT;AACF;;;ACfA,6BAAoF;AAI7E,SAASE,WAAWC,mBAAqC;AAC9D,SAAO,CAACC,QAAgBC,iBAAAA;AACtBC,kDAAkB;MAChBC,MAAM;MACNH,QAAQA,OAAO;MACfC,cAAcG,OAAOH,YAAAA;MACrBI,SAASN;MACTO,WAAW;QACTC,SAASC,OAAc;AACrB,cAAI,CAACA,SAAS,OAAOA,UAAU,SAAU,QAAO;AAChD,gBAAM,EAAEC,UAAUD,OAAOE,OAAM,IAAKF;AACpC,cAAI,OAAOC,aAAa,YAAY,OAAOC,WAAW,SAAU,QAAO;AACvE,cAAI,EAAED,YAAYE,sBAAuB,QAAO;AAChD,cAAI;AACFC,yBAAaF,QAAQD,QAAAA;AACrB,mBAAO;UACT,QAAQ;AACN,mBAAO;UACT;QACF;QACAI,eAAeC,MAAyB;AACtC,iBAAO,GAAGA,KAAKC,QAAQ;QACzB;MACF;IACF,CAAA;EACF;AACF;AA1BgBjB;;;ACJhB,IAAAkB,0BAAoF;AAG7E,SAASC,eAAeC,mBAAqC;AAClE,SAAO,CAACC,QAAgBC,iBAAAA;AACtBC,mDAAkB;MAChBC,MAAM;MACNH,QAAQA,OAAO;MACfC,cAAcG,OAAOH,YAAAA;MACrBI,SAASN;MACTO,WAAW;QACTC,SAASC,OAAc;AACrB,cAAI,OAAOA,UAAU,SAAU,QAAO;AACtC,iBAAOA,SAASC;QAClB;QACAC,eAAeC,MAAyB;AACtC,iBAAO,GAAGA,KAAKC,QAAQ;QACzB;MACF;IACF,CAAA;EACF;AACF;AAlBgBd;;;ANChB,WAAAe,gBAAc,eAJd;","names":["money_exports","import_common","HttpProblemException","HttpException","detailOrOptions","httpStatus","options","detail","type","label","errors","ValidationException","HttpProblemException","detailOrOptions","HttpStatus","UNPROCESSABLE_ENTITY","ANG","code","base","exponent","HRK","XAG","XAU","XDR","XPD","XPT","ZWL","SUPPORTED_CURRENCIES","AED","AFN","ALL","AMD","AOA","ARS","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","BMD","BND","BOB","BOV","BRL","BSD","BTN","BWP","BYN","BZD","CAD","CDF","CHE","CHF","CHW","CLF","CLP","CNY","COP","COU","CRC","CUP","CVE","CZK","DJF","DKK","DOP","DZD","EGP","ERN","ETB","EUR","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MAD","MDL","MGA","MKD","MMK","MNT","MOP","MRU","MUR","MVR","MWK","MXN","MXV","MYR","MZN","NAD","NGN","NIO","NOK","NPR","NZD","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLE","SOS","SRD","SSP","STN","SVC","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","USD","USN","UYI","UYU","UYW","UZS","VED","VES","VND","VUV","WST","XAD","XAF","XCD","XCG","XOF","XPF","YER","ZAR","ZMW","ZWG","resolveCurrency","currencyCode","field","currency","ValidationException","label","detail","errors","message","minorToMajor","minor","transform","amount","dinero","toDecimal","value","resolvedCurrency","majorToMinor","major","scale","Number","trimmed","trim","test","isNegative","startsWith","unsignedValue","slice","wholePart","fractionalPart","split","length","paddedFraction","padEnd","normalizedDigits","replace","BigInt","CurrencyAmountDto","currency","value","from","minor","currencyCode","dto","minorToMajor","IsCurrency","validationOptions","target","propertyName","registerDecorator","name","String","options","validator","validate","value","currency","amount","SUPPORTED_CURRENCIES","majorToMinor","defaultMessage","args","property","import_class_validator","IsCurrencyCode","validationOptions","target","propertyName","registerDecorator","name","String","options","validator","validate","value","SUPPORTED_CURRENCIES","defaultMessage","args","property","money_exports"]}
|
package/dist/money.d.cts
CHANGED
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
import { ValidationOptions } from 'class-validator';
|
|
2
1
|
import * as dinero_js_bigint from 'dinero.js/bigint';
|
|
3
2
|
export * from 'dinero.js/bigint';
|
|
4
|
-
|
|
5
|
-
declare class CurrencyAmountDto {
|
|
6
|
-
currency: string;
|
|
7
|
-
value: string;
|
|
8
|
-
static from(minor: bigint, currencyCode: string): CurrencyAmountDto;
|
|
9
|
-
static from(minor: bigint | null | undefined, currencyCode: string): CurrencyAmountDto | null;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
declare function IsCurrency(validationOptions?: ValidationOptions): PropertyDecorator;
|
|
13
|
-
|
|
14
|
-
declare function IsCurrencyCode(validationOptions?: ValidationOptions): PropertyDecorator;
|
|
3
|
+
import { ValidationOptions } from 'class-validator';
|
|
15
4
|
|
|
16
5
|
declare const SUPPORTED_CURRENCIES: {
|
|
17
6
|
readonly AED: dinero_js_bigint.DineroCurrency<bigint>;
|
|
@@ -227,8 +216,19 @@ type MinorToMajorTransform<TOutput> = (props: {
|
|
|
227
216
|
value: string;
|
|
228
217
|
currency: Currency;
|
|
229
218
|
}) => TOutput;
|
|
230
|
-
declare function resolveCurrency(currencyCode: CurrencyCode): Currency;
|
|
219
|
+
declare function resolveCurrency(currencyCode: CurrencyCode, field?: string): Currency;
|
|
231
220
|
declare function minorToMajor<TOutput = string>(minor: bigint, currencyCode: CurrencyCode, transform?: MinorToMajorTransform<TOutput>): string | TOutput;
|
|
232
221
|
declare function majorToMinor(major: string, currencyCode: CurrencyCode, field?: string): bigint;
|
|
233
222
|
|
|
223
|
+
declare class CurrencyAmountDto {
|
|
224
|
+
currency: CurrencyCode;
|
|
225
|
+
value: string;
|
|
226
|
+
static from(minor: bigint, currencyCode: string): CurrencyAmountDto;
|
|
227
|
+
static from(minor: bigint | null | undefined, currencyCode: string): CurrencyAmountDto | null;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
declare function IsCurrency(validationOptions?: ValidationOptions): PropertyDecorator;
|
|
231
|
+
|
|
232
|
+
declare function IsCurrencyCode(validationOptions?: ValidationOptions): PropertyDecorator;
|
|
233
|
+
|
|
234
234
|
export { type Currency, CurrencyAmountDto, type CurrencyCode, IsCurrency, IsCurrencyCode, type MinorToMajorTransform, SUPPORTED_CURRENCIES, majorToMinor, minorToMajor, resolveCurrency };
|
package/dist/money.d.ts
CHANGED
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
import { ValidationOptions } from 'class-validator';
|
|
2
1
|
import * as dinero_js_bigint from 'dinero.js/bigint';
|
|
3
2
|
export * from 'dinero.js/bigint';
|
|
4
|
-
|
|
5
|
-
declare class CurrencyAmountDto {
|
|
6
|
-
currency: string;
|
|
7
|
-
value: string;
|
|
8
|
-
static from(minor: bigint, currencyCode: string): CurrencyAmountDto;
|
|
9
|
-
static from(minor: bigint | null | undefined, currencyCode: string): CurrencyAmountDto | null;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
declare function IsCurrency(validationOptions?: ValidationOptions): PropertyDecorator;
|
|
13
|
-
|
|
14
|
-
declare function IsCurrencyCode(validationOptions?: ValidationOptions): PropertyDecorator;
|
|
3
|
+
import { ValidationOptions } from 'class-validator';
|
|
15
4
|
|
|
16
5
|
declare const SUPPORTED_CURRENCIES: {
|
|
17
6
|
readonly AED: dinero_js_bigint.DineroCurrency<bigint>;
|
|
@@ -227,8 +216,19 @@ type MinorToMajorTransform<TOutput> = (props: {
|
|
|
227
216
|
value: string;
|
|
228
217
|
currency: Currency;
|
|
229
218
|
}) => TOutput;
|
|
230
|
-
declare function resolveCurrency(currencyCode: CurrencyCode): Currency;
|
|
219
|
+
declare function resolveCurrency(currencyCode: CurrencyCode, field?: string): Currency;
|
|
231
220
|
declare function minorToMajor<TOutput = string>(minor: bigint, currencyCode: CurrencyCode, transform?: MinorToMajorTransform<TOutput>): string | TOutput;
|
|
232
221
|
declare function majorToMinor(major: string, currencyCode: CurrencyCode, field?: string): bigint;
|
|
233
222
|
|
|
223
|
+
declare class CurrencyAmountDto {
|
|
224
|
+
currency: CurrencyCode;
|
|
225
|
+
value: string;
|
|
226
|
+
static from(minor: bigint, currencyCode: string): CurrencyAmountDto;
|
|
227
|
+
static from(minor: bigint | null | undefined, currencyCode: string): CurrencyAmountDto | null;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
declare function IsCurrency(validationOptions?: ValidationOptions): PropertyDecorator;
|
|
231
|
+
|
|
232
|
+
declare function IsCurrencyCode(validationOptions?: ValidationOptions): PropertyDecorator;
|
|
233
|
+
|
|
234
234
|
export { type Currency, CurrencyAmountDto, type CurrencyCode, IsCurrency, IsCurrencyCode, type MinorToMajorTransform, SUPPORTED_CURRENCIES, majorToMinor, minorToMajor, resolveCurrency };
|
package/dist/money.js
CHANGED
|
@@ -291,8 +291,23 @@ var SUPPORTED_CURRENCIES = {
|
|
|
291
291
|
ZWG,
|
|
292
292
|
ZWL
|
|
293
293
|
};
|
|
294
|
-
function resolveCurrency(currencyCode) {
|
|
295
|
-
|
|
294
|
+
function resolveCurrency(currencyCode, field) {
|
|
295
|
+
const currency = SUPPORTED_CURRENCIES[currencyCode];
|
|
296
|
+
if (!currency) {
|
|
297
|
+
throw new ValidationException({
|
|
298
|
+
label: "Unsupported Currency",
|
|
299
|
+
detail: `Unsupported currency: "${currencyCode}".`,
|
|
300
|
+
...field ? {
|
|
301
|
+
errors: [
|
|
302
|
+
{
|
|
303
|
+
field,
|
|
304
|
+
message: "Unsupported currency."
|
|
305
|
+
}
|
|
306
|
+
]
|
|
307
|
+
} : {}
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
return currency;
|
|
296
311
|
}
|
|
297
312
|
__name(resolveCurrency, "resolveCurrency");
|
|
298
313
|
function minorToMajor(minor, currencyCode, transform) {
|
|
@@ -311,7 +326,7 @@ function minorToMajor(minor, currencyCode, transform) {
|
|
|
311
326
|
}
|
|
312
327
|
__name(minorToMajor, "minorToMajor");
|
|
313
328
|
function majorToMinor(major, currencyCode, field = "amount") {
|
|
314
|
-
const { exponent } = resolveCurrency(currencyCode);
|
|
329
|
+
const { exponent } = resolveCurrency(currencyCode, field);
|
|
315
330
|
const scale = typeof exponent === "bigint" ? Number(exponent) : exponent;
|
|
316
331
|
const trimmed = major.trim();
|
|
317
332
|
if (!/^-?\d+(\.\d+)?$/.test(trimmed)) {
|
package/dist/money.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/money/index.ts","../src/money/money.ts","../src/exceptions/validation.exception.ts","../src/exceptions/base-field.exception.ts","../src/money/currency-amount.dto.ts","../src/money/is-currency.decorator.ts","../src/money/is-currency-code.decorator.ts"],"sourcesContent":["// Money module — the ONLY entry that touches dinero.js (utilities, validators, DTO, dinero re-export)\nexport { CurrencyAmountDto } from './currency-amount.dto';\nexport { IsCurrency } from './is-currency.decorator';\nexport { IsCurrencyCode } from './is-currency-code.decorator';\nexport * from './money';\n","import { dinero, toDecimal } from 'dinero.js/bigint';\nimport {\n AED,\n AFN,\n ALL,\n AMD,\n AOA,\n ARS,\n AUD,\n AWG,\n AZN,\n BAM,\n BBD,\n BDT,\n BGN,\n BHD,\n BIF,\n BMD,\n BND,\n BOB,\n BOV,\n BRL,\n BSD,\n BTN,\n BWP,\n BYN,\n BZD,\n CAD,\n CDF,\n CHE,\n CHF,\n CHW,\n CLF,\n CLP,\n CNY,\n COP,\n COU,\n CRC,\n CUP,\n CVE,\n CZK,\n DJF,\n DKK,\n DOP,\n DZD,\n EGP,\n ERN,\n ETB,\n EUR,\n FJD,\n FKP,\n GBP,\n GEL,\n GHS,\n GIP,\n GMD,\n GNF,\n GTQ,\n GYD,\n HKD,\n HNL,\n HTG,\n HUF,\n IDR,\n ILS,\n INR,\n IQD,\n IRR,\n ISK,\n JMD,\n JOD,\n JPY,\n KES,\n KGS,\n KHR,\n KMF,\n KPW,\n KRW,\n KWD,\n KYD,\n KZT,\n LAK,\n LBP,\n LKR,\n LRD,\n LSL,\n LYD,\n MAD,\n MDL,\n MGA,\n MKD,\n MMK,\n MNT,\n MOP,\n MRU,\n MUR,\n MVR,\n MWK,\n MXN,\n MXV,\n MYR,\n MZN,\n NAD,\n NGN,\n NIO,\n NOK,\n NPR,\n NZD,\n OMR,\n PAB,\n PEN,\n PGK,\n PHP,\n PKR,\n PLN,\n PYG,\n QAR,\n RON,\n RSD,\n RUB,\n RWF,\n SAR,\n SBD,\n SCR,\n SDG,\n SEK,\n SGD,\n SHP,\n SLE,\n SOS,\n SRD,\n SSP,\n STN,\n SVC,\n SYP,\n SZL,\n THB,\n TJS,\n TMT,\n TND,\n TOP,\n TRY,\n TTD,\n TWD,\n TZS,\n UAH,\n UGX,\n USD,\n USN,\n UYI,\n UYU,\n UYW,\n UZS,\n VED,\n VES,\n VND,\n VUV,\n WST,\n XAD,\n XAF,\n XCD,\n XCG,\n XOF,\n XPF,\n YER,\n ZAR,\n ZMW,\n ZWG,\n} from 'dinero.js/bigint/currencies';\nimport { ValidationException } from '../exceptions/validation.exception';\n\nexport * from 'dinero.js/bigint';\n\nconst ANG = { code: 'ANG', base: 10n, exponent: 2n } as const;\nconst HRK = { code: 'HRK', base: 10n, exponent: 2n } as const;\nconst XAG = { code: 'XAG', base: 10n, exponent: 0n } as const;\nconst XAU = { code: 'XAU', base: 10n, exponent: 0n } as const;\nconst XDR = { code: 'XDR', base: 10n, exponent: 0n } as const;\nconst XPD = { code: 'XPD', base: 10n, exponent: 0n } as const;\nconst XPT = { code: 'XPT', base: 10n, exponent: 0n } as const;\nconst ZWL = { code: 'ZWL', base: 10n, exponent: 2n } as const;\n\nexport const SUPPORTED_CURRENCIES = {\n AED,\n AFN,\n ALL,\n AMD,\n ANG,\n AOA,\n ARS,\n AUD,\n AWG,\n AZN,\n BAM,\n BBD,\n BDT,\n BGN,\n BHD,\n BIF,\n BMD,\n BND,\n BOB,\n BOV,\n BRL,\n BSD,\n BTN,\n BWP,\n BYN,\n BZD,\n CAD,\n CDF,\n CHE,\n CHF,\n CHW,\n CLF,\n CLP,\n CNY,\n COP,\n COU,\n CRC,\n CUP,\n CVE,\n CZK,\n DJF,\n DKK,\n DOP,\n DZD,\n EGP,\n ERN,\n ETB,\n EUR,\n FJD,\n FKP,\n GBP,\n GEL,\n GHS,\n GIP,\n GMD,\n GNF,\n GTQ,\n GYD,\n HKD,\n HNL,\n HRK,\n HTG,\n HUF,\n IDR,\n ILS,\n INR,\n IQD,\n IRR,\n ISK,\n JMD,\n JOD,\n JPY,\n KES,\n KGS,\n KHR,\n KMF,\n KPW,\n KRW,\n KWD,\n KYD,\n KZT,\n LAK,\n LBP,\n LKR,\n LRD,\n LSL,\n LYD,\n MAD,\n MDL,\n MGA,\n MKD,\n MMK,\n MNT,\n MOP,\n MRU,\n MUR,\n MVR,\n MWK,\n MXN,\n MXV,\n MYR,\n MZN,\n NAD,\n NGN,\n NIO,\n NOK,\n NPR,\n NZD,\n OMR,\n PAB,\n PEN,\n PGK,\n PHP,\n PKR,\n PLN,\n PYG,\n QAR,\n RON,\n RSD,\n RUB,\n RWF,\n SAR,\n SBD,\n SCR,\n SDG,\n SEK,\n SGD,\n SHP,\n SLE,\n SOS,\n SRD,\n SSP,\n STN,\n SVC,\n SYP,\n SZL,\n THB,\n TJS,\n TMT,\n TND,\n TOP,\n TRY,\n TTD,\n TWD,\n TZS,\n UAH,\n UGX,\n USD,\n USN,\n UYI,\n UYU,\n UYW,\n UZS,\n VED,\n VES,\n VND,\n VUV,\n WST,\n XAD,\n XAF,\n XAG,\n XAU,\n XCD,\n XCG,\n XDR,\n XOF,\n XPD,\n XPF,\n XPT,\n YER,\n ZAR,\n ZMW,\n ZWG,\n ZWL,\n} as const;\n\nexport type CurrencyCode = keyof typeof SUPPORTED_CURRENCIES;\nexport type Currency = (typeof SUPPORTED_CURRENCIES)[CurrencyCode];\n\nexport type MinorToMajorTransform<TOutput> = (props: { value: string; currency: Currency }) => TOutput;\n\nexport function resolveCurrency(currencyCode: CurrencyCode): Currency {\n return SUPPORTED_CURRENCIES[currencyCode];\n}\n\nexport function minorToMajor<TOutput = string>(\n minor: bigint,\n currencyCode: CurrencyCode,\n transform?: MinorToMajorTransform<TOutput>,\n): string | TOutput {\n const currency = resolveCurrency(currencyCode);\n const amount = dinero({ amount: minor, currency });\n\n if (!transform) {\n return toDecimal(amount);\n }\n\n return toDecimal(amount, ({ value, currency: resolvedCurrency }) => transform({ value, currency: resolvedCurrency }));\n}\n\n// Throws ValidationException (HTTP 422) instead of generic Error so the\n// NestJS error filter maps it to a field-level response automatically.\n// Callers pass `field` so the validation error binds to the right form field.\nexport function majorToMinor(major: string, currencyCode: CurrencyCode, field = 'amount'): bigint {\n const { exponent } = resolveCurrency(currencyCode);\n const scale = typeof exponent === 'bigint' ? Number(exponent) : exponent;\n const trimmed = major.trim();\n\n if (!/^-?\\d+(\\.\\d+)?$/.test(trimmed)) {\n throw new ValidationException({\n detail: `Invalid amount: \"${major}\".`,\n errors: [{ field, message: 'Enter a valid number.' }],\n });\n }\n\n const isNegative = trimmed.startsWith('-');\n const unsignedValue = isNegative ? trimmed.slice(1) : trimmed;\n const [wholePart, fractionalPart = ''] = unsignedValue.split('.');\n\n if (fractionalPart.length > scale) {\n throw new ValidationException({\n detail: `Too many decimal places for ${currencyCode}. Maximum allowed is ${scale}.`,\n errors: [{ field, message: `${currencyCode} allows up to ${scale} decimal place${scale === 1 ? '' : 's'}.` }],\n });\n }\n\n const paddedFraction = fractionalPart.padEnd(scale, '0');\n const normalizedDigits = `${wholePart}${paddedFraction}`.replace(/^0+(?=\\d)/, '');\n const minor = BigInt(normalizedDigits || '0');\n\n return isNegative ? -minor : minor;\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ValidationException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Validation Failed', HttpStatus.UNPROCESSABLE_ENTITY);\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 { type CurrencyCode, minorToMajor } from './money';\n\nexport class CurrencyAmountDto {\n currency: string;\n value: string;\n\n static from(minor: bigint, currencyCode: string): CurrencyAmountDto;\n static from(minor: bigint | null | undefined, currencyCode: string): CurrencyAmountDto | null;\n static from(minor: bigint | null | undefined, currencyCode: string): CurrencyAmountDto | null {\n if (minor == null) return null;\n const dto = new CurrencyAmountDto();\n dto.currency = currencyCode;\n dto.value = minorToMajor(minor, currencyCode as CurrencyCode);\n return dto;\n }\n}\n","import { registerDecorator, type ValidationArguments, type ValidationOptions } from 'class-validator';\nimport { type CurrencyCode, majorToMinor, SUPPORTED_CURRENCIES } from './money';\n\n// Self-contained validator for `{currency, value}` payloads. Intentionally does NOT compose\n// `@ValidateNested()` + `@Type(() => CurrencyAmountDto)` — api-sdk and the consuming app each\n// load their own copy of `class-validator` (different MetadataStorage singletons), so any\n// field-level decorators registered on `CurrencyAmountDto` from inside api-sdk are invisible\n// to the consumer's validator. Doing everything here, at the consumer's call site, sidesteps\n// that and keeps the decorator usable everywhere.\n//\n// Checks performed (in order, short-circuiting):\n// 1. Value is a non-null object.\n// 2. `currency` and `value` are both strings.\n// 3. `currency` is in `SUPPORTED_CURRENCIES`.\n// 4. `majorToMinor(value, currency)` succeeds — enforces decimal precision ≤ currency exponent.\nexport function IsCurrency(validationOptions?: ValidationOptions): PropertyDecorator {\n return (target: object, propertyName: string | symbol) => {\n registerDecorator({\n name: 'isCurrency',\n target: target.constructor,\n propertyName: String(propertyName),\n options: validationOptions,\n validator: {\n validate(value: unknown): boolean {\n if (!value || typeof value !== 'object') return false;\n const { currency, value: amount } = value as Record<string, unknown>;\n if (typeof currency !== 'string' || typeof amount !== 'string') return false;\n if (!(currency in SUPPORTED_CURRENCIES)) return false;\n try {\n majorToMinor(amount, currency as CurrencyCode);\n return true;\n } catch {\n return false;\n }\n },\n defaultMessage(args: ValidationArguments): string {\n return `${args.property} must be {currency, value} where currency is a valid ISO 4217 code and value precision matches the currency exponent.`;\n },\n },\n });\n };\n}\n","import { registerDecorator, type ValidationArguments, type ValidationOptions } from 'class-validator';\nimport { SUPPORTED_CURRENCIES } from './money';\n\nexport function IsCurrencyCode(validationOptions?: ValidationOptions): PropertyDecorator {\n return (target: object, propertyName: string | symbol) => {\n registerDecorator({\n name: 'isCurrencyCode',\n target: target.constructor,\n propertyName: String(propertyName),\n options: validationOptions,\n validator: {\n validate(value: unknown): boolean {\n if (typeof value !== 'string') return false;\n return value in SUPPORTED_CURRENCIES;\n },\n defaultMessage(args: ValidationArguments): string {\n return `${args.property} must be a valid ISO 4217 currency code.`;\n },\n },\n });\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,iBAAA;SAAAA,gBAAA;;;;;;;;;;;ACAA;;;;;;;AAAA,SAASC,QAAQC,iBAAiB;AAClC,SACEC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,WACK;;;ACxKP,SAASC,kBAAkB;;;ACA3B,SAASC,qBAAiC;AAanC,IAAeC,uBAAf,cAA4CC,cAAAA;EAbnD,OAamDA;;;EACjD,YAAYC,iBAA0CC,YAAwB;AAC5E,UAAMC,UAAU,OAAOF,oBAAoB,WAAW;MAAEG,QAAQH;IAAgB,IAAIA;AAEpF,UACE;MACEI,MAAMF,QAAQE,QAAQ;MACtBC,OAAOH,QAAQG;MACfF,QAAQD,QAAQC;MAChBG,QAAQJ,QAAQI,UAAU,CAAA;IAC5B,GACAL,UAAAA;EAEJ;AACF;;;ADxBO,IAAMM,sBAAN,cAAkCC,qBAAAA;EAHzC,OAGyCA;;;EACvC,YAAYC,iBAA2C;AACrD,UAAMA,mBAAmB,qBAAqBC,WAAWC,oBAAoB;EAC/E;AACF;;;ADoKA;6BAAc;AAEd,IAAMC,MAAM;EAAEC,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMC,MAAM;EAAEH,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAME,MAAM;EAAEJ,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMG,MAAM;EAAEL,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMI,MAAM;EAAEN,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMK,MAAM;EAAEP,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMM,MAAM;EAAER,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMO,MAAM;EAAET,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AAE5C,IAAMQ,uBAAuB;EAClCC;EACAC;EACAC;EACAC;EACAf;EACAgB;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAlE;EACAmE;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACApK;EACAC;EACAoK;EACAC;EACApK;EACAqK;EACApK;EACAqK;EACApK;EACAqK;EACAC;EACAC;EACAC;EACAvK;AACF;AAOO,SAASwK,gBAAgBC,cAA0B;AACxD,SAAOxK,qBAAqBwK,YAAAA;AAC9B;AAFgBD;AAIT,SAASE,aACdC,OACAF,cACAG,WAA0C;AAE1C,QAAMC,WAAWL,gBAAgBC,YAAAA;AACjC,QAAMK,SAASC,OAAO;IAAED,QAAQH;IAAOE;EAAS,CAAA;AAEhD,MAAI,CAACD,WAAW;AACd,WAAOI,UAAUF,MAAAA;EACnB;AAEA,SAAOE,UAAUF,QAAQ,CAAC,EAAEG,OAAOJ,UAAUK,iBAAgB,MAAON,UAAU;IAAEK;IAAOJ,UAAUK;EAAiB,CAAA,CAAA;AACpH;AAbgBR;AAkBT,SAASS,aAAaC,OAAeX,cAA4BY,QAAQ,UAAQ;AACtF,QAAM,EAAE5L,SAAQ,IAAK+K,gBAAgBC,YAAAA;AACrC,QAAMa,QAAQ,OAAO7L,aAAa,WAAW8L,OAAO9L,QAAAA,IAAYA;AAChE,QAAM+L,UAAUJ,MAAMK,KAAI;AAE1B,MAAI,CAAC,kBAAkBC,KAAKF,OAAAA,GAAU;AACpC,UAAM,IAAIG,oBAAoB;MAC5BC,QAAQ,oBAAoBR,KAAAA;MAC5BS,QAAQ;QAAC;UAAER;UAAOS,SAAS;QAAwB;;IACrD,CAAA;EACF;AAEA,QAAMC,aAAaP,QAAQQ,WAAW,GAAA;AACtC,QAAMC,gBAAgBF,aAAaP,QAAQU,MAAM,CAAA,IAAKV;AACtD,QAAM,CAACW,WAAWC,iBAAiB,EAAE,IAAIH,cAAcI,MAAM,GAAA;AAE7D,MAAID,eAAeE,SAAShB,OAAO;AACjC,UAAM,IAAIK,oBAAoB;MAC5BC,QAAQ,+BAA+BnB,YAAAA,wBAAoCa,KAAAA;MAC3EO,QAAQ;QAAC;UAAER;UAAOS,SAAS,GAAGrB,YAAAA,iBAA6Ba,KAAAA,iBAAsBA,UAAU,IAAI,KAAK,GAAA;QAAO;;IAC7G,CAAA;EACF;AAEA,QAAMiB,iBAAiBH,eAAeI,OAAOlB,OAAO,GAAA;AACpD,QAAMmB,mBAAmB,GAAGN,SAAAA,GAAYI,cAAAA,GAAiBG,QAAQ,aAAa,EAAA;AAC9E,QAAM/B,QAAQgC,OAAOF,oBAAoB,GAAA;AAEzC,SAAOV,aAAa,CAACpB,QAAQA;AAC/B;AA5BgBQ;;;AGhYT,IAAMyB,oBAAN,MAAMA,mBAAAA;EAFb,OAEaA;;;EACXC;EACAC;EAIA,OAAOC,KAAKC,OAAkCC,cAAgD;AAC5F,QAAID,SAAS,KAAM,QAAO;AAC1B,UAAME,MAAM,IAAIN,mBAAAA;AAChBM,QAAIL,WAAWI;AACfC,QAAIJ,QAAQK,aAAaH,OAAOC,YAAAA;AAChC,WAAOC;EACT;AACF;;;ACfA,SAASE,yBAA2E;AAe7E,SAASC,WAAWC,mBAAqC;AAC9D,SAAO,CAACC,QAAgBC,iBAAAA;AACtBC,sBAAkB;MAChBC,MAAM;MACNH,QAAQA,OAAO;MACfC,cAAcG,OAAOH,YAAAA;MACrBI,SAASN;MACTO,WAAW;QACTC,SAASC,OAAc;AACrB,cAAI,CAACA,SAAS,OAAOA,UAAU,SAAU,QAAO;AAChD,gBAAM,EAAEC,UAAUD,OAAOE,OAAM,IAAKF;AACpC,cAAI,OAAOC,aAAa,YAAY,OAAOC,WAAW,SAAU,QAAO;AACvE,cAAI,EAAED,YAAYE,sBAAuB,QAAO;AAChD,cAAI;AACFC,yBAAaF,QAAQD,QAAAA;AACrB,mBAAO;UACT,QAAQ;AACN,mBAAO;UACT;QACF;QACAI,eAAeC,MAAyB;AACtC,iBAAO,GAAGA,KAAKC,QAAQ;QACzB;MACF;IACF,CAAA;EACF;AACF;AA1BgBjB;;;ACfhB,SAASkB,qBAAAA,0BAA2E;AAG7E,SAASC,eAAeC,mBAAqC;AAClE,SAAO,CAACC,QAAgBC,iBAAAA;AACtBC,IAAAA,mBAAkB;MAChBC,MAAM;MACNH,QAAQA,OAAO;MACfC,cAAcG,OAAOH,YAAAA;MACrBI,SAASN;MACTO,WAAW;QACTC,SAASC,OAAc;AACrB,cAAI,OAAOA,UAAU,SAAU,QAAO;AACtC,iBAAOA,SAASC;QAClB;QACAC,eAAeC,MAAyB;AACtC,iBAAO,GAAGA,KAAKC,QAAQ;QACzB;MACF;IACF,CAAA;EACF;AACF;AAlBgBd;;;ANChB,WAAAe,gBAAc;","names":["money_exports","dinero","toDecimal","AED","AFN","ALL","AMD","AOA","ARS","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","BMD","BND","BOB","BOV","BRL","BSD","BTN","BWP","BYN","BZD","CAD","CDF","CHE","CHF","CHW","CLF","CLP","CNY","COP","COU","CRC","CUP","CVE","CZK","DJF","DKK","DOP","DZD","EGP","ERN","ETB","EUR","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MAD","MDL","MGA","MKD","MMK","MNT","MOP","MRU","MUR","MVR","MWK","MXN","MXV","MYR","MZN","NAD","NGN","NIO","NOK","NPR","NZD","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLE","SOS","SRD","SSP","STN","SVC","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","USD","USN","UYI","UYU","UYW","UZS","VED","VES","VND","VUV","WST","XAD","XAF","XCD","XCG","XOF","XPF","YER","ZAR","ZMW","ZWG","HttpStatus","HttpException","HttpProblemException","HttpException","detailOrOptions","httpStatus","options","detail","type","label","errors","ValidationException","HttpProblemException","detailOrOptions","HttpStatus","UNPROCESSABLE_ENTITY","ANG","code","base","exponent","HRK","XAG","XAU","XDR","XPD","XPT","ZWL","SUPPORTED_CURRENCIES","AED","AFN","ALL","AMD","AOA","ARS","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","BMD","BND","BOB","BOV","BRL","BSD","BTN","BWP","BYN","BZD","CAD","CDF","CHE","CHF","CHW","CLF","CLP","CNY","COP","COU","CRC","CUP","CVE","CZK","DJF","DKK","DOP","DZD","EGP","ERN","ETB","EUR","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MAD","MDL","MGA","MKD","MMK","MNT","MOP","MRU","MUR","MVR","MWK","MXN","MXV","MYR","MZN","NAD","NGN","NIO","NOK","NPR","NZD","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLE","SOS","SRD","SSP","STN","SVC","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","USD","USN","UYI","UYU","UYW","UZS","VED","VES","VND","VUV","WST","XAD","XAF","XCD","XCG","XOF","XPF","YER","ZAR","ZMW","ZWG","resolveCurrency","currencyCode","minorToMajor","minor","transform","currency","amount","dinero","toDecimal","value","resolvedCurrency","majorToMinor","major","field","scale","Number","trimmed","trim","test","ValidationException","detail","errors","message","isNegative","startsWith","unsignedValue","slice","wholePart","fractionalPart","split","length","paddedFraction","padEnd","normalizedDigits","replace","BigInt","CurrencyAmountDto","currency","value","from","minor","currencyCode","dto","minorToMajor","registerDecorator","IsCurrency","validationOptions","target","propertyName","registerDecorator","name","String","options","validator","validate","value","currency","amount","SUPPORTED_CURRENCIES","majorToMinor","defaultMessage","args","property","registerDecorator","IsCurrencyCode","validationOptions","target","propertyName","registerDecorator","name","String","options","validator","validate","value","SUPPORTED_CURRENCIES","defaultMessage","args","property","money_exports"]}
|
|
1
|
+
{"version":3,"sources":["../src/money/index.ts","../src/money/money.ts","../src/exceptions/validation.exception.ts","../src/exceptions/base-field.exception.ts","../src/money/currency-amount.dto.ts","../src/money/is-currency.decorator.ts","../src/money/is-currency-code.decorator.ts"],"sourcesContent":["// Money module — the ONLY entry that touches dinero.js (utilities, validators, DTO, dinero re-export)\nexport { CurrencyAmountDto } from './currency-amount.dto';\nexport { IsCurrency } from './is-currency.decorator';\nexport { IsCurrencyCode } from './is-currency-code.decorator';\nexport * from './money';\n","import { dinero, toDecimal } from 'dinero.js/bigint';\nimport {\n AED,\n AFN,\n ALL,\n AMD,\n AOA,\n ARS,\n AUD,\n AWG,\n AZN,\n BAM,\n BBD,\n BDT,\n BGN,\n BHD,\n BIF,\n BMD,\n BND,\n BOB,\n BOV,\n BRL,\n BSD,\n BTN,\n BWP,\n BYN,\n BZD,\n CAD,\n CDF,\n CHE,\n CHF,\n CHW,\n CLF,\n CLP,\n CNY,\n COP,\n COU,\n CRC,\n CUP,\n CVE,\n CZK,\n DJF,\n DKK,\n DOP,\n DZD,\n EGP,\n ERN,\n ETB,\n EUR,\n FJD,\n FKP,\n GBP,\n GEL,\n GHS,\n GIP,\n GMD,\n GNF,\n GTQ,\n GYD,\n HKD,\n HNL,\n HTG,\n HUF,\n IDR,\n ILS,\n INR,\n IQD,\n IRR,\n ISK,\n JMD,\n JOD,\n JPY,\n KES,\n KGS,\n KHR,\n KMF,\n KPW,\n KRW,\n KWD,\n KYD,\n KZT,\n LAK,\n LBP,\n LKR,\n LRD,\n LSL,\n LYD,\n MAD,\n MDL,\n MGA,\n MKD,\n MMK,\n MNT,\n MOP,\n MRU,\n MUR,\n MVR,\n MWK,\n MXN,\n MXV,\n MYR,\n MZN,\n NAD,\n NGN,\n NIO,\n NOK,\n NPR,\n NZD,\n OMR,\n PAB,\n PEN,\n PGK,\n PHP,\n PKR,\n PLN,\n PYG,\n QAR,\n RON,\n RSD,\n RUB,\n RWF,\n SAR,\n SBD,\n SCR,\n SDG,\n SEK,\n SGD,\n SHP,\n SLE,\n SOS,\n SRD,\n SSP,\n STN,\n SVC,\n SYP,\n SZL,\n THB,\n TJS,\n TMT,\n TND,\n TOP,\n TRY,\n TTD,\n TWD,\n TZS,\n UAH,\n UGX,\n USD,\n USN,\n UYI,\n UYU,\n UYW,\n UZS,\n VED,\n VES,\n VND,\n VUV,\n WST,\n XAD,\n XAF,\n XCD,\n XCG,\n XOF,\n XPF,\n YER,\n ZAR,\n ZMW,\n ZWG,\n} from 'dinero.js/bigint/currencies';\nimport { ValidationException } from '../exceptions/validation.exception';\n\nexport * from 'dinero.js/bigint';\n\nconst ANG = { code: 'ANG', base: 10n, exponent: 2n } as const;\nconst HRK = { code: 'HRK', base: 10n, exponent: 2n } as const;\nconst XAG = { code: 'XAG', base: 10n, exponent: 0n } as const;\nconst XAU = { code: 'XAU', base: 10n, exponent: 0n } as const;\nconst XDR = { code: 'XDR', base: 10n, exponent: 0n } as const;\nconst XPD = { code: 'XPD', base: 10n, exponent: 0n } as const;\nconst XPT = { code: 'XPT', base: 10n, exponent: 0n } as const;\nconst ZWL = { code: 'ZWL', base: 10n, exponent: 2n } as const;\n\nexport const SUPPORTED_CURRENCIES = {\n AED,\n AFN,\n ALL,\n AMD,\n ANG,\n AOA,\n ARS,\n AUD,\n AWG,\n AZN,\n BAM,\n BBD,\n BDT,\n BGN,\n BHD,\n BIF,\n BMD,\n BND,\n BOB,\n BOV,\n BRL,\n BSD,\n BTN,\n BWP,\n BYN,\n BZD,\n CAD,\n CDF,\n CHE,\n CHF,\n CHW,\n CLF,\n CLP,\n CNY,\n COP,\n COU,\n CRC,\n CUP,\n CVE,\n CZK,\n DJF,\n DKK,\n DOP,\n DZD,\n EGP,\n ERN,\n ETB,\n EUR,\n FJD,\n FKP,\n GBP,\n GEL,\n GHS,\n GIP,\n GMD,\n GNF,\n GTQ,\n GYD,\n HKD,\n HNL,\n HRK,\n HTG,\n HUF,\n IDR,\n ILS,\n INR,\n IQD,\n IRR,\n ISK,\n JMD,\n JOD,\n JPY,\n KES,\n KGS,\n KHR,\n KMF,\n KPW,\n KRW,\n KWD,\n KYD,\n KZT,\n LAK,\n LBP,\n LKR,\n LRD,\n LSL,\n LYD,\n MAD,\n MDL,\n MGA,\n MKD,\n MMK,\n MNT,\n MOP,\n MRU,\n MUR,\n MVR,\n MWK,\n MXN,\n MXV,\n MYR,\n MZN,\n NAD,\n NGN,\n NIO,\n NOK,\n NPR,\n NZD,\n OMR,\n PAB,\n PEN,\n PGK,\n PHP,\n PKR,\n PLN,\n PYG,\n QAR,\n RON,\n RSD,\n RUB,\n RWF,\n SAR,\n SBD,\n SCR,\n SDG,\n SEK,\n SGD,\n SHP,\n SLE,\n SOS,\n SRD,\n SSP,\n STN,\n SVC,\n SYP,\n SZL,\n THB,\n TJS,\n TMT,\n TND,\n TOP,\n TRY,\n TTD,\n TWD,\n TZS,\n UAH,\n UGX,\n USD,\n USN,\n UYI,\n UYU,\n UYW,\n UZS,\n VED,\n VES,\n VND,\n VUV,\n WST,\n XAD,\n XAF,\n XAG,\n XAU,\n XCD,\n XCG,\n XDR,\n XOF,\n XPD,\n XPF,\n XPT,\n YER,\n ZAR,\n ZMW,\n ZWG,\n ZWL,\n} as const;\n\nexport type CurrencyCode = keyof typeof SUPPORTED_CURRENCIES;\nexport type Currency = (typeof SUPPORTED_CURRENCIES)[CurrencyCode];\n\nexport type MinorToMajorTransform<TOutput> = (props: { value: string; currency: Currency }) => TOutput;\n\nexport function resolveCurrency(currencyCode: CurrencyCode, field?: string): Currency {\n const currency = SUPPORTED_CURRENCIES[currencyCode];\n if (!currency) {\n throw new ValidationException({\n label: 'Unsupported Currency',\n detail: `Unsupported currency: \"${currencyCode}\".`,\n ...(field ? { errors: [{ field, message: 'Unsupported currency.' }] } : {}),\n });\n }\n return currency;\n}\n\nexport function minorToMajor<TOutput = string>(\n minor: bigint,\n currencyCode: CurrencyCode,\n transform?: MinorToMajorTransform<TOutput>,\n): string | TOutput {\n const currency = resolveCurrency(currencyCode);\n const amount = dinero({ amount: minor, currency });\n\n if (!transform) {\n return toDecimal(amount);\n }\n\n return toDecimal(amount, ({ value, currency: resolvedCurrency }) => transform({ value, currency: resolvedCurrency }));\n}\n\n// Converts a major-unit string to minor-unit bigint, throwing ValidationException (422) on invalid input\nexport function majorToMinor(major: string, currencyCode: CurrencyCode, field = 'amount'): bigint {\n const { exponent } = resolveCurrency(currencyCode, field);\n const scale = typeof exponent === 'bigint' ? Number(exponent) : exponent;\n const trimmed = major.trim();\n\n if (!/^-?\\d+(\\.\\d+)?$/.test(trimmed)) {\n throw new ValidationException({\n detail: `Invalid amount: \"${major}\".`,\n errors: [{ field, message: 'Enter a valid number.' }],\n });\n }\n\n const isNegative = trimmed.startsWith('-');\n const unsignedValue = isNegative ? trimmed.slice(1) : trimmed;\n const [wholePart, fractionalPart = ''] = unsignedValue.split('.');\n\n if (fractionalPart.length > scale) {\n throw new ValidationException({\n detail: `Too many decimal places for ${currencyCode}. Maximum allowed is ${scale}.`,\n errors: [{ field, message: `${currencyCode} allows up to ${scale} decimal place${scale === 1 ? '' : 's'}.` }],\n });\n }\n\n const paddedFraction = fractionalPart.padEnd(scale, '0');\n const normalizedDigits = `${wholePart}${paddedFraction}`.replace(/^0+(?=\\d)/, '');\n const minor = BigInt(normalizedDigits || '0');\n\n return isNegative ? -minor : minor;\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ValidationException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Validation Failed', HttpStatus.UNPROCESSABLE_ENTITY);\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 { type CurrencyCode, minorToMajor } from './money';\n\nexport class CurrencyAmountDto {\n currency: CurrencyCode;\n value: string;\n\n static from(minor: bigint, currencyCode: string): CurrencyAmountDto;\n static from(minor: bigint | null | undefined, currencyCode: string): CurrencyAmountDto | null;\n static from(minor: bigint | null | undefined, currencyCode: string): CurrencyAmountDto | null {\n if (minor == null) return null;\n const dto = new CurrencyAmountDto();\n dto.currency = currencyCode as CurrencyCode;\n dto.value = minorToMajor(minor, currencyCode as CurrencyCode);\n return dto;\n }\n}\n","import { registerDecorator, type ValidationArguments, type ValidationOptions } from 'class-validator';\nimport { type CurrencyCode, majorToMinor, SUPPORTED_CURRENCIES } from './money';\n\n// Self-contained validator for {currency, value} payloads — inlines all checks (not @ValidateNested) to dodge class-validator MetadataStorage duplication across api-sdk and consumers.\nexport function IsCurrency(validationOptions?: ValidationOptions): PropertyDecorator {\n return (target: object, propertyName: string | symbol) => {\n registerDecorator({\n name: 'isCurrency',\n target: target.constructor,\n propertyName: String(propertyName),\n options: validationOptions,\n validator: {\n validate(value: unknown): boolean {\n if (!value || typeof value !== 'object') return false;\n const { currency, value: amount } = value as Record<string, unknown>;\n if (typeof currency !== 'string' || typeof amount !== 'string') return false;\n if (!(currency in SUPPORTED_CURRENCIES)) return false;\n try {\n majorToMinor(amount, currency as CurrencyCode);\n return true;\n } catch {\n return false;\n }\n },\n defaultMessage(args: ValidationArguments): string {\n return `${args.property} must be {currency, value} where currency is a valid ISO 4217 code and value precision matches the currency exponent.`;\n },\n },\n });\n };\n}\n","import { registerDecorator, type ValidationArguments, type ValidationOptions } from 'class-validator';\nimport { SUPPORTED_CURRENCIES } from './money';\n\nexport function IsCurrencyCode(validationOptions?: ValidationOptions): PropertyDecorator {\n return (target: object, propertyName: string | symbol) => {\n registerDecorator({\n name: 'isCurrencyCode',\n target: target.constructor,\n propertyName: String(propertyName),\n options: validationOptions,\n validator: {\n validate(value: unknown): boolean {\n if (typeof value !== 'string') return false;\n return value in SUPPORTED_CURRENCIES;\n },\n defaultMessage(args: ValidationArguments): string {\n return `${args.property} must be a valid ISO 4217 currency code.`;\n },\n },\n });\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,iBAAA;SAAAA,gBAAA;;;;;;;;;;;ACAA;;;;;;;AAAA,SAASC,QAAQC,iBAAiB;AAClC,SACEC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,WACK;;;ACxKP,SAASC,kBAAkB;;;ACA3B,SAASC,qBAAiC;AAanC,IAAeC,uBAAf,cAA4CC,cAAAA;EAbnD,OAamDA;;;EACjD,YAAYC,iBAA0CC,YAAwB;AAC5E,UAAMC,UAAU,OAAOF,oBAAoB,WAAW;MAAEG,QAAQH;IAAgB,IAAIA;AAEpF,UACE;MACEI,MAAMF,QAAQE,QAAQ;MACtBC,OAAOH,QAAQG;MACfF,QAAQD,QAAQC;MAChBG,QAAQJ,QAAQI,UAAU,CAAA;IAC5B,GACAL,UAAAA;EAEJ;AACF;;;ADxBO,IAAMM,sBAAN,cAAkCC,qBAAAA;EAHzC,OAGyCA;;;EACvC,YAAYC,iBAA2C;AACrD,UAAMA,mBAAmB,qBAAqBC,WAAWC,oBAAoB;EAC/E;AACF;;;ADoKA;6BAAc;AAEd,IAAMC,MAAM;EAAEC,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMC,MAAM;EAAEH,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAME,MAAM;EAAEJ,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMG,MAAM;EAAEL,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMI,MAAM;EAAEN,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMK,MAAM;EAAEP,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMM,MAAM;EAAER,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AACnD,IAAMO,MAAM;EAAET,MAAM;EAAOC,MAAM;EAAKC,UAAU;AAAG;AAE5C,IAAMQ,uBAAuB;EAClCC;EACAC;EACAC;EACAC;EACAf;EACAgB;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAlE;EACAmE;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACApK;EACAC;EACAoK;EACAC;EACApK;EACAqK;EACApK;EACAqK;EACApK;EACAqK;EACAC;EACAC;EACAC;EACAvK;AACF;AAOO,SAASwK,gBAAgBC,cAA4BC,OAAc;AACxE,QAAMC,WAAW1K,qBAAqBwK,YAAAA;AACtC,MAAI,CAACE,UAAU;AACb,UAAM,IAAIC,oBAAoB;MAC5BC,OAAO;MACPC,QAAQ,0BAA0BL,YAAAA;MAClC,GAAIC,QAAQ;QAAEK,QAAQ;UAAC;YAAEL;YAAOM,SAAS;UAAwB;;MAAG,IAAI,CAAC;IAC3E,CAAA;EACF;AACA,SAAOL;AACT;AAVgBH;AAYT,SAASS,aACdC,OACAT,cACAU,WAA0C;AAE1C,QAAMR,WAAWH,gBAAgBC,YAAAA;AACjC,QAAMW,SAASC,OAAO;IAAED,QAAQF;IAAOP;EAAS,CAAA;AAEhD,MAAI,CAACQ,WAAW;AACd,WAAOG,UAAUF,MAAAA;EACnB;AAEA,SAAOE,UAAUF,QAAQ,CAAC,EAAEG,OAAOZ,UAAUa,iBAAgB,MAAOL,UAAU;IAAEI;IAAOZ,UAAUa;EAAiB,CAAA,CAAA;AACpH;AAbgBP;AAgBT,SAASQ,aAAaC,OAAejB,cAA4BC,QAAQ,UAAQ;AACtF,QAAM,EAAEjL,SAAQ,IAAK+K,gBAAgBC,cAAcC,KAAAA;AACnD,QAAMiB,QAAQ,OAAOlM,aAAa,WAAWmM,OAAOnM,QAAAA,IAAYA;AAChE,QAAMoM,UAAUH,MAAMI,KAAI;AAE1B,MAAI,CAAC,kBAAkBC,KAAKF,OAAAA,GAAU;AACpC,UAAM,IAAIjB,oBAAoB;MAC5BE,QAAQ,oBAAoBY,KAAAA;MAC5BX,QAAQ;QAAC;UAAEL;UAAOM,SAAS;QAAwB;;IACrD,CAAA;EACF;AAEA,QAAMgB,aAAaH,QAAQI,WAAW,GAAA;AACtC,QAAMC,gBAAgBF,aAAaH,QAAQM,MAAM,CAAA,IAAKN;AACtD,QAAM,CAACO,WAAWC,iBAAiB,EAAE,IAAIH,cAAcI,MAAM,GAAA;AAE7D,MAAID,eAAeE,SAASZ,OAAO;AACjC,UAAM,IAAIf,oBAAoB;MAC5BE,QAAQ,+BAA+BL,YAAAA,wBAAoCkB,KAAAA;MAC3EZ,QAAQ;QAAC;UAAEL;UAAOM,SAAS,GAAGP,YAAAA,iBAA6BkB,KAAAA,iBAAsBA,UAAU,IAAI,KAAK,GAAA;QAAO;;IAC7G,CAAA;EACF;AAEA,QAAMa,iBAAiBH,eAAeI,OAAOd,OAAO,GAAA;AACpD,QAAMe,mBAAmB,GAAGN,SAAAA,GAAYI,cAAAA,GAAiBG,QAAQ,aAAa,EAAA;AAC9E,QAAMzB,QAAQ0B,OAAOF,oBAAoB,GAAA;AAEzC,SAAOV,aAAa,CAACd,QAAQA;AAC/B;AA5BgBO;;;AGtYT,IAAMoB,oBAAN,MAAMA,mBAAAA;EAFb,OAEaA;;;EACXC;EACAC;EAIA,OAAOC,KAAKC,OAAkCC,cAAgD;AAC5F,QAAID,SAAS,KAAM,QAAO;AAC1B,UAAME,MAAM,IAAIN,mBAAAA;AAChBM,QAAIL,WAAWI;AACfC,QAAIJ,QAAQK,aAAaH,OAAOC,YAAAA;AAChC,WAAOC;EACT;AACF;;;ACfA,SAASE,yBAA2E;AAI7E,SAASC,WAAWC,mBAAqC;AAC9D,SAAO,CAACC,QAAgBC,iBAAAA;AACtBC,sBAAkB;MAChBC,MAAM;MACNH,QAAQA,OAAO;MACfC,cAAcG,OAAOH,YAAAA;MACrBI,SAASN;MACTO,WAAW;QACTC,SAASC,OAAc;AACrB,cAAI,CAACA,SAAS,OAAOA,UAAU,SAAU,QAAO;AAChD,gBAAM,EAAEC,UAAUD,OAAOE,OAAM,IAAKF;AACpC,cAAI,OAAOC,aAAa,YAAY,OAAOC,WAAW,SAAU,QAAO;AACvE,cAAI,EAAED,YAAYE,sBAAuB,QAAO;AAChD,cAAI;AACFC,yBAAaF,QAAQD,QAAAA;AACrB,mBAAO;UACT,QAAQ;AACN,mBAAO;UACT;QACF;QACAI,eAAeC,MAAyB;AACtC,iBAAO,GAAGA,KAAKC,QAAQ;QACzB;MACF;IACF,CAAA;EACF;AACF;AA1BgBjB;;;ACJhB,SAASkB,qBAAAA,0BAA2E;AAG7E,SAASC,eAAeC,mBAAqC;AAClE,SAAO,CAACC,QAAgBC,iBAAAA;AACtBC,IAAAA,mBAAkB;MAChBC,MAAM;MACNH,QAAQA,OAAO;MACfC,cAAcG,OAAOH,YAAAA;MACrBI,SAASN;MACTO,WAAW;QACTC,SAASC,OAAc;AACrB,cAAI,OAAOA,UAAU,SAAU,QAAO;AACtC,iBAAOA,SAASC;QAClB;QACAC,eAAeC,MAAyB;AACtC,iBAAO,GAAGA,KAAKC,QAAQ;QACzB;MACF;IACF,CAAA;EACF;AACF;AAlBgBd;;;ANChB,WAAAe,gBAAc;","names":["money_exports","dinero","toDecimal","AED","AFN","ALL","AMD","AOA","ARS","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","BMD","BND","BOB","BOV","BRL","BSD","BTN","BWP","BYN","BZD","CAD","CDF","CHE","CHF","CHW","CLF","CLP","CNY","COP","COU","CRC","CUP","CVE","CZK","DJF","DKK","DOP","DZD","EGP","ERN","ETB","EUR","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MAD","MDL","MGA","MKD","MMK","MNT","MOP","MRU","MUR","MVR","MWK","MXN","MXV","MYR","MZN","NAD","NGN","NIO","NOK","NPR","NZD","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLE","SOS","SRD","SSP","STN","SVC","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","USD","USN","UYI","UYU","UYW","UZS","VED","VES","VND","VUV","WST","XAD","XAF","XCD","XCG","XOF","XPF","YER","ZAR","ZMW","ZWG","HttpStatus","HttpException","HttpProblemException","HttpException","detailOrOptions","httpStatus","options","detail","type","label","errors","ValidationException","HttpProblemException","detailOrOptions","HttpStatus","UNPROCESSABLE_ENTITY","ANG","code","base","exponent","HRK","XAG","XAU","XDR","XPD","XPT","ZWL","SUPPORTED_CURRENCIES","AED","AFN","ALL","AMD","AOA","ARS","AUD","AWG","AZN","BAM","BBD","BDT","BGN","BHD","BIF","BMD","BND","BOB","BOV","BRL","BSD","BTN","BWP","BYN","BZD","CAD","CDF","CHE","CHF","CHW","CLF","CLP","CNY","COP","COU","CRC","CUP","CVE","CZK","DJF","DKK","DOP","DZD","EGP","ERN","ETB","EUR","FJD","FKP","GBP","GEL","GHS","GIP","GMD","GNF","GTQ","GYD","HKD","HNL","HTG","HUF","IDR","ILS","INR","IQD","IRR","ISK","JMD","JOD","JPY","KES","KGS","KHR","KMF","KPW","KRW","KWD","KYD","KZT","LAK","LBP","LKR","LRD","LSL","LYD","MAD","MDL","MGA","MKD","MMK","MNT","MOP","MRU","MUR","MVR","MWK","MXN","MXV","MYR","MZN","NAD","NGN","NIO","NOK","NPR","NZD","OMR","PAB","PEN","PGK","PHP","PKR","PLN","PYG","QAR","RON","RSD","RUB","RWF","SAR","SBD","SCR","SDG","SEK","SGD","SHP","SLE","SOS","SRD","SSP","STN","SVC","SYP","SZL","THB","TJS","TMT","TND","TOP","TRY","TTD","TWD","TZS","UAH","UGX","USD","USN","UYI","UYU","UYW","UZS","VED","VES","VND","VUV","WST","XAD","XAF","XCD","XCG","XOF","XPF","YER","ZAR","ZMW","ZWG","resolveCurrency","currencyCode","field","currency","ValidationException","label","detail","errors","message","minorToMajor","minor","transform","amount","dinero","toDecimal","value","resolvedCurrency","majorToMinor","major","scale","Number","trimmed","trim","test","isNegative","startsWith","unsignedValue","slice","wholePart","fractionalPart","split","length","paddedFraction","padEnd","normalizedDigits","replace","BigInt","CurrencyAmountDto","currency","value","from","minor","currencyCode","dto","minorToMajor","registerDecorator","IsCurrency","validationOptions","target","propertyName","registerDecorator","name","String","options","validator","validate","value","currency","amount","SUPPORTED_CURRENCIES","majorToMinor","defaultMessage","args","property","registerDecorator","IsCurrencyCode","validationOptions","target","propertyName","registerDecorator","name","String","options","validator","validate","value","SUPPORTED_CURRENCIES","defaultMessage","args","property","money_exports"]}
|