@substrat-run/contracts 0.78.0 → 0.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/errors.d.ts +304 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +352 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/openapi.d.ts.map +1 -1
- package/dist/openapi.js +62 -5
- package/dist/openapi.js.map +1 -1
- package/package.json +1 -1
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* The ONE error model for every surface on the platform (`docs/rfc/error-model.md`,
|
|
4
|
+
* issue #113): RFC 9457 `application/problem+json`, a CLOSED code taxonomy, and one
|
|
5
|
+
* mapper — replacing the seven hand-rolled `onError` handlers that today choose a
|
|
6
|
+
* status by matching on error message TEXT.
|
|
7
|
+
*
|
|
8
|
+
* Three properties this is built for:
|
|
9
|
+
*
|
|
10
|
+
* - **Machine-readable.** `validation_failed on field 'email'` is recoverable by a
|
|
11
|
+
* client — or by a build agent — without a person reading a log. `500 Something
|
|
12
|
+
* went wrong` is not.
|
|
13
|
+
* - **Documentable.** The same schema that validates a problem body is emitted into
|
|
14
|
+
* `/openapi.json` (`openapi.ts`), so the API surface finally describes how it can
|
|
15
|
+
* FAIL and not only how it succeeds. Decision 22 cashed in again.
|
|
16
|
+
* - **Additive to adopt.** `toProblem` maps an unrecognised throw to `internal` exactly
|
|
17
|
+
* as the hand-rolled handlers do, so each layer could adopt this without a flag day.
|
|
18
|
+
*
|
|
19
|
+
* ## Where the rollout stands
|
|
20
|
+
*
|
|
21
|
+
* Phases 1–3 are in: the taxonomy and `toProblem` (contracts), the kernel's own error
|
|
22
|
+
* classes joined to it, and `wireFailure` — the value an error becomes when it has to
|
|
23
|
+
* cross the ScopeDO boundary, because a throw cannot carry structure across it. What
|
|
24
|
+
* remains is phase 4: the transports reading `code` instead of matching messages, and
|
|
25
|
+
* the deprecated `error` duplicate coming back out of the body.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* The base for `type` URIs.
|
|
29
|
+
*
|
|
30
|
+
* DERIVED from the code rather than written per entry, deliberately: whether we
|
|
31
|
+
* actually serve a page at each of these URLs is still open (RFC §6 Q2), and nothing
|
|
32
|
+
* throws a problem yet, so no `type` value has reached a client. Flipping the
|
|
33
|
+
* decision stays a one-line change here for exactly as long as that holds.
|
|
34
|
+
*/
|
|
35
|
+
export declare const PROBLEM_TYPE_BASE = "https://substrat.net/errors";
|
|
36
|
+
/**
|
|
37
|
+
* The taxonomy. CLOSED — an open one is a suggestion.
|
|
38
|
+
*
|
|
39
|
+
* A module never invents a code. It narrows an existing one with a `reason` slug it
|
|
40
|
+
* owns (`conflict` + `reason: 'already_exported'`), which is the star topology
|
|
41
|
+
* applied to failure: a vertical branches on an engine's reason without importing
|
|
42
|
+
* the engine's types.
|
|
43
|
+
*/
|
|
44
|
+
export declare const errorCode: z.ZodEnum<{
|
|
45
|
+
conflict: "conflict";
|
|
46
|
+
forbidden: "forbidden";
|
|
47
|
+
internal: "internal";
|
|
48
|
+
not_found: "not_found";
|
|
49
|
+
permission_denied: "permission_denied";
|
|
50
|
+
precondition_failed: "precondition_failed";
|
|
51
|
+
rate_limited: "rate_limited";
|
|
52
|
+
unauthenticated: "unauthenticated";
|
|
53
|
+
unavailable: "unavailable";
|
|
54
|
+
validation_failed: "validation_failed";
|
|
55
|
+
}>;
|
|
56
|
+
export type ErrorCode = z.infer<typeof errorCode>;
|
|
57
|
+
/** `permission_denied` → `https://substrat.net/errors/permission-denied`. */
|
|
58
|
+
export declare function problemTypeFor(code: ErrorCode): string;
|
|
59
|
+
/**
|
|
60
|
+
* Status and human title per code. `Record<ErrorCode, …>` on purpose: adding a code
|
|
61
|
+
* without deciding what it means to HTTP is then a compile error, not a 500 found in
|
|
62
|
+
* production.
|
|
63
|
+
*/
|
|
64
|
+
export declare const PROBLEM_CATALOG: {
|
|
65
|
+
readonly unauthenticated: {
|
|
66
|
+
readonly status: 401;
|
|
67
|
+
readonly title: 'Unauthenticated';
|
|
68
|
+
};
|
|
69
|
+
readonly permission_denied: {
|
|
70
|
+
readonly status: 403;
|
|
71
|
+
readonly title: 'Permission denied';
|
|
72
|
+
};
|
|
73
|
+
readonly forbidden: {
|
|
74
|
+
readonly status: 403;
|
|
75
|
+
readonly title: 'Forbidden';
|
|
76
|
+
};
|
|
77
|
+
readonly not_found: {
|
|
78
|
+
readonly status: 404;
|
|
79
|
+
readonly title: 'Not found';
|
|
80
|
+
};
|
|
81
|
+
readonly conflict: {
|
|
82
|
+
readonly status: 409;
|
|
83
|
+
readonly title: 'Conflict';
|
|
84
|
+
};
|
|
85
|
+
readonly validation_failed: {
|
|
86
|
+
readonly status: 400;
|
|
87
|
+
readonly title: 'Validation failed';
|
|
88
|
+
};
|
|
89
|
+
readonly precondition_failed: {
|
|
90
|
+
readonly status: 412;
|
|
91
|
+
readonly title: 'Precondition failed';
|
|
92
|
+
};
|
|
93
|
+
readonly rate_limited: {
|
|
94
|
+
readonly status: 429;
|
|
95
|
+
readonly title: 'Rate limited';
|
|
96
|
+
};
|
|
97
|
+
readonly unavailable: {
|
|
98
|
+
readonly status: 503;
|
|
99
|
+
readonly title: 'Service unavailable';
|
|
100
|
+
};
|
|
101
|
+
readonly internal: {
|
|
102
|
+
readonly status: 500;
|
|
103
|
+
readonly title: 'Internal error';
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
/** One field-level complaint, mapped from a Zod issue. */
|
|
107
|
+
export declare const validationIssue: z.ZodObject<{
|
|
108
|
+
path: z.ZodString;
|
|
109
|
+
message: z.ZodString;
|
|
110
|
+
}, z.core.$strip>;
|
|
111
|
+
export type ValidationIssue = z.infer<typeof validationIssue>;
|
|
112
|
+
/**
|
|
113
|
+
* The extension members each code may carry — declared per entry, never free-form.
|
|
114
|
+
*
|
|
115
|
+
* These are enforced where it matters: at the THROW site, by `substratError`, which
|
|
116
|
+
* both types and parses them. The wire schema below is one flat object rather than a
|
|
117
|
+
* ten-way discriminated union, because a `oneOf` of ten variants documents worse than
|
|
118
|
+
* one object does and buys a narrowing no client asked for. Per-code narrowing of the
|
|
119
|
+
* emitted document is RFC §6 Q1, deferred with the model layer that would own it.
|
|
120
|
+
*/
|
|
121
|
+
export declare const PROBLEM_EXTENSIONS: {
|
|
122
|
+
readonly unauthenticated: z.ZodObject<{}, z.core.$strict>;
|
|
123
|
+
readonly permission_denied: z.ZodObject<{
|
|
124
|
+
permission: z.ZodOptional<z.ZodString>;
|
|
125
|
+
entity: z.ZodOptional<z.ZodObject<{
|
|
126
|
+
entityType: z.ZodString;
|
|
127
|
+
entityId: z.ZodString;
|
|
128
|
+
}, z.core.$strip>>;
|
|
129
|
+
}, z.core.$strip>;
|
|
130
|
+
readonly forbidden: z.ZodObject<{
|
|
131
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
132
|
+
}, z.core.$strip>;
|
|
133
|
+
readonly not_found: z.ZodObject<{}, z.core.$strict>;
|
|
134
|
+
readonly conflict: z.ZodObject<{
|
|
135
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
136
|
+
}, z.core.$strip>;
|
|
137
|
+
readonly validation_failed: z.ZodObject<{
|
|
138
|
+
errors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
139
|
+
path: z.ZodString;
|
|
140
|
+
message: z.ZodString;
|
|
141
|
+
}, z.core.$strip>>>;
|
|
142
|
+
}, z.core.$strip>;
|
|
143
|
+
readonly precondition_failed: z.ZodObject<{}, z.core.$strict>;
|
|
144
|
+
readonly rate_limited: z.ZodObject<{
|
|
145
|
+
retryAfter: z.ZodOptional<z.ZodNumber>;
|
|
146
|
+
}, z.core.$strip>;
|
|
147
|
+
readonly unavailable: z.ZodObject<{}, z.core.$strict>;
|
|
148
|
+
readonly internal: z.ZodObject<{}, z.core.$strict>;
|
|
149
|
+
};
|
|
150
|
+
/** The extensions legal on one code, as a type — what `substratError` accepts. */
|
|
151
|
+
export type ExtensionsFor<C extends ErrorCode> = z.infer<(typeof PROBLEM_EXTENSIONS)[C]>;
|
|
152
|
+
/**
|
|
153
|
+
* The wire body. RFC 9457 members, plus `code`, plus every declared extension.
|
|
154
|
+
*
|
|
155
|
+
* `errors.test.ts` asserts this object carries every field any entry of
|
|
156
|
+
* `PROBLEM_EXTENSIONS` declares — the join between the two is checked in CI rather
|
|
157
|
+
* than by remembering to edit both.
|
|
158
|
+
*/
|
|
159
|
+
export declare const problem: z.ZodObject<{
|
|
160
|
+
type: z.ZodString;
|
|
161
|
+
title: z.ZodString;
|
|
162
|
+
status: z.ZodNumber;
|
|
163
|
+
detail: z.ZodOptional<z.ZodString>;
|
|
164
|
+
instance: z.ZodOptional<z.ZodString>;
|
|
165
|
+
error: z.ZodOptional<z.ZodString>;
|
|
166
|
+
code: z.ZodEnum<{
|
|
167
|
+
conflict: "conflict";
|
|
168
|
+
forbidden: "forbidden";
|
|
169
|
+
internal: "internal";
|
|
170
|
+
not_found: "not_found";
|
|
171
|
+
permission_denied: "permission_denied";
|
|
172
|
+
precondition_failed: "precondition_failed";
|
|
173
|
+
rate_limited: "rate_limited";
|
|
174
|
+
unauthenticated: "unauthenticated";
|
|
175
|
+
unavailable: "unavailable";
|
|
176
|
+
validation_failed: "validation_failed";
|
|
177
|
+
}>;
|
|
178
|
+
permission: z.ZodOptional<z.ZodString>;
|
|
179
|
+
entity: z.ZodOptional<z.ZodObject<{
|
|
180
|
+
entityType: z.ZodString;
|
|
181
|
+
entityId: z.ZodString;
|
|
182
|
+
}, z.core.$strip>>;
|
|
183
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
184
|
+
errors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
185
|
+
path: z.ZodString;
|
|
186
|
+
message: z.ZodString;
|
|
187
|
+
}, z.core.$strip>>>;
|
|
188
|
+
retryAfter: z.ZodOptional<z.ZodNumber>;
|
|
189
|
+
}, z.core.$strip>;
|
|
190
|
+
export type Problem = z.infer<typeof problem>;
|
|
191
|
+
/**
|
|
192
|
+
* Where a `SubstratError` keeps its code when the class itself is unavailable.
|
|
193
|
+
*
|
|
194
|
+
* `name` is a SECOND reading of the code, not a transport for it. Phase 2 proposed it
|
|
195
|
+
* as the way to cross the `ScopeDO` hop and that was wrong — measured against workerd,
|
|
196
|
+
* a thrown error arrives carrying its message and nothing else, with `name` folded into
|
|
197
|
+
* the message and reset. **Errors cross that boundary as a value now** (`wireFailure`,
|
|
198
|
+
* below), not as a throw.
|
|
199
|
+
*
|
|
200
|
+
* What this prefix still earns: a duplicate copy of a package in one build, a structured
|
|
201
|
+
* clone, or any other place the prototype is gone but the object survives — `errorCodeOf`
|
|
202
|
+
* reads the name and still answers correctly. Cheap, and it costs nothing to keep.
|
|
203
|
+
*/
|
|
204
|
+
export declare const ERROR_NAME_PREFIX = "Substrat.";
|
|
205
|
+
/**
|
|
206
|
+
* A throw that already knows what it means.
|
|
207
|
+
*
|
|
208
|
+
* `message` stays the human sentence and nothing more, so logs, stack traces and the
|
|
209
|
+
* contract suite's message assertions all read exactly as they do today. The code
|
|
210
|
+
* rides in `name`, which is what lets it survive the hop.
|
|
211
|
+
*/
|
|
212
|
+
export declare class SubstratError extends Error {
|
|
213
|
+
readonly code: ErrorCode;
|
|
214
|
+
readonly status: number;
|
|
215
|
+
readonly extensions: Readonly<Record<string, unknown>>;
|
|
216
|
+
constructor(code: ErrorCode, message: string, extensions?: Record<string, unknown>);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* The code a throw carries, however little of it survived.
|
|
220
|
+
*
|
|
221
|
+
* Three readings, in order of fidelity: the live `code` property (same isolate), the
|
|
222
|
+
* `Substrat.<code>` name (crossed a boundary), and the legacy class names above. A
|
|
223
|
+
* throw this cannot classify is not ours, and `toProblem` answers `internal` for it.
|
|
224
|
+
*/
|
|
225
|
+
export declare function errorCodeOf(err: unknown): ErrorCode | undefined;
|
|
226
|
+
/**
|
|
227
|
+
* Build a typed error. The extensions are checked against the code at COMPILE time
|
|
228
|
+
* and parsed at runtime, so a `retryAfter` on a `not_found` is caught at the throw
|
|
229
|
+
* site rather than discovered in a response body.
|
|
230
|
+
*/
|
|
231
|
+
export declare function substratError<C extends ErrorCode>(code: C, message: string, extensions?: ExtensionsFor<C>): SubstratError;
|
|
232
|
+
/**
|
|
233
|
+
* Recognise one of ours — by shape, never by `instanceof` alone.
|
|
234
|
+
*
|
|
235
|
+
* Two copies of a package in one build already make `instanceof` a coin toss; a
|
|
236
|
+
* serialising boundary makes it a certainty in the wrong direction.
|
|
237
|
+
*/
|
|
238
|
+
export declare function isSubstratError(err: unknown): err is SubstratError;
|
|
239
|
+
/** Zod's issue list, flattened to the wire shape. */
|
|
240
|
+
export declare function validationIssuesFrom(error: z.ZodError): ValidationIssue[];
|
|
241
|
+
/**
|
|
242
|
+
* Map any throw onto a problem body and its status — the one function replacing every
|
|
243
|
+
* hand-rolled `onError` and the control plane's regex table.
|
|
244
|
+
*
|
|
245
|
+
* **`internal` never carries `detail`.** An unrecognised throw is by definition one
|
|
246
|
+
* whose message nobody reviewed for what it discloses, and these surfaces have
|
|
247
|
+
* cross-tenant reach. The existing posture is right; this preserves it rather than
|
|
248
|
+
* quietly widening it in the name of better errors.
|
|
249
|
+
*/
|
|
250
|
+
export declare function toProblem(err: unknown, instance?: string): Problem;
|
|
251
|
+
/**
|
|
252
|
+
* The statuses an operation can actually answer with today, for the emitted document.
|
|
253
|
+
*
|
|
254
|
+
* `precondition_failed` (412) and `rate_limited` (429) are declared in the taxonomy
|
|
255
|
+
* so that `If-Match` (#129) and rate limiting (#130) add no vocabulary when they
|
|
256
|
+
* land — but nothing raises them yet, and documenting a failure that cannot occur is
|
|
257
|
+
* worse than documenting none. They join this list with the features that raise them.
|
|
258
|
+
*
|
|
259
|
+
* This narrows the RFC's §6 Q1 leaning ("emit the full set") on the same reasoning
|
|
260
|
+
* that motivated the question.
|
|
261
|
+
*/
|
|
262
|
+
export declare const DOCUMENTED_ERROR_CODES: readonly ErrorCode[];
|
|
263
|
+
/**
|
|
264
|
+
* An error flattened for a boundary that carries only data — the DO↔coordinator wire
|
|
265
|
+
* (#113 phase 3, `docs/rfc/error-model.md` §3).
|
|
266
|
+
*
|
|
267
|
+
* This exists because a THROW cannot carry structure across the ScopeDO hop: workerd
|
|
268
|
+
* delivers a thrown error's message and nothing else, folding `name` into it and
|
|
269
|
+
* dropping every own property (measured — `adapter-cloudflare`'s contract suite pins
|
|
270
|
+
* it). So the error stops being thrown across the boundary and starts being returned
|
|
271
|
+
* across it, as a value, which is the one shape that survives intact.
|
|
272
|
+
*/
|
|
273
|
+
export declare const wireFailure: z.ZodObject<{
|
|
274
|
+
name: z.ZodString;
|
|
275
|
+
message: z.ZodString;
|
|
276
|
+
code: z.ZodOptional<z.ZodEnum<{
|
|
277
|
+
conflict: "conflict";
|
|
278
|
+
forbidden: "forbidden";
|
|
279
|
+
internal: "internal";
|
|
280
|
+
not_found: "not_found";
|
|
281
|
+
permission_denied: "permission_denied";
|
|
282
|
+
precondition_failed: "precondition_failed";
|
|
283
|
+
rate_limited: "rate_limited";
|
|
284
|
+
unauthenticated: "unauthenticated";
|
|
285
|
+
unavailable: "unavailable";
|
|
286
|
+
validation_failed: "validation_failed";
|
|
287
|
+
}>>;
|
|
288
|
+
extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
289
|
+
}, z.core.$strip>;
|
|
290
|
+
export type WireFailure = z.infer<typeof wireFailure>;
|
|
291
|
+
/** Flatten a throw for the wire, losing nothing this side of the boundary knows. */
|
|
292
|
+
export declare function toWireFailure(err: unknown): WireFailure;
|
|
293
|
+
/**
|
|
294
|
+
* Rebuild a throw from the wire.
|
|
295
|
+
*
|
|
296
|
+
* The rebuilt error is a `SubstratError` carrying the original `name`, NOT an instance
|
|
297
|
+
* of the original class — contracts cannot import the kernel, and reviving arbitrary
|
|
298
|
+
* classes over a wire is a capability nobody should want. That is enough for every
|
|
299
|
+
* consumer in the repo, because they all read the code or the name, never the
|
|
300
|
+
* constructor. `instanceof PermissionDenied` stays false here and always will; it is
|
|
301
|
+
* the wrong question, and `errorCodeOf` is the right one.
|
|
302
|
+
*/
|
|
303
|
+
export declare function fromWireFailure(failure: WireFailure): Error;
|
|
304
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { entityRef } from './events.js';
|
|
3
|
+
/**
|
|
4
|
+
* The ONE error model for every surface on the platform (`docs/rfc/error-model.md`,
|
|
5
|
+
* issue #113): RFC 9457 `application/problem+json`, a CLOSED code taxonomy, and one
|
|
6
|
+
* mapper — replacing the seven hand-rolled `onError` handlers that today choose a
|
|
7
|
+
* status by matching on error message TEXT.
|
|
8
|
+
*
|
|
9
|
+
* Three properties this is built for:
|
|
10
|
+
*
|
|
11
|
+
* - **Machine-readable.** `validation_failed on field 'email'` is recoverable by a
|
|
12
|
+
* client — or by a build agent — without a person reading a log. `500 Something
|
|
13
|
+
* went wrong` is not.
|
|
14
|
+
* - **Documentable.** The same schema that validates a problem body is emitted into
|
|
15
|
+
* `/openapi.json` (`openapi.ts`), so the API surface finally describes how it can
|
|
16
|
+
* FAIL and not only how it succeeds. Decision 22 cashed in again.
|
|
17
|
+
* - **Additive to adopt.** `toProblem` maps an unrecognised throw to `internal` exactly
|
|
18
|
+
* as the hand-rolled handlers do, so each layer could adopt this without a flag day.
|
|
19
|
+
*
|
|
20
|
+
* ## Where the rollout stands
|
|
21
|
+
*
|
|
22
|
+
* Phases 1–3 are in: the taxonomy and `toProblem` (contracts), the kernel's own error
|
|
23
|
+
* classes joined to it, and `wireFailure` — the value an error becomes when it has to
|
|
24
|
+
* cross the ScopeDO boundary, because a throw cannot carry structure across it. What
|
|
25
|
+
* remains is phase 4: the transports reading `code` instead of matching messages, and
|
|
26
|
+
* the deprecated `error` duplicate coming back out of the body.
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* The base for `type` URIs.
|
|
30
|
+
*
|
|
31
|
+
* DERIVED from the code rather than written per entry, deliberately: whether we
|
|
32
|
+
* actually serve a page at each of these URLs is still open (RFC §6 Q2), and nothing
|
|
33
|
+
* throws a problem yet, so no `type` value has reached a client. Flipping the
|
|
34
|
+
* decision stays a one-line change here for exactly as long as that holds.
|
|
35
|
+
*/
|
|
36
|
+
export const PROBLEM_TYPE_BASE = 'https://substrat.net/errors';
|
|
37
|
+
/**
|
|
38
|
+
* The taxonomy. CLOSED — an open one is a suggestion.
|
|
39
|
+
*
|
|
40
|
+
* A module never invents a code. It narrows an existing one with a `reason` slug it
|
|
41
|
+
* owns (`conflict` + `reason: 'already_exported'`), which is the star topology
|
|
42
|
+
* applied to failure: a vertical branches on an engine's reason without importing
|
|
43
|
+
* the engine's types.
|
|
44
|
+
*/
|
|
45
|
+
export const errorCode = z.enum([
|
|
46
|
+
'unauthenticated',
|
|
47
|
+
'permission_denied',
|
|
48
|
+
'forbidden',
|
|
49
|
+
'not_found',
|
|
50
|
+
'conflict',
|
|
51
|
+
'validation_failed',
|
|
52
|
+
'precondition_failed',
|
|
53
|
+
'rate_limited',
|
|
54
|
+
'unavailable',
|
|
55
|
+
'internal',
|
|
56
|
+
]);
|
|
57
|
+
/** `permission_denied` → `https://substrat.net/errors/permission-denied`. */
|
|
58
|
+
export function problemTypeFor(code) {
|
|
59
|
+
return `${PROBLEM_TYPE_BASE}/${code.replaceAll('_', '-')}`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Status and human title per code. `Record<ErrorCode, …>` on purpose: adding a code
|
|
63
|
+
* without deciding what it means to HTTP is then a compile error, not a 500 found in
|
|
64
|
+
* production.
|
|
65
|
+
*/
|
|
66
|
+
export const PROBLEM_CATALOG = {
|
|
67
|
+
unauthenticated: { status: 401, title: 'Unauthenticated' },
|
|
68
|
+
permission_denied: { status: 403, title: 'Permission denied' },
|
|
69
|
+
forbidden: { status: 403, title: 'Forbidden' },
|
|
70
|
+
not_found: { status: 404, title: 'Not found' },
|
|
71
|
+
conflict: { status: 409, title: 'Conflict' },
|
|
72
|
+
validation_failed: { status: 400, title: 'Validation failed' },
|
|
73
|
+
precondition_failed: { status: 412, title: 'Precondition failed' },
|
|
74
|
+
rate_limited: { status: 429, title: 'Rate limited' },
|
|
75
|
+
unavailable: { status: 503, title: 'Service unavailable' },
|
|
76
|
+
internal: { status: 500, title: 'Internal error' },
|
|
77
|
+
};
|
|
78
|
+
/** One field-level complaint, mapped from a Zod issue. */
|
|
79
|
+
export const validationIssue = z.object({
|
|
80
|
+
/** Dotted path into the input: `lines.0.quantity`. Empty for a root-level issue. */
|
|
81
|
+
path: z.string(),
|
|
82
|
+
message: z.string(),
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* The extension members each code may carry — declared per entry, never free-form.
|
|
86
|
+
*
|
|
87
|
+
* These are enforced where it matters: at the THROW site, by `substratError`, which
|
|
88
|
+
* both types and parses them. The wire schema below is one flat object rather than a
|
|
89
|
+
* ten-way discriminated union, because a `oneOf` of ten variants documents worse than
|
|
90
|
+
* one object does and buys a narrowing no client asked for. Per-code narrowing of the
|
|
91
|
+
* emitted document is RFC §6 Q1, deferred with the model layer that would own it.
|
|
92
|
+
*/
|
|
93
|
+
export const PROBLEM_EXTENSIONS = {
|
|
94
|
+
unauthenticated: z.strictObject({}),
|
|
95
|
+
permission_denied: z.object({
|
|
96
|
+
/** The permission key the check refused. */
|
|
97
|
+
permission: z.string().min(1).optional(),
|
|
98
|
+
/** Set when the refusal was a per-entity check rather than a node-level one. */
|
|
99
|
+
entity: entityRef.optional(),
|
|
100
|
+
}),
|
|
101
|
+
forbidden: z.object({ reason: z.string().min(1).optional() }),
|
|
102
|
+
not_found: z.strictObject({}),
|
|
103
|
+
conflict: z.object({ reason: z.string().min(1).optional() }),
|
|
104
|
+
validation_failed: z.object({ errors: z.array(validationIssue).optional() }),
|
|
105
|
+
precondition_failed: z.strictObject({}),
|
|
106
|
+
rate_limited: z.object({ retryAfter: z.number().int().nonnegative().optional() }),
|
|
107
|
+
unavailable: z.strictObject({}),
|
|
108
|
+
internal: z.strictObject({}),
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* The wire body. RFC 9457 members, plus `code`, plus every declared extension.
|
|
112
|
+
*
|
|
113
|
+
* `errors.test.ts` asserts this object carries every field any entry of
|
|
114
|
+
* `PROBLEM_EXTENSIONS` declares — the join between the two is checked in CI rather
|
|
115
|
+
* than by remembering to edit both.
|
|
116
|
+
*/
|
|
117
|
+
export const problem = z.object({
|
|
118
|
+
/** Canonical identifier. Resolves — an error that documents itself. */
|
|
119
|
+
type: z.string().min(1),
|
|
120
|
+
/** Short, human, and STABLE per code — clients may group on it, so it does not vary. */
|
|
121
|
+
title: z.string().min(1),
|
|
122
|
+
/** Duplicated from the HTTP status line, per RFC 9457 §3.1.2. */
|
|
123
|
+
status: z.number().int(),
|
|
124
|
+
/** What went wrong THIS time. Absent on `internal`, always — see `toProblem`. */
|
|
125
|
+
detail: z.string().optional(),
|
|
126
|
+
/** The request this refers to, when a transport knows it. */
|
|
127
|
+
instance: z.string().optional(),
|
|
128
|
+
/**
|
|
129
|
+
* DEPRECATED duplicate of `detail`, for one migration window.
|
|
130
|
+
*
|
|
131
|
+
* Every SPA in the repo reads `{ error }` today. RFC 9457 permits extension
|
|
132
|
+
* members, so carrying this lets the transports adopt problem+json without
|
|
133
|
+
* breaking a single client — which is what makes the rollout's phase 3 a
|
|
134
|
+
* non-event. Removed once the clients are moved, not "eventually".
|
|
135
|
+
*/
|
|
136
|
+
error: z.string().optional(),
|
|
137
|
+
code: errorCode,
|
|
138
|
+
// -- declared extensions (see PROBLEM_EXTENSIONS) ---------------------------
|
|
139
|
+
permission: z.string().min(1).optional(),
|
|
140
|
+
entity: entityRef.optional(),
|
|
141
|
+
reason: z.string().min(1).optional(),
|
|
142
|
+
errors: z.array(validationIssue).optional(),
|
|
143
|
+
retryAfter: z.number().int().nonnegative().optional(),
|
|
144
|
+
});
|
|
145
|
+
/**
|
|
146
|
+
* Where a `SubstratError` keeps its code when the class itself is unavailable.
|
|
147
|
+
*
|
|
148
|
+
* `name` is a SECOND reading of the code, not a transport for it. Phase 2 proposed it
|
|
149
|
+
* as the way to cross the `ScopeDO` hop and that was wrong — measured against workerd,
|
|
150
|
+
* a thrown error arrives carrying its message and nothing else, with `name` folded into
|
|
151
|
+
* the message and reset. **Errors cross that boundary as a value now** (`wireFailure`,
|
|
152
|
+
* below), not as a throw.
|
|
153
|
+
*
|
|
154
|
+
* What this prefix still earns: a duplicate copy of a package in one build, a structured
|
|
155
|
+
* clone, or any other place the prototype is gone but the object survives — `errorCodeOf`
|
|
156
|
+
* reads the name and still answers correctly. Cheap, and it costs nothing to keep.
|
|
157
|
+
*/
|
|
158
|
+
export const ERROR_NAME_PREFIX = 'Substrat.';
|
|
159
|
+
/**
|
|
160
|
+
* Class names that predate the taxonomy and already mean a code.
|
|
161
|
+
*
|
|
162
|
+
* Keeping `PermissionDenied` named `PermissionDenied` rather than renaming it to the
|
|
163
|
+
* generic form is deliberate: `vertical-host`'s classifier and several verticals match
|
|
164
|
+
* on that exact string today, and a rename would be a silent behaviour change bundled
|
|
165
|
+
* into a refactor. `ZodError` earns its row because a parse failure crossing the hop
|
|
166
|
+
* loses its `issues` array — the code is all that is left, and `validation_failed`
|
|
167
|
+
* without fields still beats `internal`.
|
|
168
|
+
*/
|
|
169
|
+
const CODE_BY_ERROR_NAME = {
|
|
170
|
+
PermissionDenied: 'permission_denied',
|
|
171
|
+
SecretBoxUnconfiguredError: 'unavailable',
|
|
172
|
+
ZodError: 'validation_failed',
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* A throw that already knows what it means.
|
|
176
|
+
*
|
|
177
|
+
* `message` stays the human sentence and nothing more, so logs, stack traces and the
|
|
178
|
+
* contract suite's message assertions all read exactly as they do today. The code
|
|
179
|
+
* rides in `name`, which is what lets it survive the hop.
|
|
180
|
+
*/
|
|
181
|
+
export class SubstratError extends Error {
|
|
182
|
+
code;
|
|
183
|
+
status;
|
|
184
|
+
extensions;
|
|
185
|
+
constructor(code, message, extensions = {}) {
|
|
186
|
+
super(message);
|
|
187
|
+
this.name = `${ERROR_NAME_PREFIX}${code}`;
|
|
188
|
+
this.code = code;
|
|
189
|
+
this.status = PROBLEM_CATALOG[code].status;
|
|
190
|
+
this.extensions = extensions;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* The code a throw carries, however little of it survived.
|
|
195
|
+
*
|
|
196
|
+
* Three readings, in order of fidelity: the live `code` property (same isolate), the
|
|
197
|
+
* `Substrat.<code>` name (crossed a boundary), and the legacy class names above. A
|
|
198
|
+
* throw this cannot classify is not ours, and `toProblem` answers `internal` for it.
|
|
199
|
+
*/
|
|
200
|
+
export function errorCodeOf(err) {
|
|
201
|
+
if (err === null || typeof err !== 'object')
|
|
202
|
+
return undefined;
|
|
203
|
+
const own = err.code;
|
|
204
|
+
if (typeof own === 'string') {
|
|
205
|
+
const parsed = errorCode.safeParse(own);
|
|
206
|
+
if (parsed.success)
|
|
207
|
+
return parsed.data;
|
|
208
|
+
}
|
|
209
|
+
const name = err.name;
|
|
210
|
+
if (typeof name !== 'string')
|
|
211
|
+
return undefined;
|
|
212
|
+
if (name.startsWith(ERROR_NAME_PREFIX)) {
|
|
213
|
+
const parsed = errorCode.safeParse(name.slice(ERROR_NAME_PREFIX.length));
|
|
214
|
+
if (parsed.success)
|
|
215
|
+
return parsed.data;
|
|
216
|
+
}
|
|
217
|
+
return CODE_BY_ERROR_NAME[name];
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Build a typed error. The extensions are checked against the code at COMPILE time
|
|
221
|
+
* and parsed at runtime, so a `retryAfter` on a `not_found` is caught at the throw
|
|
222
|
+
* site rather than discovered in a response body.
|
|
223
|
+
*/
|
|
224
|
+
export function substratError(code, message, extensions) {
|
|
225
|
+
const parsed = PROBLEM_EXTENSIONS[code].parse(extensions ?? {});
|
|
226
|
+
return new SubstratError(code, message, parsed);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Recognise one of ours — by shape, never by `instanceof` alone.
|
|
230
|
+
*
|
|
231
|
+
* Two copies of a package in one build already make `instanceof` a coin toss; a
|
|
232
|
+
* serialising boundary makes it a certainty in the wrong direction.
|
|
233
|
+
*/
|
|
234
|
+
export function isSubstratError(err) {
|
|
235
|
+
return err instanceof Error && errorCodeOf(err) !== undefined;
|
|
236
|
+
}
|
|
237
|
+
/** Zod's issue list, flattened to the wire shape. */
|
|
238
|
+
export function validationIssuesFrom(error) {
|
|
239
|
+
return error.issues.map((issue) => ({
|
|
240
|
+
path: issue.path.map(String).join('.'),
|
|
241
|
+
message: issue.message,
|
|
242
|
+
}));
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Map any throw onto a problem body and its status — the one function replacing every
|
|
246
|
+
* hand-rolled `onError` and the control plane's regex table.
|
|
247
|
+
*
|
|
248
|
+
* **`internal` never carries `detail`.** An unrecognised throw is by definition one
|
|
249
|
+
* whose message nobody reviewed for what it discloses, and these surfaces have
|
|
250
|
+
* cross-tenant reach. The existing posture is right; this preserves it rather than
|
|
251
|
+
* quietly widening it in the name of better errors.
|
|
252
|
+
*/
|
|
253
|
+
export function toProblem(err, instance) {
|
|
254
|
+
if (err instanceof z.ZodError) {
|
|
255
|
+
return build('validation_failed', 'the input did not parse', instance, {
|
|
256
|
+
errors: validationIssuesFrom(err),
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
const code = errorCodeOf(err);
|
|
260
|
+
if (code !== undefined && err instanceof Error) {
|
|
261
|
+
// `internal` is still generic even when a throw asked for it by name: the rule is
|
|
262
|
+
// about what reaches a client, not about who chose the code.
|
|
263
|
+
if (code === 'internal')
|
|
264
|
+
return build('internal', undefined, instance);
|
|
265
|
+
const extensions = err.extensions ?? {};
|
|
266
|
+
return build(code, err.message, instance, extensions);
|
|
267
|
+
}
|
|
268
|
+
return build('internal', undefined, instance);
|
|
269
|
+
}
|
|
270
|
+
function build(code, detail, instance, extensions = {}) {
|
|
271
|
+
const { status, title } = PROBLEM_CATALOG[code];
|
|
272
|
+
return problem.parse({
|
|
273
|
+
type: problemTypeFor(code),
|
|
274
|
+
title,
|
|
275
|
+
status,
|
|
276
|
+
...(detail === undefined ? {} : { detail, error: detail }),
|
|
277
|
+
...(instance === undefined ? {} : { instance }),
|
|
278
|
+
code,
|
|
279
|
+
...extensions,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* The statuses an operation can actually answer with today, for the emitted document.
|
|
284
|
+
*
|
|
285
|
+
* `precondition_failed` (412) and `rate_limited` (429) are declared in the taxonomy
|
|
286
|
+
* so that `If-Match` (#129) and rate limiting (#130) add no vocabulary when they
|
|
287
|
+
* land — but nothing raises them yet, and documenting a failure that cannot occur is
|
|
288
|
+
* worse than documenting none. They join this list with the features that raise them.
|
|
289
|
+
*
|
|
290
|
+
* This narrows the RFC's §6 Q1 leaning ("emit the full set") on the same reasoning
|
|
291
|
+
* that motivated the question.
|
|
292
|
+
*/
|
|
293
|
+
export const DOCUMENTED_ERROR_CODES = [
|
|
294
|
+
'validation_failed',
|
|
295
|
+
'unauthenticated',
|
|
296
|
+
'permission_denied',
|
|
297
|
+
'forbidden',
|
|
298
|
+
'not_found',
|
|
299
|
+
'conflict',
|
|
300
|
+
'unavailable',
|
|
301
|
+
'internal',
|
|
302
|
+
];
|
|
303
|
+
/**
|
|
304
|
+
* An error flattened for a boundary that carries only data — the DO↔coordinator wire
|
|
305
|
+
* (#113 phase 3, `docs/rfc/error-model.md` §3).
|
|
306
|
+
*
|
|
307
|
+
* This exists because a THROW cannot carry structure across the ScopeDO hop: workerd
|
|
308
|
+
* delivers a thrown error's message and nothing else, folding `name` into it and
|
|
309
|
+
* dropping every own property (measured — `adapter-cloudflare`'s contract suite pins
|
|
310
|
+
* it). So the error stops being thrown across the boundary and starts being returned
|
|
311
|
+
* across it, as a value, which is the one shape that survives intact.
|
|
312
|
+
*/
|
|
313
|
+
export const wireFailure = z.object({
|
|
314
|
+
/** The original `name`, so `PermissionDenied` still reads as itself on the far side. */
|
|
315
|
+
name: z.string().min(1),
|
|
316
|
+
message: z.string(),
|
|
317
|
+
/** Absent when the throw was never ours — a bare `Error` stays a bare `Error`. */
|
|
318
|
+
code: errorCode.optional(),
|
|
319
|
+
extensions: z.record(z.string(), z.unknown()).optional(),
|
|
320
|
+
});
|
|
321
|
+
/** Flatten a throw for the wire, losing nothing this side of the boundary knows. */
|
|
322
|
+
export function toWireFailure(err) {
|
|
323
|
+
if (!(err instanceof Error))
|
|
324
|
+
return { name: 'Error', message: String(err) };
|
|
325
|
+
const code = errorCodeOf(err);
|
|
326
|
+
if (code === undefined)
|
|
327
|
+
return { name: err.name, message: err.message };
|
|
328
|
+
return {
|
|
329
|
+
name: err.name,
|
|
330
|
+
message: err.message,
|
|
331
|
+
code,
|
|
332
|
+
extensions: { ...(err.extensions ?? {}) },
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Rebuild a throw from the wire.
|
|
337
|
+
*
|
|
338
|
+
* The rebuilt error is a `SubstratError` carrying the original `name`, NOT an instance
|
|
339
|
+
* of the original class — contracts cannot import the kernel, and reviving arbitrary
|
|
340
|
+
* classes over a wire is a capability nobody should want. That is enough for every
|
|
341
|
+
* consumer in the repo, because they all read the code or the name, never the
|
|
342
|
+
* constructor. `instanceof PermissionDenied` stays false here and always will; it is
|
|
343
|
+
* the wrong question, and `errorCodeOf` is the right one.
|
|
344
|
+
*/
|
|
345
|
+
export function fromWireFailure(failure) {
|
|
346
|
+
const err = failure.code === undefined
|
|
347
|
+
? new Error(failure.message)
|
|
348
|
+
: new SubstratError(failure.code, failure.message, { ...(failure.extensions ?? {}) });
|
|
349
|
+
err.name = failure.name;
|
|
350
|
+
return err;
|
|
351
|
+
}
|
|
352
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export * from './connections.js';
|
|
|
27
27
|
export * from './control-plane.js';
|
|
28
28
|
export * from './permission.js';
|
|
29
29
|
export * from './events.js';
|
|
30
|
+
export * from './errors.js';
|
|
30
31
|
export * from './platform-request.js';
|
|
31
32
|
export * from './manifest.js';
|
|
32
33
|
export * from './openapi.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -27,6 +27,7 @@ export * from './connections.js';
|
|
|
27
27
|
export * from './control-plane.js';
|
|
28
28
|
export * from './permission.js';
|
|
29
29
|
export * from './events.js';
|
|
30
|
+
export * from './errors.js';
|
|
30
31
|
export * from './platform-request.js';
|
|
31
32
|
export * from './manifest.js';
|
|
32
33
|
export * from './openapi.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC"}
|
package/dist/openapi.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IAClB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mFAAmF;IACnF,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9E;AAED,+EAA+E;AAC/E,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA4ED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,UAAU,GAClB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAsEzB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC5C,KAAK,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAM,GAC3E,UAAU,CAwBZ"}
|
package/dist/openapi.js
CHANGED
|
@@ -1,10 +1,62 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import { DOCUMENTED_ERROR_CODES, PROBLEM_CATALOG, problem, } from './errors.js';
|
|
3
|
+
/** Where the one problem schema lives in the document, referenced from every failure. */
|
|
4
|
+
const PROBLEM_SCHEMA_REF = '#/components/schemas/Problem';
|
|
5
|
+
/**
|
|
6
|
+
* Prose per status. Generated descriptions would read like a type listing; these say
|
|
7
|
+
* what the caller should conclude, which is the half a schema cannot carry.
|
|
8
|
+
*/
|
|
9
|
+
const ERROR_STATUS_PROSE = {
|
|
10
|
+
400: 'Validation failed — the input did not parse against the operation schema.',
|
|
11
|
+
401: 'No session — sign in (or present a bearer token) first.',
|
|
12
|
+
403: 'Refused — the caller lacks the permission this operation checks, or policy forbids it.',
|
|
13
|
+
404: 'Unknown operation, or an entity named in the input does not exist.',
|
|
14
|
+
409: 'Conflicts with current state — an illegal transition, a name already taken, or a record that is immutable now.',
|
|
15
|
+
500: 'Internal error. The body carries no `detail`, deliberately — an unreviewed message is not disclosed on a multi-tenant surface.',
|
|
16
|
+
503: 'The deployment cannot serve this — a required platform facility is unconfigured.',
|
|
7
17
|
};
|
|
18
|
+
/** Component name per documented status — `403` → `#/components/responses/Forbidden`. */
|
|
19
|
+
const ERROR_RESPONSE_NAME = {
|
|
20
|
+
400: 'ValidationFailed',
|
|
21
|
+
401: 'Unauthenticated',
|
|
22
|
+
403: 'Forbidden',
|
|
23
|
+
404: 'NotFound',
|
|
24
|
+
409: 'Conflict',
|
|
25
|
+
500: 'InternalError',
|
|
26
|
+
503: 'Unavailable',
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* The failure half of every operation, derived from the error taxonomy (#113).
|
|
30
|
+
*
|
|
31
|
+
* Bodies are `application/problem+json` (RFC 9457). Both the schema AND the responses
|
|
32
|
+
* themselves live in `components` and are referenced, which is what keeps the
|
|
33
|
+
* checked-in artifact readable: a vertical with 27 operations gains three lines per
|
|
34
|
+
* failure rather than a fully inlined body per failure per operation. `api-diff`'s
|
|
35
|
+
* document is a review artifact, so its signal-to-noise is a real constraint.
|
|
36
|
+
*
|
|
37
|
+
* Every operation currently documents the same set. Narrowing it per operation — a
|
|
38
|
+
* `409` only where a conflict is actually reachable — wants the model layer to own
|
|
39
|
+
* the declaration, and is deferred with it (error-model RFC §6 Q1).
|
|
40
|
+
*/
|
|
41
|
+
const DOCUMENTED_STATUSES = [
|
|
42
|
+
...new Set(DOCUMENTED_ERROR_CODES.map((code) => PROBLEM_CATALOG[code].status)),
|
|
43
|
+
].sort((a, b) => a - b);
|
|
44
|
+
const ERROR_RESPONSES = Object.fromEntries(DOCUMENTED_STATUSES.map((status) => [
|
|
45
|
+
String(status),
|
|
46
|
+
{ $ref: `#/components/responses/${ERROR_RESPONSE_NAME[status]}` },
|
|
47
|
+
]));
|
|
48
|
+
/** The definitions those references point at, written once per document. */
|
|
49
|
+
const ERROR_RESPONSE_COMPONENTS = Object.fromEntries(DOCUMENTED_STATUSES.map((status) => {
|
|
50
|
+
const codes = DOCUMENTED_ERROR_CODES.filter((code) => PROBLEM_CATALOG[code].status === status);
|
|
51
|
+
const codeList = codes.map((code) => `\`${code}\``).join(' or ');
|
|
52
|
+
return [
|
|
53
|
+
ERROR_RESPONSE_NAME[status],
|
|
54
|
+
{
|
|
55
|
+
description: `${ERROR_STATUS_PROSE[status]} Carries \`code\`: ${codeList}.`,
|
|
56
|
+
content: { 'application/problem+json': { schema: { $ref: PROBLEM_SCHEMA_REF } } },
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
}));
|
|
8
60
|
// The per-schema `$schema` key is dropped: OpenAPI 3.1's document-wide dialect
|
|
9
61
|
// IS draft 2020-12, so repeating it on every request body is pure noise.
|
|
10
62
|
const jsonSchema = (schema, io) => {
|
|
@@ -63,6 +115,11 @@ export function buildOpenApiDocument(info, catalog) {
|
|
|
63
115
|
info,
|
|
64
116
|
paths,
|
|
65
117
|
components: {
|
|
118
|
+
// One problem schema, referenced by every failure response above — the same
|
|
119
|
+
// object `toProblem` builds and validates, so the documented failure shape
|
|
120
|
+
// cannot drift from the emitted one.
|
|
121
|
+
schemas: { Problem: jsonSchema(problem, 'output') },
|
|
122
|
+
responses: ERROR_RESPONSE_COMPONENTS,
|
|
66
123
|
securitySchemes: {
|
|
67
124
|
// The primary path: the vertical's own session cookie. Same-origin
|
|
68
125
|
// try-it (the /api/docs page) rides it automatically — the browser
|
package/dist/openapi.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@substrat-run/contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.79.0",
|
|
4
4
|
"description": "Substrat kernel contract schemas — Zod is the source of truth (master plan D-22); OAS/JSON Schema are emitted artifacts",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|