@zeroxsolutions/response 0.14.4 → 0.14.6

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/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## 0.14.6 (2026-10-21)
2
+
3
+ ### 🚀 Features
4
+
5
+ - **response:** type a resource's data.id through a declared id schema ([3dd4f2c](https://github.com/zeroxsolutions/zeroxsolutions/commit/3dd4f2c))
6
+
7
+ ### ❤️ Thank You
8
+
9
+ - luongvantuit
10
+
11
+ ## 0.14.5 (2026-10-19)
12
+
13
+ ### 🚀 Features
14
+
15
+ - **response:** hold every error answer to the codes a transport publishes ([0824f8e](https://github.com/zeroxsolutions/zeroxsolutions/commit/0824f8e))
16
+
17
+ ### ❤️ Thank You
18
+
19
+ - Claude Opus 5.5
20
+ - Lương Văn Tú
21
+
1
22
  ## 0.14.4 (2026-10-06)
2
23
 
3
24
  ### 🩹 Fixes
@@ -58,31 +79,31 @@
58
79
  ### 🚀 Features
59
80
 
60
81
  - **response:** answer a created resource with its location ([e9c0086](https://github.com/zeroxsolutions/zeroxsolutions/commit/e9c0086))
61
- - ⚠️ **response:** refuse a declaration the standard's field rules forbid ([30e6b77](https://github.com/zeroxsolutions/zeroxsolutions/commit/30e6b77))
82
+ - ⚠️ **response:** refuse a declaration the standard's field rules forbid ([30e6b77](https://github.com/zeroxsolutions/zeroxsolutions/commit/30e6b77))
62
83
 
63
84
  ### 🩹 Fixes
64
85
 
65
- - ⚠️ **response:** walk a pipe's input when checking member names ([0949d22](https://github.com/zeroxsolutions/zeroxsolutions/commit/0949d22))
86
+ - ⚠️ **response:** walk a pipe's input when checking member names ([0949d22](https://github.com/zeroxsolutions/zeroxsolutions/commit/0949d22))
66
87
  - **response:** match link types to their schemas ([0f7c79b](https://github.com/zeroxsolutions/zeroxsolutions/commit/0f7c79b))
67
- - ⚠️ **response:** refuse a resource id that is not a string ([57f60ab](https://github.com/zeroxsolutions/zeroxsolutions/commit/57f60ab))
88
+ - ⚠️ **response:** refuse a resource id that is not a string ([57f60ab](https://github.com/zeroxsolutions/zeroxsolutions/commit/57f60ab))
68
89
  - **response:** keep a primary resource out of included ([c38859f](https://github.com/zeroxsolutions/zeroxsolutions/commit/c38859f))
69
- - ⚠️ **response:** read only the document members the standard defines ([fc5c51a](https://github.com/zeroxsolutions/zeroxsolutions/commit/fc5c51a))
70
- - ⚠️ **response:** refuse an error object that carries no member ([7d888ed](https://github.com/zeroxsolutions/zeroxsolutions/commit/7d888ed))
90
+ - ⚠️ **response:** read only the document members the standard defines ([fc5c51a](https://github.com/zeroxsolutions/zeroxsolutions/commit/fc5c51a))
91
+ - ⚠️ **response:** refuse an error object that carries no member ([7d888ed](https://github.com/zeroxsolutions/zeroxsolutions/commit/7d888ed))
71
92
 
72
- ### ⚠️ Breaking Changes
93
+ ### ⚠️ Breaking Changes
73
94
 
74
- - **response:** walk a pipe's input when checking member names ([0949d22](https://github.com/zeroxsolutions/zeroxsolutions/commit/0949d22))
95
+ - **response:** walk a pipe's input when checking member names ([0949d22](https://github.com/zeroxsolutions/zeroxsolutions/commit/0949d22))
75
96
  a nested attribute member name that breaks the
76
97
  standard's member-name rule, and sits behind a .transform() or
77
98
  .pipe(), now throws at jsonApiResource's own declaration where it
78
99
  previously passed unchecked.
79
- - **response:** refuse a declaration the standard's field rules forbid ([30e6b77](https://github.com/zeroxsolutions/zeroxsolutions/commit/30e6b77))
100
+ - **response:** refuse a declaration the standard's field rules forbid ([30e6b77](https://github.com/zeroxsolutions/zeroxsolutions/commit/30e6b77))
80
101
  jsonApiResource throws, and fails to compile, on a field named type or id, a name shared by an attribute and a relationship, an illegal member name, or a foreign-key attribute beside its relationship.
81
- - **response:** refuse a resource id that is not a string ([57f60ab](https://github.com/zeroxsolutions/zeroxsolutions/commit/57f60ab))
102
+ - **response:** refuse a resource id that is not a string ([57f60ab](https://github.com/zeroxsolutions/zeroxsolutions/commit/57f60ab))
82
103
  Row['id'] is typed string, and serializing a row, embedded row or foreign key whose id is not a string throws TypeError.
83
- - **response:** read only the document members the standard defines ([fc5c51a](https://github.com/zeroxsolutions/zeroxsolutions/commit/fc5c51a))
104
+ - **response:** read only the document members the standard defines ([fc5c51a](https://github.com/zeroxsolutions/zeroxsolutions/commit/fc5c51a))
84
105
  a data document carrying errors, an error document carrying data, and an empty relationship object are refused.
85
- - **response:** refuse an error object that carries no member ([7d888ed](https://github.com/zeroxsolutions/zeroxsolutions/commit/7d888ed))
106
+ - **response:** refuse an error object that carries no member ([7d888ed](https://github.com/zeroxsolutions/zeroxsolutions/commit/7d888ed))
86
107
  toErrorDocument throws on an empty error object.
87
108
 
88
109
  ### ❤️ Thank You
@@ -94,28 +115,28 @@
94
115
 
95
116
  ### 🚀 Features
96
117
 
97
- - ⚠️ **response:** type the fieldsets and include paths a document answers ([98bbb58](https://github.com/zeroxsolutions/zeroxsolutions/commit/98bbb58))
98
- - ⚠️ **response:** keep a resource's type, attributes and relationships as literals ([738889e](https://github.com/zeroxsolutions/zeroxsolutions/commit/738889e))
118
+ - ⚠️ **response:** type the fieldsets and include paths a document answers ([98bbb58](https://github.com/zeroxsolutions/zeroxsolutions/commit/98bbb58))
119
+ - ⚠️ **response:** keep a resource's type, attributes and relationships as literals ([738889e](https://github.com/zeroxsolutions/zeroxsolutions/commit/738889e))
99
120
 
100
121
  ### 🩹 Fixes
101
122
 
102
- - ⚠️ **response:** pin an include path stopping at a wide edge ([515a3e9](https://github.com/zeroxsolutions/zeroxsolutions/commit/515a3e9))
123
+ - ⚠️ **response:** pin an include path stopping at a wide edge ([515a3e9](https://github.com/zeroxsolutions/zeroxsolutions/commit/515a3e9))
103
124
 
104
- ### ⚠️ Breaking Changes
125
+ ### ⚠️ Breaking Changes
105
126
 
106
- - **response:** pin an include path stopping at a wide edge ([515a3e9](https://github.com/zeroxsolutions/zeroxsolutions/commit/515a3e9))
127
+ - **response:** pin an include path stopping at a wide edge ([515a3e9](https://github.com/zeroxsolutions/zeroxsolutions/commit/515a3e9))
107
128
  jsonApiResource's type parameters moved from <A, C> to
108
129
  <T, A, R, C>, so an explicit `jsonApiResource<typeof attrs, Ctx>` no
109
130
  longer compiles; remove the type arguments and let inference type it.
110
131
  The exported ResourceOptions<C> is now ResourceOptions<R>.
111
132
  BREAKING CHANGE: an explicit toOne<Ctx> or toMany<Ctx> no longer
112
133
  compiles; remove the type argument.
113
- - **response:** type the fieldsets and include paths a document answers ([98bbb58](https://github.com/zeroxsolutions/zeroxsolutions/commit/98bbb58))
134
+ - **response:** type the fieldsets and include paths a document answers ([98bbb58](https://github.com/zeroxsolutions/zeroxsolutions/commit/98bbb58))
114
135
  declaredDocumentShape answers typed fieldsets and include
115
136
  paths, walks at most three relationships by default, and answers a fieldset
116
137
  only for a type a kept path reaches. DeclaredDocumentShape is removed;
117
138
  TypedDocumentShape replaces it.
118
- - **response:** keep a resource's type, attributes and relationships as literals ([738889e](https://github.com/zeroxsolutions/zeroxsolutions/commit/738889e))
139
+ - **response:** keep a resource's type, attributes and relationships as literals ([738889e](https://github.com/zeroxsolutions/zeroxsolutions/commit/738889e))
119
140
  toOne and toMany take the related resource as their first type
120
141
  parameter and infer the loader context; a call passing the context explicitly,
121
142
  toOne<Ctx>(...), no longer compiles and drops the explicit argument.
@@ -153,13 +174,13 @@
153
174
 
154
175
  ### 💅 Refactors
155
176
 
156
- - ⚠️ **response:** list the names the package root publishes ([7b8a95d](https://github.com/zeroxsolutions/zeroxsolutions/commit/7b8a95d))
157
- - ⚠️ **response:** answer mapped errors with links and meta ([b78bc08](https://github.com/zeroxsolutions/zeroxsolutions/commit/b78bc08))
158
- - ⚠️ **response:** render every member of a JSON:API error object ([ca0c551](https://github.com/zeroxsolutions/zeroxsolutions/commit/ca0c551))
177
+ - ⚠️ **response:** list the names the package root publishes ([7b8a95d](https://github.com/zeroxsolutions/zeroxsolutions/commit/7b8a95d))
178
+ - ⚠️ **response:** answer mapped errors with links and meta ([b78bc08](https://github.com/zeroxsolutions/zeroxsolutions/commit/b78bc08))
179
+ - ⚠️ **response:** render every member of a JSON:API error object ([ca0c551](https://github.com/zeroxsolutions/zeroxsolutions/commit/ca0c551))
159
180
 
160
- ### ⚠️ Breaking Changes
181
+ ### ⚠️ Breaking Changes
161
182
 
162
- - **response:** list the names the package root publishes ([7b8a95d](https://github.com/zeroxsolutions/zeroxsolutions/commit/7b8a95d))
183
+ - **response:** list the names the package root publishes ([7b8a95d](https://github.com/zeroxsolutions/zeroxsolutions/commit/7b8a95d))
163
184
  the root no longer exports `createSerializer`,
164
185
  `serializeResource`, `serializeCollection`, `reachableResources`,
165
186
  `resourceObjectSchema`, `resourceDocumentSchema`,
@@ -169,7 +190,7 @@
169
190
  `errorObjectSchema`. Their inferred types stay listed. A resource's own
170
191
  `document`, `collectionDocument`, `serialize` and `serializeMany` declare
171
192
  and render its documents; the schema consts have no public replacement.
172
- - **response:** answer mapped errors with links and meta ([b78bc08](https://github.com/zeroxsolutions/zeroxsolutions/commit/b78bc08))
193
+ - **response:** answer mapped errors with links and meta ([b78bc08](https://github.com/zeroxsolutions/zeroxsolutions/commit/b78bc08))
173
194
  `ErrorMeta` is `DomainErrorAnswer`, whose `code` is
174
195
  required. `defineErrorMap` takes `DomainErrorEntry` objects, which
175
196
  `errorEntry(type, answer)` builds, in place of `[type, meta]` tuples.
@@ -177,7 +198,7 @@
177
198
  type argument. `UpstreamErrorMeta` is `UpstreamErrorAnswer`, and
178
199
  `toUpstreamError(map, document, fallback)` is
179
200
  `createUpstreamErrorTranslator(map, fallback)(document)`.
180
- - **response:** render every member of a JSON:API error object ([ca0c551](https://github.com/zeroxsolutions/zeroxsolutions/commit/ca0c551))
201
+ - **response:** render every member of a JSON:API error object ([ca0c551](https://github.com/zeroxsolutions/zeroxsolutions/commit/ca0c551))
181
202
  `buildErrorDocument` is `toErrorDocument`, and the
182
203
  document it renders carries `jsonapi: { version: '1.1' }`.
183
204
  `ErrorCodeMeta` is `ErrorStatus`; `ErrorRegistry` and `ErrorLike` are
@@ -225,19 +246,19 @@ Repackaged only, no source change: the previous tarball still carried the pre-fl
225
246
 
226
247
  ### 🚀 Features
227
248
 
228
- - ⚠️ **server,jsonapi:** one surface, one error-code vocabulary ([32b4aed](https://github.com/zeroxsolutions/zeroxsolutions/commit/32b4aed))
249
+ - ⚠️ **server,jsonapi:** one surface, one error-code vocabulary ([32b4aed](https://github.com/zeroxsolutions/zeroxsolutions/commit/32b4aed))
229
250
 
230
251
  ### 💅 Refactors
231
252
 
232
- - ⚠️ **query,response:** drop the seams the second spelling paid for ([40f1bca](https://github.com/zeroxsolutions/zeroxsolutions/commit/40f1bca))
253
+ - ⚠️ **query,response:** drop the seams the second spelling paid for ([40f1bca](https://github.com/zeroxsolutions/zeroxsolutions/commit/40f1bca))
233
254
 
234
- ### ⚠️ Breaking Changes
255
+ ### ⚠️ Breaking Changes
235
256
 
236
- - **server,jsonapi:** one surface, one error-code vocabulary ([32b4aed](https://github.com/zeroxsolutions/zeroxsolutions/commit/32b4aed))
257
+ - **server,jsonapi:** one surface, one error-code vocabulary ([32b4aed](https://github.com/zeroxsolutions/zeroxsolutions/commit/32b4aed))
237
258
  createErrorHandler, createValidationHook and
238
259
  jsonApiContentNegotiation take a required `namespace`; negotiateJsonApi takes it
239
260
  as a third argument. Codes these mint are now `<namespace>.<name>`.
240
- - **query,response:** drop the seams the second spelling paid for ([40f1bca](https://github.com/zeroxsolutions/zeroxsolutions/commit/40f1bca))
261
+ - **query,response:** drop the seams the second spelling paid for ([40f1bca](https://github.com/zeroxsolutions/zeroxsolutions/commit/40f1bca))
241
262
  @zeroxsolutions/query no longer exports CollectionQueryParser,
242
263
  CollectionQueryRenderer, collectionLinksWith, collectionQueryParser, parseSort,
243
264
  parseFields, parseInclude or parsePagination. collectionLinks and
@@ -253,11 +274,11 @@ Repackaged only, no source change: the previous tarball still carried the pre-fl
253
274
 
254
275
  ### 💅 Refactors
255
276
 
256
- - ⚠️ **query,response,server:** one wire spelling, flat exports ([5c57b3a](https://github.com/zeroxsolutions/zeroxsolutions/commit/5c57b3a))
277
+ - ⚠️ **query,response,server:** one wire spelling, flat exports ([5c57b3a](https://github.com/zeroxsolutions/zeroxsolutions/commit/5c57b3a))
257
278
 
258
- ### ⚠️ Breaking Changes
279
+ ### ⚠️ Breaking Changes
259
280
 
260
- - **query,response,server:** one wire spelling, flat exports ([5c57b3a](https://github.com/zeroxsolutions/zeroxsolutions/commit/5c57b3a))
281
+ - **query,response,server:** one wire spelling, flat exports ([5c57b3a](https://github.com/zeroxsolutions/zeroxsolutions/commit/5c57b3a))
261
282
  `@zeroxsolutions/response/http`, `@zeroxsolutions/query/http`
262
283
  and `@zeroxsolutions/server/hono/http` are gone, and the surviving `/jsonapi`
263
284
  and `/hono` subpaths move to the package root. Every import drops its subpath.
@@ -270,11 +291,11 @@ Repackaged only, no source change: the previous tarball still carried the pre-fl
270
291
 
271
292
  ### 💅 Refactors
272
293
 
273
- - ⚠️ **response:** key the upstream map by string, drop its builder ([d5c5e6b](https://github.com/zeroxsolutions/zeroxsolutions/commit/d5c5e6b))
294
+ - ⚠️ **response:** key the upstream map by string, drop its builder ([d5c5e6b](https://github.com/zeroxsolutions/zeroxsolutions/commit/d5c5e6b))
274
295
 
275
- ### ⚠️ Breaking Changes
296
+ ### ⚠️ Breaking Changes
276
297
 
277
- - **response:** key the upstream map by string, drop its builder ([d5c5e6b](https://github.com/zeroxsolutions/zeroxsolutions/commit/d5c5e6b))
298
+ - **response:** key the upstream map by string, drop its builder ([d5c5e6b](https://github.com/zeroxsolutions/zeroxsolutions/commit/d5c5e6b))
278
299
  defineUpstreamErrorMap is gone from both spellings. Declare the
279
300
  map as an object literal with `satisfies UpstreamErrorMap<UpstreamErrorMeta>`;
280
301
  toUpstreamError takes it unchanged.
@@ -288,11 +309,11 @@ Repackaged only, no source change: the previous tarball still carried the pre-fl
288
309
 
289
310
  ### 💅 Refactors
290
311
 
291
- - ⚠️ **response:** move the Hono handlers out, translate upstream errors ([ce60636](https://github.com/zeroxsolutions/zeroxsolutions/commit/ce60636))
312
+ - ⚠️ **response:** move the Hono handlers out, translate upstream errors ([ce60636](https://github.com/zeroxsolutions/zeroxsolutions/commit/ce60636))
292
313
 
293
- ### ⚠️ Breaking Changes
314
+ ### ⚠️ Breaking Changes
294
315
 
295
- - **response:** move the Hono handlers out, translate upstream errors ([ce60636](https://github.com/zeroxsolutions/zeroxsolutions/commit/ce60636))
316
+ - **response:** move the Hono handlers out, translate upstream errors ([ce60636](https://github.com/zeroxsolutions/zeroxsolutions/commit/ce60636))
296
317
  the ./http/server and ./jsonapi/server subpaths are gone -
297
318
  createErrorHandler and createValidationHook are @zeroxsolutions/server/http
298
319
  and @zeroxsolutions/server. Both remaining subpaths resolve to
@@ -340,11 +361,11 @@ Repackaged only, no source change: the previous tarball still carried the pre-fl
340
361
 
341
362
  ### 🚀 Features
342
363
 
343
- - ⚠️ **response:** type /jsonapi's documents off the resource's attributes ([1dcf923](https://github.com/zeroxsolutions/zeroxsolutions/commit/1dcf923))
364
+ - ⚠️ **response:** type /jsonapi's documents off the resource's attributes ([1dcf923](https://github.com/zeroxsolutions/zeroxsolutions/commit/1dcf923))
344
365
 
345
- ### ⚠️ Breaking Changes
366
+ ### ⚠️ Breaking Changes
346
367
 
347
- - **response:** type /jsonapi's documents off the resource's attributes ([1dcf923](https://github.com/zeroxsolutions/zeroxsolutions/commit/1dcf923))
368
+ - **response:** type /jsonapi's documents off the resource's attributes ([1dcf923](https://github.com/zeroxsolutions/zeroxsolutions/commit/1dcf923))
348
369
  `serialize` returns `ResourceDocument<A>` and `serializeMany`
349
370
  `CollectionDocument<A>` instead of `Row`, and `okResponse`/`listResponse` are
350
371
  generic in the resource's attribute schema.
@@ -368,11 +389,11 @@ Repackaged only, no source change: the previous tarball still carried the pre-fl
368
389
 
369
390
  ### 🚀 Features
370
391
 
371
- - ⚠️ **response:** bring /jsonapi's server half up to /http's ([a40fed4](https://github.com/zeroxsolutions/zeroxsolutions/commit/a40fed4))
392
+ - ⚠️ **response:** bring /jsonapi's server half up to /http's ([a40fed4](https://github.com/zeroxsolutions/zeroxsolutions/commit/a40fed4))
372
393
 
373
- ### ⚠️ Breaking Changes
394
+ ### ⚠️ Breaking Changes
374
395
 
375
- - **response:** bring /jsonapi's server half up to /http's ([a40fed4](https://github.com/zeroxsolutions/zeroxsolutions/commit/a40fed4))
396
+ - **response:** bring /jsonapi's server half up to /http's ([a40fed4](https://github.com/zeroxsolutions/zeroxsolutions/commit/a40fed4))
376
397
  /jsonapi/server's createErrorHandler now requires `category`.
377
398
 
378
399
  ### ❤️ Thank You
@@ -384,19 +405,19 @@ Repackaged only, no source change: the previous tarball still carried the pre-fl
384
405
 
385
406
  ### 🚀 Features
386
407
 
387
- - ⚠️ **response:** declare each JSON:API resource once ([748e006](https://github.com/zeroxsolutions/zeroxsolutions/commit/748e006))
388
- - ⚠️ **db:** let each table declare its own id column ([eca4aca](https://github.com/zeroxsolutions/zeroxsolutions/commit/eca4aca))
408
+ - ⚠️ **response:** declare each JSON:API resource once ([748e006](https://github.com/zeroxsolutions/zeroxsolutions/commit/748e006))
409
+ - ⚠️ **db:** let each table declare its own id column ([eca4aca](https://github.com/zeroxsolutions/zeroxsolutions/commit/eca4aca))
389
410
 
390
- ### ⚠️ Breaking Changes
411
+ ### ⚠️ Breaking Changes
391
412
 
392
- - **response:** declare each JSON:API resource once ([748e006](https://github.com/zeroxsolutions/zeroxsolutions/commit/748e006))
413
+ - **response:** declare each JSON:API resource once ([748e006](https://github.com/zeroxsolutions/zeroxsolutions/commit/748e006))
393
414
  `/jsonapi`'s `okResponse` / `listResponse` take a resource
394
415
  declaration instead of `(type, attributesSchema)`. `resourceDocument`,
395
416
  `resourceCollectionDocument`, `applyFields`, `mergeIncluded`,
396
417
  `documentResources` and `ResourceObject` are removed - the descriptor covers
397
418
  them. `/jsonapi/server` now exports only `createErrorHandler`; the serializer
398
419
  entry points moved behind the descriptor.
399
- - **db:** let each table declare its own id column ([eca4aca](https://github.com/zeroxsolutions/zeroxsolutions/commit/eca4aca))
420
+ - **db:** let each table declare its own id column ([eca4aca](https://github.com/zeroxsolutions/zeroxsolutions/commit/eca4aca))
400
421
  `baseTable` is removed - take `idColumn` and spread
401
422
  `timestamps`. `defaultIndexedBaseColumns` is now `timestampIndexes` and
402
423
  `BaseTableShape` is `TimestampColumns`; both were named for the removed concept.
@@ -410,11 +431,11 @@ Repackaged only, no source change: the previous tarball still carried the pre-fl
410
431
 
411
432
  ### 🚀 Features
412
433
 
413
- - ⚠️ **response:** take the isolate's own logging category, not the library's ([3409798](https://github.com/zeroxsolutions/zeroxsolutions/commit/3409798))
434
+ - ⚠️ **response:** take the isolate's own logging category, not the library's ([3409798](https://github.com/zeroxsolutions/zeroxsolutions/commit/3409798))
414
435
 
415
- ### ⚠️ Breaking Changes
436
+ ### ⚠️ Breaking Changes
416
437
 
417
- - **response:** take the isolate's own logging category, not the library's ([3409798](https://github.com/zeroxsolutions/zeroxsolutions/commit/3409798))
438
+ - **response:** take the isolate's own logging category, not the library's ([3409798](https://github.com/zeroxsolutions/zeroxsolutions/commit/3409798))
418
439
  `createErrorHandler` takes one options object and `category` is
419
440
  required - `createErrorHandler(errors)` becomes
420
441
  `createErrorHandler({ category, errors })`. Required rather than defaulted
@@ -429,11 +450,11 @@ Repackaged only, no source change: the previous tarball still carried the pre-fl
429
450
 
430
451
  ### 🚀 Features
431
452
 
432
- - ⚠️ **response:** write the unhandled 500 through logtape, under the caller's id ([fdcb75b](https://github.com/zeroxsolutions/zeroxsolutions/commit/fdcb75b))
453
+ - ⚠️ **response:** write the unhandled 500 through logtape, under the caller's id ([fdcb75b](https://github.com/zeroxsolutions/zeroxsolutions/commit/fdcb75b))
433
454
 
434
- ### ⚠️ Breaking Changes
455
+ ### ⚠️ Breaking Changes
435
456
 
436
- - **response:** write the unhandled 500 through logtape, under the caller's id ([fdcb75b](https://github.com/zeroxsolutions/zeroxsolutions/commit/fdcb75b))
457
+ - **response:** write the unhandled 500 through logtape, under the caller's id ([fdcb75b](https://github.com/zeroxsolutions/zeroxsolutions/commit/fdcb75b))
437
458
  `@logtape/logtape` is a new peer of `./http/server`, and the
438
459
  unhandled-500 line is silent in an isolate that never calls `configureSync`.
439
460
  It previously always reached stdout.
package/README.md CHANGED
@@ -67,8 +67,8 @@ them, and the serializer calls that loader when a request includes it. Nothing c
67
67
  export const trips = jsonApiResource('trips', tripAttributesSchema, {
68
68
  relationships: {
69
69
  place: toOne(
70
- () => places, // the resource the loaded rows are published as
71
- (row) => row.placeId, // beside a loader this reads the ID off the row, not the row
70
+ () => places, // the resource the loaded rows are published as
71
+ (row) => row.placeId, // beside a loader this reads the ID off the row, not the row
72
72
  { load: (ids, context: TripDocumentContext) => context.catalogue.places.byIds(ids) },
73
73
  ),
74
74
  },
@@ -83,11 +83,11 @@ deduplicated and in no order, so a page of fifty trips costs one call upstream r
83
83
  called only where the request's `include` names the relationship: a document that includes nothing makes
84
84
  no call at all, and still publishes the identifier, which is the key its own row carried.
85
85
 
86
- | The loader | What the document carries |
87
- | --- | --- |
88
- | answers a row for an id | that identifier, and the row under `included` |
89
- | answers no row for an id it was given | that identifier, and nothing under `included` |
90
- | throws | nothing; the failure comes out of `serialize` for the route to answer |
86
+ | The loader | What the document carries |
87
+ | ------------------------------------- | --------------------------------------------------------------------- |
88
+ | answers a row for an id | that identifier, and the row under `included` |
89
+ | answers no row for an id it was given | that identifier, and nothing under `included` |
90
+ | throws | nothing; the failure comes out of `serialize` for the route to answer |
91
91
 
92
92
  An id with no row back is how a row this caller may not see stays out of the document. Dropping the
93
93
  identifier with it would tell the client the trip has no place, which the row it was read off does not
@@ -117,7 +117,7 @@ export const academicsErrors = defineErrorMap([
117
117
  status: 409,
118
118
  title: 'Conflict',
119
119
  code: 'academics.class.full',
120
- meta: (error) => ({ capacity: error.capacity }), // `capacity` is typed off ClassFull
120
+ meta: (error) => ({ capacity: error.capacity }), // `capacity` is typed off ClassFull
121
121
  }),
122
122
  ]);
123
123
  ```
@@ -148,7 +148,7 @@ import { createErrorHandler } from '@zeroxsolutions/server';
148
148
 
149
149
  app.onError(
150
150
  createErrorHandler({
151
- namespace: 'academics', // every code THESE handlers mint carries it, so one surface has one vocabulary
151
+ namespace: 'academics', // every code THESE handlers mint carries it, so one surface has one vocabulary
152
152
  category: ['academics', 'http'],
153
153
  resolve: createDomainErrorResolver(academicsErrors),
154
154
  authenticationChallenge: 'Bearer',
@@ -213,13 +213,16 @@ export const PLACE_UPSTREAM_ERRORS = {
213
213
  // the return type is spelled: a callback in an object checked by `satisfies` alone is not a typed function
214
214
  // expression to @typescript-eslint/explicit-function-return-type
215
215
  meta: (upstream): Meta | undefined => {
216
- const parsed = placeFullMetaSchema.safeParse(upstream); // what the service promises, and nothing else
216
+ const parsed = placeFullMetaSchema.safeParse(upstream); // what the service promises, and nothing else
217
217
  return parsed.success ? parsed.data : undefined;
218
218
  },
219
219
  },
220
220
  } satisfies UpstreamErrorMap;
221
221
 
222
- export const translatePlaceUpstreamError = createUpstreamErrorTranslator(PLACE_UPSTREAM_ERRORS, PLACE_UPSTREAM_FALLBACK);
222
+ export const translatePlaceUpstreamError = createUpstreamErrorTranslator(
223
+ PLACE_UPSTREAM_ERRORS,
224
+ PLACE_UPSTREAM_FALLBACK,
225
+ );
223
226
  ```
224
227
 
225
228
  A route throws what the translator returns, so the one `onError` renders it like every other failure:
@@ -271,6 +274,37 @@ It locates each issue by the slot it was read from: a body member as `source.poi
271
274
  `source.parameter`, a header as `source.header`. A path segment gets `meta` instead - the spec defines
272
275
  those three members and none of them means a path segment, so borrowing one would say something false.
273
276
 
277
+ ## Holding every answer to the codes a transport publishes
278
+
279
+ A transport that publishes its error codes as a list binds that list once, and every answer it throws,
280
+ translates or maps then spells one of them or fails to compile. Each fronted service's list keys its
281
+ translator the same way, so an upstream key the service never renders is a compile error rather than a
282
+ document that silently answers the fallback.
283
+
284
+ ```ts
285
+ // entrypoints/http/error-map.ts
286
+ import { BASE_ERROR_CODES, createJsonApiErrors } from '@zeroxsolutions/response';
287
+ import { CATALOGUE_ERROR_CODES } from '@<scope>/catalogue/schema';
288
+ import { API_ERROR_CODES } from '../../lib/schema/errors.js';
289
+
290
+ const { error, translator, entry } = createJsonApiErrors(API_ERROR_CODES);
291
+
292
+ export const translateCatalogueError = translator(
293
+ CATALOGUE_ERROR_CODES,
294
+ { 'catalogue.place.not_found': { status: 404, title: 'Not Found', code: 'api.place.not_found' } },
295
+ { status: 502, title: 'Bad Gateway', code: 'api.upstream_failed' },
296
+ );
297
+
298
+ throw error({ ...BASE_ERROR_CODES.FORBIDDEN, code: 'api.forbidden' });
299
+ ```
300
+
301
+ The lists are values rather than type arguments: with nothing passed there is no list to fall back on,
302
+ where a type argument left out would widen to `string`. Neither is read at runtime. `error` also refuses
303
+ a key its answer does not declare, so a misspelled `detial` does not compile, and a thrown answer's `meta`
304
+ is data, never the reader an upstream answer carries. `entry` is `errorEntry` with its code held to the
305
+ same list. A constant passed to `error` keeps its literal code with `as const` or
306
+ `satisfies ErrorAnswer<...>`; without either, `code` widens to `string` and the call does not compile.
307
+
274
308
  ## A request document
275
309
 
276
310
  A write's body is declared off the same resource the route answers with, so the document a client reads
@@ -322,6 +356,8 @@ One root, no subpath, and `src/index.ts` lists every name it publishes:
322
356
  - the error document's types, `JsonApiError`, `BASE_ERROR_CODES`, `toErrorObject` / `toErrorDocument`;
323
357
  - `defineErrorMap` / `errorEntry` / `createDomainErrorResolver` and `createUpstreamErrorTranslator`, with
324
358
  the answer, entry and map types they take;
359
+ - `createJsonApiErrors`, the `JsonApiErrors` it returns, and `ErrorAnswer`, `CodedUpstreamErrorAnswer`
360
+ and `CodedDomainErrorAnswer`, the answers it takes;
325
361
  - `JSON_API_MEDIA_TYPE`.
326
362
 
327
363
  The document and resource-object schemas, the other link and identifier primitives and the serializer
@@ -3,6 +3,7 @@ import { type CollectionDocument, type ResourceDocument } from './document.js';
3
3
  import { errorDocumentSchema } from './errors/index.js';
4
4
  import { JSON_API_MEDIA_TYPE } from './media-type.js';
5
5
  import type { Meta, PaginationLinks } from './primitives.js';
6
+ import type { RelationshipDef } from './relationship.js';
6
7
  import type { JsonApiResource } from './resource.js';
7
8
  /**
8
9
  * An OpenAPI response object for this spelling - one media type, one schema, and the `Retry-After` a
@@ -45,7 +46,7 @@ export declare function errorResponse(description: string, options?: {
45
46
  retryAfterSeconds: number;
46
47
  }): JsonApiResponse<typeof errorDocumentSchema>;
47
48
  /** The response object for a single resource, off the resource's own declaration. */
48
- export declare function okResponse<A extends ZodObject, C = unknown>(description: string, resource: JsonApiResource<A, C>): JsonApiResponse<ZodType<ResourceDocument<output<A>>>>;
49
+ export declare function okResponse<A extends ZodObject, C = unknown, I extends string = string>(description: string, resource: JsonApiResource<A, C, string, Readonly<Record<string, RelationshipDef<C>>>, I>): JsonApiResponse<ZodType<ResourceDocument<output<A>, I>>>;
49
50
  /**
50
51
  * The response object for a collection, off the resource's own declaration.
51
52
  *
@@ -53,8 +54,8 @@ export declare function okResponse<A extends ZodObject, C = unknown>(description
53
54
  * as required and typed, so a client reads it without narrowing; one left out stays the standard's
54
55
  * optional, free-form member.
55
56
  */
56
- export declare function listResponse<A extends ZodObject, C = unknown, M extends ZodType<Meta> = never, L extends ZodType<PaginationLinks> = never>(description: string, resource: JsonApiResource<A, C>, members?: {
57
+ export declare function listResponse<A extends ZodObject, C = unknown, M extends ZodType<Meta> = never, L extends ZodType<PaginationLinks> = never, I extends string = string>(description: string, resource: JsonApiResource<A, C, string, Readonly<Record<string, RelationshipDef<C>>>, I>, members?: {
57
58
  meta?: M;
58
59
  links?: L;
59
- }): JsonApiResponse<ZodType<CollectionDocument<output<A>, output<M>, output<L>>>>;
60
+ }): JsonApiResponse<ZodType<CollectionDocument<output<A>, output<M>, output<L>, I>>>;
60
61
  //# sourceMappingURL=api-response.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-response.d.ts","sourceRoot":"","sources":["../src/api-response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACtD,OAAO,EAA4B,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACzG,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,OAAO;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,OAAO,mBAAmB,EAAE;QAAE,MAAM,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IAC3D,OAAO,CAAC,EAAE;QAAE,aAAa,EAAE,gBAAgB,CAAA;KAAE,CAAC;CAC/C;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,IAAI,CAAC;IACf,MAAM,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,OAAO,EAAE,CAAC,CAAA;KAAE,CAAC;CACzC,CAAC;AAOF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,iBAAiB,EAAE,MAAM,CAAA;CAAE,GACtC,eAAe,CAAC,OAAO,mBAAmB,CAAC,CAqB7C;AAED,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,GAAG,OAAO,EACzD,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,GAC9B,eAAe,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,CAAC,SAAS,SAAS,EACnB,CAAC,GAAG,OAAO,EACX,CAAC,SAAS,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,EAC/B,CAAC,SAAS,OAAO,CAAC,eAAe,CAAC,GAAG,KAAK,EAE1C,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EAC/B,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,CAAC,CAAA;CAAO,GACpC,eAAe,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAQ/E"}
1
+ {"version":3,"file":"api-response.d.ts","sourceRoot":"","sources":["../src/api-response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACtD,OAAO,EAA4B,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACzG,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,OAAO;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,OAAO,mBAAmB,EAAE;QAAE,MAAM,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IAC3D,OAAO,CAAC,EAAE;QAAE,aAAa,EAAE,gBAAgB,CAAA;KAAE,CAAC;CAC/C;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,IAAI,CAAC;IACf,MAAM,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,OAAO,EAAE,CAAC,CAAA;KAAE,CAAC;CACzC,CAAC;AAOF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,iBAAiB,EAAE,MAAM,CAAA;CAAE,GACtC,eAAe,CAAC,OAAO,mBAAmB,CAAC,CAqB7C;AAED,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,EACpF,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GACvF,eAAe,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAE1D;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,CAAC,SAAS,SAAS,EACnB,CAAC,GAAG,OAAO,EACX,CAAC,SAAS,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,EAC/B,CAAC,SAAS,OAAO,CAAC,eAAe,CAAC,GAAG,KAAK,EAC1C,CAAC,SAAS,MAAM,GAAG,MAAM,EAEzB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EACxF,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,CAAC,CAAA;CAAO,GACpC,eAAe,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAQlF"}
@@ -24,9 +24,6 @@ type IsWide<X> = string extends TypeOf<X> ? true : false;
24
24
  /**
25
25
  * Every dotted relationship path from `R`, at most `Depth` relationships long. A path never revisits a type,
26
26
  * which is the rule `declaredDocumentShape` walks by, and a wide edge contributes its own name and nothing below.
27
- *
28
- * It names a resource's relationship paths, not the drizzle relation paths `@zeroxsolutions/db` exports under the same
29
- * name `IncludePath`; a module importing both must alias one.
30
27
  */
31
28
  export type IncludePath<R, Depth extends number = 3, Seen extends string = TypeOf<R>> = Depth extends 0 ? never : {
32
29
  [K in keyof RelationshipsOf<R> & string]: RelatedOf<RelationshipsOf<R>[K]> extends infer X ? IsWide<X> extends true ? K : TypeOf<X> extends Seen ? never : K | `${K}.${IncludePath<X, Down[Depth], Seen | TypeOf<X>>}` : never;
@@ -1 +1 @@
1
- {"version":3,"file":"document-graph.d.ts","sourceRoot":"","sources":["../src/document-graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AACrC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,iEAAiE;AACjE,KAAK,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAE/C,KAAK,SAAS,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAEtC;;;GAGG;AACH,KAAK,eAAe,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;CAAE,GACnE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC1B,SAAS,GACT,CAAC,GACH,SAAS,CAAC;AACd,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAC,CAAA;CAAE,GAAG,CAAC,GAAG,KAAK,CAAC;AAC9E,KAAK,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,MAAM,CAAA;CAAE,GAAG,CAAC,GAAG,KAAK,CAAC;AACjF,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;CAAE,GAAG,CAAC,GAAG,SAAS,CAAC;AAE7F,oGAAoG;AACpG,KAAK,MAAM,CAAC,CAAC,IAAI,MAAM,SAAS,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,CAAC,EAAE,IAAI,SAAS,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,GACnG,KAAK,GACL;KACG,CAAC,IAAI,MAAM,eAAe,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,GACtF,MAAM,CAAC,CAAC,CAAC,SAAS,IAAI,GACpB,CAAC,GACD,MAAM,CAAC,CAAC,CAAC,SAAS,IAAI,GACpB,KAAK,GACL,CAAC,GAAG,GAAG,CAAC,IAAI,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,GAC/D,KAAK;CACV,CAAC,MAAM,eAAe,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;AAEzC,iGAAiG;AACjG,MAAM,MAAM,iBAAiB,CAAC,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,CAAC,EAAE,IAAI,SAAS,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IACtF,CAAC,GACD,CAAC,KAAK,SAAS,CAAC,GACZ,KAAK,GACL;KACG,CAAC,IAAI,MAAM,eAAe,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,GACtF,MAAM,CAAC,CAAC,CAAC,SAAS,IAAI,GACpB,KAAK,GACL,MAAM,CAAC,CAAC,CAAC,SAAS,IAAI,GACpB,KAAK,GACL,iBAAiB,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,GACvD,KAAK;CACV,CAAC,MAAM,eAAe,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AAE9C,yDAAyD;AACzD,MAAM,MAAM,aAAa,CAAC,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,iBAAiB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AAE7F,kHAAkH;AAClH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,MAAM,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;AAEvF,4CAA4C;AAC5C,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,CAAC,IAAI;KAClD,CAAC,IAAI,iBAAiB,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,SAAS,CAAC,CAAC,CAAC,EAAE;CAC1E,CAAC;AAEF,sEAAsE;AACtE,MAAM,WAAW,kBAAkB,CAAC,CAAC,EAAE,KAAK,SAAS,MAAM;IACzD,2GAA2G;IAC3G,MAAM,EAAE;SAAG,CAAC,IAAI,iBAAiB,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE;KAAE,CAAC;IAC5E,sEAAsE;IACtE,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;CAClC;AAED,mFAAmF;AACnF,MAAM,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC"}
1
+ {"version":3,"file":"document-graph.d.ts","sourceRoot":"","sources":["../src/document-graph.ts"],"names":[],"mappings":"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"}
@@ -7,18 +7,18 @@ export interface Relationship {
7
7
  links?: RelationshipLinks;
8
8
  meta?: Meta;
9
9
  }
10
- /** A resource object, with `attributes` carrying the declared attribute type. */
11
- export interface ResourceObject<A> {
10
+ /** A resource object, with `attributes` carrying the declared attribute type and `id` the declared id type. */
11
+ export interface ResourceObject<A, I extends string = string> {
12
12
  type: string;
13
- id: string;
13
+ id: I;
14
14
  attributes: A;
15
15
  relationships?: Record<string, Relationship>;
16
16
  links?: ResourceLinks;
17
17
  meta?: Meta;
18
18
  }
19
19
  /** A single-resource document. `included` holds other resource types, so its attributes stay unknown. */
20
- export interface ResourceDocument<A> {
21
- data: ResourceObject<A>;
20
+ export interface ResourceDocument<A, I extends string = string> {
21
+ data: ResourceObject<A, I>;
22
22
  included?: ResourceObject<unknown>[];
23
23
  links?: TopLevelLinks;
24
24
  meta?: Meta;
@@ -38,8 +38,8 @@ type CollectionMember<K extends 'links' | 'meta', Declared, Loose> = [Declared]
38
38
  *
39
39
  * `M` and `L` are the `meta` and `links` a route declared, `never` where it declared none.
40
40
  */
41
- export type CollectionDocument<A, M = never, L = never> = {
42
- data: ResourceObject<A>[];
41
+ export type CollectionDocument<A, M = never, L = never, I extends string = string> = {
42
+ data: ResourceObject<A, I>[];
43
43
  included?: ResourceObject<unknown>[];
44
44
  jsonapi?: JsonApiObject;
45
45
  } & CollectionMember<'links', L, PaginationLinks> & CollectionMember<'meta', M, Meta>;
@@ -50,7 +50,7 @@ export type CollectionDocument<A, M = never, L = never> = {
50
50
  * Tuple-wrapped so it does not distribute: extras that carry `meta` on one branch of a union and not the
51
51
  * other may send none, and must not type it as present.
52
52
  */
53
- export type CollectionDocumentFor<A, X> = CollectionDocument<A, [
53
+ export type CollectionDocumentFor<A, X, I extends string = string> = CollectionDocument<A, [
54
54
  X
55
55
  ] extends [{
56
56
  meta: infer M;
@@ -58,14 +58,14 @@ export type CollectionDocumentFor<A, X> = CollectionDocument<A, [
58
58
  X
59
59
  ] extends [{
60
60
  links: infer L;
61
- }] ? L : never>;
61
+ }] ? L : never, I>;
62
62
  /**
63
63
  * Wraps `attributes` into a resource object - `{ type, id, attributes?, relationships?, links?, meta? }`.
64
64
  *
65
65
  * `attributes` parses as absent here, unlike {@link ResourceObject}'s own required member: this schema
66
66
  * also validates a document read off another server, which may publish a resource with none.
67
67
  */
68
- export declare function resourceObjectSchema<C>(type: string, attributes: ZodObject, relationships?: Readonly<Record<string, RelationshipDef<C>>>): ZodType;
68
+ export declare function resourceObjectSchema<C>(type: string, attributes: ZodObject, relationships?: Readonly<Record<string, RelationshipDef<C>>>, id?: ZodType<string, string>): ZodType;
69
69
  /**
70
70
  * The document for a SINGLE resource - `{ data, included?, links?, meta?, jsonapi? }`.
71
71
  *
@@ -76,16 +76,16 @@ export declare function resourceObjectSchema<C>(type: string, attributes: ZodObj
76
76
  * Strict at the top level: the standard forbids any top-level member beyond these (extension members
77
77
  * aside), which is what refuses a `data` document that also carries `errors`.
78
78
  */
79
- export declare function resourceDocumentSchema<A = unknown, C = unknown>(root: RelatedResource<C>): ZodType<ResourceDocument<A>>;
79
+ export declare function resourceDocumentSchema<A = unknown, C = unknown, I extends string = string>(root: RelatedResource<C>): ZodType<ResourceDocument<A, I>>;
80
80
  /**
81
81
  * The document for a COLLECTION - the same members, with `data` an array and paginated `links`.
82
82
  *
83
83
  * A member in `members` replaces the standard's optional one, so the route that declared it publishes it
84
84
  * as required. Strict at the top level for the same reason as {@link resourceDocumentSchema}.
85
85
  */
86
- export declare function collectionDocumentSchema<A = unknown, C = unknown, M = never, L = never>(root: RelatedResource<C>, members?: {
86
+ export declare function collectionDocumentSchema<A = unknown, C = unknown, M = never, L = never, I extends string = string>(root: RelatedResource<C>, members?: {
87
87
  meta?: ZodType;
88
88
  links?: ZodType;
89
- }): ZodType<CollectionDocument<A, M, L>>;
89
+ }): ZodType<CollectionDocument<A, M, L, I>>;
90
90
  export {};
91
91
  //# sourceMappingURL=document.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"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"}
package/dist/document.js CHANGED
@@ -7,11 +7,11 @@ import { relationshipsSchema, reachableResources } from './relationship.js';
7
7
  * `attributes` parses as absent here, unlike {@link ResourceObject}'s own required member: this schema
8
8
  * also validates a document read off another server, which may publish a resource with none.
9
9
  */
10
- export function resourceObjectSchema(type, attributes, relationships = {}) {
10
+ export function resourceObjectSchema(type, attributes, relationships = {}, id = z.string()) {
11
11
  const linkage = relationshipsSchema(relationships);
12
12
  return z.object({
13
13
  type: z.literal(type),
14
- id: z.string(),
14
+ id,
15
15
  attributes: attributes.optional(),
16
16
  ...(linkage ? { relationships: linkage.optional() } : {}),
17
17
  links: resourceLinksSchema.optional(),
package/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@ export { declaredDocumentShape } from './document-shape.js';
9
9
  export { createDomainErrorResolver, defineErrorMap, errorEntry, type DomainErrorAnswer, type DomainErrorEntry, } from './domain-error-resolver.js';
10
10
  export type { DomainErrorMap, ErrorClass, UpstreamErrorMap } from './error-map.js';
11
11
  export { BASE_ERROR_CODES, errorDocumentSchema, JsonApiError, toErrorDocument, toErrorObject, type ErrorDocument, type ErrorLinks, type ErrorObject, type ErrorSource, type ErrorStatus, type JsonApiErrorInit, type ResolvedError, } from './errors/index.js';
12
+ export { createJsonApiErrors, type CodedDomainErrorAnswer, type CodedUpstreamErrorAnswer, type ErrorAnswer, type JsonApiErrors, } from './json-api-errors.js';
12
13
  export { JSON_API_MEDIA_TYPE } from './media-type.js';
13
14
  export { countedCollectionMetaSchema, offsetPaginationLinksSchema } from './primitives.js';
14
15
  export type { JsonApiObject, Link, Meta, PaginationLinks, RelationshipLinks, ResourceIdentifier, ResourceLinks, TopLevelLinks, } from './primitives.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,aAAa,EACb,YAAY,EACZ,UAAU,EACV,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EACV,kBAAkB,EAClB,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACL,yBAAyB,EACzB,cAAc,EACd,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,2BAA2B,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAC3F,YAAY,EACV,aAAa,EACb,IAAI,EACJ,IAAI,EACJ,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,MAAM,EACN,KAAK,EACL,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAC5F,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACpH,OAAO,EAAE,6BAA6B,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,WAAW,EAChB,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,aAAa,EACb,YAAY,EACZ,UAAU,EACV,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EACV,kBAAkB,EAClB,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACL,yBAAyB,EACzB,cAAc,EACd,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,mBAAmB,EACnB,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,WAAW,EAChB,KAAK,aAAa,GACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,2BAA2B,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAC3F,YAAY,EACV,aAAa,EACb,IAAI,EACJ,IAAI,EACJ,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,MAAM,EACN,KAAK,EACL,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAC5F,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACpH,OAAO,EAAE,6BAA6B,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,WAAW,EAChB,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ export * from './document-graph.js';
7
7
  export { declaredDocumentShape } from './document-shape.js';
8
8
  export { createDomainErrorResolver, defineErrorMap, errorEntry, } from './domain-error-resolver.js';
9
9
  export { BASE_ERROR_CODES, errorDocumentSchema, JsonApiError, toErrorDocument, toErrorObject, } from './errors/index.js';
10
+ export { createJsonApiErrors, } from './json-api-errors.js';
10
11
  export { JSON_API_MEDIA_TYPE } from './media-type.js';
11
12
  export { countedCollectionMetaSchema, offsetPaginationLinksSchema } from './primitives.js';
12
13
  export { toMany, toOne, } from './relationship.js';
@@ -0,0 +1,60 @@
1
+ import { type DomainErrorAnswer, type DomainErrorEntry } from './domain-error-resolver.js';
2
+ import type { ErrorClass } from './error-map.js';
3
+ import type { ErrorDocument, ErrorLinks, ErrorSource } from './errors/error-document.js';
4
+ import type { ErrorStatus } from './errors/error-registry.js';
5
+ import { JsonApiError } from './errors/jsonapi-error.js';
6
+ import type { Meta } from './primitives.js';
7
+ import { type UpstreamErrorAnswer } from './upstream-error.js';
8
+ /** An answer thrown as it stands, its `code` one of the consumer's own. */
9
+ export interface ErrorAnswer<C extends string> extends ErrorStatus {
10
+ code: C;
11
+ /** Human-readable and request-specific; the error's `message` falls back to the title without one. */
12
+ detail?: string;
13
+ /** Where in the request the error originates. */
14
+ source?: ErrorSource;
15
+ /** A page about this occurrence, and a page about its type of problem. */
16
+ links?: ErrorLinks;
17
+ /** The data a client acts on that no other member carries. */
18
+ meta?: Meta;
19
+ }
20
+ /** {@link UpstreamErrorAnswer}, its `code` one of the consumer's own. */
21
+ export type CodedUpstreamErrorAnswer<C extends string> = UpstreamErrorAnswer & {
22
+ code: C;
23
+ };
24
+ /** {@link DomainErrorAnswer}, its `code` one of the consumer's own. */
25
+ export type CodedDomainErrorAnswer<C extends string, E extends Error> = DomainErrorAnswer<E> & {
26
+ code: C;
27
+ };
28
+ /**
29
+ * Every key of `A` that `Shape` does not declare, typed `never`. An argument inferred into a type parameter gets no
30
+ * excess-property check, so without this a misspelled optional key, `detial` for `detail`, would compile and the
31
+ * answer would reach a client without it.
32
+ */
33
+ type Exact<A, Shape> = A & {
34
+ [K in Exclude<keyof A, keyof Shape>]: never;
35
+ };
36
+ /** What {@link createJsonApiErrors} hands back, every answer held to the codes it was given. */
37
+ export interface JsonApiErrors<C extends string> {
38
+ /** The error to throw for one answer, which `onError` renders. */
39
+ error<A extends ErrorAnswer<C>>(answer: Exact<A, ErrorAnswer<C>>): JsonApiError;
40
+ /**
41
+ * {@link createUpstreamErrorTranslator}, its answers keyed by the codes the fronted service publishes: a key it never
42
+ * renders would never match, and its document would answer the fallback without anything saying so.
43
+ */
44
+ translator<const U extends string>(upstreamCodes: readonly U[], answers: {
45
+ readonly [K in U]?: CodedUpstreamErrorAnswer<C>;
46
+ }, fallback: Omit<ErrorAnswer<C>, 'meta' | 'source'>): (document: ErrorDocument) => JsonApiError;
47
+ /** {@link errorEntry}, its answer's code held to the consumer's list. */
48
+ entry<E extends Error>(type: ErrorClass<E>, answer: CodedDomainErrorAnswer<C, E>): DomainErrorEntry;
49
+ }
50
+ /**
51
+ * Binds the error codes a transport publishes, so every answer it throws, translates or maps spells one of them or
52
+ * fails to compile.
53
+ *
54
+ * The list is a value rather than a type argument, and so is each fronted service's in `translator`: with nothing
55
+ * passed there is no list to fall back on, where a type parameter left out would widen to `string`. Neither list is
56
+ * read at runtime; the compiler has already held every answer to it.
57
+ */
58
+ export declare const createJsonApiErrors: <const C extends string>(codes: readonly C[]) => JsonApiErrors<C>;
59
+ export {};
60
+ //# sourceMappingURL=json-api-errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-api-errors.d.ts","sourceRoot":"","sources":["../src/json-api-errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACvG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAiC,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE9F,2EAA2E;AAC3E,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,WAAW;IAChE,IAAI,EAAE,CAAC,CAAC;IACR,sGAAsG;IACtG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AAED,yEAAyE;AACzE,MAAM,MAAM,wBAAwB,CAAC,CAAC,SAAS,MAAM,IAAI,mBAAmB,GAAG;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC;AAE3F,uEAAuE;AACvE,MAAM,MAAM,sBAAsB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,KAAK,IAAI,iBAAiB,CAAC,CAAC,CAAC,GAAG;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC;AAE3G;;;;GAIG;AACH,KAAK,KAAK,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,GAAG;KAAG,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,KAAK;CAAE,CAAC;AAE3E,gGAAgG;AAChG,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,MAAM;IAC7C,kEAAkE;IAClE,KAAK,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;IAChF;;;OAGG;IACH,UAAU,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAC/B,aAAa,EAAE,SAAS,CAAC,EAAE,EAC3B,OAAO,EAAE;QAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC,CAAC;KAAE,EAC5D,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,GAChD,CAAC,QAAQ,EAAE,aAAa,KAAK,YAAY,CAAC;IAC7C,yEAAyE;IACzE,KAAK,CAAC,CAAC,SAAS,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,sBAAsB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,gBAAgB,CAAC;CACrG;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC,CAKhG,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { errorEntry } from './domain-error-resolver.js';
2
+ import { JsonApiError } from './errors/jsonapi-error.js';
3
+ import { createUpstreamErrorTranslator } from './upstream-error.js';
4
+ /**
5
+ * Binds the error codes a transport publishes, so every answer it throws, translates or maps spells one of them or
6
+ * fails to compile.
7
+ *
8
+ * The list is a value rather than a type argument, and so is each fronted service's in `translator`: with nothing
9
+ * passed there is no list to fall back on, where a type parameter left out would widen to `string`. Neither list is
10
+ * read at runtime; the compiler has already held every answer to it.
11
+ */
12
+ export const createJsonApiErrors = () => ({
13
+ error: (answer) => new JsonApiError(answer),
14
+ translator: (_upstreamCodes, answers, fallback) => createUpstreamErrorTranslator(answers, fallback),
15
+ entry: (type, answer) => errorEntry(type, answer),
16
+ });
@@ -5,9 +5,15 @@ import { type CollectionExtras, type RequestedDocumentShape, type Row } from './
5
5
  /** The context every loader in a relationship map runs under. */
6
6
  type ContextOfRelationships<R> = R[keyof R] extends RelationshipDef<infer C, any> ? C : unknown;
7
7
  /** Per-entity overrides for a resource declaration. */
8
- export interface ResourceOptions<R> {
8
+ export interface ResourceOptions<R, I extends string = string> {
9
9
  /** Relationships this resource declares, keyed by the member name they take in `relationships`. */
10
10
  relationships?: R;
11
+ /**
12
+ * The id as the wire carries it, which types `data.id` in every document and the `id` of every row serialized. Pass
13
+ * the wire half of a codec (a TypeID codec's `.in`), never the codec: a client reading the document back keeps the id
14
+ * it was sent. Omitted, the id is any text.
15
+ */
16
+ id?: ZodType<I, I>;
11
17
  }
12
18
  /**
13
19
  * One resource type declared once: the schemas a route answers with, and the serializer that produces
@@ -20,14 +26,14 @@ export interface ResourceOptions<R> {
20
26
  * `C` is the context its loaders are called with, inferred from the relationships it declares and from
21
27
  * the resources they point at, so every resource in one document's graph loads under one context.
22
28
  */
23
- export interface JsonApiResource<A extends ZodObject, C = unknown, T extends string = string, R extends Readonly<Record<string, RelationshipDef<any, any>>> = Readonly<Record<string, RelationshipDef<C>>>> extends RelatedResource<C> {
29
+ export interface JsonApiResource<A extends ZodObject, C = unknown, T extends string = string, R extends Readonly<Record<string, RelationshipDef<any, any>>> = Readonly<Record<string, RelationshipDef<C>>>, I extends string = string> extends RelatedResource<C> {
24
30
  readonly type: T;
25
31
  readonly attributes: A;
26
32
  readonly relationships: R;
27
33
  /** The single-resource document schema - `{ data, included?, links?, meta?, jsonapi? }`. */
28
- readonly document: ZodType<ResourceDocument<output<A>>>;
34
+ readonly document: ZodType<ResourceDocument<output<A>, I>>;
29
35
  /** The collection document schema - the same members with `data` an array. */
30
- readonly collectionDocument: ZodType<CollectionDocument<output<A>>>;
36
+ readonly collectionDocument: ZodType<CollectionDocument<output<A>, never, never, I>>;
31
37
  /**
32
38
  * Serializes one row into a single-resource document.
33
39
  *
@@ -35,7 +41,7 @@ export interface JsonApiResource<A extends ZodObject, C = unknown, T extends str
35
41
  * and an included relationship that declares a loader is loaded before the document is built
36
42
  * @param context - what the loaders are given; the call takes it only where a loader is reachable
37
43
  */
38
- serialize(row: Row, requested?: RequestedDocumentShape, ...context: LoadContextArguments<C>): Promise<ResourceDocument<output<A>>>;
44
+ serialize(row: Row<I>, requested?: RequestedDocumentShape, ...context: LoadContextArguments<C>): Promise<ResourceDocument<output<A>, I>>;
39
45
  /**
40
46
  * Serializes rows into a collection document, merging in pagination `links` and `meta`.
41
47
  *
@@ -43,7 +49,7 @@ export interface JsonApiResource<A extends ZodObject, C = unknown, T extends str
43
49
  * declared with `listResponse`. A key that is neither `links` nor `meta` is refused, since the
44
50
  * serializer drops it unsent.
45
51
  */
46
- serializeMany<X extends CollectionExtras = Record<never, never>>(rows: Row[], extras?: X & Record<Exclude<keyof X, keyof CollectionExtras>, never>, requested?: RequestedDocumentShape, ...context: LoadContextArguments<C>): Promise<CollectionDocumentFor<output<A>, X>>;
52
+ serializeMany<X extends CollectionExtras = Record<never, never>>(rows: Row<I>[], extras?: X & Record<Exclude<keyof X, keyof CollectionExtras>, never>, requested?: RequestedDocumentShape, ...context: LoadContextArguments<C>): Promise<CollectionDocumentFor<output<A>, X, I>>;
47
53
  }
48
54
  /** A relationship map's own names, and none where the map is the empty default. */
49
55
  type RelationshipName<R> = string extends keyof R ? never : keyof R & string;
@@ -55,6 +61,6 @@ type FieldNamespace<A extends ZodObject, R> = [
55
61
  (keyof A['shape'] & string & ('type' | 'id' | RelationshipName<R>)) | (RelationshipName<R> & ('type' | 'id'))
56
62
  ] extends [never] ? unknown : never;
57
63
  /** Declares a JSON:API resource type - its `type`, the schema of its `attributes`, and its relationships. */
58
- export declare function jsonApiResource<const T extends string, A extends ZodObject, const R extends Readonly<Record<string, RelationshipDef<any, any>>> = Readonly<Record<string, never>>, C = ContextOfRelationships<R>>(type: T, attributes: A & FieldNamespace<A, R>, options?: ResourceOptions<R>): JsonApiResource<A, C, T, R>;
64
+ export declare function jsonApiResource<const T extends string, A extends ZodObject, const R extends Readonly<Record<string, RelationshipDef<any, any>>> = Readonly<Record<string, never>>, C = ContextOfRelationships<R>, const I extends string = string>(type: T, attributes: A & FieldNamespace<A, R>, options?: ResourceOptions<R, I>): JsonApiResource<A, C, T, R, I>;
59
65
  export {};
60
66
  //# sourceMappingURL=resource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"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"}
package/dist/resource.js CHANGED
@@ -41,7 +41,10 @@ function membersOf(schema) {
41
41
  /** Every member name an attribute schema declares, at every depth. */
42
42
  function memberNames(schema) {
43
43
  return membersOf(schema).flatMap((member) => member instanceof z.ZodObject
44
- ? Object.entries(member.shape).flatMap(([name, inner]) => [name, ...memberNames(inner)])
44
+ ? Object.entries(member.shape).flatMap(([name, inner]) => [
45
+ name,
46
+ ...memberNames(inner),
47
+ ])
45
48
  : []);
46
49
  }
47
50
  /**
@@ -89,7 +92,7 @@ export function jsonApiResource(type, attributes, options = {}) {
89
92
  attributes,
90
93
  relationships,
91
94
  get resourceObject() {
92
- return (object ??= resourceObjectSchema(type, attributes, relationships));
95
+ return (object ??= resourceObjectSchema(type, attributes, relationships, options.id));
93
96
  },
94
97
  get document() {
95
98
  return (one ??= resourceDocumentSchema(resource));
@@ -1,8 +1,8 @@
1
1
  import { Serializer, type SerializerOptions } from 'ts-japi';
2
2
  import type { PaginationLinks } from './primitives.js';
3
3
  /** One row as a serializer hands it over. Its `id` is the resource id, which the standard makes a string. */
4
- export interface Row {
5
- id: string;
4
+ export interface Row<I extends string = string> {
5
+ id: I;
6
6
  [member: string]: unknown;
7
7
  }
8
8
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../src/serialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,UAAU,EAAqB,KAAK,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEzF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,6GAA6G;AAC7G,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAK5D;AAED;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;AAEvE,sCAAsC;AACtC,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;AAEjD,KAAK,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;AAExD;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,mFAAmF;IACnF,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;IACrD,mEAAmE;IACnE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAgCD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,gBAAgB,EAC1B,SAAS,CAAC,EAAE,sBAAsB,GACjC,kBAAkB,CAgBpB;AAED,2EAA2E;AAC3E,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AA8CD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,kBAAkB,EAC9B,IAAI,EAAE,GAAG,EACT,MAAM,CAAC,EAAE,UAAU,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAElC;AAED,0GAA0G;AAC1G,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,kBAAkB,EAC9B,KAAK,EAAE,GAAG,EAAE,EACZ,MAAM,GAAE,gBAAqB,EAC7B,MAAM,CAAC,EAAE,UAAU,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAMlC"}
1
+ {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../src/serialize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,UAAU,EAAqB,KAAK,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEzF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,6GAA6G;AAC7G,MAAM,WAAW,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAC5C,EAAE,EAAE,CAAC,CAAC;IACN,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAK5D;AAED;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;AAEvE,sCAAsC;AACtC,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;AAEjD,KAAK,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;AAExD;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,mFAAmF;IACnF,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;IACrD,mEAAmE;IACnE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAgCD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,gBAAgB,EAC1B,SAAS,CAAC,EAAE,sBAAsB,GACjC,kBAAkB,CAgBpB;AAED,2EAA2E;AAC3E,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AA8CD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,kBAAkB,EAC9B,IAAI,EAAE,GAAG,EACT,MAAM,CAAC,EAAE,UAAU,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAElC;AAED,0GAA0G;AAC1G,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,kBAAkB,EAC9B,KAAK,EAAE,GAAG,EAAE,EACZ,MAAM,GAAE,gBAAqB,EAC7B,MAAM,CAAC,EAAE,UAAU,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAMlC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeroxsolutions/response",
3
- "version": "0.14.4",
3
+ "version": "0.14.6",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -30,7 +30,10 @@
30
30
  "zod": "^4.3.6"
31
31
  },
32
32
  "nx": {
33
- "name": "@zeroxsolutions/response"
33
+ "name": "@zeroxsolutions/response",
34
+ "targets": {
35
+ "lint-deps": {}
36
+ }
34
37
  },
35
38
  "main": "./dist/index.js",
36
39
  "module": "./dist/index.js",