@cosmneo/onion-lasagna 0.2.0 → 0.3.0
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/chunk-36IO4BM7.js +113 -0
- package/dist/chunk-36IO4BM7.js.map +1 -0
- package/dist/chunk-4BVOLXDJ.js +54 -0
- package/dist/chunk-4BVOLXDJ.js.map +1 -0
- package/dist/{chunk-GGSAAZPM.js → chunk-AUMHMWDD.js} +19 -20
- package/dist/chunk-AUMHMWDD.js.map +1 -0
- package/dist/chunk-CBTICRSM.js +34 -0
- package/dist/chunk-CBTICRSM.js.map +1 -0
- package/dist/chunk-H5TNDC5U.js +138 -0
- package/dist/chunk-H5TNDC5U.js.map +1 -0
- package/dist/chunk-KJ4JGZOE.js +96 -0
- package/dist/chunk-KJ4JGZOE.js.map +1 -0
- package/dist/chunk-MF2JDREK.js +168 -0
- package/dist/chunk-MF2JDREK.js.map +1 -0
- package/dist/chunk-RVSBIYY4.js +1 -0
- package/dist/chunk-RVSBIYY4.js.map +1 -0
- package/dist/{chunk-PUVAB3JX.js → chunk-XIRJ73IO.js} +38 -36
- package/dist/chunk-XIRJ73IO.js.map +1 -0
- package/dist/{chunk-DS7TE6KZ.js → chunk-XP6PLTV2.js} +11 -3
- package/dist/chunk-XP6PLTV2.js.map +1 -0
- package/dist/chunk-XWKHOLIP.js +191 -0
- package/dist/chunk-XWKHOLIP.js.map +1 -0
- package/dist/event-router-definition.type-CP9uTlux.d.cts +150 -0
- package/dist/event-router-definition.type-D8CG-kjZ.d.ts +150 -0
- package/dist/events/asyncapi/index.cjs +143 -0
- package/dist/events/asyncapi/index.cjs.map +1 -0
- package/dist/events/asyncapi/index.d.cts +184 -0
- package/dist/events/asyncapi/index.d.ts +184 -0
- package/dist/events/asyncapi/index.js +8 -0
- package/dist/events/asyncapi/index.js.map +1 -0
- package/dist/events/handler/index.cjs +171 -0
- package/dist/events/handler/index.cjs.map +1 -0
- package/dist/events/handler/index.d.cts +153 -0
- package/dist/events/handler/index.d.ts +153 -0
- package/dist/events/handler/index.js +21 -0
- package/dist/events/handler/index.js.map +1 -0
- package/dist/events/index.cjs +497 -0
- package/dist/events/index.cjs.map +1 -0
- package/dist/events/index.d.cts +9 -0
- package/dist/events/index.d.ts +9 -0
- package/dist/events/index.js +41 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/server/index.cjs +291 -0
- package/dist/events/server/index.cjs.map +1 -0
- package/dist/events/server/index.d.cts +281 -0
- package/dist/events/server/index.d.ts +281 -0
- package/dist/events/server/index.js +16 -0
- package/dist/events/server/index.js.map +1 -0
- package/dist/events/shared/index.cjs +85 -0
- package/dist/events/shared/index.cjs.map +1 -0
- package/dist/events/shared/index.d.cts +35 -0
- package/dist/events/shared/index.d.ts +35 -0
- package/dist/events/shared/index.js +13 -0
- package/dist/events/shared/index.js.map +1 -0
- package/dist/global.js +3 -3
- package/dist/http/index.cjs +563 -93
- package/dist/http/index.cjs.map +1 -1
- package/dist/http/index.d.cts +5 -3
- package/dist/http/index.d.ts +5 -3
- package/dist/http/index.js +30 -12
- package/dist/http/openapi/index.cjs +43 -35
- package/dist/http/openapi/index.cjs.map +1 -1
- package/dist/http/openapi/index.d.cts +8 -34
- package/dist/http/openapi/index.d.ts +8 -34
- package/dist/http/openapi/index.js +2 -2
- package/dist/http/route/index.cjs +106 -9
- package/dist/http/route/index.cjs.map +1 -1
- package/dist/http/route/index.d.cts +133 -227
- package/dist/http/route/index.d.ts +133 -227
- package/dist/http/route/index.js +5 -2
- package/dist/http/server/index.cjs +24 -19
- package/dist/http/server/index.cjs.map +1 -1
- package/dist/http/server/index.d.cts +4 -261
- package/dist/http/server/index.d.ts +4 -261
- package/dist/http/server/index.js +2 -2
- package/dist/http/shared/index.cjs.map +1 -1
- package/dist/http/shared/index.d.cts +10 -14
- package/dist/http/shared/index.d.ts +10 -14
- package/dist/http/shared/index.js +11 -127
- package/dist/http/shared/index.js.map +1 -1
- package/dist/index.js +6 -6
- package/dist/{router-definition.type-ynBhT16T.d.cts → router-definition.type-BElX-Pl4.d.cts} +169 -256
- package/dist/{router-definition.type-DORVlLNk.d.ts → router-definition.type-DxG8ncJZ.d.ts} +169 -256
- package/dist/types-B6Q1iCgf.d.ts +262 -0
- package/dist/types-afYpL7Ap.d.cts +262 -0
- package/dist/types-cke61juH.d.cts +42 -0
- package/dist/types-cke61juH.d.ts +42 -0
- package/package.json +35 -2
- package/dist/chunk-BZULBF4N.js +0 -82
- package/dist/chunk-BZULBF4N.js.map +0 -1
- package/dist/chunk-DS7TE6KZ.js.map +0 -1
- package/dist/chunk-GGSAAZPM.js.map +0 -1
- package/dist/chunk-PUVAB3JX.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/presentation/http/shared/index.ts","../../../src/global/exceptions/coded-error.error.ts","../../../src/global/exceptions/error-codes.const.ts","../../../src/global/exceptions/object-validation.error.ts","../../../src/domain/exceptions/domain.error.ts","../../../src/app/exceptions/use-case.error.ts","../../../src/app/exceptions/not-found.error.ts","../../../src/app/exceptions/conflict.error.ts","../../../src/app/exceptions/unprocessable.error.ts","../../../src/app/exceptions/forbidden.error.ts","../../../src/app/exceptions/unauthorized.error.ts","../../../src/infra/exceptions/infra.error.ts","../../../src/presentation/exceptions/controller.error.ts","../../../src/presentation/exceptions/access-denied.error.ts","../../../src/presentation/exceptions/invalid-request.error.ts","../../../src/presentation/http/shared/error-mapping.ts"],"sourcesContent":["/**\n * @fileoverview Shared utilities for HTTP framework adapters.\n *\n * @module http/shared\n */\n\nexport * from './error-mapping';\nexport * from './types';\n","import type { ErrorCode } from './error-codes.const';\n\n/**\n * Base error class for all application errors with a machine-readable code.\n *\n * Abstract class that extends the native `Error` with:\n * - A `code` property for programmatic error handling\n * - Optional `cause` for error chaining (ES2022 compatible)\n * - A `fromError` static factory pattern for error transformation\n *\n * **Why abstract:** Prevents non-declarative error usage. All errors must\n * be explicitly defined as subclasses to ensure consistent error taxonomy.\n *\n * @example Subclass implementation\n * ```typescript\n * class DbError extends InfraError {\n * static override fromError(cause: unknown): DbError {\n * return new DbError({\n * message: cause instanceof Error ? cause.message : 'Database error',\n * cause,\n * });\n * }\n * }\n * ```\n *\n * @example Usage with wrapErrorAsync\n * ```typescript\n * await wrapErrorAsync(\n * () => this.db.query(...),\n * DbError.fromError,\n * );\n * ```\n */\nexport abstract class CodedError extends Error {\n /** Machine-readable error code for programmatic handling. */\n public readonly code: ErrorCode | string;\n\n /**\n * Creates a new CodedError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error message\n * @param options.code - Machine-readable error code from ErrorCodes registry or custom string\n * @param options.cause - Optional underlying error that caused this error\n */\n constructor({\n message,\n code,\n cause,\n }: {\n message: string;\n code: ErrorCode | string;\n cause?: unknown;\n }) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n if (cause !== undefined) {\n Object.defineProperty(this, 'cause', {\n value: cause,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n }\n }\n\n /**\n * Factory method to create a typed error from a caught error.\n *\n * Subclasses should override this to provide proper error transformation.\n * Designed for use with {@link wrapErrorAsync} and {@link wrapError}.\n *\n * @param _cause - The original caught error\n * @returns A new CodedError instance\n * @throws {Error} If not overridden by subclass\n *\n * @example\n * ```typescript\n * class NotFoundError extends UseCaseError {\n * static override fromError(cause: unknown): NotFoundError {\n * return new NotFoundError({\n * message: 'Resource not found',\n * cause,\n * });\n * }\n * }\n * ```\n */\n static fromError(_cause: unknown): CodedError {\n throw new Error(`${this.name}.fromError() must be implemented by subclass`);\n }\n}\n","/**\n * Centralized registry of all error codes used across the application.\n *\n * Error codes are grouped by architectural layer to maintain clear boundaries\n * and make it easy to identify where an error originated.\n *\n * @example Using error codes in custom errors\n * ```typescript\n * import { ErrorCodes } from '@cosmneo/onion-lasagna/global';\n *\n * throw new NotFoundError({\n * message: 'User not found',\n * code: ErrorCodes.App.NOT_FOUND,\n * });\n * ```\n *\n * @example Checking error codes programmatically\n * ```typescript\n * if (error.code === ErrorCodes.App.NOT_FOUND) {\n * // Handle not found case\n * }\n * ```\n */\nexport const ErrorCodes = {\n /**\n * Domain layer error codes.\n * Used for business rule violations and invariant failures.\n */\n Domain: {\n /** Generic domain error */\n DOMAIN_ERROR: 'DOMAIN_ERROR',\n /** Business invariant was violated */\n INVARIANT_VIOLATION: 'INVARIANT_VIOLATION',\n /** Aggregate was partially loaded (missing required relations) */\n PARTIAL_LOAD: 'PARTIAL_LOAD',\n },\n\n /**\n * Application layer (use case) error codes.\n * Used for orchestration failures and business operation errors.\n */\n App: {\n /** Generic use case error */\n USE_CASE_ERROR: 'USE_CASE_ERROR',\n /** Requested resource was not found */\n NOT_FOUND: 'NOT_FOUND',\n /** Resource state conflict (e.g., duplicate, already exists) */\n CONFLICT: 'CONFLICT',\n /** Request is valid but cannot be processed due to business rules */\n UNPROCESSABLE: 'UNPROCESSABLE',\n /** Authorization denied - user lacks permission for this operation */\n FORBIDDEN: 'FORBIDDEN',\n /** Authentication required or invalid - user is not authenticated */\n UNAUTHORIZED: 'UNAUTHORIZED',\n },\n\n /**\n * Infrastructure layer error codes.\n * Used for data access, external services, and I/O failures.\n */\n Infra: {\n /** Generic infrastructure error */\n INFRA_ERROR: 'INFRA_ERROR',\n /** Database operation failed */\n DB_ERROR: 'DB_ERROR',\n /** Network connectivity or communication error */\n NETWORK_ERROR: 'NETWORK_ERROR',\n /** Operation timed out */\n TIMEOUT_ERROR: 'TIMEOUT_ERROR',\n /** External/third-party service error */\n EXTERNAL_SERVICE_ERROR: 'EXTERNAL_SERVICE_ERROR',\n },\n\n /**\n * Presentation layer error codes.\n * Used for controller, request handling, and authorization errors.\n */\n Presentation: {\n /** Generic controller error */\n CONTROLLER_ERROR: 'CONTROLLER_ERROR',\n /** Request denied due to authorization failure */\n ACCESS_DENIED: 'ACCESS_DENIED',\n /** Request validation failed (malformed input) */\n INVALID_REQUEST: 'INVALID_REQUEST',\n },\n\n /**\n * Global/cross-cutting error codes.\n * Used for validation and other cross-layer concerns.\n */\n Global: {\n /** Object/schema validation failed */\n OBJECT_VALIDATION_ERROR: 'OBJECT_VALIDATION_ERROR',\n },\n} as const;\n\n/**\n * Type representing all possible domain error codes.\n */\nexport type DomainErrorCode = (typeof ErrorCodes.Domain)[keyof typeof ErrorCodes.Domain];\n\n/**\n * Type representing all possible application error codes.\n */\nexport type AppErrorCode = (typeof ErrorCodes.App)[keyof typeof ErrorCodes.App];\n\n/**\n * Type representing all possible infrastructure error codes.\n */\nexport type InfraErrorCode = (typeof ErrorCodes.Infra)[keyof typeof ErrorCodes.Infra];\n\n/**\n * Type representing all possible presentation error codes.\n */\nexport type PresentationErrorCode =\n (typeof ErrorCodes.Presentation)[keyof typeof ErrorCodes.Presentation];\n\n/**\n * Type representing all possible global error codes.\n */\nexport type GlobalErrorCode = (typeof ErrorCodes.Global)[keyof typeof ErrorCodes.Global];\n\n/**\n * Union type of all error codes across all layers.\n *\n * Use this when you need to accept any valid error code.\n *\n * @example\n * ```typescript\n * function logError(code: ErrorCode, message: string) {\n * console.error(`[${code}] ${message}`);\n * }\n * ```\n */\nexport type ErrorCode =\n | DomainErrorCode\n | AppErrorCode\n | InfraErrorCode\n | PresentationErrorCode\n | GlobalErrorCode;\n","import { CodedError } from './coded-error.error';\nimport { ErrorCodes, type GlobalErrorCode } from './error-codes.const';\nimport type { ValidationError } from '../interfaces/types/validation-error.type';\n\n/**\n * Error thrown when object validation fails.\n *\n * Contains structured validation errors with field paths and messages,\n * making it easy to report specific validation failures to clients.\n * Thrown by all validator implementations (Zod, ArkType, TypeBox, Valibot).\n *\n * **Flow:**\n * 1. Validator throws `ObjectValidationError` with field-level errors\n * 2. Controller catches and converts to {@link InvalidRequestError}\n * 3. HTTP layer maps to 400 Bad Request with error details\n *\n * @example\n * ```typescript\n * try {\n * const dto = CreateUserDto.create(invalidData);\n * } catch (error) {\n * if (error instanceof ObjectValidationError) {\n * console.log(error.validationErrors);\n * // [\n * // { field: 'email', message: 'Invalid email format' },\n * // { field: 'age', message: 'Must be a positive number' }\n * // ]\n * }\n * }\n * ```\n */\nexport class ObjectValidationError extends CodedError {\n /**\n * Array of field-level validation errors.\n *\n * Each entry contains:\n * - `field`: Dot-notation path to the invalid field (e.g., 'user.email')\n * - `message`: Human-readable validation failure message\n */\n validationErrors: ValidationError[];\n\n /**\n * Creates a new ObjectValidationError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable summary message\n * @param options.code - Machine-readable error code (default: 'OBJECT_VALIDATION_ERROR')\n * @param options.cause - Optional underlying error from validation library\n * @param options.validationErrors - Array of field-level validation errors\n */\n constructor({\n message,\n code = ErrorCodes.Global.OBJECT_VALIDATION_ERROR,\n cause,\n validationErrors,\n }: {\n message: string;\n code?: GlobalErrorCode | string;\n cause?: unknown;\n validationErrors: ValidationError[];\n }) {\n super({ message, code, cause });\n this.validationErrors = validationErrors;\n }\n\n /**\n * Creates an ObjectValidationError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new ObjectValidationError instance with the cause attached\n */\n static override fromError(cause: unknown): ObjectValidationError {\n return new ObjectValidationError({\n message: cause instanceof Error ? cause.message : 'Validation failed',\n cause,\n validationErrors: [],\n });\n }\n}\n","import { CodedError } from '../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type DomainErrorCode } from '../../global/exceptions/error-codes.const';\n\n/**\n * Base error class for domain layer failures.\n *\n * Domain errors represent violations of business rules, invariants,\n * or aggregate consistency. They originate from the core domain logic\n * and should be caught and handled by the application layer.\n *\n * **When to throw:**\n * - Business rule violations (e.g., \"Cannot withdraw more than balance\")\n * - Invariant violations (e.g., \"Email format invalid\")\n * - Aggregate consistency failures\n *\n * **Child classes:**\n * - {@link InvariantViolationError} - Value object or entity invariant failures\n * - {@link PartialLoadError} - Incomplete aggregate reconstitution\n *\n * @example\n * ```typescript\n * if (account.balance < amount) {\n * throw new DomainError({\n * message: 'Insufficient funds for withdrawal',\n * code: 'INSUFFICIENT_FUNDS',\n * });\n * }\n * ```\n */\nexport class DomainError extends CodedError {\n /**\n * Creates a new DomainError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error description\n * @param options.code - Machine-readable error code (default: 'DOMAIN_ERROR')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Domain.DOMAIN_ERROR,\n cause,\n }: {\n message: string;\n code?: DomainErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a DomainError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new DomainError instance with the cause attached\n */\n static override fromError(cause: unknown): DomainError {\n return new DomainError({\n message: cause instanceof Error ? cause.message : 'Domain error',\n cause,\n });\n }\n}\n","import { CodedError } from '../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type AppErrorCode } from '../../global/exceptions/error-codes.const';\n\n/**\n * Base error class for application layer (use case) failures.\n *\n * Use case errors represent failures in the application's business logic\n * orchestration, such as resource conflicts, missing entities, or\n * unprocessable requests. They bridge domain errors to the presentation layer.\n *\n * **When to throw:**\n * - Resource not found (e.g., \"User with ID X not found\")\n * - Conflict states (e.g., \"Email already registered\")\n * - Unprocessable business operations\n *\n * **Child classes:**\n * - {@link ConflictError} - Resource state conflicts (HTTP 409)\n * - {@link NotFoundError} - Resource not found (HTTP 404)\n * - {@link UnprocessableError} - Valid but unprocessable request (HTTP 422)\n *\n * @example\n * ```typescript\n * const user = await this.userRepo.findById(id);\n * if (!user) {\n * throw new NotFoundError({\n * message: `User with ID ${id} not found`,\n * code: 'USER_NOT_FOUND',\n * });\n * }\n * ```\n */\nexport class UseCaseError extends CodedError {\n /**\n * Creates a new UseCaseError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error description\n * @param options.code - Machine-readable error code (default: 'USE_CASE_ERROR')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.USE_CASE_ERROR,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a UseCaseError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new UseCaseError instance with the cause attached\n */\n static override fromError(cause: unknown): UseCaseError {\n return new UseCaseError({\n message: cause instanceof Error ? cause.message : 'Use case error',\n cause,\n });\n }\n}\n","import { ErrorCodes, type AppErrorCode } from '../../global/exceptions/error-codes.const';\nimport { UseCaseError } from './use-case.error';\n\n/**\n * Error thrown when a requested resource does not exist.\n *\n * Indicates that the entity or resource referenced by the request\n * could not be found in the system.\n *\n * **When to throw:**\n * - Entity lookup by ID returns null\n * - Referenced resource doesn't exist\n * - Parent entity for a child operation not found\n *\n * @example\n * ```typescript\n * const user = await this.userRepo.findById(userId);\n * if (!user) {\n * throw new NotFoundError({\n * message: `User with ID ${userId} not found`,\n * code: 'USER_NOT_FOUND',\n * });\n * }\n * ```\n *\n * @extends UseCaseError\n */\nexport class NotFoundError extends UseCaseError {\n /**\n * Creates a new NotFoundError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of what was not found\n * @param options.code - Machine-readable error code (default: 'NOT_FOUND')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.NOT_FOUND,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a NotFoundError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new NotFoundError instance with the cause attached\n */\n static override fromError(cause: unknown): NotFoundError {\n return new NotFoundError({\n message: cause instanceof Error ? cause.message : 'Resource not found',\n cause,\n });\n }\n}\n","import { ErrorCodes, type AppErrorCode } from '../../global/exceptions/error-codes.const';\nimport { UseCaseError } from './use-case.error';\n\n/**\n * Error thrown when an operation conflicts with existing state.\n *\n * Indicates that the requested operation cannot be completed because\n * it would violate uniqueness constraints or cause state conflicts.\n *\n * **When to throw:**\n * - Duplicate unique field (e.g., email already registered)\n * - Optimistic locking conflict (stale version)\n * - Concurrent modification detected\n *\n * @example\n * ```typescript\n * const existing = await this.userRepo.findByEmail(email);\n * if (existing) {\n * throw new ConflictError({\n * message: 'Email already registered',\n * code: 'EMAIL_ALREADY_EXISTS',\n * });\n * }\n * ```\n *\n * @extends UseCaseError\n */\nexport class ConflictError extends UseCaseError {\n /**\n * Creates a new ConflictError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of the conflict\n * @param options.code - Machine-readable error code (default: 'CONFLICT')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.CONFLICT,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a ConflictError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new ConflictError instance with the cause attached\n */\n static override fromError(cause: unknown): ConflictError {\n return new ConflictError({\n message: cause instanceof Error ? cause.message : 'Conflict error',\n cause,\n });\n }\n}\n","import { ErrorCodes, type AppErrorCode } from '../../global/exceptions/error-codes.const';\nimport { UseCaseError } from './use-case.error';\n\n/**\n * Error thrown when a request is valid but cannot be processed.\n *\n * The request is syntactically correct and passes validation, but\n * business logic prevents the operation from being completed.\n *\n * **When to throw:**\n * - Business rule prevents operation (e.g., insufficient balance)\n * - Invalid state transition (e.g., canceling a completed order)\n * - Preconditions not met for the operation\n *\n * @example\n * ```typescript\n * if (account.balance < amount) {\n * throw new UnprocessableError({\n * message: 'Insufficient balance for withdrawal',\n * code: 'INSUFFICIENT_BALANCE',\n * });\n * }\n * ```\n *\n * @extends UseCaseError\n */\nexport class UnprocessableError extends UseCaseError {\n /**\n * Creates a new UnprocessableError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of why the request cannot be processed\n * @param options.code - Machine-readable error code (default: 'UNPROCESSABLE')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.UNPROCESSABLE,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates an UnprocessableError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new UnprocessableError instance with the cause attached\n */\n static override fromError(cause: unknown): UnprocessableError {\n return new UnprocessableError({\n message: cause instanceof Error ? cause.message : 'Unprocessable request',\n cause,\n });\n }\n}\n","import { ErrorCodes, type AppErrorCode } from '../../global/exceptions/error-codes.const';\nimport { UseCaseError } from './use-case.error';\n\n/**\n * Error thrown when authorization for an operation is denied.\n *\n * Indicates that the user is authenticated but lacks permission to perform\n * the requested operation. Commonly thrown from the `authorize()` method\n * of use cases when access checks fail.\n *\n * **When to throw:**\n * - User doesn't own the resource they're trying to modify\n * - User lacks required role or permission\n * - Organization/tenant isolation violation\n * - Business rule restricts the operation for this user\n *\n * **Difference from AccessDeniedError:**\n * - `ForbiddenError` is an application layer error (use case authorization)\n * - `AccessDeniedError` is a presentation layer error (controller/guard level)\n *\n * @example Use case authorization\n * ```typescript\n * class UpdateActivityUseCase extends BaseInboundAdapter<Input, Output, AuthContext> {\n * protected async authorize(input: Input): Promise<AuthContext> {\n * const activity = await this.activityRepo.findById(input.activityId);\n * if (!activity) {\n * throw new NotFoundError({ message: 'Activity not found' });\n * }\n * if (activity.organizationId !== input.organizationId) {\n * throw new ForbiddenError({\n * message: 'Not authorized to modify this activity',\n * code: 'ACTIVITY_ACCESS_DENIED',\n * });\n * }\n * return { activity };\n * }\n * }\n * ```\n *\n * @example Role-based authorization\n * ```typescript\n * if (!user.roles.includes('admin')) {\n * throw new ForbiddenError({\n * message: 'Admin role required for this operation',\n * });\n * }\n * ```\n *\n * @extends UseCaseError\n */\nexport class ForbiddenError extends UseCaseError {\n /**\n * Creates a new ForbiddenError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of why authorization was denied\n * @param options.code - Machine-readable error code (default: 'FORBIDDEN')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.FORBIDDEN,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a ForbiddenError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new ForbiddenError instance with the cause attached\n */\n static override fromError(cause: unknown): ForbiddenError {\n return new ForbiddenError({\n message: cause instanceof Error ? cause.message : 'Operation forbidden',\n cause,\n });\n }\n}\n","import { ErrorCodes, type AppErrorCode } from '../../global/exceptions/error-codes.const';\nimport { UseCaseError } from './use-case.error';\n\n/**\n * Error thrown when authentication is required or invalid.\n *\n * Indicates that the user is not authenticated or their authentication\n * credentials are invalid/expired. This is different from `ForbiddenError`\n * which is for authenticated users who lack permission.\n *\n * **When to throw:**\n * - User is not logged in but authentication is required\n * - Authentication token is missing, invalid, or expired\n * - Session has been invalidated\n * - API key is invalid or revoked\n *\n * **Difference from ForbiddenError:**\n * - `UnauthorizedError` (401) = Not authenticated (who are you?)\n * - `ForbiddenError` (403) = Authenticated but not authorized (you can't do this)\n *\n * @example Missing authentication\n * ```typescript\n * protected async authorize(input: Input): Promise<AuthContext> {\n * if (!input.userId) {\n * throw new UnauthorizedError({ message: 'Authentication required' });\n * }\n *\n * const user = await this.userRepo.findById(input.userId);\n * if (!user) {\n * throw new UnauthorizedError({ message: 'Invalid user credentials' });\n * }\n *\n * return { user };\n * }\n * ```\n *\n * @example Token validation\n * ```typescript\n * if (!token || isTokenExpired(token)) {\n * throw new UnauthorizedError({\n * message: 'Session expired, please log in again',\n * code: 'SESSION_EXPIRED',\n * });\n * }\n * ```\n *\n * @extends UseCaseError\n */\nexport class UnauthorizedError extends UseCaseError {\n /**\n * Creates a new UnauthorizedError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of why authentication failed\n * @param options.code - Machine-readable error code (default: 'UNAUTHORIZED')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.UNAUTHORIZED,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates an UnauthorizedError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new UnauthorizedError instance with the cause attached\n */\n static override fromError(cause: unknown): UnauthorizedError {\n return new UnauthorizedError({\n message: cause instanceof Error ? cause.message : 'Authentication required',\n cause,\n });\n }\n}\n","import { CodedError } from '../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type InfraErrorCode } from '../../global/exceptions/error-codes.const';\n\n/**\n * Base error class for infrastructure layer failures.\n *\n * Infrastructure errors represent failures in external dependencies\n * such as databases, network services, file systems, or third-party APIs.\n * They are automatically created by {@link BaseOutboundAdapter} when\n * repository or gateway methods fail.\n *\n * **When to throw:**\n * - Database connection or query failures\n * - Network timeouts or connection errors\n * - External API failures\n * - File system errors\n *\n * **Child classes:**\n * - {@link DbError} - Database operation failures\n * - {@link NetworkError} - Network connectivity issues\n * - {@link TimeoutError} - Operation timeout\n * - {@link ExternalServiceError} - Third-party service failures\n *\n * @example\n * ```typescript\n * // In a repository extending BaseOutboundAdapter\n * protected override createInfraError(error: unknown, methodName: string): InfraError {\n * return new DbError({\n * message: `Database error in ${methodName}`,\n * cause: error,\n * });\n * }\n * ```\n */\nexport class InfraError extends CodedError {\n /**\n * Creates a new InfraError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error description\n * @param options.code - Machine-readable error code (default: 'INFRA_ERROR')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Infra.INFRA_ERROR,\n cause,\n }: {\n message: string;\n code?: InfraErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates an InfraError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new InfraError instance with the cause attached\n */\n static override fromError(cause: unknown): InfraError {\n return new InfraError({\n message: cause instanceof Error ? cause.message : 'Infrastructure error',\n cause,\n });\n }\n}\n","import { CodedError } from '../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type PresentationErrorCode } from '../../global/exceptions/error-codes.const';\n\n/**\n * Base error class for presentation layer (controller) failures.\n *\n * Controller errors represent failures in request handling,\n * such as access control violations or malformed requests.\n * They are the outermost error layer and typically map to HTTP responses.\n *\n * **When to throw:**\n * - Access control failures (unauthorized/forbidden)\n * - Request validation failures\n * - Unexpected controller execution errors\n *\n * **Child classes:**\n * - {@link AccessDeniedError} - Authorization failures (HTTP 403)\n * - {@link InvalidRequestError} - Request validation failures (HTTP 400)\n *\n * @example\n * ```typescript\n * // Thrown automatically by BaseController for unexpected errors\n * throw new ControllerError({\n * message: 'Controller execution failed',\n * cause: originalError,\n * });\n * ```\n */\nexport class ControllerError extends CodedError {\n /**\n * Creates a new ControllerError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error description\n * @param options.code - Machine-readable error code (default: 'CONTROLLER_ERROR')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Presentation.CONTROLLER_ERROR,\n cause,\n }: {\n message: string;\n code?: PresentationErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a ControllerError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new ControllerError instance with the cause attached\n */\n static override fromError(cause: unknown): ControllerError {\n return new ControllerError({\n message: cause instanceof Error ? cause.message : 'Controller error',\n cause,\n });\n }\n}\n","import { CodedError } from '../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type PresentationErrorCode } from '../../global/exceptions/error-codes.const';\n\n/**\n * Error thrown when access to a resource is denied.\n *\n * Indicates that the requester does not have permission to perform\n * the requested operation. Thrown by {@link GuardedController} when\n * an access guard returns `isAllowed: false`.\n *\n * **When thrown:**\n * - Access guard denies the request\n * - User lacks required permissions\n * - Resource ownership check fails\n *\n * @example GuardedController usage\n * ```typescript\n * const controller = GuardedController.create({\n * accessGuard: (req) => ({\n * isAllowed: req.user?.role === 'admin',\n * reason: 'Admin access required',\n * }),\n * // ... other config\n * });\n * ```\n *\n * @example Manual usage\n * ```typescript\n * if (!user.canAccess(resource)) {\n * throw new AccessDeniedError({\n * message: 'You do not have access to this resource',\n * code: 'RESOURCE_ACCESS_DENIED',\n * });\n * }\n * ```\n *\n * @extends CodedError\n */\nexport class AccessDeniedError extends CodedError {\n /**\n * Creates a new AccessDeniedError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of why access was denied\n * @param options.code - Machine-readable error code (default: 'ACCESS_DENIED')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Presentation.ACCESS_DENIED,\n cause,\n }: {\n message: string;\n code?: PresentationErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates an AccessDeniedError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new AccessDeniedError instance with the cause attached\n */\n static override fromError(cause: unknown): AccessDeniedError {\n return new AccessDeniedError({\n message: cause instanceof Error ? cause.message : 'Access denied',\n cause,\n });\n }\n}\n","import { CodedError } from '../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type PresentationErrorCode } from '../../global/exceptions/error-codes.const';\nimport type { ValidationError } from '../../global/interfaces/types/validation-error.type';\n\n/**\n * Error thrown when request validation fails at the controller level.\n *\n * Contains structured validation errors with field paths and messages,\n * converted from {@link ObjectValidationError} by {@link BaseController}.\n * Provides detailed feedback about which fields failed validation.\n *\n * **When thrown:**\n * - Request DTO validation fails\n * - Malformed request data\n * - Missing required fields\n *\n * @example\n * ```typescript\n * // Automatically thrown by BaseController when DTO validation fails\n * // The validationErrors array contains field-level details:\n * // [\n * // { field: 'email', message: 'Invalid email format' },\n * // { field: 'age', message: 'Must be a positive number' }\n * // ]\n * ```\n *\n * @example Manual usage\n * ```typescript\n * throw new InvalidRequestError({\n * message: 'Request validation failed',\n * validationErrors: [\n * { field: 'username', message: 'Username is required' },\n * ],\n * });\n * ```\n *\n * @extends CodedError\n */\nexport class InvalidRequestError extends CodedError {\n /**\n * Array of field-level validation errors.\n *\n * Each entry contains:\n * - `field`: Dot-notation path to the invalid field\n * - `message`: Human-readable validation failure message\n */\n readonly validationErrors: ValidationError[];\n\n /**\n * Creates a new InvalidRequestError instance.\n *\n * @param options - Error configuration\n * @param options.message - Summary of the validation failure\n * @param options.code - Machine-readable error code (default: 'INVALID_REQUEST')\n * @param options.cause - Optional underlying error\n * @param options.validationErrors - Array of field-level validation errors\n */\n constructor({\n message,\n code = ErrorCodes.Presentation.INVALID_REQUEST,\n cause,\n validationErrors,\n }: {\n message: string;\n code?: PresentationErrorCode | string;\n cause?: unknown;\n validationErrors: ValidationError[];\n }) {\n super({ message, code, cause });\n this.validationErrors = validationErrors;\n }\n\n /**\n * Creates an InvalidRequestError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new InvalidRequestError instance with the cause attached\n */\n static override fromError(cause: unknown): InvalidRequestError {\n return new InvalidRequestError({\n message: cause instanceof Error ? cause.message : 'Invalid request',\n cause,\n validationErrors: [],\n });\n }\n}\n","/**\n * @fileoverview Centralized error mapping for HTTP frameworks.\n *\n * Provides a single source of truth for mapping onion-lasagna errors\n * to HTTP status codes and response bodies.\n *\n * @module http/shared/error-mapping\n */\n\nimport { CodedError } from '../../../global/exceptions/coded-error.error';\nimport { ObjectValidationError } from '../../../global/exceptions/object-validation.error';\nimport { DomainError } from '../../../domain/exceptions/domain.error';\nimport { UseCaseError } from '../../../app/exceptions/use-case.error';\nimport { NotFoundError } from '../../../app/exceptions/not-found.error';\nimport { ConflictError } from '../../../app/exceptions/conflict.error';\nimport { UnprocessableError } from '../../../app/exceptions/unprocessable.error';\nimport { ForbiddenError } from '../../../app/exceptions/forbidden.error';\nimport { UnauthorizedError } from '../../../app/exceptions/unauthorized.error';\nimport { InfraError } from '../../../infra/exceptions/infra.error';\nimport { ControllerError } from '../../exceptions/controller.error';\nimport { AccessDeniedError } from '../../exceptions/access-denied.error';\nimport { InvalidRequestError } from '../../exceptions/invalid-request.error';\nimport type { ErrorResponseBody, MappedErrorResponse } from './types';\n\n// ============================================================================\n// Constants and Interfaces\n// ============================================================================\n\n/**\n * Default masked error response for internal errors.\n */\nconst MASKED_ERROR_BODY: ErrorResponseBody = {\n message: 'An unexpected error occurred',\n errorCode: 'INTERNAL_ERROR',\n};\n\n/**\n * Known internal error type names that should be masked.\n */\nconst INTERNAL_ERROR_TYPES = [\n 'DomainError',\n 'InfraError',\n 'ControllerError',\n 'NetworkError',\n 'PersistenceError',\n 'ExternalServiceError',\n 'InvariantViolationError',\n];\n\n/**\n * Validation error item structure.\n */\ninterface ValidationErrorInput {\n field: string;\n message: string;\n}\n\n/**\n * Validation error structure for string-based checking.\n */\ninterface ValidationErrorItem {\n field: string;\n message: string;\n}\n\n/**\n * Interface for errors with validation items.\n */\ninterface ErrorWithValidation {\n message: string;\n code: string;\n validationErrors: ValidationErrorItem[];\n}\n\n/**\n * Interface for coded errors.\n */\ninterface CodedErrorLike {\n message: string;\n code: string;\n}\n\n// ============================================================================\n// String-based type checking helpers (for bundled code compatibility)\n// ============================================================================\n\n/**\n * Checks if error matches a specific error type by checking its constructor name.\n * This approach avoids issues with multiple class instances in bundled code.\n * Handles both original names and tsup's mangled names (prefixed with _).\n *\n * @param error - The error to check\n * @param typeName - The error type name to match\n * @returns True if error matches the type name\n */\nexport function isErrorType(error: unknown, typeName: string): error is CodedErrorLike {\n if (!error || typeof error !== 'object') return false;\n // Guard against objects without constructor (e.g., Object.create(null))\n const constructor = Object.prototype.hasOwnProperty.call(error, 'constructor')\n ? (error as { constructor?: { name?: string } }).constructor\n : Object.getPrototypeOf(error)?.constructor;\n if (!constructor) return false;\n const name = constructor.name;\n // Check both the original name and the mangled name (tsup prefixes with _)\n return name === typeName || name === `_${typeName}`;\n}\n\n/**\n * Checks if error has validation errors array.\n *\n * @param error - The error to check\n * @returns True if error has validationErrors property\n */\nexport function hasValidationErrors(error: unknown): error is ErrorWithValidation {\n if (!error || typeof error !== 'object') return false;\n return (\n 'validationErrors' in error && Array.isArray((error as ErrorWithValidation).validationErrors)\n );\n}\n\n// ============================================================================\n// Response body builders\n// ============================================================================\n\n/**\n * Builds a validation error response body from error details.\n *\n * This is a shared helper used by both instanceof-based and string-based\n * error mapping functions to avoid duplication.\n *\n * @param message - The error message\n * @param code - The error code\n * @param validationErrors - Array of field validation errors\n * @returns Error response body with errorItems\n */\nfunction buildValidationErrorBody(\n message: string,\n code: string,\n validationErrors: readonly ValidationErrorInput[],\n): ErrorResponseBody {\n return {\n message,\n errorCode: code,\n errorItems: validationErrors.map((e) => ({\n item: e.field,\n message: e.message,\n })),\n };\n}\n\n/**\n * Builds a simple error response body from error details.\n *\n * @param message - The error message\n * @param code - The error code\n * @returns Error response body\n */\nfunction buildSimpleErrorBody(message: string, code: string): ErrorResponseBody {\n return {\n message,\n errorCode: code,\n };\n}\n\n// ============================================================================\n// Primary error mapping functions (with bundled code fallback)\n// ============================================================================\n\n/**\n * Maps an error to the appropriate HTTP status code.\n * Uses instanceof first, then falls back to name-based checking for bundled code.\n *\n * @param error - The error to map\n * @returns HTTP status code\n */\nexport function getHttpStatusCode(error: unknown): number {\n // Try instanceof first (faster)\n if (error instanceof ObjectValidationError) return 400;\n if (error instanceof InvalidRequestError) return 400;\n if (error instanceof UnauthorizedError) return 401;\n if (error instanceof ForbiddenError) return 403;\n if (error instanceof AccessDeniedError) return 403;\n if (error instanceof NotFoundError) return 404;\n if (error instanceof ConflictError) return 409;\n if (error instanceof UnprocessableError) return 422;\n if (error instanceof UseCaseError) return 400;\n\n // Fall back to name-based checking for bundled code (e.g., _NotFoundError)\n if (isErrorType(error, 'ObjectValidationError')) return 400;\n if (isErrorType(error, 'InvalidRequestError')) return 400;\n if (isErrorType(error, 'UnauthorizedError')) return 401;\n if (isErrorType(error, 'ForbiddenError')) return 403;\n if (isErrorType(error, 'AccessDeniedError')) return 403;\n if (isErrorType(error, 'NotFoundError')) return 404;\n if (isErrorType(error, 'ConflictError')) return 409;\n if (isErrorType(error, 'UnprocessableError')) return 422;\n if (isErrorType(error, 'UseCaseError')) return 400;\n\n return 500;\n}\n\n/**\n * Checks if an error should have its details masked in the response.\n *\n * Security-sensitive errors (domain, infrastructure, controller) are masked\n * to prevent leaking implementation details.\n * Uses instanceof first, then falls back to name-based checking for bundled code.\n *\n * @param error - The error to check\n * @returns True if error details should be hidden\n */\nexport function shouldMaskError(error: unknown): boolean {\n // Try instanceof first (faster)\n if (\n error instanceof DomainError ||\n error instanceof InfraError ||\n error instanceof ControllerError\n ) {\n return true;\n }\n\n // Fall back to name-based checking for bundled code\n for (const errorType of INTERNAL_ERROR_TYPES) {\n if (isErrorType(error, errorType)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Creates the response body for an error.\n * Uses instanceof first, then falls back to name-based checking for bundled code.\n *\n * @param error - The error to create body for\n * @returns Error response body\n */\nexport function createErrorResponseBody(error: unknown): ErrorResponseBody {\n // Masked errors - hide internal details\n if (shouldMaskError(error)) {\n return MASKED_ERROR_BODY;\n }\n\n // Validation errors - include field details (try instanceof first)\n if (error instanceof ObjectValidationError) {\n return buildValidationErrorBody(error.message, error.code, error.validationErrors);\n }\n if (error instanceof InvalidRequestError) {\n return buildValidationErrorBody(error.message, error.code, error.validationErrors);\n }\n\n // Validation errors - fall back to name-based checking for bundled code\n if (isErrorType(error, 'ObjectValidationError') && hasValidationErrors(error)) {\n return buildValidationErrorBody(error.message, error.code, error.validationErrors);\n }\n if (isErrorType(error, 'InvalidRequestError') && hasValidationErrors(error)) {\n return buildValidationErrorBody(error.message, error.code, error.validationErrors);\n }\n\n // Other coded errors - expose message and code (try instanceof first)\n if (error instanceof CodedError) {\n return buildSimpleErrorBody(error.message, error.code);\n }\n\n // Other coded errors - fall back to name-based checking\n if (isErrorType(error, 'CodedError')) {\n return buildSimpleErrorBody(error.message, error.code);\n }\n\n // Check for any error with message and code properties\n if (\n error &&\n typeof error === 'object' &&\n 'message' in error &&\n 'code' in error &&\n typeof (error as CodedErrorLike).message === 'string' &&\n typeof (error as CodedErrorLike).code === 'string'\n ) {\n return buildSimpleErrorBody((error as CodedErrorLike).message, (error as CodedErrorLike).code);\n }\n\n // Unknown errors - mask\n return MASKED_ERROR_BODY;\n}\n\n/**\n * Maps an error to a complete HTTP response structure.\n *\n * Mapping strategy:\n * - `ObjectValidationError` → 400 Bad Request (with field errors)\n * - `InvalidRequestError` → 400 Bad Request (with field errors)\n * - `UseCaseError` → 400 Bad Request\n * - `UnauthorizedError` → 401 Unauthorized (authentication required/invalid)\n * - `ForbiddenError` → 403 Forbidden (authorization denied in use case)\n * - `AccessDeniedError` → 403 Forbidden (access denied at controller/guard level)\n * - `NotFoundError` → 404 Not Found\n * - `ConflictError` → 409 Conflict\n * - `UnprocessableError` → 422 Unprocessable Entity\n * - `DomainError` → 500 Internal Server Error (masked)\n * - `InfraError` → 500 Internal Server Error (masked)\n * - `ControllerError` → 500 Internal Server Error (masked)\n * - Unknown → 500 Internal Server Error (masked)\n *\n * @param error - The error to map\n * @returns Mapped error response with status and body\n */\nexport function mapErrorToHttpResponse(error: unknown): MappedErrorResponse {\n return {\n status: getHttpStatusCode(error),\n body: createErrorResponseBody(error),\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/http/shared/index.ts","../../../src/global/exceptions/coded-error.error.ts","../../../src/global/exceptions/error-codes.const.ts","../../../src/global/exceptions/object-validation.error.ts","../../../src/domain/exceptions/domain.error.ts","../../../src/app/exceptions/use-case.error.ts","../../../src/app/exceptions/not-found.error.ts","../../../src/app/exceptions/conflict.error.ts","../../../src/app/exceptions/unprocessable.error.ts","../../../src/app/exceptions/forbidden.error.ts","../../../src/app/exceptions/unauthorized.error.ts","../../../src/infra/exceptions/infra.error.ts","../../../src/presentation/exceptions/controller.error.ts","../../../src/presentation/exceptions/access-denied.error.ts","../../../src/presentation/exceptions/invalid-request.error.ts","../../../src/presentation/http/shared/error-mapping.ts"],"sourcesContent":["/**\n * @fileoverview Shared utilities for HTTP framework adapters.\n *\n * @module http/shared\n */\n\nexport * from './error-mapping';\nexport * from './types';\n","import type { ErrorCode } from './error-codes.const';\n\n/**\n * Base error class for all application errors with a machine-readable code.\n *\n * Abstract class that extends the native `Error` with:\n * - A `code` property for programmatic error handling\n * - Optional `cause` for error chaining (ES2022 compatible)\n * - A `fromError` static factory pattern for error transformation\n *\n * **Why abstract:** Prevents non-declarative error usage. All errors must\n * be explicitly defined as subclasses to ensure consistent error taxonomy.\n *\n * @example Subclass implementation\n * ```typescript\n * class DbError extends InfraError {\n * static override fromError(cause: unknown): DbError {\n * return new DbError({\n * message: cause instanceof Error ? cause.message : 'Database error',\n * cause,\n * });\n * }\n * }\n * ```\n *\n * @example Usage with wrapErrorAsync\n * ```typescript\n * await wrapErrorAsync(\n * () => this.db.query(...),\n * DbError.fromError,\n * );\n * ```\n */\nexport abstract class CodedError extends Error {\n /** Machine-readable error code for programmatic handling. */\n public readonly code: ErrorCode | string;\n\n /**\n * Creates a new CodedError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error message\n * @param options.code - Machine-readable error code from ErrorCodes registry or custom string\n * @param options.cause - Optional underlying error that caused this error\n */\n constructor({\n message,\n code,\n cause,\n }: {\n message: string;\n code: ErrorCode | string;\n cause?: unknown;\n }) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n if (cause !== undefined) {\n Object.defineProperty(this, 'cause', {\n value: cause,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n }\n }\n\n /**\n * Factory method to create a typed error from a caught error.\n *\n * Subclasses should override this to provide proper error transformation.\n * Designed for use with {@link wrapErrorAsync} and {@link wrapError}.\n *\n * @param _cause - The original caught error\n * @returns A new CodedError instance\n * @throws {Error} If not overridden by subclass\n *\n * @example\n * ```typescript\n * class NotFoundError extends UseCaseError {\n * static override fromError(cause: unknown): NotFoundError {\n * return new NotFoundError({\n * message: 'Resource not found',\n * cause,\n * });\n * }\n * }\n * ```\n */\n static fromError(_cause: unknown): CodedError {\n throw new Error(`${this.name}.fromError() must be implemented by subclass`);\n }\n}\n","/**\n * Centralized registry of all error codes used across the application.\n *\n * Error codes are grouped by architectural layer to maintain clear boundaries\n * and make it easy to identify where an error originated.\n *\n * @example Using error codes in custom errors\n * ```typescript\n * import { ErrorCodes } from '@cosmneo/onion-lasagna/global';\n *\n * throw new NotFoundError({\n * message: 'User not found',\n * code: ErrorCodes.App.NOT_FOUND,\n * });\n * ```\n *\n * @example Checking error codes programmatically\n * ```typescript\n * if (error.code === ErrorCodes.App.NOT_FOUND) {\n * // Handle not found case\n * }\n * ```\n */\nexport const ErrorCodes = {\n /**\n * Domain layer error codes.\n * Used for business rule violations and invariant failures.\n */\n Domain: {\n /** Generic domain error */\n DOMAIN_ERROR: 'DOMAIN_ERROR',\n /** Business invariant was violated */\n INVARIANT_VIOLATION: 'INVARIANT_VIOLATION',\n /** Aggregate was partially loaded (missing required relations) */\n PARTIAL_LOAD: 'PARTIAL_LOAD',\n },\n\n /**\n * Application layer (use case) error codes.\n * Used for orchestration failures and business operation errors.\n */\n App: {\n /** Generic use case error */\n USE_CASE_ERROR: 'USE_CASE_ERROR',\n /** Requested resource was not found */\n NOT_FOUND: 'NOT_FOUND',\n /** Resource state conflict (e.g., duplicate, already exists) */\n CONFLICT: 'CONFLICT',\n /** Request is valid but cannot be processed due to business rules */\n UNPROCESSABLE: 'UNPROCESSABLE',\n /** Authorization denied - user lacks permission for this operation */\n FORBIDDEN: 'FORBIDDEN',\n /** Authentication required or invalid - user is not authenticated */\n UNAUTHORIZED: 'UNAUTHORIZED',\n },\n\n /**\n * Infrastructure layer error codes.\n * Used for data access, external services, and I/O failures.\n */\n Infra: {\n /** Generic infrastructure error */\n INFRA_ERROR: 'INFRA_ERROR',\n /** Database operation failed */\n DB_ERROR: 'DB_ERROR',\n /** Network connectivity or communication error */\n NETWORK_ERROR: 'NETWORK_ERROR',\n /** Operation timed out */\n TIMEOUT_ERROR: 'TIMEOUT_ERROR',\n /** External/third-party service error */\n EXTERNAL_SERVICE_ERROR: 'EXTERNAL_SERVICE_ERROR',\n },\n\n /**\n * Presentation layer error codes.\n * Used for controller, request handling, and authorization errors.\n */\n Presentation: {\n /** Generic controller error */\n CONTROLLER_ERROR: 'CONTROLLER_ERROR',\n /** Request denied due to authorization failure */\n ACCESS_DENIED: 'ACCESS_DENIED',\n /** Request validation failed (malformed input) */\n INVALID_REQUEST: 'INVALID_REQUEST',\n },\n\n /**\n * Global/cross-cutting error codes.\n * Used for validation and other cross-layer concerns.\n */\n Global: {\n /** Object/schema validation failed */\n OBJECT_VALIDATION_ERROR: 'OBJECT_VALIDATION_ERROR',\n },\n} as const;\n\n/**\n * Type representing all possible domain error codes.\n */\nexport type DomainErrorCode = (typeof ErrorCodes.Domain)[keyof typeof ErrorCodes.Domain];\n\n/**\n * Type representing all possible application error codes.\n */\nexport type AppErrorCode = (typeof ErrorCodes.App)[keyof typeof ErrorCodes.App];\n\n/**\n * Type representing all possible infrastructure error codes.\n */\nexport type InfraErrorCode = (typeof ErrorCodes.Infra)[keyof typeof ErrorCodes.Infra];\n\n/**\n * Type representing all possible presentation error codes.\n */\nexport type PresentationErrorCode =\n (typeof ErrorCodes.Presentation)[keyof typeof ErrorCodes.Presentation];\n\n/**\n * Type representing all possible global error codes.\n */\nexport type GlobalErrorCode = (typeof ErrorCodes.Global)[keyof typeof ErrorCodes.Global];\n\n/**\n * Union type of all error codes across all layers.\n *\n * Use this when you need to accept any valid error code.\n *\n * @example\n * ```typescript\n * function logError(code: ErrorCode, message: string) {\n * console.error(`[${code}] ${message}`);\n * }\n * ```\n */\nexport type ErrorCode =\n | DomainErrorCode\n | AppErrorCode\n | InfraErrorCode\n | PresentationErrorCode\n | GlobalErrorCode;\n","import { CodedError } from './coded-error.error';\nimport { ErrorCodes, type GlobalErrorCode } from './error-codes.const';\nimport type { ValidationError } from '../interfaces/types/validation-error.type';\n\n/**\n * Error thrown when object validation fails.\n *\n * Contains structured validation errors with field paths and messages,\n * making it easy to report specific validation failures to clients.\n * Thrown by all validator implementations (Zod, ArkType, TypeBox, Valibot).\n *\n * **Flow:**\n * 1. Validator throws `ObjectValidationError` with field-level errors\n * 2. Controller catches and converts to {@link InvalidRequestError}\n * 3. HTTP layer maps to 400 Bad Request with error details\n *\n * @example\n * ```typescript\n * try {\n * const dto = CreateUserDto.create(invalidData);\n * } catch (error) {\n * if (error instanceof ObjectValidationError) {\n * console.log(error.validationErrors);\n * // [\n * // { field: 'email', message: 'Invalid email format' },\n * // { field: 'age', message: 'Must be a positive number' }\n * // ]\n * }\n * }\n * ```\n */\nexport class ObjectValidationError extends CodedError {\n /**\n * Array of field-level validation errors.\n *\n * Each entry contains:\n * - `field`: Dot-notation path to the invalid field (e.g., 'user.email')\n * - `message`: Human-readable validation failure message\n */\n validationErrors: ValidationError[];\n\n /**\n * Creates a new ObjectValidationError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable summary message\n * @param options.code - Machine-readable error code (default: 'OBJECT_VALIDATION_ERROR')\n * @param options.cause - Optional underlying error from validation library\n * @param options.validationErrors - Array of field-level validation errors\n */\n constructor({\n message,\n code = ErrorCodes.Global.OBJECT_VALIDATION_ERROR,\n cause,\n validationErrors,\n }: {\n message: string;\n code?: GlobalErrorCode | string;\n cause?: unknown;\n validationErrors: ValidationError[];\n }) {\n super({ message, code, cause });\n this.validationErrors = validationErrors;\n }\n\n /**\n * Creates an ObjectValidationError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new ObjectValidationError instance with the cause attached\n */\n static override fromError(cause: unknown): ObjectValidationError {\n return new ObjectValidationError({\n message: cause instanceof Error ? cause.message : 'Validation failed',\n cause,\n validationErrors: [],\n });\n }\n}\n","import { CodedError } from '../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type DomainErrorCode } from '../../global/exceptions/error-codes.const';\n\n/**\n * Base error class for domain layer failures.\n *\n * Domain errors represent violations of business rules, invariants,\n * or aggregate consistency. They originate from the core domain logic\n * and should be caught and handled by the application layer.\n *\n * **When to throw:**\n * - Business rule violations (e.g., \"Cannot withdraw more than balance\")\n * - Invariant violations (e.g., \"Email format invalid\")\n * - Aggregate consistency failures\n *\n * **Child classes:**\n * - {@link InvariantViolationError} - Value object or entity invariant failures\n * - {@link PartialLoadError} - Incomplete aggregate reconstitution\n *\n * @example\n * ```typescript\n * if (account.balance < amount) {\n * throw new DomainError({\n * message: 'Insufficient funds for withdrawal',\n * code: 'INSUFFICIENT_FUNDS',\n * });\n * }\n * ```\n */\nexport class DomainError extends CodedError {\n /**\n * Creates a new DomainError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error description\n * @param options.code - Machine-readable error code (default: 'DOMAIN_ERROR')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Domain.DOMAIN_ERROR,\n cause,\n }: {\n message: string;\n code?: DomainErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a DomainError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new DomainError instance with the cause attached\n */\n static override fromError(cause: unknown): DomainError {\n return new DomainError({\n message: cause instanceof Error ? cause.message : 'Domain error',\n cause,\n });\n }\n}\n","import { CodedError } from '../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type AppErrorCode } from '../../global/exceptions/error-codes.const';\n\n/**\n * Base error class for application layer (use case) failures.\n *\n * Use case errors represent failures in the application's business logic\n * orchestration, such as resource conflicts, missing entities, or\n * unprocessable requests. They bridge domain errors to the presentation layer.\n *\n * **When to throw:**\n * - Resource not found (e.g., \"User with ID X not found\")\n * - Conflict states (e.g., \"Email already registered\")\n * - Unprocessable business operations\n *\n * **Child classes:**\n * - {@link ConflictError} - Resource state conflicts (HTTP 409)\n * - {@link NotFoundError} - Resource not found (HTTP 404)\n * - {@link UnprocessableError} - Valid but unprocessable request (HTTP 422)\n *\n * @example\n * ```typescript\n * const user = await this.userRepo.findById(id);\n * if (!user) {\n * throw new NotFoundError({\n * message: `User with ID ${id} not found`,\n * code: 'USER_NOT_FOUND',\n * });\n * }\n * ```\n */\nexport class UseCaseError extends CodedError {\n /**\n * Creates a new UseCaseError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error description\n * @param options.code - Machine-readable error code (default: 'USE_CASE_ERROR')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.USE_CASE_ERROR,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a UseCaseError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new UseCaseError instance with the cause attached\n */\n static override fromError(cause: unknown): UseCaseError {\n return new UseCaseError({\n message: cause instanceof Error ? cause.message : 'Use case error',\n cause,\n });\n }\n}\n","import { ErrorCodes, type AppErrorCode } from '../../global/exceptions/error-codes.const';\nimport { UseCaseError } from './use-case.error';\n\n/**\n * Error thrown when a requested resource does not exist.\n *\n * Indicates that the entity or resource referenced by the request\n * could not be found in the system.\n *\n * **When to throw:**\n * - Entity lookup by ID returns null\n * - Referenced resource doesn't exist\n * - Parent entity for a child operation not found\n *\n * @example\n * ```typescript\n * const user = await this.userRepo.findById(userId);\n * if (!user) {\n * throw new NotFoundError({\n * message: `User with ID ${userId} not found`,\n * code: 'USER_NOT_FOUND',\n * });\n * }\n * ```\n *\n * @extends UseCaseError\n */\nexport class NotFoundError extends UseCaseError {\n /**\n * Creates a new NotFoundError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of what was not found\n * @param options.code - Machine-readable error code (default: 'NOT_FOUND')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.NOT_FOUND,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a NotFoundError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new NotFoundError instance with the cause attached\n */\n static override fromError(cause: unknown): NotFoundError {\n return new NotFoundError({\n message: cause instanceof Error ? cause.message : 'Resource not found',\n cause,\n });\n }\n}\n","import { ErrorCodes, type AppErrorCode } from '../../global/exceptions/error-codes.const';\nimport { UseCaseError } from './use-case.error';\n\n/**\n * Error thrown when an operation conflicts with existing state.\n *\n * Indicates that the requested operation cannot be completed because\n * it would violate uniqueness constraints or cause state conflicts.\n *\n * **When to throw:**\n * - Duplicate unique field (e.g., email already registered)\n * - Optimistic locking conflict (stale version)\n * - Concurrent modification detected\n *\n * @example\n * ```typescript\n * const existing = await this.userRepo.findByEmail(email);\n * if (existing) {\n * throw new ConflictError({\n * message: 'Email already registered',\n * code: 'EMAIL_ALREADY_EXISTS',\n * });\n * }\n * ```\n *\n * @extends UseCaseError\n */\nexport class ConflictError extends UseCaseError {\n /**\n * Creates a new ConflictError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of the conflict\n * @param options.code - Machine-readable error code (default: 'CONFLICT')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.CONFLICT,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a ConflictError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new ConflictError instance with the cause attached\n */\n static override fromError(cause: unknown): ConflictError {\n return new ConflictError({\n message: cause instanceof Error ? cause.message : 'Conflict error',\n cause,\n });\n }\n}\n","import { ErrorCodes, type AppErrorCode } from '../../global/exceptions/error-codes.const';\nimport { UseCaseError } from './use-case.error';\n\n/**\n * Error thrown when a request is valid but cannot be processed.\n *\n * The request is syntactically correct and passes validation, but\n * business logic prevents the operation from being completed.\n *\n * **When to throw:**\n * - Business rule prevents operation (e.g., insufficient balance)\n * - Invalid state transition (e.g., canceling a completed order)\n * - Preconditions not met for the operation\n *\n * @example\n * ```typescript\n * if (account.balance < amount) {\n * throw new UnprocessableError({\n * message: 'Insufficient balance for withdrawal',\n * code: 'INSUFFICIENT_BALANCE',\n * });\n * }\n * ```\n *\n * @extends UseCaseError\n */\nexport class UnprocessableError extends UseCaseError {\n /**\n * Creates a new UnprocessableError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of why the request cannot be processed\n * @param options.code - Machine-readable error code (default: 'UNPROCESSABLE')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.UNPROCESSABLE,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates an UnprocessableError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new UnprocessableError instance with the cause attached\n */\n static override fromError(cause: unknown): UnprocessableError {\n return new UnprocessableError({\n message: cause instanceof Error ? cause.message : 'Unprocessable request',\n cause,\n });\n }\n}\n","import { ErrorCodes, type AppErrorCode } from '../../global/exceptions/error-codes.const';\nimport { UseCaseError } from './use-case.error';\n\n/**\n * Error thrown when authorization for an operation is denied.\n *\n * Indicates that the user is authenticated but lacks permission to perform\n * the requested operation. Commonly thrown from the `authorize()` method\n * of use cases when access checks fail.\n *\n * **When to throw:**\n * - User doesn't own the resource they're trying to modify\n * - User lacks required role or permission\n * - Organization/tenant isolation violation\n * - Business rule restricts the operation for this user\n *\n * **Difference from AccessDeniedError:**\n * - `ForbiddenError` is an application layer error (use case authorization)\n * - `AccessDeniedError` is a presentation layer error (controller/guard level)\n *\n * @example Use case authorization\n * ```typescript\n * class UpdateActivityUseCase extends BaseInboundAdapter<Input, Output, AuthContext> {\n * protected async authorize(input: Input): Promise<AuthContext> {\n * const activity = await this.activityRepo.findById(input.activityId);\n * if (!activity) {\n * throw new NotFoundError({ message: 'Activity not found' });\n * }\n * if (activity.organizationId !== input.organizationId) {\n * throw new ForbiddenError({\n * message: 'Not authorized to modify this activity',\n * code: 'ACTIVITY_ACCESS_DENIED',\n * });\n * }\n * return { activity };\n * }\n * }\n * ```\n *\n * @example Role-based authorization\n * ```typescript\n * if (!user.roles.includes('admin')) {\n * throw new ForbiddenError({\n * message: 'Admin role required for this operation',\n * });\n * }\n * ```\n *\n * @extends UseCaseError\n */\nexport class ForbiddenError extends UseCaseError {\n /**\n * Creates a new ForbiddenError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of why authorization was denied\n * @param options.code - Machine-readable error code (default: 'FORBIDDEN')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.FORBIDDEN,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a ForbiddenError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new ForbiddenError instance with the cause attached\n */\n static override fromError(cause: unknown): ForbiddenError {\n return new ForbiddenError({\n message: cause instanceof Error ? cause.message : 'Operation forbidden',\n cause,\n });\n }\n}\n","import { ErrorCodes, type AppErrorCode } from '../../global/exceptions/error-codes.const';\nimport { UseCaseError } from './use-case.error';\n\n/**\n * Error thrown when authentication is required or invalid.\n *\n * Indicates that the user is not authenticated or their authentication\n * credentials are invalid/expired. This is different from `ForbiddenError`\n * which is for authenticated users who lack permission.\n *\n * **When to throw:**\n * - User is not logged in but authentication is required\n * - Authentication token is missing, invalid, or expired\n * - Session has been invalidated\n * - API key is invalid or revoked\n *\n * **Difference from ForbiddenError:**\n * - `UnauthorizedError` (401) = Not authenticated (who are you?)\n * - `ForbiddenError` (403) = Authenticated but not authorized (you can't do this)\n *\n * @example Missing authentication\n * ```typescript\n * protected async authorize(input: Input): Promise<AuthContext> {\n * if (!input.userId) {\n * throw new UnauthorizedError({ message: 'Authentication required' });\n * }\n *\n * const user = await this.userRepo.findById(input.userId);\n * if (!user) {\n * throw new UnauthorizedError({ message: 'Invalid user credentials' });\n * }\n *\n * return { user };\n * }\n * ```\n *\n * @example Token validation\n * ```typescript\n * if (!token || isTokenExpired(token)) {\n * throw new UnauthorizedError({\n * message: 'Session expired, please log in again',\n * code: 'SESSION_EXPIRED',\n * });\n * }\n * ```\n *\n * @extends UseCaseError\n */\nexport class UnauthorizedError extends UseCaseError {\n /**\n * Creates a new UnauthorizedError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of why authentication failed\n * @param options.code - Machine-readable error code (default: 'UNAUTHORIZED')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.UNAUTHORIZED,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates an UnauthorizedError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new UnauthorizedError instance with the cause attached\n */\n static override fromError(cause: unknown): UnauthorizedError {\n return new UnauthorizedError({\n message: cause instanceof Error ? cause.message : 'Authentication required',\n cause,\n });\n }\n}\n","import { CodedError } from '../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type InfraErrorCode } from '../../global/exceptions/error-codes.const';\n\n/**\n * Base error class for infrastructure layer failures.\n *\n * Infrastructure errors represent failures in external dependencies\n * such as databases, network services, file systems, or third-party APIs.\n * They are automatically created by {@link BaseOutboundAdapter} when\n * repository or gateway methods fail.\n *\n * **When to throw:**\n * - Database connection or query failures\n * - Network timeouts or connection errors\n * - External API failures\n * - File system errors\n *\n * **Child classes:**\n * - {@link DbError} - Database operation failures\n * - {@link NetworkError} - Network connectivity issues\n * - {@link TimeoutError} - Operation timeout\n * - {@link ExternalServiceError} - Third-party service failures\n *\n * @example\n * ```typescript\n * // In a repository extending BaseOutboundAdapter\n * protected override createInfraError(error: unknown, methodName: string): InfraError {\n * return new DbError({\n * message: `Database error in ${methodName}`,\n * cause: error,\n * });\n * }\n * ```\n */\nexport class InfraError extends CodedError {\n /**\n * Creates a new InfraError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error description\n * @param options.code - Machine-readable error code (default: 'INFRA_ERROR')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Infra.INFRA_ERROR,\n cause,\n }: {\n message: string;\n code?: InfraErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates an InfraError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new InfraError instance with the cause attached\n */\n static override fromError(cause: unknown): InfraError {\n return new InfraError({\n message: cause instanceof Error ? cause.message : 'Infrastructure error',\n cause,\n });\n }\n}\n","import { CodedError } from '../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type PresentationErrorCode } from '../../global/exceptions/error-codes.const';\n\n/**\n * Base error class for presentation layer (controller) failures.\n *\n * Controller errors represent failures in request handling,\n * such as access control violations or malformed requests.\n * They are the outermost error layer and typically map to HTTP responses.\n *\n * **When to throw:**\n * - Access control failures (unauthorized/forbidden)\n * - Request validation failures\n * - Unexpected controller execution errors\n *\n * **Child classes:**\n * - {@link AccessDeniedError} - Authorization failures (HTTP 403)\n * - {@link InvalidRequestError} - Request validation failures (HTTP 400)\n *\n * @example\n * ```typescript\n * // Thrown automatically by BaseController for unexpected errors\n * throw new ControllerError({\n * message: 'Controller execution failed',\n * cause: originalError,\n * });\n * ```\n */\nexport class ControllerError extends CodedError {\n /**\n * Creates a new ControllerError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error description\n * @param options.code - Machine-readable error code (default: 'CONTROLLER_ERROR')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Presentation.CONTROLLER_ERROR,\n cause,\n }: {\n message: string;\n code?: PresentationErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a ControllerError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new ControllerError instance with the cause attached\n */\n static override fromError(cause: unknown): ControllerError {\n return new ControllerError({\n message: cause instanceof Error ? cause.message : 'Controller error',\n cause,\n });\n }\n}\n","import { CodedError } from '../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type PresentationErrorCode } from '../../global/exceptions/error-codes.const';\n\n/**\n * Error thrown when access to a resource is denied.\n *\n * Indicates that the requester does not have permission to perform\n * the requested operation. Thrown by {@link GuardedController} when\n * an access guard returns `isAllowed: false`.\n *\n * **When thrown:**\n * - Access guard denies the request\n * - User lacks required permissions\n * - Resource ownership check fails\n *\n * @example GuardedController usage\n * ```typescript\n * const controller = GuardedController.create({\n * accessGuard: (req) => ({\n * isAllowed: req.user?.role === 'admin',\n * reason: 'Admin access required',\n * }),\n * // ... other config\n * });\n * ```\n *\n * @example Manual usage\n * ```typescript\n * if (!user.canAccess(resource)) {\n * throw new AccessDeniedError({\n * message: 'You do not have access to this resource',\n * code: 'RESOURCE_ACCESS_DENIED',\n * });\n * }\n * ```\n *\n * @extends CodedError\n */\nexport class AccessDeniedError extends CodedError {\n /**\n * Creates a new AccessDeniedError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of why access was denied\n * @param options.code - Machine-readable error code (default: 'ACCESS_DENIED')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Presentation.ACCESS_DENIED,\n cause,\n }: {\n message: string;\n code?: PresentationErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates an AccessDeniedError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new AccessDeniedError instance with the cause attached\n */\n static override fromError(cause: unknown): AccessDeniedError {\n return new AccessDeniedError({\n message: cause instanceof Error ? cause.message : 'Access denied',\n cause,\n });\n }\n}\n","import { CodedError } from '../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type PresentationErrorCode } from '../../global/exceptions/error-codes.const';\nimport type { ValidationError } from '../../global/interfaces/types/validation-error.type';\n\n/**\n * Error thrown when request validation fails at the controller level.\n *\n * Contains structured validation errors with field paths and messages,\n * converted from {@link ObjectValidationError} by {@link BaseController}.\n * Provides detailed feedback about which fields failed validation.\n *\n * **When thrown:**\n * - Request DTO validation fails\n * - Malformed request data\n * - Missing required fields\n *\n * @example\n * ```typescript\n * // Automatically thrown by BaseController when DTO validation fails\n * // The validationErrors array contains field-level details:\n * // [\n * // { field: 'email', message: 'Invalid email format' },\n * // { field: 'age', message: 'Must be a positive number' }\n * // ]\n * ```\n *\n * @example Manual usage\n * ```typescript\n * throw new InvalidRequestError({\n * message: 'Request validation failed',\n * validationErrors: [\n * { field: 'username', message: 'Username is required' },\n * ],\n * });\n * ```\n *\n * @extends CodedError\n */\nexport class InvalidRequestError extends CodedError {\n /**\n * Array of field-level validation errors.\n *\n * Each entry contains:\n * - `field`: Dot-notation path to the invalid field\n * - `message`: Human-readable validation failure message\n */\n readonly validationErrors: ValidationError[];\n\n /**\n * Creates a new InvalidRequestError instance.\n *\n * @param options - Error configuration\n * @param options.message - Summary of the validation failure\n * @param options.code - Machine-readable error code (default: 'INVALID_REQUEST')\n * @param options.cause - Optional underlying error\n * @param options.validationErrors - Array of field-level validation errors\n */\n constructor({\n message,\n code = ErrorCodes.Presentation.INVALID_REQUEST,\n cause,\n validationErrors,\n }: {\n message: string;\n code?: PresentationErrorCode | string;\n cause?: unknown;\n validationErrors: ValidationError[];\n }) {\n super({ message, code, cause });\n this.validationErrors = validationErrors;\n }\n\n /**\n * Creates an InvalidRequestError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new InvalidRequestError instance with the cause attached\n */\n static override fromError(cause: unknown): InvalidRequestError {\n return new InvalidRequestError({\n message: cause instanceof Error ? cause.message : 'Invalid request',\n cause,\n validationErrors: [],\n });\n }\n}\n","/**\n * @fileoverview Centralized error mapping for HTTP frameworks.\n *\n * Provides a single source of truth for mapping onion-lasagna errors\n * to HTTP status codes and response bodies.\n *\n * @module http/shared/error-mapping\n */\n\nimport { CodedError } from '../../../global/exceptions/coded-error.error';\nimport { ObjectValidationError } from '../../../global/exceptions/object-validation.error';\nimport { DomainError } from '../../../domain/exceptions/domain.error';\nimport { UseCaseError } from '../../../app/exceptions/use-case.error';\nimport { NotFoundError } from '../../../app/exceptions/not-found.error';\nimport { ConflictError } from '../../../app/exceptions/conflict.error';\nimport { UnprocessableError } from '../../../app/exceptions/unprocessable.error';\nimport { ForbiddenError } from '../../../app/exceptions/forbidden.error';\nimport { UnauthorizedError } from '../../../app/exceptions/unauthorized.error';\nimport { InfraError } from '../../../infra/exceptions/infra.error';\nimport { ControllerError } from '../../exceptions/controller.error';\nimport { AccessDeniedError } from '../../exceptions/access-denied.error';\nimport { InvalidRequestError } from '../../exceptions/invalid-request.error';\nimport type { ErrorResponseBody, MappedErrorResponse } from './types';\n\n// ============================================================================\n// Constants and Interfaces\n// ============================================================================\n\n/**\n * Default masked error response for internal errors.\n */\nconst MASKED_ERROR_BODY: ErrorResponseBody = {\n message: 'An unexpected error occurred',\n errorCode: 'INTERNAL_ERROR',\n};\n\n/**\n * Known internal error type names that should be masked.\n */\nconst INTERNAL_ERROR_TYPES = [\n 'DomainError',\n 'InfraError',\n 'ControllerError',\n 'NetworkError',\n 'PersistenceError',\n 'ExternalServiceError',\n 'InvariantViolationError',\n];\n\n/**\n * Validation error item structure.\n */\ninterface ValidationErrorInput {\n field: string;\n message: string;\n}\n\n/**\n * Validation error structure for string-based checking.\n */\ninterface ValidationErrorItem {\n field: string;\n message: string;\n}\n\n/**\n * Interface for errors with validation items.\n */\ninterface ErrorWithValidation {\n message: string;\n code: string;\n validationErrors: ValidationErrorItem[];\n}\n\n/**\n * Interface for coded errors.\n */\ninterface CodedErrorLike {\n message: string;\n code: string;\n}\n\n// ============================================================================\n// String-based type checking helpers (for bundled code compatibility)\n// ============================================================================\n\n/**\n * Checks if error matches a specific error type by checking its constructor name.\n * This approach avoids issues with multiple class instances in bundled code.\n * Handles both original names and tsup's mangled names (prefixed with _).\n *\n * @param error - The error to check\n * @param typeName - The error type name to match\n * @returns True if error matches the type name\n */\nexport function isErrorType(error: unknown, typeName: string): error is CodedErrorLike {\n if (!error || typeof error !== 'object') return false;\n // Guard against objects without constructor (e.g., Object.create(null))\n const constructor = Object.prototype.hasOwnProperty.call(error, 'constructor')\n ? (error as { constructor?: { name?: string } }).constructor\n : Object.getPrototypeOf(error)?.constructor;\n if (!constructor) return false;\n const name = constructor.name;\n // Check both the original name and the mangled name (tsup prefixes with _)\n return name === typeName || name === `_${typeName}`;\n}\n\n/**\n * Checks if error has validation errors array.\n *\n * @param error - The error to check\n * @returns True if error has validationErrors property\n */\nexport function hasValidationErrors(error: unknown): error is ErrorWithValidation {\n if (!error || typeof error !== 'object') return false;\n return (\n 'validationErrors' in error && Array.isArray((error as ErrorWithValidation).validationErrors)\n );\n}\n\n// ============================================================================\n// Response body builders\n// ============================================================================\n\n/**\n * Builds a validation error response body from error details.\n *\n * @param message - The error message\n * @param code - The error code\n * @param validationErrors - Array of field validation errors\n * @returns Error response body with errorItems\n */\nfunction buildValidationErrorBody(\n message: string,\n code: string,\n validationErrors: readonly ValidationErrorInput[],\n): ErrorResponseBody {\n return {\n message,\n errorCode: code,\n errorItems: validationErrors.map((e) => ({\n item: e.field,\n message: e.message,\n })),\n };\n}\n\n/**\n * Builds a simple error response body from error details.\n *\n * @param message - The error message\n * @param code - The error code\n * @returns Error response body\n */\nfunction buildSimpleErrorBody(message: string, code: string): ErrorResponseBody {\n return {\n message,\n errorCode: code,\n };\n}\n\n// ============================================================================\n// Primary error mapping functions (with bundled code fallback)\n// ============================================================================\n\n/**\n * Maps an error to the appropriate HTTP status code.\n * Uses instanceof first, then falls back to name-based checking for bundled code.\n *\n * @param error - The error to map\n * @returns HTTP status code\n */\nexport function getHttpStatusCode(error: unknown): number {\n // Try instanceof first (faster)\n if (error instanceof ObjectValidationError) return 400;\n if (error instanceof InvalidRequestError) return 400;\n if (error instanceof UnauthorizedError) return 401;\n if (error instanceof ForbiddenError) return 403;\n if (error instanceof AccessDeniedError) return 403;\n if (error instanceof NotFoundError) return 404;\n if (error instanceof ConflictError) return 409;\n if (error instanceof UnprocessableError) return 422;\n if (error instanceof UseCaseError) return 400;\n\n // Fall back to name-based checking for bundled code (e.g., _NotFoundError)\n if (isErrorType(error, 'ObjectValidationError')) return 400;\n if (isErrorType(error, 'InvalidRequestError')) return 400;\n if (isErrorType(error, 'UnauthorizedError')) return 401;\n if (isErrorType(error, 'ForbiddenError')) return 403;\n if (isErrorType(error, 'AccessDeniedError')) return 403;\n if (isErrorType(error, 'NotFoundError')) return 404;\n if (isErrorType(error, 'ConflictError')) return 409;\n if (isErrorType(error, 'UnprocessableError')) return 422;\n if (isErrorType(error, 'UseCaseError')) return 400;\n\n return 500;\n}\n\n/**\n * Checks if an error should have its details masked in the response.\n *\n * Security-sensitive errors (domain, infrastructure, controller) are masked\n * to prevent leaking implementation details.\n * Uses instanceof first, then falls back to name-based checking for bundled code.\n *\n * @param error - The error to check\n * @returns True if error details should be hidden\n */\nexport function shouldMaskError(error: unknown): boolean {\n // Try instanceof first (faster)\n if (\n error instanceof DomainError ||\n error instanceof InfraError ||\n error instanceof ControllerError\n ) {\n return true;\n }\n\n // Fall back to name-based checking for bundled code\n for (const errorType of INTERNAL_ERROR_TYPES) {\n if (isErrorType(error, errorType)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Creates the response body for an error.\n * Uses instanceof first, then falls back to name-based checking for bundled code.\n *\n * @param error - The error to create body for\n * @returns Error response body\n */\nexport function createErrorResponseBody(error: unknown): ErrorResponseBody {\n // Masked errors - hide internal details\n if (shouldMaskError(error)) {\n return MASKED_ERROR_BODY;\n }\n\n // Validation errors - include field details (try instanceof first)\n if (error instanceof ObjectValidationError) {\n return buildValidationErrorBody(error.message, error.code, error.validationErrors);\n }\n if (error instanceof InvalidRequestError) {\n return buildValidationErrorBody(error.message, error.code, error.validationErrors);\n }\n\n // Validation errors - fall back to name-based checking for bundled code\n if (isErrorType(error, 'ObjectValidationError') && hasValidationErrors(error)) {\n return buildValidationErrorBody(error.message, error.code, error.validationErrors);\n }\n if (isErrorType(error, 'InvalidRequestError') && hasValidationErrors(error)) {\n return buildValidationErrorBody(error.message, error.code, error.validationErrors);\n }\n\n // Other coded errors - expose message and code (try instanceof first)\n if (error instanceof CodedError) {\n return buildSimpleErrorBody(error.message, error.code);\n }\n\n // Other coded errors - fall back to name-based checking\n if (isErrorType(error, 'CodedError')) {\n return buildSimpleErrorBody(error.message, error.code);\n }\n\n // Check for any error with message and code properties\n if (\n error &&\n typeof error === 'object' &&\n 'message' in error &&\n 'code' in error &&\n typeof (error as CodedErrorLike).message === 'string' &&\n typeof (error as CodedErrorLike).code === 'string'\n ) {\n return buildSimpleErrorBody((error as CodedErrorLike).message, (error as CodedErrorLike).code);\n }\n\n // Unknown errors - mask\n return MASKED_ERROR_BODY;\n}\n\n/**\n * Maps an error to a complete HTTP response structure.\n *\n * Mapping strategy (checked in order):\n * 1. `ObjectValidationError` / `InvalidRequestError` → 400 Bad Request (with field errors)\n * 2. `UseCaseError` → 400 Bad Request\n * 3. `UnauthorizedError` → 401 Unauthorized\n * 4. `ForbiddenError` / `AccessDeniedError` → 403 Forbidden\n * 5. `NotFoundError` → 404 Not Found\n * 6. `ConflictError` → 409 Conflict\n * 7. `UnprocessableError` → 422 Unprocessable Entity\n * 8. `DomainError` / `InfraError` / `ControllerError` → 500 Internal Server Error (masked)\n * 9. Unknown → 500 Internal Server Error (masked)\n *\n * @param error - The error to map\n * @returns Mapped error response with status and body\n */\nexport function mapErrorToHttpResponse(error: unknown): MappedErrorResponse {\n return {\n status: getHttpStatusCode(error),\n body: createErrorResponseBody(error),\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -125,20 +125,16 @@ declare function createErrorResponseBody(error: unknown): ErrorResponseBody;
|
|
|
125
125
|
/**
|
|
126
126
|
* Maps an error to a complete HTTP response structure.
|
|
127
127
|
*
|
|
128
|
-
* Mapping strategy:
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
* - `DomainError` → 500 Internal Server Error (masked)
|
|
139
|
-
* - `InfraError` → 500 Internal Server Error (masked)
|
|
140
|
-
* - `ControllerError` → 500 Internal Server Error (masked)
|
|
141
|
-
* - Unknown → 500 Internal Server Error (masked)
|
|
128
|
+
* Mapping strategy (checked in order):
|
|
129
|
+
* 1. `ObjectValidationError` / `InvalidRequestError` → 400 Bad Request (with field errors)
|
|
130
|
+
* 2. `UseCaseError` → 400 Bad Request
|
|
131
|
+
* 3. `UnauthorizedError` → 401 Unauthorized
|
|
132
|
+
* 4. `ForbiddenError` / `AccessDeniedError` → 403 Forbidden
|
|
133
|
+
* 5. `NotFoundError` → 404 Not Found
|
|
134
|
+
* 6. `ConflictError` → 409 Conflict
|
|
135
|
+
* 7. `UnprocessableError` → 422 Unprocessable Entity
|
|
136
|
+
* 8. `DomainError` / `InfraError` / `ControllerError` → 500 Internal Server Error (masked)
|
|
137
|
+
* 9. Unknown → 500 Internal Server Error (masked)
|
|
142
138
|
*
|
|
143
139
|
* @param error - The error to map
|
|
144
140
|
* @returns Mapped error response with status and body
|
|
@@ -125,20 +125,16 @@ declare function createErrorResponseBody(error: unknown): ErrorResponseBody;
|
|
|
125
125
|
/**
|
|
126
126
|
* Maps an error to a complete HTTP response structure.
|
|
127
127
|
*
|
|
128
|
-
* Mapping strategy:
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
* - `DomainError` → 500 Internal Server Error (masked)
|
|
139
|
-
* - `InfraError` → 500 Internal Server Error (masked)
|
|
140
|
-
* - `ControllerError` → 500 Internal Server Error (masked)
|
|
141
|
-
* - Unknown → 500 Internal Server Error (masked)
|
|
128
|
+
* Mapping strategy (checked in order):
|
|
129
|
+
* 1. `ObjectValidationError` / `InvalidRequestError` → 400 Bad Request (with field errors)
|
|
130
|
+
* 2. `UseCaseError` → 400 Bad Request
|
|
131
|
+
* 3. `UnauthorizedError` → 401 Unauthorized
|
|
132
|
+
* 4. `ForbiddenError` / `AccessDeniedError` → 403 Forbidden
|
|
133
|
+
* 5. `NotFoundError` → 404 Not Found
|
|
134
|
+
* 6. `ConflictError` → 409 Conflict
|
|
135
|
+
* 7. `UnprocessableError` → 422 Unprocessable Entity
|
|
136
|
+
* 8. `DomainError` / `InfraError` / `ControllerError` → 500 Internal Server Error (masked)
|
|
137
|
+
* 9. Unknown → 500 Internal Server Error (masked)
|
|
142
138
|
*
|
|
143
139
|
* @param error - The error to map
|
|
144
140
|
* @returns Mapped error response with status and body
|
|
@@ -1,131 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import {
|
|
14
|
-
ControllerError,
|
|
15
|
-
InvalidRequestError,
|
|
16
|
-
UnauthorizedError,
|
|
17
|
-
UseCaseError
|
|
18
|
-
} from "../../chunk-T7S574XQ.js";
|
|
19
|
-
import {
|
|
20
|
-
CodedError
|
|
21
|
-
} from "../../chunk-A4JUAZK4.js";
|
|
22
|
-
|
|
23
|
-
// src/presentation/http/shared/error-mapping.ts
|
|
24
|
-
var MASKED_ERROR_BODY = {
|
|
25
|
-
message: "An unexpected error occurred",
|
|
26
|
-
errorCode: "INTERNAL_ERROR"
|
|
27
|
-
};
|
|
28
|
-
var INTERNAL_ERROR_TYPES = [
|
|
29
|
-
"DomainError",
|
|
30
|
-
"InfraError",
|
|
31
|
-
"ControllerError",
|
|
32
|
-
"NetworkError",
|
|
33
|
-
"PersistenceError",
|
|
34
|
-
"ExternalServiceError",
|
|
35
|
-
"InvariantViolationError"
|
|
36
|
-
];
|
|
37
|
-
function isErrorType(error, typeName) {
|
|
38
|
-
if (!error || typeof error !== "object") return false;
|
|
39
|
-
const constructor = Object.prototype.hasOwnProperty.call(error, "constructor") ? error.constructor : Object.getPrototypeOf(error)?.constructor;
|
|
40
|
-
if (!constructor) return false;
|
|
41
|
-
const name = constructor.name;
|
|
42
|
-
return name === typeName || name === `_${typeName}`;
|
|
43
|
-
}
|
|
44
|
-
function hasValidationErrors(error) {
|
|
45
|
-
if (!error || typeof error !== "object") return false;
|
|
46
|
-
return "validationErrors" in error && Array.isArray(error.validationErrors);
|
|
47
|
-
}
|
|
48
|
-
function buildValidationErrorBody(message, code, validationErrors) {
|
|
49
|
-
return {
|
|
50
|
-
message,
|
|
51
|
-
errorCode: code,
|
|
52
|
-
errorItems: validationErrors.map((e) => ({
|
|
53
|
-
item: e.field,
|
|
54
|
-
message: e.message
|
|
55
|
-
}))
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
function buildSimpleErrorBody(message, code) {
|
|
59
|
-
return {
|
|
60
|
-
message,
|
|
61
|
-
errorCode: code
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
function getHttpStatusCode(error) {
|
|
65
|
-
if (error instanceof ObjectValidationError) return 400;
|
|
66
|
-
if (error instanceof InvalidRequestError) return 400;
|
|
67
|
-
if (error instanceof UnauthorizedError) return 401;
|
|
68
|
-
if (error instanceof ForbiddenError) return 403;
|
|
69
|
-
if (error instanceof AccessDeniedError) return 403;
|
|
70
|
-
if (error instanceof NotFoundError) return 404;
|
|
71
|
-
if (error instanceof ConflictError) return 409;
|
|
72
|
-
if (error instanceof UnprocessableError) return 422;
|
|
73
|
-
if (error instanceof UseCaseError) return 400;
|
|
74
|
-
if (isErrorType(error, "ObjectValidationError")) return 400;
|
|
75
|
-
if (isErrorType(error, "InvalidRequestError")) return 400;
|
|
76
|
-
if (isErrorType(error, "UnauthorizedError")) return 401;
|
|
77
|
-
if (isErrorType(error, "ForbiddenError")) return 403;
|
|
78
|
-
if (isErrorType(error, "AccessDeniedError")) return 403;
|
|
79
|
-
if (isErrorType(error, "NotFoundError")) return 404;
|
|
80
|
-
if (isErrorType(error, "ConflictError")) return 409;
|
|
81
|
-
if (isErrorType(error, "UnprocessableError")) return 422;
|
|
82
|
-
if (isErrorType(error, "UseCaseError")) return 400;
|
|
83
|
-
return 500;
|
|
84
|
-
}
|
|
85
|
-
function shouldMaskError(error) {
|
|
86
|
-
if (error instanceof DomainError || error instanceof InfraError || error instanceof ControllerError) {
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
for (const errorType of INTERNAL_ERROR_TYPES) {
|
|
90
|
-
if (isErrorType(error, errorType)) {
|
|
91
|
-
return true;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
function createErrorResponseBody(error) {
|
|
97
|
-
if (shouldMaskError(error)) {
|
|
98
|
-
return MASKED_ERROR_BODY;
|
|
99
|
-
}
|
|
100
|
-
if (error instanceof ObjectValidationError) {
|
|
101
|
-
return buildValidationErrorBody(error.message, error.code, error.validationErrors);
|
|
102
|
-
}
|
|
103
|
-
if (error instanceof InvalidRequestError) {
|
|
104
|
-
return buildValidationErrorBody(error.message, error.code, error.validationErrors);
|
|
105
|
-
}
|
|
106
|
-
if (isErrorType(error, "ObjectValidationError") && hasValidationErrors(error)) {
|
|
107
|
-
return buildValidationErrorBody(error.message, error.code, error.validationErrors);
|
|
108
|
-
}
|
|
109
|
-
if (isErrorType(error, "InvalidRequestError") && hasValidationErrors(error)) {
|
|
110
|
-
return buildValidationErrorBody(error.message, error.code, error.validationErrors);
|
|
111
|
-
}
|
|
112
|
-
if (error instanceof CodedError) {
|
|
113
|
-
return buildSimpleErrorBody(error.message, error.code);
|
|
114
|
-
}
|
|
115
|
-
if (isErrorType(error, "CodedError")) {
|
|
116
|
-
return buildSimpleErrorBody(error.message, error.code);
|
|
117
|
-
}
|
|
118
|
-
if (error && typeof error === "object" && "message" in error && "code" in error && typeof error.message === "string" && typeof error.code === "string") {
|
|
119
|
-
return buildSimpleErrorBody(error.message, error.code);
|
|
120
|
-
}
|
|
121
|
-
return MASKED_ERROR_BODY;
|
|
122
|
-
}
|
|
123
|
-
function mapErrorToHttpResponse(error) {
|
|
124
|
-
return {
|
|
125
|
-
status: getHttpStatusCode(error),
|
|
126
|
-
body: createErrorResponseBody(error)
|
|
127
|
-
};
|
|
128
|
-
}
|
|
2
|
+
createErrorResponseBody,
|
|
3
|
+
getHttpStatusCode,
|
|
4
|
+
hasValidationErrors,
|
|
5
|
+
isErrorType,
|
|
6
|
+
mapErrorToHttpResponse,
|
|
7
|
+
shouldMaskError
|
|
8
|
+
} from "../../chunk-H5TNDC5U.js";
|
|
9
|
+
import "../../chunk-2BVCU32G.js";
|
|
10
|
+
import "../../chunk-T7S574XQ.js";
|
|
11
|
+
import "../../chunk-3BY5RBF2.js";
|
|
12
|
+
import "../../chunk-A4JUAZK4.js";
|
|
129
13
|
export {
|
|
130
14
|
createErrorResponseBody,
|
|
131
15
|
getHttpStatusCode,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/presentation/http/shared/error-mapping.ts"],"sourcesContent":["/**\n * @fileoverview Centralized error mapping for HTTP frameworks.\n *\n * Provides a single source of truth for mapping onion-lasagna errors\n * to HTTP status codes and response bodies.\n *\n * @module http/shared/error-mapping\n */\n\nimport { CodedError } from '../../../global/exceptions/coded-error.error';\nimport { ObjectValidationError } from '../../../global/exceptions/object-validation.error';\nimport { DomainError } from '../../../domain/exceptions/domain.error';\nimport { UseCaseError } from '../../../app/exceptions/use-case.error';\nimport { NotFoundError } from '../../../app/exceptions/not-found.error';\nimport { ConflictError } from '../../../app/exceptions/conflict.error';\nimport { UnprocessableError } from '../../../app/exceptions/unprocessable.error';\nimport { ForbiddenError } from '../../../app/exceptions/forbidden.error';\nimport { UnauthorizedError } from '../../../app/exceptions/unauthorized.error';\nimport { InfraError } from '../../../infra/exceptions/infra.error';\nimport { ControllerError } from '../../exceptions/controller.error';\nimport { AccessDeniedError } from '../../exceptions/access-denied.error';\nimport { InvalidRequestError } from '../../exceptions/invalid-request.error';\nimport type { ErrorResponseBody, MappedErrorResponse } from './types';\n\n// ============================================================================\n// Constants and Interfaces\n// ============================================================================\n\n/**\n * Default masked error response for internal errors.\n */\nconst MASKED_ERROR_BODY: ErrorResponseBody = {\n message: 'An unexpected error occurred',\n errorCode: 'INTERNAL_ERROR',\n};\n\n/**\n * Known internal error type names that should be masked.\n */\nconst INTERNAL_ERROR_TYPES = [\n 'DomainError',\n 'InfraError',\n 'ControllerError',\n 'NetworkError',\n 'PersistenceError',\n 'ExternalServiceError',\n 'InvariantViolationError',\n];\n\n/**\n * Validation error item structure.\n */\ninterface ValidationErrorInput {\n field: string;\n message: string;\n}\n\n/**\n * Validation error structure for string-based checking.\n */\ninterface ValidationErrorItem {\n field: string;\n message: string;\n}\n\n/**\n * Interface for errors with validation items.\n */\ninterface ErrorWithValidation {\n message: string;\n code: string;\n validationErrors: ValidationErrorItem[];\n}\n\n/**\n * Interface for coded errors.\n */\ninterface CodedErrorLike {\n message: string;\n code: string;\n}\n\n// ============================================================================\n// String-based type checking helpers (for bundled code compatibility)\n// ============================================================================\n\n/**\n * Checks if error matches a specific error type by checking its constructor name.\n * This approach avoids issues with multiple class instances in bundled code.\n * Handles both original names and tsup's mangled names (prefixed with _).\n *\n * @param error - The error to check\n * @param typeName - The error type name to match\n * @returns True if error matches the type name\n */\nexport function isErrorType(error: unknown, typeName: string): error is CodedErrorLike {\n if (!error || typeof error !== 'object') return false;\n // Guard against objects without constructor (e.g., Object.create(null))\n const constructor = Object.prototype.hasOwnProperty.call(error, 'constructor')\n ? (error as { constructor?: { name?: string } }).constructor\n : Object.getPrototypeOf(error)?.constructor;\n if (!constructor) return false;\n const name = constructor.name;\n // Check both the original name and the mangled name (tsup prefixes with _)\n return name === typeName || name === `_${typeName}`;\n}\n\n/**\n * Checks if error has validation errors array.\n *\n * @param error - The error to check\n * @returns True if error has validationErrors property\n */\nexport function hasValidationErrors(error: unknown): error is ErrorWithValidation {\n if (!error || typeof error !== 'object') return false;\n return (\n 'validationErrors' in error && Array.isArray((error as ErrorWithValidation).validationErrors)\n );\n}\n\n// ============================================================================\n// Response body builders\n// ============================================================================\n\n/**\n * Builds a validation error response body from error details.\n *\n * This is a shared helper used by both instanceof-based and string-based\n * error mapping functions to avoid duplication.\n *\n * @param message - The error message\n * @param code - The error code\n * @param validationErrors - Array of field validation errors\n * @returns Error response body with errorItems\n */\nfunction buildValidationErrorBody(\n message: string,\n code: string,\n validationErrors: readonly ValidationErrorInput[],\n): ErrorResponseBody {\n return {\n message,\n errorCode: code,\n errorItems: validationErrors.map((e) => ({\n item: e.field,\n message: e.message,\n })),\n };\n}\n\n/**\n * Builds a simple error response body from error details.\n *\n * @param message - The error message\n * @param code - The error code\n * @returns Error response body\n */\nfunction buildSimpleErrorBody(message: string, code: string): ErrorResponseBody {\n return {\n message,\n errorCode: code,\n };\n}\n\n// ============================================================================\n// Primary error mapping functions (with bundled code fallback)\n// ============================================================================\n\n/**\n * Maps an error to the appropriate HTTP status code.\n * Uses instanceof first, then falls back to name-based checking for bundled code.\n *\n * @param error - The error to map\n * @returns HTTP status code\n */\nexport function getHttpStatusCode(error: unknown): number {\n // Try instanceof first (faster)\n if (error instanceof ObjectValidationError) return 400;\n if (error instanceof InvalidRequestError) return 400;\n if (error instanceof UnauthorizedError) return 401;\n if (error instanceof ForbiddenError) return 403;\n if (error instanceof AccessDeniedError) return 403;\n if (error instanceof NotFoundError) return 404;\n if (error instanceof ConflictError) return 409;\n if (error instanceof UnprocessableError) return 422;\n if (error instanceof UseCaseError) return 400;\n\n // Fall back to name-based checking for bundled code (e.g., _NotFoundError)\n if (isErrorType(error, 'ObjectValidationError')) return 400;\n if (isErrorType(error, 'InvalidRequestError')) return 400;\n if (isErrorType(error, 'UnauthorizedError')) return 401;\n if (isErrorType(error, 'ForbiddenError')) return 403;\n if (isErrorType(error, 'AccessDeniedError')) return 403;\n if (isErrorType(error, 'NotFoundError')) return 404;\n if (isErrorType(error, 'ConflictError')) return 409;\n if (isErrorType(error, 'UnprocessableError')) return 422;\n if (isErrorType(error, 'UseCaseError')) return 400;\n\n return 500;\n}\n\n/**\n * Checks if an error should have its details masked in the response.\n *\n * Security-sensitive errors (domain, infrastructure, controller) are masked\n * to prevent leaking implementation details.\n * Uses instanceof first, then falls back to name-based checking for bundled code.\n *\n * @param error - The error to check\n * @returns True if error details should be hidden\n */\nexport function shouldMaskError(error: unknown): boolean {\n // Try instanceof first (faster)\n if (\n error instanceof DomainError ||\n error instanceof InfraError ||\n error instanceof ControllerError\n ) {\n return true;\n }\n\n // Fall back to name-based checking for bundled code\n for (const errorType of INTERNAL_ERROR_TYPES) {\n if (isErrorType(error, errorType)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Creates the response body for an error.\n * Uses instanceof first, then falls back to name-based checking for bundled code.\n *\n * @param error - The error to create body for\n * @returns Error response body\n */\nexport function createErrorResponseBody(error: unknown): ErrorResponseBody {\n // Masked errors - hide internal details\n if (shouldMaskError(error)) {\n return MASKED_ERROR_BODY;\n }\n\n // Validation errors - include field details (try instanceof first)\n if (error instanceof ObjectValidationError) {\n return buildValidationErrorBody(error.message, error.code, error.validationErrors);\n }\n if (error instanceof InvalidRequestError) {\n return buildValidationErrorBody(error.message, error.code, error.validationErrors);\n }\n\n // Validation errors - fall back to name-based checking for bundled code\n if (isErrorType(error, 'ObjectValidationError') && hasValidationErrors(error)) {\n return buildValidationErrorBody(error.message, error.code, error.validationErrors);\n }\n if (isErrorType(error, 'InvalidRequestError') && hasValidationErrors(error)) {\n return buildValidationErrorBody(error.message, error.code, error.validationErrors);\n }\n\n // Other coded errors - expose message and code (try instanceof first)\n if (error instanceof CodedError) {\n return buildSimpleErrorBody(error.message, error.code);\n }\n\n // Other coded errors - fall back to name-based checking\n if (isErrorType(error, 'CodedError')) {\n return buildSimpleErrorBody(error.message, error.code);\n }\n\n // Check for any error with message and code properties\n if (\n error &&\n typeof error === 'object' &&\n 'message' in error &&\n 'code' in error &&\n typeof (error as CodedErrorLike).message === 'string' &&\n typeof (error as CodedErrorLike).code === 'string'\n ) {\n return buildSimpleErrorBody((error as CodedErrorLike).message, (error as CodedErrorLike).code);\n }\n\n // Unknown errors - mask\n return MASKED_ERROR_BODY;\n}\n\n/**\n * Maps an error to a complete HTTP response structure.\n *\n * Mapping strategy:\n * - `ObjectValidationError` → 400 Bad Request (with field errors)\n * - `InvalidRequestError` → 400 Bad Request (with field errors)\n * - `UseCaseError` → 400 Bad Request\n * - `UnauthorizedError` → 401 Unauthorized (authentication required/invalid)\n * - `ForbiddenError` → 403 Forbidden (authorization denied in use case)\n * - `AccessDeniedError` → 403 Forbidden (access denied at controller/guard level)\n * - `NotFoundError` → 404 Not Found\n * - `ConflictError` → 409 Conflict\n * - `UnprocessableError` → 422 Unprocessable Entity\n * - `DomainError` → 500 Internal Server Error (masked)\n * - `InfraError` → 500 Internal Server Error (masked)\n * - `ControllerError` → 500 Internal Server Error (masked)\n * - Unknown → 500 Internal Server Error (masked)\n *\n * @param error - The error to map\n * @returns Mapped error response with status and body\n */\nexport function mapErrorToHttpResponse(error: unknown): MappedErrorResponse {\n return {\n status: getHttpStatusCode(error),\n body: createErrorResponseBody(error),\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
fieldChanged
|
|
3
|
+
} from "./chunk-3QKQCJSP.js";
|
|
1
4
|
import {
|
|
2
5
|
AccessDeniedError,
|
|
3
6
|
ConflictError,
|
|
@@ -7,12 +10,6 @@ import {
|
|
|
7
10
|
NotFoundError,
|
|
8
11
|
UnprocessableError
|
|
9
12
|
} from "./chunk-2BVCU32G.js";
|
|
10
|
-
import {
|
|
11
|
-
fieldChanged
|
|
12
|
-
} from "./chunk-3QKQCJSP.js";
|
|
13
|
-
import {
|
|
14
|
-
ObjectValidationError
|
|
15
|
-
} from "./chunk-3BY5RBF2.js";
|
|
16
13
|
import {
|
|
17
14
|
ControllerError,
|
|
18
15
|
InvalidRequestError,
|
|
@@ -25,6 +22,9 @@ import {
|
|
|
25
22
|
wrapErrorUnless,
|
|
26
23
|
wrapErrorUnlessAsync
|
|
27
24
|
} from "./chunk-ZG26OQFN.js";
|
|
25
|
+
import {
|
|
26
|
+
ObjectValidationError
|
|
27
|
+
} from "./chunk-3BY5RBF2.js";
|
|
28
28
|
import {
|
|
29
29
|
CodedError,
|
|
30
30
|
ErrorCodes
|