@cullet/erp-core 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/KIT_CONTEXT.md +1 -67
  2. package/dist/app-error.d.cts +108 -0
  3. package/dist/application/index.cjs +26 -0
  4. package/dist/application/index.d.cts +2 -0
  5. package/dist/application/index.d.ts +1 -1
  6. package/dist/application/index.js +2 -1
  7. package/dist/domain/index.cjs +16 -0
  8. package/dist/domain/index.d.cts +3 -0
  9. package/dist/domain/index.d.ts +3 -0
  10. package/dist/domain/index.js +3 -0
  11. package/dist/domain-event-contracts.cjs +33 -0
  12. package/dist/domain-event-contracts.cjs.map +1 -0
  13. package/dist/domain-event-contracts.d.cts +27 -0
  14. package/dist/domain-event-contracts.d.ts +27 -0
  15. package/dist/domain-event-contracts.js +22 -0
  16. package/dist/domain-event-contracts.js.map +1 -0
  17. package/dist/domain-exception.cjs +17 -0
  18. package/dist/domain-exception.cjs.map +1 -0
  19. package/dist/domain-exception.d.cts +7 -0
  20. package/dist/domain-exception.d.ts +7 -0
  21. package/dist/domain-exception.js +12 -0
  22. package/dist/domain-exception.js.map +1 -0
  23. package/dist/errors/index.cjs +41 -0
  24. package/dist/errors/index.d.cts +3 -0
  25. package/dist/errors/index.js +1 -1
  26. package/dist/exceptions/index.cjs +17 -0
  27. package/dist/exceptions/index.d.cts +5 -0
  28. package/dist/exceptions/index.d.ts +5 -0
  29. package/dist/exceptions/index.js +7 -0
  30. package/dist/exceptions/validation-field.cjs +3 -0
  31. package/dist/exceptions/validation-field.d.cts +2 -0
  32. package/dist/gate-engine-registry.cjs +308 -0
  33. package/dist/gate-engine-registry.cjs.map +1 -0
  34. package/dist/gate-engine-registry.d.cts +81 -0
  35. package/dist/gate-engine-registry.d.ts +2 -1
  36. package/dist/gate-engine-registry.js +2 -1
  37. package/dist/gate-engine-registry.js.map +1 -1
  38. package/dist/gate-types.d.cts +171 -0
  39. package/dist/gate-types.d.ts +3 -139
  40. package/dist/gate-v1-payload.schema.cjs +638 -0
  41. package/dist/gate-v1-payload.schema.cjs.map +1 -0
  42. package/dist/gate-v1-payload.schema.js +2 -116
  43. package/dist/gate-v1-payload.schema.js.map +1 -1
  44. package/dist/hashing.cjs +66 -0
  45. package/dist/hashing.cjs.map +1 -0
  46. package/dist/immutable.cjs +77 -0
  47. package/dist/immutable.cjs.map +1 -0
  48. package/dist/immutable.d.cts +6 -0
  49. package/dist/immutable.d.ts +6 -0
  50. package/dist/immutable.js +54 -0
  51. package/dist/immutable.js.map +1 -0
  52. package/dist/index.cjs +163 -0
  53. package/dist/index.cjs.map +1 -0
  54. package/dist/index.d.cts +30 -0
  55. package/dist/index.d.ts +15 -160
  56. package/dist/index.js +19 -176
  57. package/dist/index.js.map +1 -1
  58. package/dist/invalid-state-transition-exception.cjs +47 -0
  59. package/dist/invalid-state-transition-exception.cjs.map +1 -0
  60. package/dist/invalid-state-transition-exception.js +30 -0
  61. package/dist/invalid-state-transition-exception.js.map +1 -0
  62. package/dist/invariant-violation-exception.cjs +16 -0
  63. package/dist/invariant-violation-exception.cjs.map +1 -0
  64. package/dist/invariant-violation-exception.js +11 -0
  65. package/dist/invariant-violation-exception.js.map +1 -0
  66. package/dist/not-found-error.cjs +65 -0
  67. package/dist/not-found-error.cjs.map +1 -0
  68. package/dist/not-found-error.js +1 -1
  69. package/dist/outcome.cjs +97 -0
  70. package/dist/outcome.cjs.map +1 -0
  71. package/dist/outcome.d.cts +140 -0
  72. package/dist/outcome.d.ts +140 -0
  73. package/dist/outcome.js +1 -1
  74. package/dist/parse-gate-payload.d.cts +62 -0
  75. package/dist/parse-gate-payload.d.ts +2 -1
  76. package/dist/path.d.cts +90 -0
  77. package/dist/path.d.ts +2 -1
  78. package/dist/plugin.cjs +79 -0
  79. package/dist/plugin.cjs.map +1 -0
  80. package/dist/plugin.d.cts +85 -0
  81. package/dist/plugin.d.ts +85 -0
  82. package/dist/plugin.js +74 -0
  83. package/dist/plugin.js.map +1 -0
  84. package/dist/plugins/index.cjs +3 -0
  85. package/dist/plugins/index.d.cts +2 -0
  86. package/dist/plugins/index.d.ts +2 -0
  87. package/dist/plugins/index.js +2 -0
  88. package/dist/policies/engines/index.cjs +10 -0
  89. package/dist/policies/engines/index.d.cts +4 -0
  90. package/dist/policies/engines/index.d.ts +1 -1
  91. package/dist/policies/engines/v1/gate/index.cjs +91 -0
  92. package/dist/policies/engines/v1/gate/index.cjs.map +1 -0
  93. package/dist/policies/engines/v1/gate/index.d.cts +121 -0
  94. package/dist/policies/engines/v1/gate/index.d.ts +2 -1
  95. package/dist/policies/engines/v1/gate/index.js +2 -1
  96. package/dist/policies/engines/v1/gate/index.js.map +1 -1
  97. package/dist/policies/index.cjs +41 -0
  98. package/dist/policies/index.d.cts +7 -0
  99. package/dist/policies/index.d.ts +2 -1
  100. package/dist/policies/index.js +2 -1
  101. package/dist/policy-service.cjs +1190 -0
  102. package/dist/policy-service.cjs.map +1 -0
  103. package/dist/policy-service.d.cts +559 -0
  104. package/dist/policy-service.d.ts +2 -1
  105. package/dist/policy-service.js +6 -3
  106. package/dist/policy-service.js.map +1 -1
  107. package/dist/result/index.cjs +7 -0
  108. package/dist/result/index.d.cts +2 -0
  109. package/dist/result/index.d.ts +2 -0
  110. package/dist/result/index.js +3 -0
  111. package/dist/result.cjs +135 -0
  112. package/dist/result.cjs.map +1 -0
  113. package/dist/result.js +118 -0
  114. package/dist/result.js.map +1 -0
  115. package/dist/ruleset-registry.cjs +47 -0
  116. package/dist/ruleset-registry.cjs.map +1 -0
  117. package/dist/ruleset-registry.js +42 -0
  118. package/dist/ruleset-registry.js.map +1 -0
  119. package/dist/rulesets/index.cjs +3 -0
  120. package/dist/rulesets/index.d.cts +2 -0
  121. package/dist/rulesets/index.d.ts +2 -0
  122. package/dist/rulesets/index.js +2 -0
  123. package/dist/temporal-guards.cjs +32 -0
  124. package/dist/temporal-guards.cjs.map +1 -0
  125. package/dist/temporal-guards.js +2 -17
  126. package/dist/temporal-guards.js.map +1 -1
  127. package/dist/temporal-use-case.cjs +191 -0
  128. package/dist/temporal-use-case.cjs.map +1 -0
  129. package/dist/temporal-use-case.d.cts +304 -0
  130. package/dist/temporal-use-case.d.ts +4 -9
  131. package/dist/temporal-use-case.js +6 -140
  132. package/dist/temporal-use-case.js.map +1 -1
  133. package/dist/unexpected-error.cjs +208 -0
  134. package/dist/unexpected-error.cjs.map +1 -0
  135. package/dist/unexpected-error.js +179 -0
  136. package/dist/unexpected-error.js.map +1 -0
  137. package/dist/use-case.cjs +96 -0
  138. package/dist/use-case.cjs.map +1 -0
  139. package/dist/use-case.js +91 -0
  140. package/dist/use-case.js.map +1 -0
  141. package/dist/uuid-identifier.cjs +65 -0
  142. package/dist/uuid-identifier.cjs.map +1 -0
  143. package/dist/uuid-identifier.d.cts +230 -0
  144. package/dist/uuid-identifier.d.ts +230 -0
  145. package/dist/uuid-identifier.js +60 -0
  146. package/dist/uuid-identifier.js.map +1 -0
  147. package/dist/validation-code.cjs +60 -0
  148. package/dist/validation-code.cjs.map +1 -0
  149. package/dist/validation-code.d.cts +23 -0
  150. package/dist/validation-code.d.ts +23 -0
  151. package/dist/validation-code.js +1 -177
  152. package/dist/validation-code.js.map +1 -1
  153. package/dist/validation-error.cjs +1020 -0
  154. package/dist/validation-error.cjs.map +1 -0
  155. package/dist/validation-error.d.cts +777 -0
  156. package/dist/validation-error.d.ts +1 -21
  157. package/dist/validation-error.js +1 -1
  158. package/dist/validation-exception.cjs +41 -0
  159. package/dist/validation-exception.cjs.map +1 -0
  160. package/dist/validation-exception.d.cts +50 -0
  161. package/dist/validation-exception.d.ts +50 -0
  162. package/dist/validation-exception.js +8 -2
  163. package/dist/validation-exception.js.map +1 -1
  164. package/dist/validation-field.cjs +28 -0
  165. package/dist/validation-field.cjs.map +1 -0
  166. package/dist/validation-field.d.cts +12 -0
  167. package/dist/value-object-ruleset.contracts.d.cts +36 -0
  168. package/dist/value-object-ruleset.contracts.d.ts +36 -0
  169. package/dist/value-object.cjs +208 -0
  170. package/dist/value-object.cjs.map +1 -0
  171. package/dist/value-object.js +191 -0
  172. package/dist/value-object.js.map +1 -0
  173. package/dist/version.d.cts +10 -0
  174. package/dist/version.d.ts +10 -0
  175. package/dist/versioning/index.cjs +7 -0
  176. package/dist/versioning/index.d.cts +3 -0
  177. package/dist/versioning/index.d.ts +3 -0
  178. package/dist/versioning/index.js +3 -0
  179. package/meta.json +18 -3
  180. package/package.json +165 -17
  181. package/src/core/domain/rulesets/index.ts +7 -0
  182. package/src/core/domain/uuid-identifier.ts +72 -0
  183. package/src/core/domain/value-object.ts +37 -5
  184. package/src/core/exceptions/index.ts +13 -0
  185. package/src/core/index.ts +14 -2
  186. package/src/core/plugins/index.ts +7 -0
  187. package/src/core/plugins/plugin.ts +99 -0
  188. package/src/core/plugins/types.ts +53 -0
  189. package/src/core/versioning/index.ts +14 -0
  190. package/src/domain/index.ts +7 -0
  191. package/src/exceptions/index.ts +1 -0
  192. package/src/plugins/index.ts +1 -0
  193. package/src/result/index.ts +2 -0
  194. package/src/rulesets/index.ts +1 -0
  195. package/src/version.ts +1 -1
  196. package/src/versioning/index.ts +1 -0
@@ -0,0 +1,777 @@
1
+ import { a as JsonSafeRecord, n as AppErrorOptions, r as ErrorSeverity, t as AppError } from "./app-error.cjs";
2
+ import { t as ValidationCode } from "./validation-code.cjs";
3
+ import { t as ValidationField } from "./validation-field.cjs";
4
+
5
+ //#region src/core/errors/error-codes.d.ts
6
+ declare const ErrorCodes: {
7
+ readonly authentication: {
8
+ readonly missingToken: "sec.authn.missing_token";
9
+ readonly invalidToken: "sec.authn.invalid_token";
10
+ readonly expiredToken: "sec.authn.expired_token";
11
+ readonly invalidCredentials: "sec.authn.invalid_credentials";
12
+ };
13
+ readonly authorization: {
14
+ readonly forbidden: "sec.authz.forbidden";
15
+ readonly policyDenied: "sec.authz.policy_denied";
16
+ readonly missingCapability: "sec.authz.missing_capability";
17
+ readonly outOfScope: "sec.authz.out_of_scope";
18
+ };
19
+ readonly businessRuleViolation: "business_rule_violation";
20
+ readonly conflict: {
21
+ readonly alreadyExists: "conf.already_exists";
22
+ readonly duplicate: "conf.duplicate";
23
+ readonly uniqueViolation: "conf.unique_violation";
24
+ };
25
+ readonly idempotency: {
26
+ readonly keyMissing: "idemp.key_missing";
27
+ readonly inProgress: "idemp.in_progress";
28
+ readonly payloadMismatch: "idemp.payload_mismatch";
29
+ readonly replayNotSupported: "idemp.replay_not_supported";
30
+ };
31
+ readonly integration: {
32
+ readonly timeout: "int.timeout";
33
+ readonly unreachable: "int.unreachable";
34
+ readonly badResponse: "int.bad_response";
35
+ };
36
+ readonly legacyIncompatible: "legacy_incompatible";
37
+ readonly notFound: "not_found";
38
+ readonly serialization: {
39
+ readonly deserializePrefix: "ser.des";
40
+ readonly serializePrefix: "ser.ser";
41
+ };
42
+ readonly temporal: {
43
+ readonly expired: "tmp.expired";
44
+ readonly notYetValid: "tmp.not_yet_valid";
45
+ };
46
+ readonly unexpected: "unexpected";
47
+ readonly validation: "validation_error";
48
+ };
49
+ type SerializationCodeDirection = "deserialize" | "serialize";
50
+ declare function serializationErrorCode(direction: SerializationCodeDirection, category: string): string;
51
+ //#endregion
52
+ //#region src/core/errors/utils/json-safe.d.ts
53
+ /**
54
+ * Ensures metadata is JSON-serializable.
55
+ *
56
+ * **Allowed:** string, number, boolean, null, arrays, and plain objects.
57
+ *
58
+ * **Converted to placeholder:** Date, BigInt, class instances, functions,
59
+ * symbols, undefined, and circular references (which would otherwise make
60
+ * `JSON.stringify` throw).
61
+ *
62
+ * @throws {TypeError} If `input` is not a plain object at the root level.
63
+ */
64
+ declare function assertJsonSafeMetadata(input: unknown): JsonSafeRecord;
65
+ //#endregion
66
+ //#region src/core/errors/authentication-error.d.ts
67
+ type AuthenticationErrorReason = "missing_token" | "malformed_token" | "invalid_token" | "expired_token" | "revoked_token" | "invalid_credentials" | "session_not_found" | "session_expired" | "unknown";
68
+ type AuthenticationErrorMetadata = {
69
+ reason: AuthenticationErrorReason;
70
+ authScheme?: "bearer" | "cookie" | "basic" | "unknown";
71
+ tokenLocation?: "header" | "cookie" | "query" | "unknown";
72
+ expiresAtIso?: string;
73
+ correlationId?: string;
74
+ requestId?: string;
75
+ details?: string;
76
+ };
77
+ type AuthenticationErrorFactoryOptions = Omit<AuthenticationErrorMetadata, "reason"> & Omit<AppErrorOptions, "metadata">;
78
+ declare class AuthenticationError extends AppError {
79
+ readonly reason: AuthenticationErrorReason;
80
+ private constructor();
81
+ static missingToken(options?: AuthenticationErrorFactoryOptions): AuthenticationError;
82
+ static invalidToken(options?: AuthenticationErrorFactoryOptions & {
83
+ cause?: unknown;
84
+ }): AuthenticationError;
85
+ static expiredToken(options?: AuthenticationErrorFactoryOptions & {
86
+ sessionId?: string;
87
+ }): AuthenticationError;
88
+ static invalidCredentials(options?: Pick<AuthenticationErrorFactoryOptions, "correlationId" | "requestId" | "type" | "severity" | "createdAtIso" | "publicMessage">): AuthenticationError;
89
+ }
90
+ //#endregion
91
+ //#region src/core/errors/authorization-error.d.ts
92
+ type AuthorizationErrorReason = "forbidden" | "missing_role" | "missing_capability" | "out_of_scope" | "outside_time_window" | "policy_denied" | "unknown";
93
+ type AuthorizationRequirement = {
94
+ role?: string;
95
+ capability?: string;
96
+ scope?: string;
97
+ };
98
+ type AuthorizationErrorMetadata = {
99
+ reason: AuthorizationErrorReason;
100
+ /** Stable action you evaluated (not an HTTP route — a "business action") */
101
+ action: string;
102
+ /** Resource identification (without leaking the full payload) */
103
+ resource?: {
104
+ type: string;
105
+ id?: string;
106
+ };
107
+ /** Optional: actor (do not include sensitive data) */
108
+ actor?: {
109
+ userId: string;
110
+ role?: string;
111
+ };
112
+ /** Optional: expected requirement */
113
+ required?: AuthorizationRequirement;
114
+ /** Optional: policy (when you already have PolicyEvaluation or similar) */
115
+ policyId?: string;
116
+ policyVersion?: number;
117
+ evaluatedAtIso?: string;
118
+ decision?: "allow" | "deny";
119
+ reasonCode?: string;
120
+ /** Optional: additional non-sensitive info */
121
+ details?: string;
122
+ };
123
+ /**
124
+ * Options for AuthorizationError factory methods.
125
+ * Combines metadata fields (except 'reason') with common AppError options.
126
+ */
127
+ type AuthorizationErrorFactoryOptions = Omit<AuthorizationErrorMetadata, "reason"> & Omit<AppErrorOptions, "metadata">;
128
+ /**
129
+ * Raised when an authenticated actor is not allowed to perform a business
130
+ * action — the "you may not" error, distinct from authentication ("who are
131
+ * you"). Maps to an HTTP 403 at the edge.
132
+ *
133
+ * The discriminating {@link reason} records *why* access was denied (a flat
134
+ * forbid, a missing role/capability, an out-of-scope target, or a policy
135
+ * decision) so the boundary can shape the response without re-deriving it. The
136
+ * metadata is deliberately built around a stable business `action` and a
137
+ * type/id resource reference rather than an HTTP route or full payload, keeping
138
+ * sensitive data out of logs. Instances are frozen. Construct through the
139
+ * static factories, never directly.
140
+ */
141
+ declare class AuthorizationError extends AppError {
142
+ readonly reason: AuthorizationErrorReason;
143
+ private constructor();
144
+ /**
145
+ * A flat denial with no more specific reason — the actor simply may not
146
+ * perform this action. Reach for a more precise factory
147
+ * ({@link AuthorizationError.missingCapability}, {@link AuthorizationError.outOfScope},
148
+ * {@link AuthorizationError.policyDenied}) when the cause is known.
149
+ */
150
+ static forbidden(input: AuthorizationErrorFactoryOptions): AuthorizationError;
151
+ /**
152
+ * The action was denied by an evaluated policy. Captures the deciding
153
+ * policy's id, version, and evaluation instant into the metadata (with
154
+ * `decision: "deny"`) so the denial is auditable back to the exact policy
155
+ * that produced it.
156
+ *
157
+ * @param input - Factory options plus the required `policyId`,
158
+ * `policyVersion`, and `evaluatedAtIso` of the deciding policy.
159
+ */
160
+ static policyDenied(input: AuthorizationErrorFactoryOptions & {
161
+ policyId: string;
162
+ policyVersion: number;
163
+ evaluatedAtIso: string;
164
+ }): AuthorizationError;
165
+ /**
166
+ * The actor lacks a required role or capability. The expected
167
+ * {@link AuthorizationRequirement} is recorded so the boundary can tell the
168
+ * caller precisely what grant is missing.
169
+ *
170
+ * @param input - Factory options plus the `required` role/capability/scope.
171
+ */
172
+ static missingCapability(input: AuthorizationErrorFactoryOptions & {
173
+ required: AuthorizationRequirement;
174
+ }): AuthorizationError;
175
+ /**
176
+ * The actor may perform the action in general, but not on *this* target —
177
+ * the resource falls outside the actor's permitted scope (e.g. a different
178
+ * school or tenant than the one they are bound to).
179
+ *
180
+ * @param input - Factory options plus the optional `required` scope that the
181
+ * target failed to satisfy.
182
+ */
183
+ static outOfScope(input: AuthorizationErrorFactoryOptions & {
184
+ required?: AuthorizationRequirement;
185
+ }): AuthorizationError;
186
+ }
187
+ //#endregion
188
+ //#region src/core/errors/business-rule-violation-error.d.ts
189
+ declare class BusinessRuleViolationError extends AppError {
190
+ constructor(rule: string, message: string, detail?: Record<string, unknown>, options?: AppErrorOptions);
191
+ }
192
+ //#endregion
193
+ //#region src/core/errors/conflict-error.d.ts
194
+ /**
195
+ * Conflict kinds we want to distinguish semantically.
196
+ */
197
+ type ConflictKind = "already_exists" | "duplicate" | "unique_violation";
198
+ /**
199
+ * Metadata attached to conflicts without exposing sensitive values.
200
+ */
201
+ type ConflictErrorMetadata = {
202
+ kind: ConflictKind;
203
+ entity: string;
204
+ operation?: string;
205
+ field?: string;
206
+ constraintName?: string;
207
+ existingId?: string;
208
+ valueHash?: string;
209
+ valuePreview?: string;
210
+ detectedAtIso?: string;
211
+ correlationId?: string;
212
+ requestId?: string;
213
+ commandId?: string;
214
+ hint?: string;
215
+ };
216
+ /**
217
+ * Storage-level description of a unique-constraint breach, as reported by a
218
+ * database driver. Used to translate a raw DB error into a domain
219
+ * {@link DuplicateError} via {@link translateUniqueViolationToDuplicate}.
220
+ */
221
+ type UniqueConstraintViolation = {
222
+ kind: "unique_violation";
223
+ constraintName?: string;
224
+ table?: string;
225
+ columns?: string[];
226
+ };
227
+ /**
228
+ * Base for errors that signal a state conflict — the request collides with data
229
+ * that already exists. Common at an HTTP 409 boundary.
230
+ *
231
+ * The discriminating {@link kind} lets a handler branch on *why* it conflicted
232
+ * (an already-existing record, a domain duplicate, or a raw storage uniqueness
233
+ * breach) without `instanceof` chains. Abstract: construct one of the concrete
234
+ * subclasses through its `detected(...)` factory, which fills in the right code,
235
+ * message, and metadata. Instances are frozen, so a conflict error can be shared
236
+ * and rethrown without risk of tampering.
237
+ */
238
+ declare abstract class ConflictError extends AppError {
239
+ readonly kind: ConflictKind;
240
+ protected constructor(params: {
241
+ message: string;
242
+ code: string;
243
+ kind: ConflictKind;
244
+ metadata: Omit<ConflictErrorMetadata, "kind">;
245
+ cause?: unknown;
246
+ } & AppErrorOptions);
247
+ }
248
+ /**
249
+ * The operation cannot proceed because a matching record already exists —
250
+ * e.g. creating something whose natural key is already taken. Construct via
251
+ * {@link AlreadyExistsError.detected}.
252
+ */
253
+ declare class AlreadyExistsError extends ConflictError {
254
+ private constructor();
255
+ /**
256
+ * Builds an {@link AlreadyExistsError} for a detected collision. `operation`
257
+ * defaults to `"create"` and a generic retry `hint` is supplied when none is
258
+ * given, so the error is actionable even from a minimal call site.
259
+ *
260
+ * @param input - The conflicting entity plus optional non-sensitive context
261
+ * (operation, field, existing id, value hash/preview, correlation ids).
262
+ */
263
+ static detected(input: {
264
+ entity: string;
265
+ operation?: string;
266
+ field?: string;
267
+ existingId?: string;
268
+ valueHash?: string;
269
+ valuePreview?: string;
270
+ detectedAtIso?: string;
271
+ correlationId?: string;
272
+ requestId?: string;
273
+ commandId?: string;
274
+ hint?: string;
275
+ cause?: unknown;
276
+ }): AlreadyExistsError;
277
+ }
278
+ /**
279
+ * A domain-level duplicate: the data being written would duplicate an existing
280
+ * record under the model's own uniqueness rules. Use this when the duplication
281
+ * is recognized in the domain, as opposed to a raw DB constraint
282
+ * ({@link UniqueConstraintViolationError}). Construct via
283
+ * {@link DuplicateError.detected}.
284
+ */
285
+ declare class DuplicateError extends ConflictError {
286
+ private constructor();
287
+ /**
288
+ * Builds a {@link DuplicateError} for a detected duplicate, defaulting to a
289
+ * "adjust the data so it does not duplicate" hint when none is provided.
290
+ *
291
+ * @param input - The conflicting entity plus optional non-sensitive context
292
+ * (field, constraint name, existing id, value hash/preview, correlation ids).
293
+ */
294
+ static detected(input: {
295
+ entity: string;
296
+ operation?: string;
297
+ field?: string;
298
+ constraintName?: string;
299
+ existingId?: string;
300
+ valueHash?: string;
301
+ valuePreview?: string;
302
+ detectedAtIso?: string;
303
+ correlationId?: string;
304
+ requestId?: string;
305
+ commandId?: string;
306
+ hint?: string;
307
+ cause?: unknown;
308
+ }): DuplicateError;
309
+ }
310
+ /**
311
+ * A uniqueness breach surfaced by the storage layer itself (a database unique
312
+ * index), carrying the raw {@link UniqueConstraintViolation} (constraint, table,
313
+ * columns). Keep this distinct from {@link DuplicateError}: this one is the
314
+ * infrastructure signal; translate it into a domain duplicate at the boundary
315
+ * with {@link translateUniqueViolationToDuplicate} when the model should own the
316
+ * message. Construct via {@link UniqueConstraintViolationError.detected}.
317
+ */
318
+ declare class UniqueConstraintViolationError extends ConflictError {
319
+ private constructor();
320
+ /**
321
+ * Builds a {@link UniqueConstraintViolationError} from the constraint details
322
+ * a driver reports, packaging them into a nested `violation` payload.
323
+ *
324
+ * @param input - The entity plus the offending constraint name, table, and
325
+ * columns, and optional correlation ids.
326
+ */
327
+ static detected(input: {
328
+ entity: string;
329
+ operation?: string;
330
+ constraintName?: string;
331
+ table?: string;
332
+ columns?: string[];
333
+ detectedAtIso?: string;
334
+ correlationId?: string;
335
+ requestId?: string;
336
+ commandId?: string;
337
+ cause?: unknown;
338
+ }): UniqueConstraintViolationError;
339
+ }
340
+ /**
341
+ * Translates a raw storage {@link UniqueConstraintViolation} into a domain-level
342
+ * {@link DuplicateError}. This is the seam where an infrastructure concern (a DB
343
+ * unique index firing) is re-expressed in the language of the model, so callers
344
+ * upstream catch a `DuplicateError` and never have to know a database was
345
+ * involved.
346
+ *
347
+ * @param input - The entity, the driver-reported `violation`, and optional
348
+ * request context (`ctx`) carrying correlation ids and a clock instant.
349
+ * @returns A {@link DuplicateError} carrying the constraint name as its field hint.
350
+ */
351
+ declare function translateUniqueViolationToDuplicate(input: {
352
+ entity: string;
353
+ operation?: string;
354
+ violation: UniqueConstraintViolation;
355
+ field?: string;
356
+ ctx?: {
357
+ correlationId?: string;
358
+ requestId?: string;
359
+ commandId?: string;
360
+ nowIso?: string;
361
+ };
362
+ cause?: unknown;
363
+ }): DuplicateError;
364
+ //#endregion
365
+ //#region src/core/shared/hashing.d.ts
366
+ declare function sha256Hex(value: string): string;
367
+ /**
368
+ * Deterministic JSON string with object keys sorted recursively, so key order
369
+ * does not affect the output.
370
+ *
371
+ * Follows `JSON.stringify` semantics for the values it serializes: `undefined`,
372
+ * functions and symbols are dropped, non-finite numbers become `null`, `bigint`
373
+ * throws, and `Map`/`Set` serialize as `{}`. Distinct payloads can therefore
374
+ * collapse to the same string — for collision-resistant hashing use
375
+ * `PolicyHashing.canonicalJson` (policies/utils), which rejects those values
376
+ * up front.
377
+ *
378
+ * @throws {TypeError} On circular references (mirroring `JSON.stringify`).
379
+ */
380
+ declare function stableStringify(value: unknown): string;
381
+ declare function payloadHash(value: unknown): string;
382
+ //#endregion
383
+ //#region src/core/errors/idempotency-error.d.ts
384
+ type IdempotencyFailureKind = "key_missing" | "in_progress" | "payload_mismatch" | "replay_not_supported" | "unknown";
385
+ type IdempotencyErrorMetadata = {
386
+ kind: IdempotencyFailureKind;
387
+ operation: string;
388
+ scope?: string;
389
+ entity?: string;
390
+ keyHash?: string;
391
+ keyPreview?: string;
392
+ incomingPayloadHash?: string;
393
+ existingPayloadHash?: string;
394
+ idempotencyRecordId?: string;
395
+ correlationId?: string;
396
+ requestId?: string;
397
+ commandId?: string;
398
+ detectedAtIso?: string;
399
+ hint?: string;
400
+ details?: string;
401
+ };
402
+ type IdempotencyErrorConstructorInput = {
403
+ message: string;
404
+ code: string;
405
+ kind: IdempotencyFailureKind;
406
+ metadata: Omit<IdempotencyErrorMetadata, "kind">;
407
+ cause?: unknown;
408
+ };
409
+ declare abstract class IdempotencyError extends AppError {
410
+ readonly kind: IdempotencyFailureKind;
411
+ protected constructor(input: IdempotencyErrorConstructorInput);
412
+ static keyMissing(input: {
413
+ operation: string;
414
+ scope?: string;
415
+ entity?: string;
416
+ correlationId?: string;
417
+ requestId?: string;
418
+ commandId?: string;
419
+ detectedAtIso?: string;
420
+ hint?: string;
421
+ details?: string;
422
+ cause?: unknown;
423
+ }): IdempotencyKeyMissingError;
424
+ static inProgress(input: {
425
+ operation: string;
426
+ scope?: string;
427
+ entity?: string;
428
+ key?: string;
429
+ keyHash?: string;
430
+ keyPreview?: string;
431
+ idempotencyRecordId?: string;
432
+ correlationId?: string;
433
+ requestId?: string;
434
+ commandId?: string;
435
+ detectedAtIso?: string;
436
+ hint?: string;
437
+ details?: string;
438
+ cause?: unknown;
439
+ }): IdempotencyInProgressError;
440
+ static payloadMismatch(input: {
441
+ operation: string;
442
+ scope?: string;
443
+ entity?: string;
444
+ key?: string;
445
+ keyHash?: string;
446
+ keyPreview?: string;
447
+ incomingPayloadHash?: string;
448
+ existingPayloadHash?: string;
449
+ idempotencyRecordId?: string;
450
+ correlationId?: string;
451
+ requestId?: string;
452
+ commandId?: string;
453
+ detectedAtIso?: string;
454
+ hint?: string;
455
+ details?: string;
456
+ cause?: unknown;
457
+ }): IdempotencyPayloadMismatchError;
458
+ static replayNotSupported(input: {
459
+ operation: string;
460
+ scope?: string;
461
+ entity?: string;
462
+ key?: string;
463
+ keyHash?: string;
464
+ keyPreview?: string;
465
+ idempotencyRecordId?: string;
466
+ correlationId?: string;
467
+ requestId?: string;
468
+ commandId?: string;
469
+ detectedAtIso?: string;
470
+ hint?: string;
471
+ details?: string;
472
+ cause?: unknown;
473
+ }): IdempotencyReplayNotSupportedError;
474
+ }
475
+ declare class IdempotencyKeyMissingError extends IdempotencyError {
476
+ private constructor();
477
+ static detected(input: {
478
+ operation: string;
479
+ scope?: string;
480
+ entity?: string;
481
+ correlationId?: string;
482
+ requestId?: string;
483
+ commandId?: string;
484
+ detectedAtIso?: string;
485
+ hint?: string;
486
+ details?: string;
487
+ cause?: unknown;
488
+ }): IdempotencyKeyMissingError;
489
+ }
490
+ declare class IdempotencyInProgressError extends IdempotencyError {
491
+ private constructor();
492
+ static detected(input: {
493
+ operation: string;
494
+ scope?: string;
495
+ entity?: string;
496
+ key?: string;
497
+ keyHash?: string;
498
+ keyPreview?: string;
499
+ idempotencyRecordId?: string;
500
+ correlationId?: string;
501
+ requestId?: string;
502
+ commandId?: string;
503
+ detectedAtIso?: string;
504
+ hint?: string;
505
+ details?: string;
506
+ cause?: unknown;
507
+ }): IdempotencyInProgressError;
508
+ }
509
+ declare class IdempotencyPayloadMismatchError extends IdempotencyError {
510
+ private constructor();
511
+ static detected(input: {
512
+ operation: string;
513
+ scope?: string;
514
+ entity?: string;
515
+ key?: string;
516
+ keyHash?: string;
517
+ keyPreview?: string;
518
+ incomingPayloadHash?: string;
519
+ existingPayloadHash?: string;
520
+ idempotencyRecordId?: string;
521
+ correlationId?: string;
522
+ requestId?: string;
523
+ commandId?: string;
524
+ detectedAtIso?: string;
525
+ hint?: string;
526
+ details?: string;
527
+ cause?: unknown;
528
+ }): IdempotencyPayloadMismatchError;
529
+ }
530
+ declare class IdempotencyReplayNotSupportedError extends IdempotencyError {
531
+ private constructor();
532
+ static detected(input: {
533
+ operation: string;
534
+ scope?: string;
535
+ entity?: string;
536
+ key?: string;
537
+ keyHash?: string;
538
+ keyPreview?: string;
539
+ idempotencyRecordId?: string;
540
+ correlationId?: string;
541
+ requestId?: string;
542
+ commandId?: string;
543
+ detectedAtIso?: string;
544
+ hint?: string;
545
+ details?: string;
546
+ cause?: unknown;
547
+ }): IdempotencyReplayNotSupportedError;
548
+ }
549
+ //#endregion
550
+ //#region src/core/errors/integration-error.d.ts
551
+ type IntegrationErrorReason = "timeout" | "unreachable" | "bad_response" | "unknown";
552
+ type IntegrationErrorMetadata = {
553
+ reason: IntegrationErrorReason;
554
+ provider: string;
555
+ operation: string;
556
+ startedAtIso: string;
557
+ durationMs: number;
558
+ detectedAtIso?: string;
559
+ correlationId?: string;
560
+ requestId?: string;
561
+ commandId?: string;
562
+ details?: string;
563
+ statusCode?: number;
564
+ responseCode?: string;
565
+ };
566
+ /**
567
+ * Raised when a call to an external provider fails — a timeout, an unreachable
568
+ * endpoint, or a malformed response. This is the boundary error that separates
569
+ * "our code is fine, the outside world misbehaved" from internal faults, which
570
+ * matters for retry and alerting decisions.
571
+ *
572
+ * Every instance records the `provider`, the `operation`, and timing
573
+ * (`startedAtIso` / `durationMs`) so failures are correlatable across services
574
+ * and a slow dependency is visible in the metadata. The discriminating
575
+ * {@link reason} lets callers decide whether a failure is worth retrying.
576
+ * Instances are frozen; construct through the static factories.
577
+ */
578
+ declare class IntegrationError extends AppError {
579
+ readonly reason: IntegrationErrorReason;
580
+ private constructor();
581
+ /**
582
+ * The provider did not respond within the allotted time. Usually retryable,
583
+ * since a timeout leaves the outcome unknown rather than known-failed.
584
+ */
585
+ static timeout(options: IntegrationErrorTimeoutOptions): IntegrationError;
586
+ /**
587
+ * The provider could not be reached at all (connection refused, DNS
588
+ * failure, network partition) — the request never landed.
589
+ */
590
+ static unreachable(options: IntegrationErrorEndpointOptions): IntegrationError;
591
+ /**
592
+ * The provider answered, but with something the system cannot use — an
593
+ * unexpected status, an unparsable body, or a contract mismatch. Unlike a
594
+ * timeout this is a definite failure, so blind retries rarely help.
595
+ */
596
+ static badResponse(options: IntegrationErrorEndpointOptions): IntegrationError;
597
+ }
598
+ type IntegrationErrorBaseOptions = {
599
+ provider: string;
600
+ operation: string;
601
+ startedAtIso: string;
602
+ durationMs: number;
603
+ detectedAtIso?: string;
604
+ correlationId?: string;
605
+ requestId?: string;
606
+ commandId?: string;
607
+ details?: string;
608
+ statusCode?: number;
609
+ responseCode?: string;
610
+ cause?: unknown;
611
+ type?: string;
612
+ severity?: ErrorSeverity;
613
+ createdAtIso?: string;
614
+ publicMessage?: string;
615
+ };
616
+ type IntegrationErrorTimeoutOptions = IntegrationErrorBaseOptions;
617
+ type IntegrationErrorEndpointOptions = IntegrationErrorBaseOptions;
618
+ //#endregion
619
+ //#region src/core/errors/legacy-incompatible-error.d.ts
620
+ declare class LegacyIncompatibleError extends AppError {
621
+ constructor(message: string, context?: Record<string, unknown>, options?: AppErrorOptions);
622
+ }
623
+ //#endregion
624
+ //#region src/core/errors/not-found-error.d.ts
625
+ /**
626
+ * Raised when a requested resource does not exist. Maps naturally onto an HTTP
627
+ * 404 at the edge, but stays transport-agnostic here.
628
+ *
629
+ * The `resource` name builds the message (`"<resource> not found"`) and, with
630
+ * the optional lookup `criteria`, lands in the metadata so logs show *what* was
631
+ * searched for without the caller having to restate it in the message.
632
+ */
633
+ declare class NotFoundError extends AppError {
634
+ /**
635
+ * @param resource - Human-readable name of the missing resource (e.g. `"Order"`).
636
+ * @param criteria - Optional lookup keys used in the search; recorded in
637
+ * metadata to aid debugging. Avoid putting sensitive values here.
638
+ * @param options - Optional cause, correlation ids, and extra metadata.
639
+ */
640
+ constructor(resource: string, criteria?: Record<string, unknown>, options?: AppErrorOptions);
641
+ }
642
+ //#endregion
643
+ //#region src/core/errors/serialization-error.d.ts
644
+ type SerializationDirection = "serialize" | "deserialize";
645
+ type SerializationFailureCategory = "invalid_json" | "invalid_shape" | "missing_field" | "unexpected_field" | "invalid_type" | "schema_version_missing" | "schema_version_unsupported" | "mapping_not_implemented" | "contract_mismatch" | "parse_failed" | "stringify_failed" | "unknown";
646
+ type SerializationBoundary = "http_in" | "http_out" | "graphql_in" | "graphql_out" | "dto_to_domain" | "domain_to_dto" | "persistence_to_domain" | "domain_to_persistence" | "event_in" | "event_out" | "projection" | "unknown";
647
+ /**
648
+ * Metadata shared by serialization/deserialization failures. Payload previews must be sanitized.
649
+ */
650
+ type SerializationErrorMetadata = {
651
+ direction: SerializationDirection;
652
+ category: SerializationFailureCategory;
653
+ boundary: SerializationBoundary;
654
+ contract: string;
655
+ schemaVersion?: number | string;
656
+ path?: string;
657
+ payloadPreview?: string;
658
+ correlationId?: string;
659
+ requestId?: string;
660
+ commandId?: string;
661
+ hint?: string;
662
+ details?: string;
663
+ };
664
+ type SerializationErrorOptions = Omit<AppErrorOptions, "metadata"> & {
665
+ message: string;
666
+ code: string;
667
+ metadata: Omit<SerializationErrorMetadata, "direction" | "category">;
668
+ direction: SerializationDirection;
669
+ category: SerializationFailureCategory;
670
+ };
671
+ declare abstract class SerializationError extends AppError {
672
+ readonly direction: SerializationDirection;
673
+ readonly category: SerializationFailureCategory;
674
+ readonly boundary: SerializationBoundary;
675
+ readonly contract: string;
676
+ protected constructor(input: SerializationErrorOptions);
677
+ }
678
+ declare class SerializationInError extends SerializationError {
679
+ private constructor();
680
+ static failure(category: SerializationFailureCategory, metadata: Omit<SerializationErrorMetadata, "direction" | "category"> & {
681
+ cause?: unknown;
682
+ }): SerializationInError;
683
+ }
684
+ declare class SerializationOutError extends SerializationError {
685
+ private constructor();
686
+ static failure(category: SerializationFailureCategory, metadata: Omit<SerializationErrorMetadata, "direction" | "category"> & {
687
+ cause?: unknown;
688
+ }): SerializationOutError;
689
+ }
690
+ declare class SerializationCodes {
691
+ static code(direction: SerializationDirection, category: SerializationFailureCategory): string;
692
+ }
693
+ declare class SerializationMessages {
694
+ static message(direction: SerializationDirection, category: SerializationFailureCategory): string;
695
+ }
696
+ declare function safePreview(value: unknown, limit?: number): string | undefined;
697
+ //#endregion
698
+ //#region src/core/errors/temporal-error.d.ts
699
+ type TemporalKind = "expired" | "not_yet_valid";
700
+ type TemporalPrecision = "EXACT" | "ESTIMATED" | "UNKNOWN" | "APPROXIMATE";
701
+ type TemporalErrorMetadata = {
702
+ resourceType: string;
703
+ resourceId?: string;
704
+ operation?: string;
705
+ validFromIso?: string | null;
706
+ validUntilIso?: string | null;
707
+ evaluatedAtIso: string;
708
+ policyId?: string;
709
+ precision?: TemporalPrecision;
710
+ hint?: string;
711
+ details?: string;
712
+ correlationId?: string;
713
+ requestId?: string;
714
+ commandId?: string;
715
+ };
716
+ type TemporalErrorOptions = {
717
+ message: string;
718
+ code: string;
719
+ kind: TemporalKind;
720
+ metadata: TemporalErrorMetadata;
721
+ } & AppErrorOptions;
722
+ declare abstract class TemporalError extends AppError {
723
+ readonly kind: TemporalKind;
724
+ readonly resourceType: string;
725
+ readonly evaluatedAtIso: string;
726
+ protected constructor(input: TemporalErrorOptions);
727
+ }
728
+ type TemporalCreationInput = TemporalErrorMetadata & Partial<Omit<AppErrorOptions, "metadata">> & {
729
+ cause?: unknown;
730
+ };
731
+ declare class ExpiredError extends TemporalError {
732
+ private constructor();
733
+ static detected(input: TemporalCreationInput): ExpiredError;
734
+ }
735
+ declare class NotYetValidError extends TemporalError {
736
+ private constructor();
737
+ static detected(input: TemporalCreationInput): NotYetValidError;
738
+ }
739
+ declare function evaluateTemporalWindow(input: {
740
+ validFromIso?: string | null;
741
+ validUntilIso?: string | null;
742
+ evaluatedAtIso: string;
743
+ }): {
744
+ expired: boolean;
745
+ notYetValid: boolean;
746
+ } | null;
747
+ //#endregion
748
+ //#region src/core/errors/unexpected-error.d.ts
749
+ declare class UnexpectedError extends AppError {
750
+ constructor(message?: string, cause?: unknown, options?: Omit<AppErrorOptions, "cause">);
751
+ }
752
+ //#endregion
753
+ //#region src/core/errors/validation-error.d.ts
754
+ /**
755
+ * Raised when a single input fails a validation rule — the canonical
756
+ * "this field is wrong, and here is why" error.
757
+ *
758
+ * It pins the offending `field` and a machine-readable `validationCode` into
759
+ * the metadata (merged ahead of any caller-supplied metadata) so an API layer
760
+ * can map the failure straight onto a form field without parsing the message.
761
+ * The fixed {@link ErrorCodes.validation} code lets callers catch all
762
+ * validation failures uniformly while still distinguishing the specific rule
763
+ * through `validationCode`.
764
+ */
765
+ declare class ValidationError extends AppError {
766
+ /**
767
+ * @param field - The input that failed validation; surfaced as `metadata.field`.
768
+ * @param code - The specific rule that was violated; surfaced as `metadata.validationCode`.
769
+ * @param message - The developer-facing description of the failure.
770
+ * @param options - Optional cause, correlation ids, and extra metadata
771
+ * (merged over the field/code metadata, never overwriting it by accident).
772
+ */
773
+ constructor(field: ValidationField, code: ValidationCode, message: string, options?: AppErrorOptions);
774
+ }
775
+ //#endregion
776
+ export { serializationErrorCode as $, IdempotencyPayloadMismatchError as A, UniqueConstraintViolation as B, IntegrationErrorMetadata as C, IdempotencyFailureKind as D, IdempotencyErrorMetadata as E, AlreadyExistsError as F, AuthorizationErrorMetadata as G, translateUniqueViolationToDuplicate as H, ConflictError as I, AuthenticationError as J, AuthorizationErrorReason as K, ConflictErrorMetadata as L, payloadHash as M, sha256Hex as N, IdempotencyInProgressError as O, stableStringify as P, ErrorCodes as Q, ConflictKind as R, IntegrationError as S, IdempotencyError as T, BusinessRuleViolationError as U, UniqueConstraintViolationError as V, AuthorizationError as W, AuthenticationErrorReason as X, AuthenticationErrorMetadata as Y, assertJsonSafeMetadata as Z, 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, AuthorizationRequirement 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 };
777
+ //# sourceMappingURL=validation-error.d.cts.map