@cullet/erp-core 1.5.0 → 2.0.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/KIT_CONTEXT.md +2 -2
- package/dist/abac/index.d.cts +2 -2
- package/dist/abac/index.d.ts +2 -2
- package/dist/aggregate-version.cjs +14 -0
- package/dist/aggregate-version.cjs.map +1 -0
- package/dist/aggregate-version.js +9 -0
- package/dist/aggregate-version.js.map +1 -0
- package/dist/app-error.cjs +8 -1
- package/dist/app-error.cjs.map +1 -1
- package/dist/app-error.js +8 -1
- package/dist/app-error.js.map +1 -1
- package/dist/application/index.cjs +8 -4
- package/dist/application/index.d.cts +2 -2
- package/dist/application/index.d.ts +2 -2
- package/dist/application/index.js +1 -2
- package/dist/authorization-error.cjs +67 -17
- package/dist/authorization-error.cjs.map +1 -1
- package/dist/authorization-error.d.cts +6 -2
- package/dist/authorization-error.d.ts +6 -2
- package/dist/authorization-error.js +50 -18
- package/dist/authorization-error.js.map +1 -1
- package/dist/authorizer.port.d.cts +18 -3
- package/dist/authorizer.port.d.ts +18 -3
- package/dist/composite-authorizer.d.cts +63 -10
- package/dist/composite-authorizer.d.ts +63 -10
- package/dist/condition-evaluator.cjs +115 -184
- package/dist/condition-evaluator.cjs.map +1 -1
- package/dist/condition-evaluator.js +116 -179
- package/dist/condition-evaluator.js.map +1 -1
- package/dist/core-config.d.cts +53 -6
- package/dist/core-config.d.ts +53 -6
- package/dist/decorate.cjs +14 -0
- package/dist/decorate.js +9 -0
- package/dist/domain/index.cjs +107 -2
- package/dist/domain/index.cjs.map +1 -0
- package/dist/domain/index.d.cts +25 -1
- package/dist/domain/index.d.ts +25 -1
- package/dist/domain/index.js +99 -3
- package/dist/domain/index.js.map +1 -0
- package/dist/domain-event-contracts.cjs +12 -8
- package/dist/domain-event-contracts.cjs.map +1 -1
- package/dist/domain-event-contracts.d.cts +29 -4
- package/dist/domain-event-contracts.d.ts +29 -4
- package/dist/domain-event-contracts.js +11 -7
- package/dist/domain-event-contracts.js.map +1 -1
- package/dist/domain-exception.cjs +2 -1
- package/dist/domain-exception.cjs.map +1 -1
- package/dist/domain-exception.js +2 -1
- package/dist/domain-exception.js.map +1 -1
- package/dist/errors/index.cjs +1 -1
- package/dist/errors/index.d.cts +1 -1
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +2 -2
- package/dist/exceptions/index.cjs +2 -2
- package/dist/exceptions/index.d.cts +1 -2
- package/dist/exceptions/index.d.ts +1 -2
- package/dist/exceptions/index.js +2 -2
- package/dist/gate-engine-registry.cjs.map +1 -1
- package/dist/gate-engine-registry.d.cts +1 -1
- package/dist/gate-engine-registry.d.ts +1 -1
- package/dist/gate-engine-registry.js.map +1 -1
- package/dist/gate-v1-payload.schema.cjs +11 -6
- package/dist/gate-v1-payload.schema.cjs.map +1 -1
- package/dist/gate-v1-payload.schema.js +11 -6
- package/dist/gate-v1-payload.schema.js.map +1 -1
- package/dist/hashing.cjs +1 -1
- package/dist/hashing.cjs.map +1 -1
- package/dist/hashing.js +2 -2
- package/dist/hashing.js.map +1 -1
- package/dist/immutable.cjs +25 -12
- package/dist/immutable.cjs.map +1 -1
- package/dist/immutable.js +24 -11
- package/dist/immutable.js.map +1 -1
- package/dist/index.cjs +13 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -10
- package/dist/index.d.ts +9 -10
- package/dist/index.js +7 -9
- package/dist/index.js.map +1 -1
- package/dist/invalid-state-transition-exception.cjs +6 -6
- package/dist/invalid-state-transition-exception.cjs.map +1 -1
- package/dist/invalid-state-transition-exception.js +6 -6
- package/dist/invalid-state-transition-exception.js.map +1 -1
- package/dist/invariant-violation-exception.cjs +2 -2
- package/dist/invariant-violation-exception.cjs.map +1 -1
- package/dist/invariant-violation-exception.js +2 -2
- package/dist/invariant-violation-exception.js.map +1 -1
- package/dist/not-found-error.cjs +6 -4
- package/dist/not-found-error.cjs.map +1 -1
- package/dist/not-found-error.js +6 -4
- package/dist/not-found-error.js.map +1 -1
- package/dist/outcome.cjs +5 -5
- package/dist/outcome.cjs.map +1 -1
- package/dist/outcome.js +5 -5
- package/dist/outcome.js.map +1 -1
- package/dist/parse-gate-payload.d.cts +1 -1
- package/dist/parse-gate-payload.d.ts +1 -1
- package/dist/path.d.cts +2 -2
- package/dist/path.d.ts +2 -2
- package/dist/plugin.cjs +23 -13
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +22 -8
- package/dist/plugin.d.ts +22 -8
- package/dist/plugin.js +23 -13
- package/dist/plugin.js.map +1 -1
- package/dist/policies/engines/index.d.cts +1 -1
- package/dist/policies/engines/index.d.ts +1 -1
- package/dist/policies/engines/v1/gate/index.d.cts +3 -15
- package/dist/policies/engines/v1/gate/index.d.ts +3 -15
- package/dist/policies/index.d.cts +1 -1
- package/dist/policies/index.d.ts +1 -1
- package/dist/policy-bridge.cjs +30 -2
- package/dist/policy-bridge.cjs.map +1 -1
- package/dist/policy-bridge.d.cts +18 -0
- package/dist/policy-bridge.d.ts +18 -0
- package/dist/policy-bridge.js +30 -2
- package/dist/policy-bridge.js.map +1 -1
- package/dist/policy-service.cjs +40 -46
- package/dist/policy-service.cjs.map +1 -1
- package/dist/policy-service.d.cts +72 -9
- package/dist/policy-service.d.ts +72 -9
- package/dist/policy-service.js +42 -48
- package/dist/policy-service.js.map +1 -1
- package/dist/requested-by.cjs +1 -1
- package/dist/requested-by.cjs.map +1 -1
- package/dist/requested-by.js +1 -1
- package/dist/requested-by.js.map +1 -1
- package/dist/result.cjs +29 -1
- package/dist/result.cjs.map +1 -1
- package/dist/result.d.cts +12 -0
- package/dist/result.d.ts +12 -0
- package/dist/result.js +29 -1
- package/dist/result.js.map +1 -1
- package/dist/rule.cjs +94 -24
- package/dist/rule.cjs.map +1 -1
- package/dist/rule.js +94 -24
- package/dist/rule.js.map +1 -1
- package/dist/ruleset-registry.cjs +19 -0
- package/dist/ruleset-registry.cjs.map +1 -1
- package/dist/ruleset-registry.js +19 -0
- package/dist/ruleset-registry.js.map +1 -1
- package/dist/stable-stringify.cjs +43 -3
- package/dist/stable-stringify.cjs.map +1 -1
- package/dist/stable-stringify.js +38 -4
- package/dist/stable-stringify.js.map +1 -1
- package/dist/temporal-snapshot.d.cts +87 -0
- package/dist/temporal-snapshot.d.ts +87 -0
- package/dist/temporal-use-case.cjs +169 -16
- package/dist/temporal-use-case.cjs.map +1 -1
- package/dist/temporal-use-case.d.cts +76 -43
- package/dist/temporal-use-case.d.ts +76 -43
- package/dist/temporal-use-case.js +162 -15
- package/dist/temporal-use-case.js.map +1 -1
- package/dist/unexpected-error.cjs +4 -2
- package/dist/unexpected-error.cjs.map +1 -1
- package/dist/unexpected-error.js +4 -2
- package/dist/unexpected-error.js.map +1 -1
- package/dist/uuid-identifier.cjs +140 -2
- package/dist/uuid-identifier.cjs.map +1 -1
- package/dist/uuid-identifier.d.cts +26 -7
- package/dist/uuid-identifier.d.ts +26 -7
- package/dist/uuid-identifier.js +135 -3
- package/dist/uuid-identifier.js.map +1 -1
- package/dist/uuid.cjs +11 -6
- package/dist/uuid.cjs.map +1 -1
- package/dist/uuid.js +11 -6
- package/dist/uuid.js.map +1 -1
- package/dist/validation-code.cjs +9 -0
- package/dist/validation-code.cjs.map +1 -1
- package/dist/validation-code.d.cts +3 -0
- package/dist/validation-code.d.ts +3 -0
- package/dist/validation-code.js +9 -0
- package/dist/validation-code.js.map +1 -1
- package/dist/validation-error.cjs +42 -67
- package/dist/validation-error.cjs.map +1 -1
- package/dist/validation-error.d.cts +24 -8
- package/dist/validation-error.d.ts +24 -8
- package/dist/validation-error.js +41 -66
- package/dist/validation-error.js.map +1 -1
- package/dist/validation-exception.cjs +17 -6
- package/dist/validation-exception.cjs.map +1 -1
- package/dist/validation-exception.d.cts +33 -9
- package/dist/validation-exception.d.ts +33 -9
- package/dist/validation-exception.js +17 -6
- package/dist/validation-exception.js.map +1 -1
- package/dist/validation-field.cjs +3 -0
- package/dist/validation-field.cjs.map +1 -1
- package/dist/validation-field.d.cts +1 -0
- package/dist/validation-field.d.ts +1 -0
- package/dist/validation-field.js +3 -0
- package/dist/validation-field.js.map +1 -1
- package/dist/value-object-ruleset.contracts.d.cts +10 -0
- package/dist/value-object-ruleset.contracts.d.ts +10 -0
- package/dist/value-object.cjs +12 -2
- package/dist/value-object.cjs.map +1 -1
- package/dist/value-object.d.cts +16 -0
- package/dist/value-object.d.ts +16 -0
- package/dist/value-object.js +13 -3
- package/dist/value-object.js.map +1 -1
- package/dist/version.d.cts +27 -0
- package/dist/version.d.ts +27 -0
- package/dist/versioning/index.d.cts +2 -2
- package/dist/versioning/index.d.ts +2 -2
- package/meta.json +3 -2
- package/package.json +1 -1
- package/src/core/abac/authorizer.ts +60 -10
- package/src/core/abac/domain/policy-set.ts +52 -5
- package/src/core/abac/domain/rule.ts +28 -16
- package/src/core/abac/index.ts +7 -1
- package/src/core/application/commands/command.ts +14 -1
- package/src/core/application/commands/requested-by.ts +12 -3
- package/src/core/application/index.ts +2 -1
- package/src/core/application/policy-error-mapper.ts +6 -0
- package/src/core/application/ports/index.ts +7 -0
- package/src/core/application/ports/temporal-repository.port.ts +35 -2
- package/src/core/application/queries/index.ts +1 -1
- package/src/core/application/queries/query.ts +19 -2
- package/src/core/application/temporal/temporal-use-case.ts +31 -4
- package/src/core/application/use-case.ts +44 -7
- package/src/core/config/core-config.ts +46 -25
- package/src/core/config/index.ts +1 -0
- package/src/core/config/policy-reporter.ts +32 -1
- package/src/core/domain/entity.ts +50 -7
- package/src/core/domain/rulesets/entity-ruleset.contracts.ts +0 -2
- package/src/core/domain/rulesets/ruleset-registry.ts +24 -0
- package/src/core/domain/rulesets/value-object-ruleset.contracts.ts +1 -7
- package/src/core/domain/temporal/half-open-interval.ts +34 -0
- package/src/core/domain/temporal/temporal-snapshot.ts +13 -2
- package/src/core/domain/temporal/transaction-time.ts +19 -15
- package/src/core/domain/temporal/valid-time.ts +20 -15
- package/src/core/domain/uuid-identifier.ts +5 -3
- package/src/core/domain/value-object.ts +17 -0
- package/src/core/errors/authentication-error.ts +5 -31
- package/src/core/errors/authorization-error.ts +12 -20
- package/src/core/errors/business-rule-violation-error.ts +4 -1
- package/src/core/errors/idempotency-error.ts +5 -2
- package/src/core/errors/index.ts +4 -0
- package/src/core/errors/integration-error.ts +4 -24
- package/src/core/errors/legacy-incompatible-error.ts +1 -0
- package/src/core/errors/not-found-error.ts +4 -1
- package/src/core/errors/temporal-error.ts +22 -20
- package/src/core/errors/unexpected-error.ts +5 -1
- package/src/core/errors/utils/factory-helpers.ts +70 -0
- package/src/core/errors/utils/index.ts +5 -0
- package/src/core/errors/utils/json-safe.ts +15 -1
- package/src/core/errors/validation-error.ts +4 -1
- package/src/core/exceptions/business-rule-violation-exception.ts +2 -1
- package/src/core/exceptions/domain-exception.ts +9 -1
- package/src/core/exceptions/entity-not-found-exception.ts +5 -1
- package/src/core/exceptions/invalid-state-transition-exception.ts +5 -2
- package/src/core/exceptions/invariant-violation-exception.ts +2 -2
- package/src/core/exceptions/validation-code.ts +14 -0
- package/src/core/exceptions/validation-exception.ts +44 -5
- package/src/core/exceptions/validation-field.ts +11 -1
- package/src/core/plugins/plugin.ts +25 -15
- package/src/core/plugins/types.ts +4 -2
- package/src/core/policies/asof/asof.ts +12 -0
- package/src/core/policies/catalog/policy-catalog-entry.ts +3 -1
- package/src/core/policies/catalog/policy-catalog.ts +5 -1
- package/src/core/policies/context/context-builder.ts +20 -0
- package/src/core/policies/context/context-resolver.ts +5 -0
- package/src/core/policies/context/context-seed.ts +11 -0
- package/src/core/policies/defs/in-memory-policy-definition-repo.ts +0 -2
- package/src/core/policies/engines/parse-gate-payload.ts +9 -0
- package/src/core/policies/engines/v1/condition-date-operands.ts +112 -0
- package/src/core/policies/engines/v1/condition-evaluator.ts +99 -325
- package/src/core/policies/engines/v1/condition-schema.ts +23 -19
- package/src/core/policies/engines/v1/condition-types.ts +18 -11
- package/src/core/policies/index.ts +4 -6
- package/src/core/policies/service/policy-service.ts +46 -35
- package/src/core/policies/utils/hash.ts +5 -69
- package/src/core/policies/utils/result.ts +1 -1
- package/src/core/rbac/access-request.ts +12 -2
- package/src/core/rbac/authorizer.ts +8 -1
- package/src/core/rbac/domain/role.ts +20 -0
- package/src/core/rbac/domain/scope.ts +6 -1
- package/src/core/result/index.ts +5 -0
- package/src/core/result/outcome.ts +5 -7
- package/src/core/result/result.ts +34 -1
- package/src/core/shared/hashing.ts +6 -3
- package/src/core/shared/immutable.ts +22 -4
- package/src/core/shared/stable-stringify.ts +91 -4
- package/src/core/shared/uuid.ts +11 -6
- package/src/core/versioning/domain-event-contracts.ts +43 -15
- package/src/core/versioning/index.ts +1 -0
- package/src/core/versioning/version.ts +30 -1
- package/src/domain/index.ts +5 -0
- package/src/examples/rulesets/entity/order-creation-rules-v1.ts +1 -1
- package/src/examples/rulesets/entity/order-invariants-v1.ts +2 -4
- package/src/examples/rulesets/entity/order-invariants-v2.ts +2 -4
- package/src/examples/rulesets/value-object/cpf-rules-v1.ts +2 -4
- package/src/examples/rulesets/value-object/cpf-rules-v2.ts +2 -4
- package/src/examples/rulesets/value-object/person-name-rules-v1.ts +2 -4
- package/src/examples/rulesets/value-object/person-name-rules-v2.ts +2 -4
- package/src/result/index.ts +7 -2
- package/src/version.ts +1 -1
- package/dist/domain-exception.d.cts +0 -7
- package/dist/domain-exception.d.ts +0 -7
- package/dist/entity.cjs +0 -122
- package/dist/entity.cjs.map +0 -1
- package/dist/entity.js +0 -111
- package/dist/entity.js.map +0 -1
- package/dist/use-case.cjs +0 -92
- package/dist/use-case.cjs.map +0 -1
- package/dist/use-case.js +0 -87
- package/dist/use-case.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation-error.cjs","names":["AppError","ErrorCodes","compactMetadata","AppError","ErrorCodes","AppError","ErrorCodes","AppError","ErrorCodes","AppError","ErrorCodes","AppError","serializationErrorCode","AppError","ErrorCodes","AppError","ErrorCodes"],"sources":["../src/core/errors/authentication-error.ts","../src/core/errors/conflict-error.ts","../src/core/errors/idempotency-error.ts","../src/core/errors/integration-error.ts","../src/core/errors/legacy-incompatible-error.ts","../src/core/errors/serialization-error.ts","../src/core/errors/temporal-error.ts","../src/core/errors/validation-error.ts"],"sourcesContent":["import { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\nimport type { AppErrorOptions, ErrorSeverity } from \"./types.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype AuthenticationErrorReason =\n | \"missing_token\"\n | \"malformed_token\"\n | \"invalid_token\"\n | \"expired_token\"\n | \"revoked_token\"\n | \"invalid_credentials\"\n | \"session_not_found\"\n | \"session_expired\"\n | \"unknown\";\n\ntype AuthenticationErrorMetadata = {\n reason: AuthenticationErrorReason;\n authScheme?: \"bearer\" | \"cookie\" | \"basic\" | \"unknown\";\n tokenLocation?: \"header\" | \"cookie\" | \"query\" | \"unknown\";\n expiresAtIso?: string;\n correlationId?: string;\n requestId?: string;\n details?: string;\n};\n\ntype AuthenticationErrorFactoryOptions = Omit<\n AuthenticationErrorMetadata,\n \"reason\"\n> &\n Omit<AppErrorOptions, \"metadata\">;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// AuthenticationError\n// ─────────────────────────────────────────────────────────────────────────────\n\nclass AuthenticationError extends AppError {\n public readonly reason: AuthenticationErrorReason;\n\n private constructor(params: {\n message: string;\n code: string;\n reason: AuthenticationErrorReason;\n metadata?: Omit<AuthenticationErrorMetadata, \"reason\">;\n cause?: unknown;\n type?: string;\n severity?: ErrorSeverity;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n createdAtIso?: string;\n publicMessage?: string;\n }) {\n super(params.message, params.code, {\n cause: params.cause,\n metadata: {\n reason: params.reason,\n ...(params.metadata ?? {}),\n },\n type: params.type,\n severity: params.severity,\n correlationId: params.correlationId,\n requestId: params.requestId,\n commandId: params.commandId,\n createdAtIso: params.createdAtIso,\n publicMessage: params.publicMessage,\n });\n\n this.reason = params.reason;\n Object.freeze(this);\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Factory methods\n // ─────────────────────────────────────────────────────────────────────────\n\n static missingToken(\n options?: AuthenticationErrorFactoryOptions,\n ): AuthenticationError {\n return new AuthenticationError({\n message: \"Missing credentials\",\n code: ErrorCodes.authentication.missingToken,\n reason: \"missing_token\",\n metadata: compactMetadata(options),\n ...extractAppErrorOptions(options),\n });\n }\n\n static invalidToken(\n options?: AuthenticationErrorFactoryOptions & { cause?: unknown },\n ): AuthenticationError {\n return new AuthenticationError({\n message: \"Invalid credentials\",\n code: ErrorCodes.authentication.invalidToken,\n reason: \"invalid_token\",\n metadata: compactMetadata({\n authScheme: options?.authScheme,\n tokenLocation: options?.tokenLocation,\n details: options?.details,\n correlationId: options?.correlationId,\n requestId: options?.requestId,\n }),\n ...extractAppErrorOptions(options),\n });\n }\n\n static expiredToken(\n options?: AuthenticationErrorFactoryOptions & { sessionId?: string },\n ): AuthenticationError {\n return new AuthenticationError({\n message: \"Expired credentials\",\n code: ErrorCodes.authentication.expiredToken,\n reason: \"expired_token\",\n metadata: compactMetadata(options),\n ...extractAppErrorOptions(options),\n });\n }\n\n static invalidCredentials(\n options?: Pick<\n AuthenticationErrorFactoryOptions,\n | \"correlationId\"\n | \"requestId\"\n | \"type\"\n | \"severity\"\n | \"createdAtIso\"\n | \"publicMessage\"\n >,\n ): AuthenticationError {\n return new AuthenticationError({\n message: \"Invalid username or password\",\n code: ErrorCodes.authentication.invalidCredentials,\n reason: \"invalid_credentials\",\n metadata: compactMetadata(options),\n ...extractAppErrorOptions(options),\n });\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction extractAppErrorOptions(options?: Partial<AppErrorOptions>) {\n return {\n cause: options?.cause,\n type: options?.type,\n severity: options?.severity,\n correlationId: options?.correlationId,\n requestId: options?.requestId,\n commandId: options?.commandId,\n createdAtIso: options?.createdAtIso,\n publicMessage: options?.publicMessage,\n };\n}\n\nfunction compactMetadata<T extends Record<string, unknown>>(\n input?: T,\n): T | undefined {\n if (!input) return undefined;\n\n return Object.fromEntries(\n Object.entries(input).filter(([, value]) => value !== undefined),\n ) as T;\n}\n\nexport { AuthenticationError };\nexport type { AuthenticationErrorMetadata, AuthenticationErrorReason };\n","import { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\nimport type { AppErrorOptions } from \"./types.js\";\n\n/**\n * Conflict kinds we want to distinguish semantically.\n */\ntype ConflictKind = \"already_exists\" | \"duplicate\" | \"unique_violation\";\n\n/**\n * Metadata attached to conflicts without exposing sensitive values.\n */\ntype ConflictErrorMetadata = {\n kind: ConflictKind;\n entity: string;\n operation?: string;\n field?: string;\n constraintName?: string;\n existingId?: string;\n valueHash?: string;\n valuePreview?: string;\n detectedAtIso?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n hint?: string;\n};\n\n/**\n * Storage-level description of a unique-constraint breach, as reported by a\n * database driver. Used to translate a raw DB error into a domain\n * {@link DuplicateError} via {@link translateUniqueViolationToDuplicate}.\n */\ntype UniqueConstraintViolation = {\n kind: \"unique_violation\";\n constraintName?: string;\n table?: string;\n columns?: string[];\n};\n\n/**\n * Base for errors that signal a state conflict — the request collides with data\n * that already exists. Common at an HTTP 409 boundary.\n *\n * The discriminating {@link kind} lets a handler branch on *why* it conflicted\n * (an already-existing record, a domain duplicate, or a raw storage uniqueness\n * breach) without `instanceof` chains. Abstract: construct one of the concrete\n * subclasses through its `detected(...)` factory, which fills in the right code,\n * message, and metadata. Instances are frozen, so a conflict error can be shared\n * and rethrown without risk of tampering.\n */\nabstract class ConflictError extends AppError {\n public readonly kind: ConflictKind;\n\n protected constructor(\n params: {\n message: string;\n code: string;\n kind: ConflictKind;\n metadata: Omit<ConflictErrorMetadata, \"kind\">;\n cause?: unknown;\n } & AppErrorOptions,\n ) {\n super(params.message, params.code, {\n ...params,\n metadata: {\n kind: params.kind,\n ...params.metadata,\n },\n });\n\n this.kind = params.kind;\n Object.freeze(this);\n }\n}\n\n/**\n * The operation cannot proceed because a matching record already exists —\n * e.g. creating something whose natural key is already taken. Construct via\n * {@link AlreadyExistsError.detected}.\n */\nclass AlreadyExistsError extends ConflictError {\n private constructor(\n input: {\n metadata: Omit<ConflictErrorMetadata, \"kind\">;\n cause?: unknown;\n } & AppErrorOptions,\n ) {\n super({\n message:\n \"A matching record already exists for the requested operation\",\n code: ErrorCodes.conflict.alreadyExists,\n kind: \"already_exists\",\n ...input,\n });\n }\n\n /**\n * Builds an {@link AlreadyExistsError} for a detected collision. `operation`\n * defaults to `\"create\"` and a generic retry `hint` is supplied when none is\n * given, so the error is actionable even from a minimal call site.\n *\n * @param input - The conflicting entity plus optional non-sensitive context\n * (operation, field, existing id, value hash/preview, correlation ids).\n */\n static detected(input: {\n entity: string;\n operation?: string;\n field?: string;\n existingId?: string;\n valueHash?: string;\n valuePreview?: string;\n detectedAtIso?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n hint?: string;\n cause?: unknown;\n }): AlreadyExistsError {\n return new AlreadyExistsError({\n metadata: {\n entity: input.entity,\n operation: input.operation ?? \"create\",\n field: input.field,\n existingId: input.existingId,\n valueHash: input.valueHash,\n valuePreview: input.valuePreview,\n detectedAtIso: input.detectedAtIso,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n hint: input.hint ?? \"Verify existing records before retrying.\",\n },\n cause: input.cause,\n });\n }\n}\n\n/**\n * A domain-level duplicate: the data being written would duplicate an existing\n * record under the model's own uniqueness rules. Use this when the duplication\n * is recognized in the domain, as opposed to a raw DB constraint\n * ({@link UniqueConstraintViolationError}). Construct via\n * {@link DuplicateError.detected}.\n */\nclass DuplicateError extends ConflictError {\n private constructor(\n input: {\n metadata: Omit<ConflictErrorMetadata, \"kind\">;\n cause?: unknown;\n } & AppErrorOptions,\n ) {\n super({\n message: \"Conflict: an existing record violates uniqueness\",\n code: ErrorCodes.conflict.duplicate,\n kind: \"duplicate\",\n ...input,\n });\n }\n\n /**\n * Builds a {@link DuplicateError} for a detected duplicate, defaulting to a\n * \"adjust the data so it does not duplicate\" hint when none is provided.\n *\n * @param input - The conflicting entity plus optional non-sensitive context\n * (field, constraint name, existing id, value hash/preview, correlation ids).\n */\n static detected(input: {\n entity: string;\n operation?: string;\n field?: string;\n constraintName?: string;\n existingId?: string;\n valueHash?: string;\n valuePreview?: string;\n detectedAtIso?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n hint?: string;\n cause?: unknown;\n }): DuplicateError {\n return new DuplicateError({\n metadata: {\n entity: input.entity,\n operation: input.operation,\n field: input.field,\n constraintName: input.constraintName,\n existingId: input.existingId,\n valueHash: input.valueHash,\n valuePreview: input.valuePreview,\n detectedAtIso: input.detectedAtIso,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n hint:\n input.hint ??\n \"Adjust the data so it does not duplicate existing records.\",\n },\n cause: input.cause,\n });\n }\n}\n\n/**\n * A uniqueness breach surfaced by the storage layer itself (a database unique\n * index), carrying the raw {@link UniqueConstraintViolation} (constraint, table,\n * columns). Keep this distinct from {@link DuplicateError}: this one is the\n * infrastructure signal; translate it into a domain duplicate at the boundary\n * with {@link translateUniqueViolationToDuplicate} when the model should own the\n * message. Construct via {@link UniqueConstraintViolationError.detected}.\n */\nclass UniqueConstraintViolationError extends ConflictError {\n private constructor(\n input: {\n metadata: Omit<ConflictErrorMetadata, \"kind\"> & {\n violation: UniqueConstraintViolation;\n };\n cause?: unknown;\n } & AppErrorOptions,\n ) {\n super({\n message: \"Uniqueness violation in storage\",\n code: ErrorCodes.conflict.uniqueViolation,\n kind: \"unique_violation\",\n ...input,\n });\n }\n\n /**\n * Builds a {@link UniqueConstraintViolationError} from the constraint details\n * a driver reports, packaging them into a nested `violation` payload.\n *\n * @param input - The entity plus the offending constraint name, table, and\n * columns, and optional correlation ids.\n */\n static detected(input: {\n entity: string;\n operation?: string;\n constraintName?: string;\n table?: string;\n columns?: string[];\n detectedAtIso?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n cause?: unknown;\n }): UniqueConstraintViolationError {\n return new UniqueConstraintViolationError({\n metadata: {\n entity: input.entity,\n operation: input.operation,\n constraintName: input.constraintName,\n detectedAtIso: input.detectedAtIso,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n violation: {\n kind: \"unique_violation\",\n constraintName: input.constraintName,\n table: input.table,\n columns: input.columns,\n },\n hint: \"Uniqueness conflict detected in the database.\",\n },\n cause: input.cause,\n });\n }\n}\n\n/**\n * Translates a raw storage {@link UniqueConstraintViolation} into a domain-level\n * {@link DuplicateError}. This is the seam where an infrastructure concern (a DB\n * unique index firing) is re-expressed in the language of the model, so callers\n * upstream catch a `DuplicateError` and never have to know a database was\n * involved.\n *\n * @param input - The entity, the driver-reported `violation`, and optional\n * request context (`ctx`) carrying correlation ids and a clock instant.\n * @returns A {@link DuplicateError} carrying the constraint name as its field hint.\n */\nfunction translateUniqueViolationToDuplicate(input: {\n entity: string;\n operation?: string;\n violation: UniqueConstraintViolation;\n field?: string;\n ctx?: {\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n nowIso?: string;\n };\n cause?: unknown;\n}): DuplicateError {\n return DuplicateError.detected({\n entity: input.entity,\n operation: input.operation,\n field: input.field,\n constraintName: input.violation.constraintName,\n detectedAtIso: input.ctx?.nowIso,\n correlationId: input.ctx?.correlationId,\n requestId: input.ctx?.requestId,\n commandId: input.ctx?.commandId,\n cause: input.cause,\n });\n}\n\nexport {\n AlreadyExistsError,\n ConflictError,\n DuplicateError,\n translateUniqueViolationToDuplicate,\n UniqueConstraintViolationError,\n};\n\nexport type { ConflictErrorMetadata, ConflictKind, UniqueConstraintViolation };\n","import { payloadHash, sha256Hex, stableStringify } from \"../shared/hashing.js\";\n\nimport { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\n\nexport type IdempotencyFailureKind =\n | \"key_missing\"\n | \"in_progress\"\n | \"payload_mismatch\"\n | \"replay_not_supported\"\n | \"unknown\";\n\nexport type IdempotencyErrorMetadata = {\n kind: IdempotencyFailureKind;\n operation: string;\n scope?: string;\n entity?: string;\n keyHash?: string;\n keyPreview?: string;\n incomingPayloadHash?: string;\n existingPayloadHash?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n};\n\ntype IdempotencyErrorConstructorInput = {\n message: string;\n code: string;\n kind: IdempotencyFailureKind;\n metadata: Omit<IdempotencyErrorMetadata, \"kind\">;\n cause?: unknown;\n};\n\nabstract class IdempotencyError extends AppError {\n public readonly kind: IdempotencyFailureKind;\n\n protected constructor(input: IdempotencyErrorConstructorInput) {\n super(input.message, input.code, {\n cause: input.cause,\n metadata: { kind: input.kind, ...input.metadata },\n });\n\n this.kind = input.kind;\n Object.freeze(this);\n }\n\n static keyMissing(input: {\n operation: string;\n scope?: string;\n entity?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyKeyMissingError {\n return IdempotencyKeyMissingError.detected(input);\n }\n\n static inProgress(input: {\n operation: string;\n scope?: string;\n entity?: string;\n key?: string;\n keyHash?: string;\n keyPreview?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyInProgressError {\n return IdempotencyInProgressError.detected(input);\n }\n\n static payloadMismatch(input: {\n operation: string;\n scope?: string;\n entity?: string;\n key?: string;\n keyHash?: string;\n keyPreview?: string;\n incomingPayloadHash?: string;\n existingPayloadHash?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyPayloadMismatchError {\n return IdempotencyPayloadMismatchError.detected(input);\n }\n\n static replayNotSupported(input: {\n operation: string;\n scope?: string;\n entity?: string;\n key?: string;\n keyHash?: string;\n keyPreview?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyReplayNotSupportedError {\n return IdempotencyReplayNotSupportedError.detected(input);\n }\n}\n\nclass IdempotencyKeyMissingError extends IdempotencyError {\n private constructor(input: {\n metadata: Omit<IdempotencyErrorMetadata, \"kind\">;\n cause?: unknown;\n }) {\n super({\n message:\n \"Idempotency key/commandId missing for the requested operation\",\n code: ErrorCodes.idempotency.keyMissing,\n kind: \"key_missing\",\n metadata: input.metadata,\n cause: input.cause,\n });\n }\n\n static detected(input: {\n operation: string;\n scope?: string;\n entity?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyKeyMissingError {\n return new IdempotencyKeyMissingError({\n cause: input.cause,\n metadata: {\n operation: input.operation,\n scope: input.scope,\n entity: input.entity,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n detectedAtIso: input.detectedAtIso,\n hint:\n input.hint ??\n \"Send a commandId/idempotency key to prevent duplicate processing.\",\n details: input.details,\n },\n });\n }\n}\n\nclass IdempotencyInProgressError extends IdempotencyError {\n private constructor(input: {\n metadata: Omit<IdempotencyErrorMetadata, \"kind\">;\n cause?: unknown;\n }) {\n super({\n message: \"The same business intent is already being processed\",\n code: ErrorCodes.idempotency.inProgress,\n kind: \"in_progress\",\n metadata: input.metadata,\n cause: input.cause,\n });\n }\n\n static detected(input: {\n operation: string;\n scope?: string;\n entity?: string;\n key?: string;\n keyHash?: string;\n keyPreview?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyInProgressError {\n const resolved = resolveKeyIdentity(\n input.key,\n input.keyHash,\n input.keyPreview,\n );\n\n return new IdempotencyInProgressError({\n cause: input.cause,\n metadata: {\n operation: input.operation,\n scope: input.scope,\n entity: input.entity,\n keyHash: resolved.keyHash,\n keyPreview: resolved.keyPreview,\n idempotencyRecordId: input.idempotencyRecordId,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n detectedAtIso: input.detectedAtIso,\n hint:\n input.hint ??\n \"Wait for completion and retry using the same key.\",\n details: input.details,\n },\n });\n }\n}\n\nclass IdempotencyPayloadMismatchError extends IdempotencyError {\n private constructor(input: {\n metadata: Omit<IdempotencyErrorMetadata, \"kind\">;\n cause?: unknown;\n }) {\n super({\n message: \"The idempotency key was reused with a different payload\",\n code: ErrorCodes.idempotency.payloadMismatch,\n kind: \"payload_mismatch\",\n metadata: input.metadata,\n cause: input.cause,\n });\n }\n\n static detected(input: {\n operation: string;\n scope?: string;\n entity?: string;\n key?: string;\n keyHash?: string;\n keyPreview?: string;\n incomingPayloadHash?: string;\n existingPayloadHash?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyPayloadMismatchError {\n const resolved = resolveKeyIdentity(\n input.key,\n input.keyHash,\n input.keyPreview,\n );\n\n return new IdempotencyPayloadMismatchError({\n cause: input.cause,\n metadata: {\n operation: input.operation,\n scope: input.scope,\n entity: input.entity,\n keyHash: resolved.keyHash,\n keyPreview: resolved.keyPreview,\n incomingPayloadHash: input.incomingPayloadHash,\n existingPayloadHash: input.existingPayloadHash,\n idempotencyRecordId: input.idempotencyRecordId,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n detectedAtIso: input.detectedAtIso,\n hint:\n input.hint ??\n \"Use a new idempotency key for a new intent. The same key should only be reused for retries of the same payload.\",\n details: input.details,\n },\n });\n }\n}\n\nclass IdempotencyReplayNotSupportedError extends IdempotencyError {\n private constructor(input: {\n metadata: Omit<IdempotencyErrorMetadata, \"kind\">;\n cause?: unknown;\n }) {\n super({\n message:\n \"Re-execution detected, but replay of the previous result is not implemented\",\n code: ErrorCodes.idempotency.replayNotSupported,\n kind: \"replay_not_supported\",\n metadata: input.metadata,\n cause: input.cause,\n });\n }\n\n static detected(input: {\n operation: string;\n scope?: string;\n entity?: string;\n key?: string;\n keyHash?: string;\n keyPreview?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyReplayNotSupportedError {\n const resolved = resolveKeyIdentity(\n input.key,\n input.keyHash,\n input.keyPreview,\n );\n\n return new IdempotencyReplayNotSupportedError({\n cause: input.cause,\n metadata: {\n operation: input.operation,\n scope: input.scope,\n entity: input.entity,\n keyHash: resolved.keyHash,\n keyPreview: resolved.keyPreview,\n idempotencyRecordId: input.idempotencyRecordId,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n detectedAtIso: input.detectedAtIso,\n hint:\n input.hint ??\n \"Try again later, or enable result replay for full idempotency.\",\n details: input.details,\n },\n });\n }\n}\n\nfunction resolveKeyIdentity(\n key?: string,\n keyHash?: string,\n keyPreview?: string,\n): { keyHash?: string; keyPreview?: string } {\n const preview =\n keyPreview ??\n (key ? (key.length <= 8 ? key : key.slice(0, 8)) : undefined);\n\n return {\n keyHash: keyHash,\n keyPreview: preview,\n };\n}\n\nexport {\n IdempotencyError,\n IdempotencyKeyMissingError,\n IdempotencyInProgressError,\n IdempotencyPayloadMismatchError,\n IdempotencyReplayNotSupportedError,\n sha256Hex,\n stableStringify,\n payloadHash,\n};\n","import type { AppErrorOptions, ErrorSeverity } from \"./types.js\";\nimport { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\n\ntype IntegrationErrorReason =\n | \"timeout\"\n | \"unreachable\"\n | \"bad_response\"\n | \"unknown\";\n\ntype IntegrationErrorMetadata = {\n reason: IntegrationErrorReason;\n provider: string;\n operation: string;\n startedAtIso: string;\n durationMs: number;\n detectedAtIso?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n details?: string;\n statusCode?: number;\n responseCode?: string;\n};\n\ntype IntegrationErrorAppOptions = Pick<\n AppErrorOptions,\n | \"cause\"\n | \"type\"\n | \"severity\"\n | \"correlationId\"\n | \"requestId\"\n | \"commandId\"\n | \"createdAtIso\"\n | \"publicMessage\"\n>;\n\ntype IntegrationErrorConstructorParams = {\n message: string;\n code: string;\n reason: IntegrationErrorReason;\n metadata: IntegrationErrorMetadata;\n} & IntegrationErrorAppOptions;\n\n/**\n * Raised when a call to an external provider fails — a timeout, an unreachable\n * endpoint, or a malformed response. This is the boundary error that separates\n * \"our code is fine, the outside world misbehaved\" from internal faults, which\n * matters for retry and alerting decisions.\n *\n * Every instance records the `provider`, the `operation`, and timing\n * (`startedAtIso` / `durationMs`) so failures are correlatable across services\n * and a slow dependency is visible in the metadata. The discriminating\n * {@link reason} lets callers decide whether a failure is worth retrying.\n * Instances are frozen; construct through the static factories.\n */\nclass IntegrationError extends AppError {\n public readonly reason: IntegrationErrorReason;\n\n private constructor(params: IntegrationErrorConstructorParams) {\n const { message, code, metadata, ...rest } = params;\n super(message, code, {\n ...rest,\n metadata,\n });\n\n this.reason = params.reason;\n Object.freeze(this);\n }\n\n /**\n * The provider did not respond within the allotted time. Usually retryable,\n * since a timeout leaves the outcome unknown rather than known-failed.\n */\n static timeout(options: IntegrationErrorTimeoutOptions): IntegrationError {\n return new IntegrationError({\n message: \"Timeout while integrating with external provider\",\n code: ErrorCodes.integration.timeout,\n reason: \"timeout\",\n metadata: buildMetadata({ reason: \"timeout\", ...options }),\n ...pickAppErrorFields(options),\n });\n }\n\n /**\n * The provider could not be reached at all (connection refused, DNS\n * failure, network partition) — the request never landed.\n */\n static unreachable(\n options: IntegrationErrorEndpointOptions,\n ): IntegrationError {\n return new IntegrationError({\n message: \"Provider unavailable\",\n code: ErrorCodes.integration.unreachable,\n reason: \"unreachable\",\n metadata: buildMetadata({ reason: \"unreachable\", ...options }),\n ...pickAppErrorFields(options),\n });\n }\n\n /**\n * The provider answered, but with something the system cannot use — an\n * unexpected status, an unparsable body, or a contract mismatch. Unlike a\n * timeout this is a definite failure, so blind retries rarely help.\n */\n static badResponse(\n options: IntegrationErrorEndpointOptions,\n ): IntegrationError {\n return new IntegrationError({\n message: \"Unexpected response from provider\",\n code: ErrorCodes.integration.badResponse,\n reason: \"bad_response\",\n metadata: buildMetadata({ reason: \"bad_response\", ...options }),\n ...pickAppErrorFields(options),\n });\n }\n}\n\ntype IntegrationErrorBaseOptions = {\n provider: string;\n operation: string;\n startedAtIso: string;\n durationMs: number;\n detectedAtIso?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n details?: string;\n statusCode?: number;\n responseCode?: string;\n cause?: unknown;\n type?: string;\n severity?: ErrorSeverity;\n createdAtIso?: string;\n publicMessage?: string;\n};\n\ntype IntegrationErrorTimeoutOptions = IntegrationErrorBaseOptions;\ntype IntegrationErrorEndpointOptions = IntegrationErrorBaseOptions;\n\nfunction buildMetadata(\n input: IntegrationErrorBaseOptions & { reason: IntegrationErrorReason },\n): IntegrationErrorMetadata {\n return compactMetadata({\n reason: input.reason,\n provider: input.provider,\n operation: input.operation,\n startedAtIso: input.startedAtIso,\n durationMs: input.durationMs,\n detectedAtIso: input.detectedAtIso,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n details: input.details,\n statusCode: input.statusCode,\n responseCode: input.responseCode,\n }) as IntegrationErrorMetadata;\n}\n\nfunction pickAppErrorFields(\n options: IntegrationErrorBaseOptions,\n): IntegrationErrorAppOptions {\n return {\n cause: options.cause,\n type: options.type,\n severity: options.severity,\n correlationId: options.correlationId,\n requestId: options.requestId,\n commandId: options.commandId,\n createdAtIso: options.createdAtIso,\n publicMessage: options.publicMessage,\n };\n}\n\nfunction compactMetadata<T extends Record<string, unknown>>(input: T): T {\n return Object.fromEntries(\n Object.entries(input).filter(([, value]) => value !== undefined),\n ) as T;\n}\n\nexport { IntegrationError };\nexport type { IntegrationErrorReason, IntegrationErrorMetadata };\n","import { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\nimport type { AppErrorOptions } from \"./types.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// LegacyIncompatibleError\n// ─────────────────────────────────────────────────────────────────────────────\n\nclass LegacyIncompatibleError extends AppError {\n constructor(\n message: string,\n context?: Record<string, unknown>,\n options?: AppErrorOptions,\n ) {\n const mergedMetadata = options?.metadata\n ? { ...(context ?? {}), ...options.metadata }\n : context;\n\n super(message, ErrorCodes.legacyIncompatible, {\n ...options,\n metadata: mergedMetadata,\n });\n }\n}\n\nexport { LegacyIncompatibleError };\n","import { AppError } from \"./app-error.js\";\nimport { serializationErrorCode } from \"./error-codes.js\";\nimport type { AppErrorOptions } from \"./types.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype SerializationDirection = \"serialize\" | \"deserialize\";\n\ntype SerializationFailureCategory =\n | \"invalid_json\"\n | \"invalid_shape\"\n | \"missing_field\"\n | \"unexpected_field\"\n | \"invalid_type\"\n | \"schema_version_missing\"\n | \"schema_version_unsupported\"\n | \"mapping_not_implemented\"\n | \"contract_mismatch\"\n | \"parse_failed\"\n | \"stringify_failed\"\n | \"unknown\";\n\ntype SerializationBoundary =\n | \"http_in\"\n | \"http_out\"\n | \"graphql_in\"\n | \"graphql_out\"\n | \"dto_to_domain\"\n | \"domain_to_dto\"\n | \"persistence_to_domain\"\n | \"domain_to_persistence\"\n | \"event_in\"\n | \"event_out\"\n | \"projection\"\n | \"unknown\";\n\n/**\n * Metadata shared by serialization/deserialization failures. Payload previews must be sanitized.\n */\ntype SerializationErrorMetadata = {\n direction: SerializationDirection;\n category: SerializationFailureCategory;\n boundary: SerializationBoundary;\n contract: string;\n schemaVersion?: number | string;\n path?: string;\n payloadPreview?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n hint?: string;\n details?: string;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Base error\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype SerializationErrorOptions = Omit<AppErrorOptions, \"metadata\"> & {\n message: string;\n code: string;\n metadata: Omit<SerializationErrorMetadata, \"direction\" | \"category\">;\n direction: SerializationDirection;\n category: SerializationFailureCategory;\n};\n\nabstract class SerializationError extends AppError {\n public readonly direction: SerializationDirection;\n public readonly category: SerializationFailureCategory;\n public readonly boundary: SerializationBoundary;\n public readonly contract: string;\n\n protected constructor(input: SerializationErrorOptions) {\n super(input.message ?? \"Serialization failure\", input.code, {\n cause: input.cause,\n metadata: {\n direction: input.direction,\n category: input.category,\n ...input.metadata,\n },\n type: input.type,\n severity: input.severity,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n createdAtIso: input.createdAtIso,\n publicMessage: input.publicMessage,\n });\n\n this.direction = input.direction;\n this.category = input.category;\n this.boundary = input.metadata.boundary;\n this.contract = input.metadata.contract;\n\n Object.freeze(this);\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Serialization In\n// ─────────────────────────────────────────────────────────────────────────────\n\nclass SerializationInError extends SerializationError {\n private constructor(input: SerializationErrorOptions) {\n super(input);\n }\n\n static failure(\n category: SerializationFailureCategory,\n metadata: Omit<SerializationErrorMetadata, \"direction\" | \"category\"> & {\n cause?: unknown;\n },\n ): SerializationInError {\n return new SerializationInError({\n message: SerializationMessages.message(\"deserialize\", category),\n code: SerializationCodes.code(\"deserialize\", category),\n category,\n direction: \"deserialize\",\n metadata,\n cause: metadata.cause,\n });\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Serialization\n// ─────────────────────────────────────────────────────────────────────────────\n\nclass SerializationOutError extends SerializationError {\n private constructor(input: SerializationErrorOptions) {\n super(input);\n }\n\n static failure(\n category: SerializationFailureCategory,\n metadata: Omit<SerializationErrorMetadata, \"direction\" | \"category\"> & {\n cause?: unknown;\n },\n ): SerializationOutError {\n return new SerializationOutError({\n message: SerializationMessages.message(\"serialize\", category),\n code: SerializationCodes.code(\"serialize\", category),\n category,\n direction: \"serialize\",\n metadata,\n cause: metadata.cause,\n });\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Codes + Messages helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\nclass SerializationCodes {\n static code(\n direction: SerializationDirection,\n category: SerializationFailureCategory,\n ): string {\n return serializationErrorCode(direction, category);\n }\n}\n\nclass SerializationMessages {\n static message(\n direction: SerializationDirection,\n category: SerializationFailureCategory,\n ): string {\n if (direction === \"deserialize\") {\n if (category === \"invalid_json\") {\n return \"Invalid payload: malformed JSON\";\n }\n if (category === \"schema_version_missing\") {\n return \"Invalid payload: schemaVersion is missing\";\n }\n if (category === \"schema_version_unsupported\") {\n return \"Invalid payload: schemaVersion is not supported\";\n }\n if (category === \"invalid_shape\") {\n return \"Invalid payload: incompatible shape\";\n }\n if (category === \"mapping_not_implemented\") {\n return \"Unsupported payload: mapping not implemented\";\n }\n if (category === \"contract_mismatch\") {\n return \"Payload does not match the expected contract\";\n }\n return \"Failed to parse incoming payload\";\n }\n\n if (category === \"stringify_failed\") {\n return \"Failed to serialize the response\";\n }\n if (category === \"contract_mismatch\") {\n return \"Response does not match the expected contract\";\n }\n return \"Failed to build the response\";\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Utilities\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction safePreview(value: unknown, limit = 240): string | undefined {\n try {\n const serialized =\n typeof value === \"string\" ? value : JSON.stringify(value);\n return serialized.length > limit\n ? `${serialized.slice(0, limit)}…`\n : serialized;\n } catch {\n return undefined;\n }\n}\n\nexport {\n safePreview,\n SerializationCodes,\n SerializationError,\n SerializationInError as DeserializationError,\n SerializationInError,\n SerializationMessages,\n SerializationOutError,\n};\nexport type {\n SerializationBoundary,\n SerializationDirection,\n SerializationErrorMetadata,\n SerializationFailureCategory,\n};\n","import { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\nimport type { AppErrorOptions } from \"./types.js\";\n\ntype TemporalKind = \"expired\" | \"not_yet_valid\";\n\ntype TemporalPrecision = \"EXACT\" | \"ESTIMATED\" | \"UNKNOWN\" | \"APPROXIMATE\";\n\ntype TemporalErrorMetadata = {\n resourceType: string;\n resourceId?: string;\n operation?: string;\n validFromIso?: string | null;\n validUntilIso?: string | null;\n evaluatedAtIso: string;\n policyId?: string;\n precision?: TemporalPrecision;\n hint?: string;\n details?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n};\n\ntype TemporalErrorOptions = {\n message: string;\n code: string;\n kind: TemporalKind;\n metadata: TemporalErrorMetadata;\n} & AppErrorOptions;\n\nabstract class TemporalError extends AppError {\n public readonly kind: TemporalKind;\n public readonly resourceType: string;\n public readonly evaluatedAtIso: string;\n\n protected constructor(input: TemporalErrorOptions) {\n super(input.message, input.code, {\n ...input,\n metadata: {\n kind: input.kind,\n ...input.metadata,\n },\n });\n\n this.kind = input.kind;\n this.resourceType = input.metadata.resourceType;\n this.evaluatedAtIso = input.metadata.evaluatedAtIso;\n Object.freeze(this);\n }\n}\n\ntype TemporalCreationInput = TemporalErrorMetadata &\n Partial<Omit<AppErrorOptions, \"metadata\">> & {\n cause?: unknown;\n };\n\nclass ExpiredError extends TemporalError {\n private constructor(input: TemporalErrorOptions) {\n super(input);\n }\n\n static detected(input: TemporalCreationInput): ExpiredError {\n return new ExpiredError({\n message: \"The validity of the resource/action has expired\",\n code: ErrorCodes.temporal.expired,\n kind: \"expired\",\n metadata: {\n ...input,\n hint:\n input.hint ??\n \"The window has expired. Request a new link or try again within the valid period.\",\n },\n cause: input.cause,\n type: input.type,\n severity: input.severity,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n createdAtIso: input.createdAtIso,\n publicMessage: input.publicMessage,\n });\n }\n}\n\nclass NotYetValidError extends TemporalError {\n private constructor(input: TemporalErrorOptions) {\n super(input);\n }\n\n static detected(input: TemporalCreationInput): NotYetValidError {\n return new NotYetValidError({\n message: \"The resource/action is not yet valid\",\n code: ErrorCodes.temporal.notYetValid,\n kind: \"not_yet_valid\",\n metadata: {\n ...input,\n hint:\n input.hint ??\n \"Not yet within the valid period. Try again later.\",\n },\n cause: input.cause,\n type: input.type,\n severity: input.severity,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n createdAtIso: input.createdAtIso,\n publicMessage: input.publicMessage,\n });\n }\n}\n\nfunction evaluateTemporalWindow(input: {\n validFromIso?: string | null;\n validUntilIso?: string | null;\n evaluatedAtIso: string;\n}): { expired: boolean; notYetValid: boolean } | null {\n const evaluatedMs = Date.parse(input.evaluatedAtIso);\n if (Number.isNaN(evaluatedMs)) return null;\n\n let notYetValid = false;\n\n if (input.validFromIso) {\n const fromMs = Date.parse(input.validFromIso);\n if (!Number.isNaN(fromMs) && evaluatedMs < fromMs) {\n notYetValid = true;\n }\n }\n\n if (input.validUntilIso) {\n const untilMs = Date.parse(input.validUntilIso);\n if (!Number.isNaN(untilMs) && evaluatedMs > untilMs) {\n return { expired: true, notYetValid: false };\n }\n }\n\n return { expired: false, notYetValid };\n}\n\nexport {\n evaluateTemporalWindow,\n ExpiredError,\n NotYetValidError,\n TemporalError,\n};\nexport type { TemporalErrorMetadata, TemporalKind, TemporalPrecision };\n","import { ValidationCode } from \"../exceptions/validation-code.js\";\nimport { ValidationField } from \"../exceptions/validation-field.js\";\n\nimport { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\nimport type { AppErrorOptions } from \"./types.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ValidationError\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Raised when a single input fails a validation rule — the canonical\n * \"this field is wrong, and here is why\" error.\n *\n * It pins the offending `field` and a machine-readable `validationCode` into\n * the metadata (merged ahead of any caller-supplied metadata) so an API layer\n * can map the failure straight onto a form field without parsing the message.\n * The fixed {@link ErrorCodes.validation} code lets callers catch all\n * validation failures uniformly while still distinguishing the specific rule\n * through `validationCode`.\n */\nclass ValidationError extends AppError {\n /**\n * @param field - The input that failed validation; surfaced as `metadata.field`.\n * @param code - The specific rule that was violated; surfaced as `metadata.validationCode`.\n * @param message - The developer-facing description of the failure.\n * @param options - Optional cause, correlation ids, and extra metadata\n * (merged over the field/code metadata, never overwriting it by accident).\n */\n constructor(\n field: ValidationField,\n code: ValidationCode,\n message: string,\n options?: AppErrorOptions,\n ) {\n const baseMetadata = {\n field: field.value,\n validationCode: code.value,\n };\n const mergedMetadata = options?.metadata\n ? { ...baseMetadata, ...options.metadata }\n : baseMetadata;\n\n super(message, ErrorCodes.validation, {\n ...options,\n metadata: mergedMetadata,\n });\n }\n}\n\nexport { ValidationError };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"validation-error.cjs","names":["AppError","ErrorCodes","compactMetadata","pickAppErrorOptions","AppError","ErrorCodes","AppError","ErrorCodes","sha256Hex","AppError","ErrorCodes","pickAppErrorOptions","compactMetadata","AppError","ErrorCodes","AppError","serializationErrorCode","AppError","ErrorCodes","stripAppErrorOptions","pickAppErrorOptions","AppError","ErrorCodes"],"sources":["../src/core/errors/authentication-error.ts","../src/core/errors/conflict-error.ts","../src/core/errors/idempotency-error.ts","../src/core/errors/integration-error.ts","../src/core/errors/legacy-incompatible-error.ts","../src/core/errors/serialization-error.ts","../src/core/errors/temporal-error.ts","../src/core/errors/validation-error.ts"],"sourcesContent":["import { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\nimport type { AppErrorOptions, ErrorSeverity } from \"./types.js\";\nimport { compactMetadata, pickAppErrorOptions } from \"./utils/index.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype AuthenticationErrorReason =\n | \"missing_token\"\n | \"malformed_token\"\n | \"invalid_token\"\n | \"expired_token\"\n | \"revoked_token\"\n | \"invalid_credentials\"\n | \"session_not_found\"\n | \"session_expired\"\n | \"unknown\";\n\ntype AuthenticationErrorMetadata = {\n reason: AuthenticationErrorReason;\n authScheme?: \"bearer\" | \"cookie\" | \"basic\" | \"unknown\";\n tokenLocation?: \"header\" | \"cookie\" | \"query\" | \"unknown\";\n expiresAtIso?: string;\n correlationId?: string;\n requestId?: string;\n details?: string;\n};\n\ntype AuthenticationErrorFactoryOptions = Omit<\n AuthenticationErrorMetadata,\n \"reason\"\n> &\n Omit<AppErrorOptions, \"metadata\">;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// AuthenticationError\n// ─────────────────────────────────────────────────────────────────────────────\n\nclass AuthenticationError extends AppError {\n public readonly reason: AuthenticationErrorReason;\n\n private constructor(params: {\n message: string;\n code: string;\n reason: AuthenticationErrorReason;\n metadata?: Omit<AuthenticationErrorMetadata, \"reason\">;\n cause?: unknown;\n type?: string;\n severity?: ErrorSeverity;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n createdAtIso?: string;\n publicMessage?: string;\n }) {\n super(params.message, params.code, {\n cause: params.cause,\n metadata: {\n reason: params.reason,\n ...(params.metadata ?? {}),\n },\n type: params.type,\n severity: params.severity,\n correlationId: params.correlationId,\n requestId: params.requestId,\n commandId: params.commandId,\n createdAtIso: params.createdAtIso,\n publicMessage: params.publicMessage,\n });\n\n this.reason = params.reason;\n Object.freeze(this);\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Factory methods\n // ─────────────────────────────────────────────────────────────────────────\n\n static missingToken(\n options?: AuthenticationErrorFactoryOptions,\n ): AuthenticationError {\n return new AuthenticationError({\n message: \"Missing credentials\",\n code: ErrorCodes.authentication.missingToken,\n reason: \"missing_token\",\n metadata: compactMetadata(options),\n ...pickAppErrorOptions(options),\n });\n }\n\n static invalidToken(\n options?: AuthenticationErrorFactoryOptions & { cause?: unknown },\n ): AuthenticationError {\n return new AuthenticationError({\n message: \"Invalid credentials\",\n code: ErrorCodes.authentication.invalidToken,\n reason: \"invalid_token\",\n metadata: compactMetadata({\n authScheme: options?.authScheme,\n tokenLocation: options?.tokenLocation,\n details: options?.details,\n correlationId: options?.correlationId,\n requestId: options?.requestId,\n }),\n ...pickAppErrorOptions(options),\n });\n }\n\n static expiredToken(\n options?: AuthenticationErrorFactoryOptions & { sessionId?: string },\n ): AuthenticationError {\n return new AuthenticationError({\n message: \"Expired credentials\",\n code: ErrorCodes.authentication.expiredToken,\n reason: \"expired_token\",\n metadata: compactMetadata(options),\n ...pickAppErrorOptions(options),\n });\n }\n\n static invalidCredentials(\n options?: Pick<\n AuthenticationErrorFactoryOptions,\n | \"correlationId\"\n | \"requestId\"\n | \"type\"\n | \"severity\"\n | \"createdAtIso\"\n | \"publicMessage\"\n >,\n ): AuthenticationError {\n return new AuthenticationError({\n message: \"Invalid username or password\",\n code: ErrorCodes.authentication.invalidCredentials,\n reason: \"invalid_credentials\",\n metadata: compactMetadata(options),\n ...pickAppErrorOptions(options),\n });\n }\n}\n\nexport { AuthenticationError };\nexport type { AuthenticationErrorMetadata, AuthenticationErrorReason };\n","import { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\nimport type { AppErrorOptions } from \"./types.js\";\n\n/**\n * Conflict kinds we want to distinguish semantically.\n */\ntype ConflictKind = \"already_exists\" | \"duplicate\" | \"unique_violation\";\n\n/**\n * Metadata attached to conflicts without exposing sensitive values.\n */\ntype ConflictErrorMetadata = {\n kind: ConflictKind;\n entity: string;\n operation?: string;\n field?: string;\n constraintName?: string;\n existingId?: string;\n valueHash?: string;\n valuePreview?: string;\n detectedAtIso?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n hint?: string;\n};\n\n/**\n * Storage-level description of a unique-constraint breach, as reported by a\n * database driver. Used to translate a raw DB error into a domain\n * {@link DuplicateError} via {@link translateUniqueViolationToDuplicate}.\n */\ntype UniqueConstraintViolation = {\n kind: \"unique_violation\";\n constraintName?: string;\n table?: string;\n columns?: string[];\n};\n\n/**\n * Base for errors that signal a state conflict — the request collides with data\n * that already exists. Common at an HTTP 409 boundary.\n *\n * The discriminating {@link kind} lets a handler branch on *why* it conflicted\n * (an already-existing record, a domain duplicate, or a raw storage uniqueness\n * breach) without `instanceof` chains. Abstract: construct one of the concrete\n * subclasses through its `detected(...)` factory, which fills in the right code,\n * message, and metadata. Instances are frozen, so a conflict error can be shared\n * and rethrown without risk of tampering.\n */\nabstract class ConflictError extends AppError {\n public readonly kind: ConflictKind;\n\n protected constructor(\n params: {\n message: string;\n code: string;\n kind: ConflictKind;\n metadata: Omit<ConflictErrorMetadata, \"kind\">;\n cause?: unknown;\n } & AppErrorOptions,\n ) {\n super(params.message, params.code, {\n ...params,\n metadata: {\n kind: params.kind,\n ...params.metadata,\n },\n });\n\n this.kind = params.kind;\n Object.freeze(this);\n }\n}\n\n/**\n * The operation cannot proceed because a matching record already exists —\n * e.g. creating something whose natural key is already taken. Construct via\n * {@link AlreadyExistsError.detected}.\n */\nclass AlreadyExistsError extends ConflictError {\n private constructor(\n input: {\n metadata: Omit<ConflictErrorMetadata, \"kind\">;\n cause?: unknown;\n } & AppErrorOptions,\n ) {\n super({\n message:\n \"A matching record already exists for the requested operation\",\n code: ErrorCodes.conflict.alreadyExists,\n kind: \"already_exists\",\n ...input,\n });\n }\n\n /**\n * Builds an {@link AlreadyExistsError} for a detected collision. `operation`\n * defaults to `\"create\"` and a generic retry `hint` is supplied when none is\n * given, so the error is actionable even from a minimal call site.\n *\n * @param input - The conflicting entity plus optional non-sensitive context\n * (operation, field, existing id, value hash/preview, correlation ids).\n */\n static detected(input: {\n entity: string;\n operation?: string;\n field?: string;\n existingId?: string;\n valueHash?: string;\n valuePreview?: string;\n detectedAtIso?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n hint?: string;\n cause?: unknown;\n }): AlreadyExistsError {\n return new AlreadyExistsError({\n metadata: {\n entity: input.entity,\n operation: input.operation ?? \"create\",\n field: input.field,\n existingId: input.existingId,\n valueHash: input.valueHash,\n valuePreview: input.valuePreview,\n detectedAtIso: input.detectedAtIso,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n hint: input.hint ?? \"Verify existing records before retrying.\",\n },\n cause: input.cause,\n });\n }\n}\n\n/**\n * A domain-level duplicate: the data being written would duplicate an existing\n * record under the model's own uniqueness rules. Use this when the duplication\n * is recognized in the domain, as opposed to a raw DB constraint\n * ({@link UniqueConstraintViolationError}). Construct via\n * {@link DuplicateError.detected}.\n */\nclass DuplicateError extends ConflictError {\n private constructor(\n input: {\n metadata: Omit<ConflictErrorMetadata, \"kind\">;\n cause?: unknown;\n } & AppErrorOptions,\n ) {\n super({\n message: \"Conflict: an existing record violates uniqueness\",\n code: ErrorCodes.conflict.duplicate,\n kind: \"duplicate\",\n ...input,\n });\n }\n\n /**\n * Builds a {@link DuplicateError} for a detected duplicate, defaulting to a\n * \"adjust the data so it does not duplicate\" hint when none is provided.\n *\n * @param input - The conflicting entity plus optional non-sensitive context\n * (field, constraint name, existing id, value hash/preview, correlation ids).\n */\n static detected(input: {\n entity: string;\n operation?: string;\n field?: string;\n constraintName?: string;\n existingId?: string;\n valueHash?: string;\n valuePreview?: string;\n detectedAtIso?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n hint?: string;\n cause?: unknown;\n }): DuplicateError {\n return new DuplicateError({\n metadata: {\n entity: input.entity,\n operation: input.operation,\n field: input.field,\n constraintName: input.constraintName,\n existingId: input.existingId,\n valueHash: input.valueHash,\n valuePreview: input.valuePreview,\n detectedAtIso: input.detectedAtIso,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n hint:\n input.hint ??\n \"Adjust the data so it does not duplicate existing records.\",\n },\n cause: input.cause,\n });\n }\n}\n\n/**\n * A uniqueness breach surfaced by the storage layer itself (a database unique\n * index), carrying the raw {@link UniqueConstraintViolation} (constraint, table,\n * columns). Keep this distinct from {@link DuplicateError}: this one is the\n * infrastructure signal; translate it into a domain duplicate at the boundary\n * with {@link translateUniqueViolationToDuplicate} when the model should own the\n * message. Construct via {@link UniqueConstraintViolationError.detected}.\n */\nclass UniqueConstraintViolationError extends ConflictError {\n private constructor(\n input: {\n metadata: Omit<ConflictErrorMetadata, \"kind\"> & {\n violation: UniqueConstraintViolation;\n };\n cause?: unknown;\n } & AppErrorOptions,\n ) {\n super({\n message: \"Uniqueness violation in storage\",\n code: ErrorCodes.conflict.uniqueViolation,\n kind: \"unique_violation\",\n ...input,\n });\n }\n\n /**\n * Builds a {@link UniqueConstraintViolationError} from the constraint details\n * a driver reports, packaging them into a nested `violation` payload.\n *\n * @param input - The entity plus the offending constraint name, table, and\n * columns, and optional correlation ids.\n */\n static detected(input: {\n entity: string;\n operation?: string;\n constraintName?: string;\n table?: string;\n columns?: string[];\n detectedAtIso?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n cause?: unknown;\n }): UniqueConstraintViolationError {\n return new UniqueConstraintViolationError({\n metadata: {\n entity: input.entity,\n operation: input.operation,\n constraintName: input.constraintName,\n detectedAtIso: input.detectedAtIso,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n violation: {\n kind: \"unique_violation\",\n constraintName: input.constraintName,\n table: input.table,\n columns: input.columns,\n },\n hint: \"Uniqueness conflict detected in the database.\",\n },\n cause: input.cause,\n });\n }\n}\n\n/**\n * Translates a raw storage {@link UniqueConstraintViolation} into a domain-level\n * {@link DuplicateError}. This is the seam where an infrastructure concern (a DB\n * unique index firing) is re-expressed in the language of the model, so callers\n * upstream catch a `DuplicateError` and never have to know a database was\n * involved.\n *\n * @param input - The entity, the driver-reported `violation`, and optional\n * request context (`ctx`) carrying correlation ids and a clock instant.\n * @returns A {@link DuplicateError} carrying the constraint name as its field hint.\n */\nfunction translateUniqueViolationToDuplicate(input: {\n entity: string;\n operation?: string;\n violation: UniqueConstraintViolation;\n field?: string;\n ctx?: {\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n nowIso?: string;\n };\n cause?: unknown;\n}): DuplicateError {\n return DuplicateError.detected({\n entity: input.entity,\n operation: input.operation,\n field: input.field,\n constraintName: input.violation.constraintName,\n detectedAtIso: input.ctx?.nowIso,\n correlationId: input.ctx?.correlationId,\n requestId: input.ctx?.requestId,\n commandId: input.ctx?.commandId,\n cause: input.cause,\n });\n}\n\nexport {\n AlreadyExistsError,\n ConflictError,\n DuplicateError,\n translateUniqueViolationToDuplicate,\n UniqueConstraintViolationError,\n};\n\nexport type { ConflictErrorMetadata, ConflictKind, UniqueConstraintViolation };\n","import { payloadHash, sha256Hex } from \"../shared/hashing.js\";\nimport { stableStringify } from \"../shared/stable-stringify.js\";\n\nimport { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\n\nexport type IdempotencyFailureKind =\n | \"key_missing\"\n | \"in_progress\"\n | \"payload_mismatch\"\n | \"replay_not_supported\"\n | \"unknown\";\n\nexport type IdempotencyErrorMetadata = {\n kind: IdempotencyFailureKind;\n operation: string;\n scope?: string;\n entity?: string;\n keyHash?: string;\n keyPreview?: string;\n incomingPayloadHash?: string;\n existingPayloadHash?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n};\n\ntype IdempotencyErrorConstructorInput = {\n message: string;\n code: string;\n kind: IdempotencyFailureKind;\n metadata: Omit<IdempotencyErrorMetadata, \"kind\">;\n cause?: unknown;\n};\n\nabstract class IdempotencyError extends AppError {\n public readonly kind: IdempotencyFailureKind;\n\n protected constructor(input: IdempotencyErrorConstructorInput) {\n super(input.message, input.code, {\n cause: input.cause,\n metadata: { kind: input.kind, ...input.metadata },\n });\n\n this.kind = input.kind;\n Object.freeze(this);\n }\n\n static keyMissing(input: {\n operation: string;\n scope?: string;\n entity?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyKeyMissingError {\n return IdempotencyKeyMissingError.detected(input);\n }\n\n static inProgress(input: {\n operation: string;\n scope?: string;\n entity?: string;\n key?: string;\n keyHash?: string;\n keyPreview?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyInProgressError {\n return IdempotencyInProgressError.detected(input);\n }\n\n static payloadMismatch(input: {\n operation: string;\n scope?: string;\n entity?: string;\n key?: string;\n keyHash?: string;\n keyPreview?: string;\n incomingPayloadHash?: string;\n existingPayloadHash?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyPayloadMismatchError {\n return IdempotencyPayloadMismatchError.detected(input);\n }\n\n static replayNotSupported(input: {\n operation: string;\n scope?: string;\n entity?: string;\n key?: string;\n keyHash?: string;\n keyPreview?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyReplayNotSupportedError {\n return IdempotencyReplayNotSupportedError.detected(input);\n }\n}\n\nclass IdempotencyKeyMissingError extends IdempotencyError {\n private constructor(input: {\n metadata: Omit<IdempotencyErrorMetadata, \"kind\">;\n cause?: unknown;\n }) {\n super({\n message:\n \"Idempotency key/commandId missing for the requested operation\",\n code: ErrorCodes.idempotency.keyMissing,\n kind: \"key_missing\",\n metadata: input.metadata,\n cause: input.cause,\n });\n }\n\n static detected(input: {\n operation: string;\n scope?: string;\n entity?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyKeyMissingError {\n return new IdempotencyKeyMissingError({\n cause: input.cause,\n metadata: {\n operation: input.operation,\n scope: input.scope,\n entity: input.entity,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n detectedAtIso: input.detectedAtIso,\n hint:\n input.hint ??\n \"Send a commandId/idempotency key to prevent duplicate processing.\",\n details: input.details,\n },\n });\n }\n}\n\nclass IdempotencyInProgressError extends IdempotencyError {\n private constructor(input: {\n metadata: Omit<IdempotencyErrorMetadata, \"kind\">;\n cause?: unknown;\n }) {\n super({\n message: \"The same business intent is already being processed\",\n code: ErrorCodes.idempotency.inProgress,\n kind: \"in_progress\",\n metadata: input.metadata,\n cause: input.cause,\n });\n }\n\n static detected(input: {\n operation: string;\n scope?: string;\n entity?: string;\n key?: string;\n keyHash?: string;\n keyPreview?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyInProgressError {\n const resolved = resolveKeyIdentity(\n input.key,\n input.keyHash,\n input.keyPreview,\n );\n\n return new IdempotencyInProgressError({\n cause: input.cause,\n metadata: {\n operation: input.operation,\n scope: input.scope,\n entity: input.entity,\n keyHash: resolved.keyHash,\n keyPreview: resolved.keyPreview,\n idempotencyRecordId: input.idempotencyRecordId,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n detectedAtIso: input.detectedAtIso,\n hint:\n input.hint ??\n \"Wait for completion and retry using the same key.\",\n details: input.details,\n },\n });\n }\n}\n\nclass IdempotencyPayloadMismatchError extends IdempotencyError {\n private constructor(input: {\n metadata: Omit<IdempotencyErrorMetadata, \"kind\">;\n cause?: unknown;\n }) {\n super({\n message: \"The idempotency key was reused with a different payload\",\n code: ErrorCodes.idempotency.payloadMismatch,\n kind: \"payload_mismatch\",\n metadata: input.metadata,\n cause: input.cause,\n });\n }\n\n static detected(input: {\n operation: string;\n scope?: string;\n entity?: string;\n key?: string;\n keyHash?: string;\n keyPreview?: string;\n incomingPayloadHash?: string;\n existingPayloadHash?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyPayloadMismatchError {\n const resolved = resolveKeyIdentity(\n input.key,\n input.keyHash,\n input.keyPreview,\n );\n\n return new IdempotencyPayloadMismatchError({\n cause: input.cause,\n metadata: {\n operation: input.operation,\n scope: input.scope,\n entity: input.entity,\n keyHash: resolved.keyHash,\n keyPreview: resolved.keyPreview,\n incomingPayloadHash: input.incomingPayloadHash,\n existingPayloadHash: input.existingPayloadHash,\n idempotencyRecordId: input.idempotencyRecordId,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n detectedAtIso: input.detectedAtIso,\n hint:\n input.hint ??\n \"Use a new idempotency key for a new intent. The same key should only be reused for retries of the same payload.\",\n details: input.details,\n },\n });\n }\n}\n\nclass IdempotencyReplayNotSupportedError extends IdempotencyError {\n private constructor(input: {\n metadata: Omit<IdempotencyErrorMetadata, \"kind\">;\n cause?: unknown;\n }) {\n super({\n message:\n \"Re-execution detected, but replay of the previous result is not implemented\",\n code: ErrorCodes.idempotency.replayNotSupported,\n kind: \"replay_not_supported\",\n metadata: input.metadata,\n cause: input.cause,\n });\n }\n\n static detected(input: {\n operation: string;\n scope?: string;\n entity?: string;\n key?: string;\n keyHash?: string;\n keyPreview?: string;\n idempotencyRecordId?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n detectedAtIso?: string;\n hint?: string;\n details?: string;\n cause?: unknown;\n }): IdempotencyReplayNotSupportedError {\n const resolved = resolveKeyIdentity(\n input.key,\n input.keyHash,\n input.keyPreview,\n );\n\n return new IdempotencyReplayNotSupportedError({\n cause: input.cause,\n metadata: {\n operation: input.operation,\n scope: input.scope,\n entity: input.entity,\n keyHash: resolved.keyHash,\n keyPreview: resolved.keyPreview,\n idempotencyRecordId: input.idempotencyRecordId,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n detectedAtIso: input.detectedAtIso,\n hint:\n input.hint ??\n \"Try again later, or enable result replay for full idempotency.\",\n details: input.details,\n },\n });\n }\n}\n\nfunction resolveKeyIdentity(\n key?: string,\n keyHash?: string,\n keyPreview?: string,\n): { keyHash?: string; keyPreview?: string } {\n const preview =\n keyPreview ??\n (key ? (key.length <= 8 ? key : key.slice(0, 8)) : undefined);\n\n return {\n // Derive the hash from the raw key when the caller didn't supply one —\n // cheap traceability without leaking the key itself.\n keyHash: keyHash ?? (key ? sha256Hex(key) : undefined),\n keyPreview: preview,\n };\n}\n\nexport {\n IdempotencyError,\n IdempotencyKeyMissingError,\n IdempotencyInProgressError,\n IdempotencyPayloadMismatchError,\n IdempotencyReplayNotSupportedError,\n sha256Hex,\n stableStringify,\n payloadHash,\n};\n","import type { AppErrorOptions, ErrorSeverity } from \"./types.js\";\nimport { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\nimport { compactMetadata, pickAppErrorOptions } from \"./utils/index.js\";\n\ntype IntegrationErrorReason =\n | \"timeout\"\n | \"unreachable\"\n | \"bad_response\"\n | \"unknown\";\n\ntype IntegrationErrorMetadata = {\n reason: IntegrationErrorReason;\n provider: string;\n operation: string;\n startedAtIso: string;\n durationMs: number;\n detectedAtIso?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n details?: string;\n statusCode?: number;\n responseCode?: string;\n};\n\ntype IntegrationErrorAppOptions = Pick<\n AppErrorOptions,\n | \"cause\"\n | \"type\"\n | \"severity\"\n | \"correlationId\"\n | \"requestId\"\n | \"commandId\"\n | \"createdAtIso\"\n | \"publicMessage\"\n>;\n\ntype IntegrationErrorConstructorParams = {\n message: string;\n code: string;\n reason: IntegrationErrorReason;\n metadata: IntegrationErrorMetadata;\n} & IntegrationErrorAppOptions;\n\n/**\n * Raised when a call to an external provider fails — a timeout, an unreachable\n * endpoint, or a malformed response. This is the boundary error that separates\n * \"our code is fine, the outside world misbehaved\" from internal faults, which\n * matters for retry and alerting decisions.\n *\n * Every instance records the `provider`, the `operation`, and timing\n * (`startedAtIso` / `durationMs`) so failures are correlatable across services\n * and a slow dependency is visible in the metadata. The discriminating\n * {@link reason} lets callers decide whether a failure is worth retrying.\n * Instances are frozen; construct through the static factories.\n */\nclass IntegrationError extends AppError {\n public readonly reason: IntegrationErrorReason;\n\n private constructor(params: IntegrationErrorConstructorParams) {\n const { message, code, metadata, ...rest } = params;\n super(message, code, {\n ...rest,\n metadata,\n });\n\n this.reason = params.reason;\n Object.freeze(this);\n }\n\n /**\n * The provider did not respond within the allotted time. Usually retryable,\n * since a timeout leaves the outcome unknown rather than known-failed.\n */\n static timeout(options: IntegrationErrorTimeoutOptions): IntegrationError {\n return new IntegrationError({\n message: \"Timeout while integrating with external provider\",\n code: ErrorCodes.integration.timeout,\n reason: \"timeout\",\n metadata: buildMetadata({ reason: \"timeout\", ...options }),\n ...pickAppErrorOptions(options),\n });\n }\n\n /**\n * The provider could not be reached at all (connection refused, DNS\n * failure, network partition) — the request never landed.\n */\n static unreachable(\n options: IntegrationErrorEndpointOptions,\n ): IntegrationError {\n return new IntegrationError({\n message: \"Provider unavailable\",\n code: ErrorCodes.integration.unreachable,\n reason: \"unreachable\",\n metadata: buildMetadata({ reason: \"unreachable\", ...options }),\n ...pickAppErrorOptions(options),\n });\n }\n\n /**\n * The provider answered, but with something the system cannot use — an\n * unexpected status, an unparsable body, or a contract mismatch. Unlike a\n * timeout this is a definite failure, so blind retries rarely help.\n */\n static badResponse(\n options: IntegrationErrorEndpointOptions,\n ): IntegrationError {\n return new IntegrationError({\n message: \"Unexpected response from provider\",\n code: ErrorCodes.integration.badResponse,\n reason: \"bad_response\",\n metadata: buildMetadata({ reason: \"bad_response\", ...options }),\n ...pickAppErrorOptions(options),\n });\n }\n}\n\ntype IntegrationErrorBaseOptions = {\n provider: string;\n operation: string;\n startedAtIso: string;\n durationMs: number;\n detectedAtIso?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n details?: string;\n statusCode?: number;\n responseCode?: string;\n cause?: unknown;\n type?: string;\n severity?: ErrorSeverity;\n createdAtIso?: string;\n publicMessage?: string;\n};\n\ntype IntegrationErrorTimeoutOptions = IntegrationErrorBaseOptions;\ntype IntegrationErrorEndpointOptions = IntegrationErrorBaseOptions;\n\nfunction buildMetadata(\n input: IntegrationErrorBaseOptions & { reason: IntegrationErrorReason },\n): IntegrationErrorMetadata {\n return compactMetadata({\n reason: input.reason,\n provider: input.provider,\n operation: input.operation,\n startedAtIso: input.startedAtIso,\n durationMs: input.durationMs,\n detectedAtIso: input.detectedAtIso,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n details: input.details,\n statusCode: input.statusCode,\n responseCode: input.responseCode,\n }) as IntegrationErrorMetadata;\n}\n\nexport { IntegrationError };\nexport type { IntegrationErrorReason, IntegrationErrorMetadata };\n","import { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\nimport type { AppErrorOptions } from \"./types.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// LegacyIncompatibleError\n// ─────────────────────────────────────────────────────────────────────────────\n\nclass LegacyIncompatibleError extends AppError {\n constructor(\n message: string,\n context?: Record<string, unknown>,\n options?: AppErrorOptions,\n ) {\n const mergedMetadata = options?.metadata\n ? { ...(context ?? {}), ...options.metadata }\n : context;\n\n super(message, ErrorCodes.legacyIncompatible, {\n ...options,\n metadata: mergedMetadata,\n });\n Object.freeze(this);\n }\n}\n\nexport { LegacyIncompatibleError };\n","import { AppError } from \"./app-error.js\";\nimport { serializationErrorCode } from \"./error-codes.js\";\nimport type { AppErrorOptions } from \"./types.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype SerializationDirection = \"serialize\" | \"deserialize\";\n\ntype SerializationFailureCategory =\n | \"invalid_json\"\n | \"invalid_shape\"\n | \"missing_field\"\n | \"unexpected_field\"\n | \"invalid_type\"\n | \"schema_version_missing\"\n | \"schema_version_unsupported\"\n | \"mapping_not_implemented\"\n | \"contract_mismatch\"\n | \"parse_failed\"\n | \"stringify_failed\"\n | \"unknown\";\n\ntype SerializationBoundary =\n | \"http_in\"\n | \"http_out\"\n | \"graphql_in\"\n | \"graphql_out\"\n | \"dto_to_domain\"\n | \"domain_to_dto\"\n | \"persistence_to_domain\"\n | \"domain_to_persistence\"\n | \"event_in\"\n | \"event_out\"\n | \"projection\"\n | \"unknown\";\n\n/**\n * Metadata shared by serialization/deserialization failures. Payload previews must be sanitized.\n */\ntype SerializationErrorMetadata = {\n direction: SerializationDirection;\n category: SerializationFailureCategory;\n boundary: SerializationBoundary;\n contract: string;\n schemaVersion?: number | string;\n path?: string;\n payloadPreview?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n hint?: string;\n details?: string;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Base error\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype SerializationErrorOptions = Omit<AppErrorOptions, \"metadata\"> & {\n message: string;\n code: string;\n metadata: Omit<SerializationErrorMetadata, \"direction\" | \"category\">;\n direction: SerializationDirection;\n category: SerializationFailureCategory;\n};\n\nabstract class SerializationError extends AppError {\n public readonly direction: SerializationDirection;\n public readonly category: SerializationFailureCategory;\n public readonly boundary: SerializationBoundary;\n public readonly contract: string;\n\n protected constructor(input: SerializationErrorOptions) {\n super(input.message ?? \"Serialization failure\", input.code, {\n cause: input.cause,\n metadata: {\n direction: input.direction,\n category: input.category,\n ...input.metadata,\n },\n type: input.type,\n severity: input.severity,\n correlationId: input.correlationId,\n requestId: input.requestId,\n commandId: input.commandId,\n createdAtIso: input.createdAtIso,\n publicMessage: input.publicMessage,\n });\n\n this.direction = input.direction;\n this.category = input.category;\n this.boundary = input.metadata.boundary;\n this.contract = input.metadata.contract;\n\n Object.freeze(this);\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Serialization In\n// ─────────────────────────────────────────────────────────────────────────────\n\nclass SerializationInError extends SerializationError {\n private constructor(input: SerializationErrorOptions) {\n super(input);\n }\n\n static failure(\n category: SerializationFailureCategory,\n metadata: Omit<SerializationErrorMetadata, \"direction\" | \"category\"> & {\n cause?: unknown;\n },\n ): SerializationInError {\n return new SerializationInError({\n message: SerializationMessages.message(\"deserialize\", category),\n code: SerializationCodes.code(\"deserialize\", category),\n category,\n direction: \"deserialize\",\n metadata,\n cause: metadata.cause,\n });\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Serialization\n// ─────────────────────────────────────────────────────────────────────────────\n\nclass SerializationOutError extends SerializationError {\n private constructor(input: SerializationErrorOptions) {\n super(input);\n }\n\n static failure(\n category: SerializationFailureCategory,\n metadata: Omit<SerializationErrorMetadata, \"direction\" | \"category\"> & {\n cause?: unknown;\n },\n ): SerializationOutError {\n return new SerializationOutError({\n message: SerializationMessages.message(\"serialize\", category),\n code: SerializationCodes.code(\"serialize\", category),\n category,\n direction: \"serialize\",\n metadata,\n cause: metadata.cause,\n });\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Codes + Messages helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\nclass SerializationCodes {\n static code(\n direction: SerializationDirection,\n category: SerializationFailureCategory,\n ): string {\n return serializationErrorCode(direction, category);\n }\n}\n\nclass SerializationMessages {\n static message(\n direction: SerializationDirection,\n category: SerializationFailureCategory,\n ): string {\n if (direction === \"deserialize\") {\n if (category === \"invalid_json\") {\n return \"Invalid payload: malformed JSON\";\n }\n if (category === \"schema_version_missing\") {\n return \"Invalid payload: schemaVersion is missing\";\n }\n if (category === \"schema_version_unsupported\") {\n return \"Invalid payload: schemaVersion is not supported\";\n }\n if (category === \"invalid_shape\") {\n return \"Invalid payload: incompatible shape\";\n }\n if (category === \"mapping_not_implemented\") {\n return \"Unsupported payload: mapping not implemented\";\n }\n if (category === \"contract_mismatch\") {\n return \"Payload does not match the expected contract\";\n }\n return \"Failed to parse incoming payload\";\n }\n\n if (category === \"stringify_failed\") {\n return \"Failed to serialize the response\";\n }\n if (category === \"contract_mismatch\") {\n return \"Response does not match the expected contract\";\n }\n return \"Failed to build the response\";\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Utilities\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction safePreview(value: unknown, limit = 240): string | undefined {\n try {\n const serialized =\n typeof value === \"string\" ? value : JSON.stringify(value);\n return serialized.length > limit\n ? `${serialized.slice(0, limit)}…`\n : serialized;\n } catch {\n return undefined;\n }\n}\n\nexport {\n safePreview,\n SerializationCodes,\n SerializationError,\n SerializationInError as DeserializationError,\n SerializationInError,\n SerializationMessages,\n SerializationOutError,\n};\nexport type {\n SerializationBoundary,\n SerializationDirection,\n SerializationErrorMetadata,\n SerializationFailureCategory,\n};\n","import { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\nimport type { AppErrorOptions } from \"./types.js\";\nimport { pickAppErrorOptions, stripAppErrorOptions } from \"./utils/index.js\";\n\ntype TemporalKind = \"expired\" | \"not_yet_valid\";\n\ntype TemporalPrecision = \"EXACT\" | \"ESTIMATED\" | \"UNKNOWN\" | \"APPROXIMATE\";\n\ntype TemporalErrorMetadata = {\n resourceType: string;\n resourceId?: string;\n operation?: string;\n validFromIso?: string | null;\n validUntilIso?: string | null;\n evaluatedAtIso: string;\n policyId?: string;\n precision?: TemporalPrecision;\n hint?: string;\n details?: string;\n correlationId?: string;\n requestId?: string;\n commandId?: string;\n};\n\ntype TemporalErrorOptions = {\n message: string;\n code: string;\n kind: TemporalKind;\n metadata: TemporalErrorMetadata;\n} & AppErrorOptions;\n\nabstract class TemporalError extends AppError {\n public readonly kind: TemporalKind;\n public readonly resourceType: string;\n public readonly evaluatedAtIso: string;\n\n protected constructor(input: TemporalErrorOptions) {\n super(input.message, input.code, {\n ...input,\n metadata: {\n kind: input.kind,\n ...input.metadata,\n },\n });\n\n this.kind = input.kind;\n this.resourceType = input.metadata.resourceType;\n this.evaluatedAtIso = input.metadata.evaluatedAtIso;\n Object.freeze(this);\n }\n}\n\ntype TemporalCreationInput = TemporalErrorMetadata &\n Partial<Omit<AppErrorOptions, \"metadata\">> & {\n cause?: unknown;\n };\n\nclass ExpiredError extends TemporalError {\n private constructor(input: TemporalErrorOptions) {\n super(input);\n }\n\n static detected(input: TemporalCreationInput): ExpiredError {\n return new ExpiredError({\n message: \"The validity of the resource/action has expired\",\n code: ErrorCodes.temporal.expired,\n kind: \"expired\",\n metadata: {\n ...stripAppErrorOptions(input),\n hint:\n input.hint ??\n \"The window has expired. Request a new link or try again within the valid period.\",\n },\n ...pickAppErrorOptions(input),\n });\n }\n}\n\nclass NotYetValidError extends TemporalError {\n private constructor(input: TemporalErrorOptions) {\n super(input);\n }\n\n static detected(input: TemporalCreationInput): NotYetValidError {\n return new NotYetValidError({\n message: \"The resource/action is not yet valid\",\n code: ErrorCodes.temporal.notYetValid,\n kind: \"not_yet_valid\",\n metadata: {\n ...stripAppErrorOptions(input),\n hint:\n input.hint ??\n \"Not yet within the valid period. Try again later.\",\n },\n ...pickAppErrorOptions(input),\n });\n }\n}\n\n/**\n * Evaluates whether `evaluatedAtIso` falls inside the [`validFromIso`,\n * `validUntilIso`] window.\n *\n * Fails **closed**: a boundary that is present but unparseable is treated as if\n * the window were closed on that side (a bad `validUntilIso` → expired, a bad\n * `validFromIso` → not-yet-valid), never silently ignored — these checks guard\n * access (invites, links, tokens), so a typo in an expiry must not disable\n * expiry. A `null`/absent boundary means \"no bound on that side\", which is\n * distinct from a malformed one. Returns `null` only when `evaluatedAtIso`\n * itself is unparseable (nothing can be decided).\n *\n * For an inverted window (`validFrom` > `validUntil`) `expired` wins, since the\n * upper-bound check short-circuits.\n */\nfunction evaluateTemporalWindow(input: {\n validFromIso?: string | null;\n validUntilIso?: string | null;\n evaluatedAtIso: string;\n}): { expired: boolean; notYetValid: boolean } | null {\n const evaluatedMs = Date.parse(input.evaluatedAtIso);\n if (Number.isNaN(evaluatedMs)) return null;\n\n let notYetValid = false;\n\n if (input.validFromIso) {\n const fromMs = Date.parse(input.validFromIso);\n if (Number.isNaN(fromMs) || evaluatedMs < fromMs) {\n notYetValid = true;\n }\n }\n\n if (input.validUntilIso) {\n const untilMs = Date.parse(input.validUntilIso);\n if (Number.isNaN(untilMs) || evaluatedMs > untilMs) {\n return { expired: true, notYetValid: false };\n }\n }\n\n return { expired: false, notYetValid };\n}\n\nexport {\n evaluateTemporalWindow,\n ExpiredError,\n NotYetValidError,\n TemporalError,\n};\nexport type { TemporalErrorMetadata, TemporalKind, TemporalPrecision };\n","import { ValidationCode } from \"../exceptions/validation-code.js\";\nimport { ValidationField } from \"../exceptions/validation-field.js\";\n\nimport { AppError } from \"./app-error.js\";\nimport { ErrorCodes } from \"./error-codes.js\";\nimport type { AppErrorOptions } from \"./types.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ValidationError\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Raised when a single input fails a validation rule — the canonical\n * \"this field is wrong, and here is why\" error.\n *\n * It pins the offending `field` and a machine-readable `validationCode` into\n * the metadata (merged ahead of any caller-supplied metadata) so an API layer\n * can map the failure straight onto a form field without parsing the message.\n * The fixed {@link ErrorCodes.validation} code lets callers catch all\n * validation failures uniformly while still distinguishing the specific rule\n * through `validationCode`.\n */\nclass ValidationError extends AppError {\n /**\n * @param field - The input that failed validation; surfaced as `metadata.field`.\n * @param code - The specific rule that was violated; surfaced as `metadata.validationCode`.\n * @param message - The developer-facing description of the failure.\n * @param options - Optional cause, correlation ids, and extra metadata\n * (merged over the field/code metadata, never overwriting it by accident).\n */\n constructor(\n field: ValidationField,\n code: ValidationCode,\n message: string,\n options?: AppErrorOptions,\n ) {\n const baseMetadata = {\n field: field.value,\n validationCode: code.value,\n };\n // `field`/`validationCode` spread last so caller metadata is merged\n // over them without ever overwriting them by accident.\n const mergedMetadata = options?.metadata\n ? { ...options.metadata, ...baseMetadata }\n : baseMetadata;\n\n super(message, ErrorCodes.validation, {\n ...options,\n metadata: mergedMetadata,\n });\n Object.freeze(this);\n }\n}\n\nexport { ValidationError };\n"],"mappings":"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"}
|
|
@@ -269,6 +269,10 @@ declare function translateUniqueViolationToDuplicate(input: {
|
|
|
269
269
|
cause?: unknown;
|
|
270
270
|
}): DuplicateError;
|
|
271
271
|
//#endregion
|
|
272
|
+
//#region src/core/shared/hashing.d.ts
|
|
273
|
+
declare function sha256Hex(value: string): string;
|
|
274
|
+
declare function payloadHash(value: unknown): string;
|
|
275
|
+
//#endregion
|
|
272
276
|
//#region src/core/shared/stable-stringify.d.ts
|
|
273
277
|
/**
|
|
274
278
|
* Deterministic JSON string with object keys sorted recursively, so key order
|
|
@@ -277,18 +281,15 @@ declare function translateUniqueViolationToDuplicate(input: {
|
|
|
277
281
|
* Follows `JSON.stringify` semantics for the values it serializes: `undefined`,
|
|
278
282
|
* functions and symbols are dropped, non-finite numbers become `null`, `bigint`
|
|
279
283
|
* throws, and `Map`/`Set` serialize as `{}`. Distinct payloads can therefore
|
|
280
|
-
* collapse to the same string — for
|
|
281
|
-
*
|
|
282
|
-
*
|
|
284
|
+
* collapse to the same string — this is fine for the structural-equality use it
|
|
285
|
+
* serves (comparing two value objects), but **not** for hashing. For a
|
|
286
|
+
* collision-resistant canonical form use {@link canonicalStringify}, which
|
|
287
|
+
* rejects those lossy values up front.
|
|
283
288
|
*
|
|
284
289
|
* @throws {TypeError} On circular references (mirroring `JSON.stringify`).
|
|
285
290
|
*/
|
|
286
291
|
declare function stableStringify(value: unknown): string;
|
|
287
292
|
//#endregion
|
|
288
|
-
//#region src/core/shared/hashing.d.ts
|
|
289
|
-
declare function sha256Hex(value: string): string;
|
|
290
|
-
declare function payloadHash(value: unknown): string;
|
|
291
|
-
//#endregion
|
|
292
293
|
//#region src/core/errors/idempotency-error.d.ts
|
|
293
294
|
type IdempotencyFailureKind = "key_missing" | "in_progress" | "payload_mismatch" | "replay_not_supported" | "unknown";
|
|
294
295
|
type IdempotencyErrorMetadata = {
|
|
@@ -645,6 +646,21 @@ declare class NotYetValidError extends TemporalError {
|
|
|
645
646
|
private constructor();
|
|
646
647
|
static detected(input: TemporalCreationInput): NotYetValidError;
|
|
647
648
|
}
|
|
649
|
+
/**
|
|
650
|
+
* Evaluates whether `evaluatedAtIso` falls inside the [`validFromIso`,
|
|
651
|
+
* `validUntilIso`] window.
|
|
652
|
+
*
|
|
653
|
+
* Fails **closed**: a boundary that is present but unparseable is treated as if
|
|
654
|
+
* the window were closed on that side (a bad `validUntilIso` → expired, a bad
|
|
655
|
+
* `validFromIso` → not-yet-valid), never silently ignored — these checks guard
|
|
656
|
+
* access (invites, links, tokens), so a typo in an expiry must not disable
|
|
657
|
+
* expiry. A `null`/absent boundary means "no bound on that side", which is
|
|
658
|
+
* distinct from a malformed one. Returns `null` only when `evaluatedAtIso`
|
|
659
|
+
* itself is unparseable (nothing can be decided).
|
|
660
|
+
*
|
|
661
|
+
* For an inverted window (`validFrom` > `validUntil`) `expired` wins, since the
|
|
662
|
+
* upper-bound check short-circuits.
|
|
663
|
+
*/
|
|
648
664
|
declare function evaluateTemporalWindow(input: {
|
|
649
665
|
validFromIso?: string | null;
|
|
650
666
|
validUntilIso?: string | null;
|
|
@@ -682,5 +698,5 @@ declare class ValidationError extends AppError {
|
|
|
682
698
|
constructor(field: ValidationField, code: ValidationCode, message: string, options?: AppErrorOptions);
|
|
683
699
|
}
|
|
684
700
|
//#endregion
|
|
685
|
-
export { IdempotencyPayloadMismatchError as A, UniqueConstraintViolation as B, IntegrationErrorMetadata as C, IdempotencyFailureKind as D, IdempotencyErrorMetadata as E, AlreadyExistsError as F, AuthenticationErrorMetadata as G, translateUniqueViolationToDuplicate as H, ConflictError as I, ErrorCodes as J, AuthenticationErrorReason as K, ConflictErrorMetadata as L,
|
|
701
|
+
export { IdempotencyPayloadMismatchError as A, UniqueConstraintViolation as B, IntegrationErrorMetadata as C, IdempotencyFailureKind as D, IdempotencyErrorMetadata as E, AlreadyExistsError as F, AuthenticationErrorMetadata as G, translateUniqueViolationToDuplicate as H, ConflictError as I, ErrorCodes as J, AuthenticationErrorReason as K, ConflictErrorMetadata as L, stableStringify as M, payloadHash as N, IdempotencyInProgressError as O, sha256Hex as P, ConflictKind as R, IntegrationError as S, IdempotencyError as T, BusinessRuleViolationError as U, UniqueConstraintViolationError as V, AuthenticationError as W, serializationErrorCode as Y, SerializationMessages as _, TemporalError as a, NotFoundError as b, TemporalPrecision as c, SerializationCodes as d, SerializationDirection as f, SerializationInError as g, SerializationFailureCategory as h, NotYetValidError as i, IdempotencyReplayNotSupportedError as j, IdempotencyKeyMissingError as k, evaluateTemporalWindow as l, SerializationErrorMetadata as m, UnexpectedError as n, TemporalErrorMetadata as o, SerializationError as p, assertJsonSafeMetadata as q, ExpiredError as r, TemporalKind as s, ValidationError as t, SerializationBoundary as u, SerializationOutError as v, IntegrationErrorReason as w, LegacyIncompatibleError as x, safePreview as y, DuplicateError as z };
|
|
686
702
|
//# sourceMappingURL=validation-error.d.cts.map
|
|
@@ -269,6 +269,10 @@ declare function translateUniqueViolationToDuplicate(input: {
|
|
|
269
269
|
cause?: unknown;
|
|
270
270
|
}): DuplicateError;
|
|
271
271
|
//#endregion
|
|
272
|
+
//#region src/core/shared/hashing.d.ts
|
|
273
|
+
declare function sha256Hex(value: string): string;
|
|
274
|
+
declare function payloadHash(value: unknown): string;
|
|
275
|
+
//#endregion
|
|
272
276
|
//#region src/core/shared/stable-stringify.d.ts
|
|
273
277
|
/**
|
|
274
278
|
* Deterministic JSON string with object keys sorted recursively, so key order
|
|
@@ -277,18 +281,15 @@ declare function translateUniqueViolationToDuplicate(input: {
|
|
|
277
281
|
* Follows `JSON.stringify` semantics for the values it serializes: `undefined`,
|
|
278
282
|
* functions and symbols are dropped, non-finite numbers become `null`, `bigint`
|
|
279
283
|
* throws, and `Map`/`Set` serialize as `{}`. Distinct payloads can therefore
|
|
280
|
-
* collapse to the same string — for
|
|
281
|
-
*
|
|
282
|
-
*
|
|
284
|
+
* collapse to the same string — this is fine for the structural-equality use it
|
|
285
|
+
* serves (comparing two value objects), but **not** for hashing. For a
|
|
286
|
+
* collision-resistant canonical form use {@link canonicalStringify}, which
|
|
287
|
+
* rejects those lossy values up front.
|
|
283
288
|
*
|
|
284
289
|
* @throws {TypeError} On circular references (mirroring `JSON.stringify`).
|
|
285
290
|
*/
|
|
286
291
|
declare function stableStringify(value: unknown): string;
|
|
287
292
|
//#endregion
|
|
288
|
-
//#region src/core/shared/hashing.d.ts
|
|
289
|
-
declare function sha256Hex(value: string): string;
|
|
290
|
-
declare function payloadHash(value: unknown): string;
|
|
291
|
-
//#endregion
|
|
292
293
|
//#region src/core/errors/idempotency-error.d.ts
|
|
293
294
|
type IdempotencyFailureKind = "key_missing" | "in_progress" | "payload_mismatch" | "replay_not_supported" | "unknown";
|
|
294
295
|
type IdempotencyErrorMetadata = {
|
|
@@ -645,6 +646,21 @@ declare class NotYetValidError extends TemporalError {
|
|
|
645
646
|
private constructor();
|
|
646
647
|
static detected(input: TemporalCreationInput): NotYetValidError;
|
|
647
648
|
}
|
|
649
|
+
/**
|
|
650
|
+
* Evaluates whether `evaluatedAtIso` falls inside the [`validFromIso`,
|
|
651
|
+
* `validUntilIso`] window.
|
|
652
|
+
*
|
|
653
|
+
* Fails **closed**: a boundary that is present but unparseable is treated as if
|
|
654
|
+
* the window were closed on that side (a bad `validUntilIso` → expired, a bad
|
|
655
|
+
* `validFromIso` → not-yet-valid), never silently ignored — these checks guard
|
|
656
|
+
* access (invites, links, tokens), so a typo in an expiry must not disable
|
|
657
|
+
* expiry. A `null`/absent boundary means "no bound on that side", which is
|
|
658
|
+
* distinct from a malformed one. Returns `null` only when `evaluatedAtIso`
|
|
659
|
+
* itself is unparseable (nothing can be decided).
|
|
660
|
+
*
|
|
661
|
+
* For an inverted window (`validFrom` > `validUntil`) `expired` wins, since the
|
|
662
|
+
* upper-bound check short-circuits.
|
|
663
|
+
*/
|
|
648
664
|
declare function evaluateTemporalWindow(input: {
|
|
649
665
|
validFromIso?: string | null;
|
|
650
666
|
validUntilIso?: string | null;
|
|
@@ -682,5 +698,5 @@ declare class ValidationError extends AppError {
|
|
|
682
698
|
constructor(field: ValidationField, code: ValidationCode, message: string, options?: AppErrorOptions);
|
|
683
699
|
}
|
|
684
700
|
//#endregion
|
|
685
|
-
export { IdempotencyPayloadMismatchError as A, UniqueConstraintViolation as B, IntegrationErrorMetadata as C, IdempotencyFailureKind as D, IdempotencyErrorMetadata as E, AlreadyExistsError as F, AuthenticationErrorMetadata as G, translateUniqueViolationToDuplicate as H, ConflictError as I, ErrorCodes as J, AuthenticationErrorReason as K, ConflictErrorMetadata as L,
|
|
701
|
+
export { IdempotencyPayloadMismatchError as A, UniqueConstraintViolation as B, IntegrationErrorMetadata as C, IdempotencyFailureKind as D, IdempotencyErrorMetadata as E, AlreadyExistsError as F, AuthenticationErrorMetadata as G, translateUniqueViolationToDuplicate as H, ConflictError as I, ErrorCodes as J, AuthenticationErrorReason as K, ConflictErrorMetadata as L, stableStringify as M, payloadHash as N, IdempotencyInProgressError as O, sha256Hex as P, ConflictKind as R, IntegrationError as S, IdempotencyError as T, BusinessRuleViolationError as U, UniqueConstraintViolationError as V, AuthenticationError as W, serializationErrorCode as Y, SerializationMessages as _, TemporalError as a, NotFoundError as b, TemporalPrecision as c, SerializationCodes as d, SerializationDirection as f, SerializationInError as g, SerializationFailureCategory as h, NotYetValidError as i, IdempotencyReplayNotSupportedError as j, IdempotencyKeyMissingError as k, evaluateTemporalWindow as l, SerializationErrorMetadata as m, UnexpectedError as n, TemporalErrorMetadata as o, SerializationError as p, assertJsonSafeMetadata as q, ExpiredError as r, TemporalKind as s, ValidationError as t, SerializationBoundary as u, SerializationOutError as v, IntegrationErrorReason as w, LegacyIncompatibleError as x, safePreview as y, DuplicateError as z };
|
|
686
702
|
//# sourceMappingURL=validation-error.d.ts.map
|