@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.
- package/KIT_CONTEXT.md +1 -67
- package/dist/app-error.d.cts +108 -0
- package/dist/application/index.cjs +26 -0
- package/dist/application/index.d.cts +2 -0
- package/dist/application/index.d.ts +1 -1
- package/dist/application/index.js +2 -1
- package/dist/domain/index.cjs +16 -0
- package/dist/domain/index.d.cts +3 -0
- package/dist/domain/index.d.ts +3 -0
- package/dist/domain/index.js +3 -0
- package/dist/domain-event-contracts.cjs +33 -0
- package/dist/domain-event-contracts.cjs.map +1 -0
- package/dist/domain-event-contracts.d.cts +27 -0
- package/dist/domain-event-contracts.d.ts +27 -0
- package/dist/domain-event-contracts.js +22 -0
- package/dist/domain-event-contracts.js.map +1 -0
- package/dist/domain-exception.cjs +17 -0
- package/dist/domain-exception.cjs.map +1 -0
- package/dist/domain-exception.d.cts +7 -0
- package/dist/domain-exception.d.ts +7 -0
- package/dist/domain-exception.js +12 -0
- package/dist/domain-exception.js.map +1 -0
- package/dist/errors/index.cjs +41 -0
- package/dist/errors/index.d.cts +3 -0
- package/dist/errors/index.js +1 -1
- package/dist/exceptions/index.cjs +17 -0
- package/dist/exceptions/index.d.cts +5 -0
- package/dist/exceptions/index.d.ts +5 -0
- package/dist/exceptions/index.js +7 -0
- package/dist/exceptions/validation-field.cjs +3 -0
- package/dist/exceptions/validation-field.d.cts +2 -0
- package/dist/gate-engine-registry.cjs +308 -0
- package/dist/gate-engine-registry.cjs.map +1 -0
- package/dist/gate-engine-registry.d.cts +81 -0
- package/dist/gate-engine-registry.d.ts +2 -1
- package/dist/gate-engine-registry.js +2 -1
- package/dist/gate-engine-registry.js.map +1 -1
- package/dist/gate-types.d.cts +171 -0
- package/dist/gate-types.d.ts +3 -139
- package/dist/gate-v1-payload.schema.cjs +638 -0
- package/dist/gate-v1-payload.schema.cjs.map +1 -0
- package/dist/gate-v1-payload.schema.js +2 -116
- package/dist/gate-v1-payload.schema.js.map +1 -1
- package/dist/hashing.cjs +66 -0
- package/dist/hashing.cjs.map +1 -0
- package/dist/immutable.cjs +77 -0
- package/dist/immutable.cjs.map +1 -0
- package/dist/immutable.d.cts +6 -0
- package/dist/immutable.d.ts +6 -0
- package/dist/immutable.js +54 -0
- package/dist/immutable.js.map +1 -0
- package/dist/index.cjs +163 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +30 -0
- package/dist/index.d.ts +15 -160
- package/dist/index.js +19 -176
- package/dist/index.js.map +1 -1
- package/dist/invalid-state-transition-exception.cjs +47 -0
- package/dist/invalid-state-transition-exception.cjs.map +1 -0
- package/dist/invalid-state-transition-exception.js +30 -0
- package/dist/invalid-state-transition-exception.js.map +1 -0
- package/dist/invariant-violation-exception.cjs +16 -0
- package/dist/invariant-violation-exception.cjs.map +1 -0
- package/dist/invariant-violation-exception.js +11 -0
- package/dist/invariant-violation-exception.js.map +1 -0
- package/dist/not-found-error.cjs +65 -0
- package/dist/not-found-error.cjs.map +1 -0
- package/dist/not-found-error.js +1 -1
- package/dist/outcome.cjs +97 -0
- package/dist/outcome.cjs.map +1 -0
- package/dist/outcome.d.cts +140 -0
- package/dist/outcome.d.ts +140 -0
- package/dist/outcome.js +1 -1
- package/dist/parse-gate-payload.d.cts +62 -0
- package/dist/parse-gate-payload.d.ts +2 -1
- package/dist/path.d.cts +90 -0
- package/dist/path.d.ts +2 -1
- package/dist/plugin.cjs +79 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.cts +85 -0
- package/dist/plugin.d.ts +85 -0
- package/dist/plugin.js +74 -0
- package/dist/plugin.js.map +1 -0
- package/dist/plugins/index.cjs +3 -0
- package/dist/plugins/index.d.cts +2 -0
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.js +2 -0
- package/dist/policies/engines/index.cjs +10 -0
- package/dist/policies/engines/index.d.cts +4 -0
- package/dist/policies/engines/index.d.ts +1 -1
- package/dist/policies/engines/v1/gate/index.cjs +91 -0
- package/dist/policies/engines/v1/gate/index.cjs.map +1 -0
- package/dist/policies/engines/v1/gate/index.d.cts +121 -0
- package/dist/policies/engines/v1/gate/index.d.ts +2 -1
- package/dist/policies/engines/v1/gate/index.js +2 -1
- package/dist/policies/engines/v1/gate/index.js.map +1 -1
- package/dist/policies/index.cjs +41 -0
- package/dist/policies/index.d.cts +7 -0
- package/dist/policies/index.d.ts +2 -1
- package/dist/policies/index.js +2 -1
- package/dist/policy-service.cjs +1190 -0
- package/dist/policy-service.cjs.map +1 -0
- package/dist/policy-service.d.cts +559 -0
- package/dist/policy-service.d.ts +2 -1
- package/dist/policy-service.js +6 -3
- package/dist/policy-service.js.map +1 -1
- package/dist/result/index.cjs +7 -0
- package/dist/result/index.d.cts +2 -0
- package/dist/result/index.d.ts +2 -0
- package/dist/result/index.js +3 -0
- package/dist/result.cjs +135 -0
- package/dist/result.cjs.map +1 -0
- package/dist/result.js +118 -0
- package/dist/result.js.map +1 -0
- package/dist/ruleset-registry.cjs +47 -0
- package/dist/ruleset-registry.cjs.map +1 -0
- package/dist/ruleset-registry.js +42 -0
- package/dist/ruleset-registry.js.map +1 -0
- package/dist/rulesets/index.cjs +3 -0
- package/dist/rulesets/index.d.cts +2 -0
- package/dist/rulesets/index.d.ts +2 -0
- package/dist/rulesets/index.js +2 -0
- package/dist/temporal-guards.cjs +32 -0
- package/dist/temporal-guards.cjs.map +1 -0
- package/dist/temporal-guards.js +2 -17
- package/dist/temporal-guards.js.map +1 -1
- package/dist/temporal-use-case.cjs +191 -0
- package/dist/temporal-use-case.cjs.map +1 -0
- package/dist/temporal-use-case.d.cts +304 -0
- package/dist/temporal-use-case.d.ts +4 -9
- package/dist/temporal-use-case.js +6 -140
- package/dist/temporal-use-case.js.map +1 -1
- package/dist/unexpected-error.cjs +208 -0
- package/dist/unexpected-error.cjs.map +1 -0
- package/dist/unexpected-error.js +179 -0
- package/dist/unexpected-error.js.map +1 -0
- package/dist/use-case.cjs +96 -0
- package/dist/use-case.cjs.map +1 -0
- package/dist/use-case.js +91 -0
- package/dist/use-case.js.map +1 -0
- package/dist/uuid-identifier.cjs +65 -0
- package/dist/uuid-identifier.cjs.map +1 -0
- package/dist/uuid-identifier.d.cts +230 -0
- package/dist/uuid-identifier.d.ts +230 -0
- package/dist/uuid-identifier.js +60 -0
- package/dist/uuid-identifier.js.map +1 -0
- package/dist/validation-code.cjs +60 -0
- package/dist/validation-code.cjs.map +1 -0
- package/dist/validation-code.d.cts +23 -0
- package/dist/validation-code.d.ts +23 -0
- package/dist/validation-code.js +1 -177
- package/dist/validation-code.js.map +1 -1
- package/dist/validation-error.cjs +1020 -0
- package/dist/validation-error.cjs.map +1 -0
- package/dist/validation-error.d.cts +777 -0
- package/dist/validation-error.d.ts +1 -21
- package/dist/validation-error.js +1 -1
- package/dist/validation-exception.cjs +41 -0
- package/dist/validation-exception.cjs.map +1 -0
- package/dist/validation-exception.d.cts +50 -0
- package/dist/validation-exception.d.ts +50 -0
- package/dist/validation-exception.js +8 -2
- package/dist/validation-exception.js.map +1 -1
- package/dist/validation-field.cjs +28 -0
- package/dist/validation-field.cjs.map +1 -0
- package/dist/validation-field.d.cts +12 -0
- package/dist/value-object-ruleset.contracts.d.cts +36 -0
- package/dist/value-object-ruleset.contracts.d.ts +36 -0
- package/dist/value-object.cjs +208 -0
- package/dist/value-object.cjs.map +1 -0
- package/dist/value-object.js +191 -0
- package/dist/value-object.js.map +1 -0
- package/dist/version.d.cts +10 -0
- package/dist/version.d.ts +10 -0
- package/dist/versioning/index.cjs +7 -0
- package/dist/versioning/index.d.cts +3 -0
- package/dist/versioning/index.d.ts +3 -0
- package/dist/versioning/index.js +3 -0
- package/meta.json +18 -3
- package/package.json +165 -17
- package/src/core/domain/rulesets/index.ts +7 -0
- package/src/core/domain/uuid-identifier.ts +72 -0
- package/src/core/domain/value-object.ts +37 -5
- package/src/core/exceptions/index.ts +13 -0
- package/src/core/index.ts +14 -2
- package/src/core/plugins/index.ts +7 -0
- package/src/core/plugins/plugin.ts +99 -0
- package/src/core/plugins/types.ts +53 -0
- package/src/core/versioning/index.ts +14 -0
- package/src/domain/index.ts +7 -0
- package/src/exceptions/index.ts +1 -0
- package/src/plugins/index.ts +1 -0
- package/src/result/index.ts +2 -0
- package/src/rulesets/index.ts +1 -0
- package/src/version.ts +1 -1
- 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
|