@haddowg/json-api-client 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/ajv.d.cts +1 -1
- package/dist/ajv.d.mts +1 -1
- package/dist/index.cjs +128 -37
- package/dist/index.d.cts +31 -9
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +31 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +125 -38
- package/dist/index.mjs.map +1 -1
- package/dist/{validate-CfrCMZkA.d.cts → validate-CJPivkqT.d.cts} +382 -78
- package/dist/validate-CJPivkqT.d.cts.map +1 -0
- package/dist/{validate-CfrCMZkA.d.mts → validate-CJPivkqT.d.mts} +382 -78
- package/dist/validate-CJPivkqT.d.mts.map +1 -0
- package/package.json +1 -1
- package/dist/validate-CfrCMZkA.d.cts.map +0 -1
- package/dist/validate-CfrCMZkA.d.mts.map +0 -1
package/README.md
CHANGED
|
@@ -132,7 +132,7 @@ const albums = await client.albums.list({ withCount: ['tracks'] })
|
|
|
132
132
|
All three collection surfaces (top-level lists, related collections, to-many relationship arrays)
|
|
133
133
|
expose the same `$page` + `$next()` / `$prev()`. Navigation is **count-free-safe** — driven by
|
|
134
134
|
link presence, not a total. Cursor pagination is just a paginator `kind`; page with
|
|
135
|
-
`page[
|
|
135
|
+
`page[after]` / `page[before]` / `page[size]` query params and walk it with `$next()`:
|
|
136
136
|
|
|
137
137
|
```ts
|
|
138
138
|
let page = await client.tracks.list({ page: { size: 50 } })
|
|
@@ -262,6 +262,10 @@ Status matchers: `hasStatus(n)`, `is4xx()`, `is5xx()`, `isBadRequest()` /400,
|
|
|
262
262
|
`parameter`) — the payoff for form/validation UX. Each error keeps its raw `source.pointer` as an
|
|
263
263
|
escape hatch; atomic errors also carry an `opIndex`.
|
|
264
264
|
|
|
265
|
+
`hasErrorCode(err, code)` is true when `err` is a `JsonApiError` and any of its error objects
|
|
266
|
+
carries `code`. A generated client exports a version bound to its server's documented `ErrorCode`
|
|
267
|
+
union, so a misspelt code fails to compile and a match narrows to `JsonApiError<ErrorCode>`.
|
|
268
|
+
|
|
265
269
|
> A response that parses but violates the JSON:API envelope shape (not a document, a member
|
|
266
270
|
> missing `type`/`id`) throws a `StructuralGuardError` — distinct from a server-reported
|
|
267
271
|
> `JsonApiError`. These light structural guards are always on; full per-field validation is opt-in
|
package/dist/ajv.d.cts
CHANGED
package/dist/ajv.d.mts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -16,6 +16,9 @@ var StructuralGuardError = class extends Error {
|
|
|
16
16
|
/**
|
|
17
17
|
* Thrown for any non-2xx JSON:API response. Carries the parsed error document plus
|
|
18
18
|
* expressive status matchers and pointer-grouping helpers.
|
|
19
|
+
*
|
|
20
|
+
* `C` types each error object's `code` (see {@link JsonApiErrorObject}). It is a compile-time
|
|
21
|
+
* hint only: the runtime never checks a code against it.
|
|
19
22
|
*/
|
|
20
23
|
var JsonApiError = class extends Error {
|
|
21
24
|
status;
|
|
@@ -80,6 +83,60 @@ var JsonApiError = class extends Error {
|
|
|
80
83
|
return out;
|
|
81
84
|
}
|
|
82
85
|
};
|
|
86
|
+
/**
|
|
87
|
+
* True when `err` is a {@link JsonApiError} and any of its error objects carries `code`. Takes
|
|
88
|
+
* any string, so it also matches codes the server never documented. A generated client exports a
|
|
89
|
+
* `hasErrorCode` bound to its server's `ErrorCode` union, which rejects a misspelt code at
|
|
90
|
+
* compile time; reach for this one only to match an undocumented code.
|
|
91
|
+
*/
|
|
92
|
+
function hasErrorCode(err, code) {
|
|
93
|
+
return err instanceof JsonApiError && err.errors.some((e) => e.code === code);
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region src/pagination.ts
|
|
97
|
+
/** The wire key for each role when the server keeps the default names. */
|
|
98
|
+
const CANONICAL_PAGE_KEYS = {
|
|
99
|
+
page: {
|
|
100
|
+
number: "number",
|
|
101
|
+
size: "size"
|
|
102
|
+
},
|
|
103
|
+
offset: {
|
|
104
|
+
offset: "offset",
|
|
105
|
+
limit: "limit"
|
|
106
|
+
},
|
|
107
|
+
cursor: {
|
|
108
|
+
after: "after",
|
|
109
|
+
before: "before",
|
|
110
|
+
size: "size"
|
|
111
|
+
},
|
|
112
|
+
fixed: { number: "number" },
|
|
113
|
+
none: {}
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Resolve the strategy that answers a read from the endpoint's paginator and the `page` the
|
|
117
|
+
* request sends. A menu answers with the arm named by `page.kind`, else its `default`.
|
|
118
|
+
*/
|
|
119
|
+
function resolvePaginator(paginator, page) {
|
|
120
|
+
if (paginator === void 0) return {
|
|
121
|
+
kind: "none",
|
|
122
|
+
keys: {}
|
|
123
|
+
};
|
|
124
|
+
if (typeof paginator === "string") return {
|
|
125
|
+
kind: paginator,
|
|
126
|
+
keys: CANONICAL_PAGE_KEYS[paginator]
|
|
127
|
+
};
|
|
128
|
+
if (paginator.strategy !== "multi") return {
|
|
129
|
+
kind: paginator.strategy,
|
|
130
|
+
keys: paginator.keys
|
|
131
|
+
};
|
|
132
|
+
const picked = page?.["kind"];
|
|
133
|
+
const arm = typeof picked === "string" && Object.hasOwn(paginator.arms, picked) ? picked : void 0;
|
|
134
|
+
const resolved = resolvePaginator(paginator.arms[arm ?? paginator.default]);
|
|
135
|
+
return arm === void 0 ? resolved : {
|
|
136
|
+
...resolved,
|
|
137
|
+
arm
|
|
138
|
+
};
|
|
139
|
+
}
|
|
83
140
|
//#endregion
|
|
84
141
|
//#region src/validate.ts
|
|
85
142
|
/** Whether a `validate` option is the schema-driven config (vs a bare validator function). */
|
|
@@ -192,9 +249,10 @@ const defineGetter = (target, key, get) => {
|
|
|
192
249
|
* full resource) — a structural guess can't tell them apart for an attribute-less,
|
|
193
250
|
* relation-less resource, so the caller passes the surface it issued.
|
|
194
251
|
*
|
|
195
|
-
* `paginatorOverride` sets the top-level array's `$page
|
|
196
|
-
*
|
|
197
|
-
*
|
|
252
|
+
* `paginatorOverride` sets the top-level array's `$page` for a related/relationship read, where the
|
|
253
|
+
* paginator is the RELATION's (which may diverge from the related type's collection — D6a), for a
|
|
254
|
+
* menu read that picked an arm, and where an empty page carries no member to sniff a type from. A
|
|
255
|
+
* bare kind is read with its canonical wire keys. `primaryType` is preferred for a
|
|
198
256
|
* top-level collection read (statically-known); both override the sniff-from-`data[0]` fallback.
|
|
199
257
|
*/
|
|
200
258
|
function materialise(doc, ctx, linkage = false, primaryType, paginatorOverride) {
|
|
@@ -247,7 +305,7 @@ function buildNode(raw, env, index, nodes, ctx) {
|
|
|
247
305
|
for (const [name, rel] of Object.entries(rels)) {
|
|
248
306
|
if (!("data" in rel)) continue;
|
|
249
307
|
const relDesc = resType?.relations[name];
|
|
250
|
-
node[name] = hydrateRelation(rel, relDesc?.cardinality,
|
|
308
|
+
node[name] = hydrateRelation(rel, relDesc?.cardinality, resolvePaginator(relatedPaginator(relDesc, ctx)), env, index, nodes, ctx);
|
|
251
309
|
}
|
|
252
310
|
attachResourceEnvelope(node, raw, env, rels);
|
|
253
311
|
return node;
|
|
@@ -257,13 +315,13 @@ function buildNode(raw, env, index, nodes, ctx) {
|
|
|
257
315
|
* linked-but-not-included member stays an identifier, an empty to-one is `null`, and a
|
|
258
316
|
* to-many is always an augmented array (of views and/or identifiers).
|
|
259
317
|
*
|
|
260
|
-
* `
|
|
261
|
-
*
|
|
318
|
+
* `related` is the relation's paginator (from the descriptor), threaded so a to-many array
|
|
319
|
+
* reports the same `$page` it would on its dedicated endpoint without a `page` argument.
|
|
262
320
|
*/
|
|
263
|
-
function hydrateRelation(rel, cardinality,
|
|
321
|
+
function hydrateRelation(rel, cardinality, related, env, index, nodes, ctx) {
|
|
264
322
|
const data = rel.data;
|
|
265
|
-
if (Array.isArray(data)) return augmentRelationArray(data.map((member) => resolveMember(member, env, index, nodes, ctx)), rel,
|
|
266
|
-
if (data === void 0 && cardinality === "many") return augmentRelationArray([], rel,
|
|
323
|
+
if (Array.isArray(data)) return augmentRelationArray(data.map((member) => resolveMember(member, env, index, nodes, ctx)), rel, related, ctx);
|
|
324
|
+
if (data === void 0 && cardinality === "many") return augmentRelationArray([], rel, related, ctx);
|
|
267
325
|
if (data === null || data === void 0) return data === null ? null : void 0;
|
|
268
326
|
if (isObject$2(data)) return resolveMember(data, env, index, nodes, ctx, {
|
|
269
327
|
links: rel.links,
|
|
@@ -370,33 +428,35 @@ function augmentArray(members, doc, ctx, linkage, primaryType, paginatorOverride
|
|
|
370
428
|
const links = doc.links;
|
|
371
429
|
defineGetter(arr, "$links", () => links);
|
|
372
430
|
defineGetter(arr, "$meta", () => doc.meta);
|
|
373
|
-
attachPage(arr, paginatorOverride
|
|
431
|
+
attachPage(arr, paginatorOverride === void 0 ? resolvePaginator(primaryPaginator(doc, ctx, primaryType)) : typeof paginatorOverride === "string" ? resolvePaginator(paginatorOverride) : paginatorOverride, pageMeta(doc.meta), links, ctx, linkage);
|
|
374
432
|
return arr;
|
|
375
433
|
}
|
|
376
434
|
/**
|
|
377
|
-
* A to-many relationship array: `$page`/links/meta come from the relationship object.
|
|
378
|
-
* is the
|
|
435
|
+
* A to-many relationship array: `$page`/links/meta come from the relationship object.
|
|
436
|
+
* `paginator` is the relation's (so an in-document compound-include to-many reports the same
|
|
379
437
|
* discriminant it would when fetched at its own relationship/related endpoint — "one model,
|
|
380
438
|
* three surfaces").
|
|
381
439
|
*/
|
|
382
|
-
function augmentRelationArray(members, rel,
|
|
440
|
+
function augmentRelationArray(members, rel, paginator, ctx) {
|
|
383
441
|
const arr = [...members];
|
|
384
442
|
const links = rel.links;
|
|
385
443
|
defineGetter(arr, "$links", () => links);
|
|
386
444
|
defineGetter(arr, "$meta", () => rel.meta);
|
|
387
|
-
attachPage(arr,
|
|
445
|
+
attachPage(arr, paginator, pageMeta(rel.meta), links, ctx, false);
|
|
388
446
|
return arr;
|
|
389
447
|
}
|
|
390
448
|
/** Attach `$page` + `$next()`/`$prev()` driven by link presence (count-free-safe). */
|
|
391
|
-
function attachPage(arr,
|
|
449
|
+
function attachPage(arr, paginator, meta, links, ctx, linkage) {
|
|
392
450
|
const page = {
|
|
393
|
-
kind,
|
|
451
|
+
kind: paginator.kind,
|
|
452
|
+
keys: paginator.keys,
|
|
394
453
|
links: pageLinks(links)
|
|
395
454
|
};
|
|
455
|
+
if (paginator.arm !== void 0) page.arm = paginator.arm;
|
|
396
456
|
if (meta !== void 0) page.meta = meta;
|
|
397
457
|
defineGetter(arr, "$page", () => page);
|
|
398
|
-
define(arr, "$next", (options) => navigateLink(page.links.next, ctx, linkage,
|
|
399
|
-
define(arr, "$prev", (options) => navigateLink(page.links.prev, ctx, linkage,
|
|
458
|
+
define(arr, "$next", (options) => navigateLink(page.links.next, ctx, linkage, paginator, options?.signal));
|
|
459
|
+
define(arr, "$prev", (options) => navigateLink(page.links.prev, ctx, linkage, paginator, options?.signal));
|
|
400
460
|
}
|
|
401
461
|
const navigateLink = (link, ctx, linkage, paginator, signal) => {
|
|
402
462
|
if (link === void 0) return Promise.resolve(void 0);
|
|
@@ -423,18 +483,18 @@ const linkHref = (link) => {
|
|
|
423
483
|
};
|
|
424
484
|
const pageMeta = (meta) => isObject$2(meta?.["page"]) ? meta["page"] : void 0;
|
|
425
485
|
/**
|
|
426
|
-
* The document's paginator
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
486
|
+
* The document's paginator (from the primary type's descriptor). Prefers the statically-known
|
|
487
|
+
* `primaryType` (passed by the descriptor binding at the call site) so an EMPTY page still reports
|
|
488
|
+
* the collection's real kind; falls back to sniffing the first member's type (for a re-materialised
|
|
489
|
+
* `$next()` page or a related read, where the primary type isn't threaded).
|
|
430
490
|
*/
|
|
431
|
-
function
|
|
491
|
+
function primaryPaginator(doc, ctx, primaryType) {
|
|
432
492
|
const first = Array.isArray(doc.data) ? doc.data[0] : doc.data;
|
|
433
493
|
const type = primaryType ?? (isObject$2(first) && typeof first["type"] === "string" ? first["type"] : void 0);
|
|
434
|
-
return type !== void 0 ? ctx.descriptor[type]?.paginator
|
|
494
|
+
return type !== void 0 ? ctx.descriptor[type]?.paginator : void 0;
|
|
435
495
|
}
|
|
436
496
|
/**
|
|
437
|
-
* A to-many relation's paginator
|
|
497
|
+
* A to-many relation's paginator. The relation's OWN related/relationship endpoint may
|
|
438
498
|
* paginate differently than the related type's top-level collection (D6a), so prefer the
|
|
439
499
|
* per-relation `paginator` (carried in the descriptor only when it diverges); otherwise fall back
|
|
440
500
|
* to the related type's own paginator (the relationship and related endpoints both paginate that
|
|
@@ -442,11 +502,14 @@ function paginatorKind(doc, ctx, primaryType) {
|
|
|
442
502
|
* resolves off its first declared related type (its members span types, matching the relationship
|
|
443
503
|
* endpoint's first-member resolution).
|
|
444
504
|
*/
|
|
445
|
-
function
|
|
505
|
+
function relatedPaginator(relation, ctx) {
|
|
446
506
|
if (relation?.paginator !== void 0) return relation.paginator;
|
|
447
507
|
const relatedType = relation?.types[0];
|
|
448
|
-
|
|
449
|
-
|
|
508
|
+
return relatedType === void 0 ? void 0 : ctx.descriptor[relatedType]?.paginator;
|
|
509
|
+
}
|
|
510
|
+
/** The kind a relation's related read answers with when it sends no `page`. See {@link relatedPaginator}. */
|
|
511
|
+
function relatedPaginatorKind(relation, ctx) {
|
|
512
|
+
return resolvePaginator(relatedPaginator(relation, ctx)).kind;
|
|
450
513
|
}
|
|
451
514
|
//#endregion
|
|
452
515
|
//#region src/types.ts
|
|
@@ -476,6 +539,14 @@ const ATOMIC_MEDIA_TYPE = mediaType({ ext: [ATOMIC_EXT] });
|
|
|
476
539
|
//#endregion
|
|
477
540
|
//#region src/request.ts
|
|
478
541
|
const isAbsolute = (path) => /^https?:\/\//i.test(path);
|
|
542
|
+
const RELATIVE_ORIGIN = "http://relative.invalid";
|
|
543
|
+
/** Resolve a server link against `baseUrl` per RFC 3986. An absolute link is kept verbatim. */
|
|
544
|
+
function resolveLink(link, baseUrl) {
|
|
545
|
+
if (isAbsolute(link)) return link;
|
|
546
|
+
if (isAbsolute(baseUrl)) return new URL(link, baseUrl).href;
|
|
547
|
+
const resolved = new URL(link, new URL(baseUrl, RELATIVE_ORIGIN));
|
|
548
|
+
return resolved.origin === RELATIVE_ORIGIN ? resolved.pathname + resolved.search + resolved.hash : resolved.href;
|
|
549
|
+
}
|
|
479
550
|
const append = (parts, key, value) => {
|
|
480
551
|
if (value === void 0 || value === null || value === "") return;
|
|
481
552
|
parts.push(`${key}=${encodeURIComponent(String(value))}`);
|
|
@@ -512,14 +583,14 @@ function serializeQuery(query) {
|
|
|
512
583
|
return parts.join("&");
|
|
513
584
|
}
|
|
514
585
|
/**
|
|
515
|
-
* Execute a request: build the URL (
|
|
516
|
-
* else `baseUrl + path`), apply content negotiation and any async per-request headers,
|
|
586
|
+
* Execute a request: build the URL (a server link resolved against `baseUrl`, an absolute path
|
|
587
|
+
* verbatim, else `baseUrl + path`), apply content negotiation and any async per-request headers,
|
|
517
588
|
* then drive the transport. A 2xx with a body parses to a {@link Document}; an empty /
|
|
518
589
|
* 204 body resolves to `undefined`. A non-2xx throws a {@link JsonApiError} carrying the
|
|
519
590
|
* parsed error objects (tolerating a non-JSON error body with an empty list).
|
|
520
591
|
*/
|
|
521
592
|
async function execute(ctx, req) {
|
|
522
|
-
let url = isAbsolute(req.path) ? req.path : ctx.baseUrl + req.path;
|
|
593
|
+
let url = req.link ? resolveLink(req.path, ctx.baseUrl) : isAbsolute(req.path) ? req.path : ctx.baseUrl + req.path;
|
|
523
594
|
if (req.query) {
|
|
524
595
|
const qs = serializeQuery(req.query);
|
|
525
596
|
if (qs) url += (url.includes("?") ? "&" : "?") + qs;
|
|
@@ -949,6 +1020,18 @@ const fetchTransport = async (req) => {
|
|
|
949
1020
|
/** Substitute `{key}` placeholders in a path template (`/albums/{id}/{rel}` -> `/albums/1/tracks`). */
|
|
950
1021
|
const fill = (template, vars) => template.replace(/\{(\w+)\}/g, (_, key) => vars[key] ?? `{${key}}`);
|
|
951
1022
|
/**
|
|
1023
|
+
* Fill a type's path template, putting a relation's URI segment (its `uriField`, else its name)
|
|
1024
|
+
* in place of `{rel}`. `vars.rel` stays the relation's name everywhere else.
|
|
1025
|
+
*/
|
|
1026
|
+
function fillPath(ctx, type, template, vars) {
|
|
1027
|
+
const rel = vars["rel"];
|
|
1028
|
+
const uriField = rel === void 0 ? void 0 : ctx.descriptor[type]?.relations[rel]?.uriField;
|
|
1029
|
+
return fill(template, uriField === void 0 ? vars : {
|
|
1030
|
+
...vars,
|
|
1031
|
+
rel: uriField
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
/**
|
|
952
1035
|
* Run an operation: resolve the path template from the type's descriptor, fill its
|
|
953
1036
|
* placeholders, execute, and materialise the resulting document. A no-body / 204 response
|
|
954
1037
|
* materialises to `undefined`; an operation the type does not declare (no path template) throws
|
|
@@ -961,7 +1044,7 @@ async function run(ctx, type, operation, vars, query, linkage = false, relationF
|
|
|
961
1044
|
if (template === void 0) throw new Error(`No "${operation}" path declared for type "${type}"`);
|
|
962
1045
|
const req = {
|
|
963
1046
|
method: "GET",
|
|
964
|
-
path:
|
|
1047
|
+
path: fillPath(ctx, type, template, vars)
|
|
965
1048
|
};
|
|
966
1049
|
if (query !== void 0) {
|
|
967
1050
|
const { signal, ...params } = query;
|
|
@@ -970,8 +1053,10 @@ async function run(ctx, type, operation, vars, query, linkage = false, relationF
|
|
|
970
1053
|
negotiateProfiles(ctx, type, params, req, relationForCount);
|
|
971
1054
|
}
|
|
972
1055
|
const doc = await execute(ctx.request, req);
|
|
1056
|
+
const relation = (operation === "fetchRelated" || operation === "fetchRelationship") && vars["rel"] !== void 0 ? ctx.descriptor[type]?.relations[vars["rel"]] : void 0;
|
|
1057
|
+
const paginator = operation === "fetchMany" ? ctx.descriptor[type]?.paginator : relation !== void 0 ? relatedPaginator(relation, ctx.materialise) : void 0;
|
|
973
1058
|
const primaryType = operation === "fetchMany" ? type : void 0;
|
|
974
|
-
const paginatorOverride =
|
|
1059
|
+
const paginatorOverride = paginator === void 0 ? void 0 : resolvePaginator(paginator, query?.page);
|
|
975
1060
|
return doc === void 0 ? void 0 : materialise(doc, ctx.materialise, linkage, primaryType, paginatorOverride);
|
|
976
1061
|
}
|
|
977
1062
|
/**
|
|
@@ -1009,7 +1094,7 @@ async function runWrite(ctx, spec) {
|
|
|
1009
1094
|
if (template === void 0) throw new Error(`No "${spec.operation}" path declared for type "${spec.type}"`);
|
|
1010
1095
|
const req = {
|
|
1011
1096
|
method: spec.method,
|
|
1012
|
-
path:
|
|
1097
|
+
path: fillPath(ctx, spec.type, template, spec.vars),
|
|
1013
1098
|
body: spec.body
|
|
1014
1099
|
};
|
|
1015
1100
|
if (spec.query !== void 0) req.query = spec.query;
|
|
@@ -1108,8 +1193,9 @@ function relationshipAccessor(ctx, type, id, rel) {
|
|
|
1108
1193
|
return mutations === void 0 ? true : mutations[verb] === true;
|
|
1109
1194
|
};
|
|
1110
1195
|
const accessor = {};
|
|
1111
|
-
|
|
1112
|
-
if (relation?.
|
|
1196
|
+
const readable = relation?.writeOnly !== true;
|
|
1197
|
+
if (readable && relation?.relationship !== false) accessor["get"] = (query) => run(ctx, type, "fetchRelationship", vars, query, true, rel);
|
|
1198
|
+
if (readable && relation?.related !== false) accessor["related"] = (query) => run(ctx, type, "fetchRelated", vars, query, false, rel);
|
|
1113
1199
|
if (cardinality === "many") {
|
|
1114
1200
|
if (advertises("add")) accessor["add"] = (refs) => mutate("POST", refs);
|
|
1115
1201
|
if (advertises("remove")) accessor["remove"] = (refs) => mutate("DELETE", refs);
|
|
@@ -1188,7 +1274,7 @@ function typeAccessor(ctx, type) {
|
|
|
1188
1274
|
* not per-type codegen: `client.<type>` yields a {@link TypeAccessor}, `.id(id)` a handle,
|
|
1189
1275
|
* and a handle's relation accessors drive the relationship/related endpoints. Navigation
|
|
1190
1276
|
* (`$next()`/`$prev()`, related links) is wired through `materialise`'s `navigate` seam,
|
|
1191
|
-
* which
|
|
1277
|
+
* which resolves the server's link against `baseUrl`, executes it and re-materialises.
|
|
1192
1278
|
*/
|
|
1193
1279
|
function createClient(descriptor, options) {
|
|
1194
1280
|
const request = {
|
|
@@ -1206,6 +1292,7 @@ function createClient(descriptor, options) {
|
|
|
1206
1292
|
const doc = await execute(request, {
|
|
1207
1293
|
method: "GET",
|
|
1208
1294
|
path: url,
|
|
1295
|
+
link: true,
|
|
1209
1296
|
...signal !== void 0 ? { signal } : {}
|
|
1210
1297
|
});
|
|
1211
1298
|
return doc === void 0 ? void 0 : materialise(doc, ctx.materialise, linkage, void 0, paginator);
|
|
@@ -1238,6 +1325,7 @@ function createClient(descriptor, options) {
|
|
|
1238
1325
|
//#endregion
|
|
1239
1326
|
exports.ATOMIC_EXT = ATOMIC_EXT;
|
|
1240
1327
|
exports.ATOMIC_MEDIA_TYPE = ATOMIC_MEDIA_TYPE;
|
|
1328
|
+
exports.CANONICAL_PAGE_KEYS = CANONICAL_PAGE_KEYS;
|
|
1241
1329
|
exports.HANDLE_RESERVED = HANDLE_RESERVED;
|
|
1242
1330
|
exports.JSON_API_MEDIA_TYPE = JSON_API_MEDIA_TYPE;
|
|
1243
1331
|
exports.JsonApiError = JsonApiError;
|
|
@@ -1246,11 +1334,14 @@ exports.assertJsonApiDocument = assertJsonApiDocument;
|
|
|
1246
1334
|
exports.createClient = createClient;
|
|
1247
1335
|
exports.execute = execute;
|
|
1248
1336
|
exports.fetchTransport = fetchTransport;
|
|
1337
|
+
exports.hasErrorCode = hasErrorCode;
|
|
1249
1338
|
exports.materialise = materialise;
|
|
1250
1339
|
exports.mediaType = mediaType;
|
|
1340
|
+
exports.relatedPaginator = relatedPaginator;
|
|
1251
1341
|
exports.relatedPaginatorKind = relatedPaginatorKind;
|
|
1252
1342
|
exports.remapPointer = remapPointer;
|
|
1253
1343
|
exports.remapRelationshipPointer = remapRelationshipPointer;
|
|
1344
|
+
exports.resolvePaginator = resolvePaginator;
|
|
1254
1345
|
exports.resolveValidator = resolveValidator;
|
|
1255
1346
|
exports.runAtomic = runAtomic;
|
|
1256
1347
|
exports.serializeQuery = serializeQuery;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as RelationshipAccessor, $t as ActionDescriptor, A as DefaultActionTypes, At as DocumentEnvelope, B as IdentifierMember, Bt as relatedPaginatorKind, C as fetchTransport, Ct as ATOMIC_MEDIA_TYPE, D as Collection, Dt as ResourceIdentifier, E as Client, Et as MediaTypeParams, F as FieldSelectionMap, Ft as RelationView, G as MemberName, Gt as PageLinks, H as IncludedRelations, Ht as ExactPageParams, I as FieldsMap, It as ResourceEnvelope, J as ReadableRelationName, Jt as PageParams, K as PivotInput, Kt as PageMeta, L as FilterKey, Lt as ResourceLinks, M as DefaultWriteAttributes, Mt as EdgeEnvelope, N as EdgeMembers, Nt as MaterialiseContext, O as CountToken, Ot as mediaType, P as ErrorCodeOf, Pt as NavigateOptions, Q as RelationReadQuery, Qt as resolvePaginator, R as FilterQuery, Rt as materialise, S as TransportResponse, St as ATOMIC_EXT, T as AtomicResultOf, Tt as LocalIdentifier, U as LinkageRef, Ut as Page, V as IncludePath, Vt as CANONICAL_PAGE_KEYS, W as ListPageParams, Wt as PageKeys, X as RelationPageParams, Xt as ResolvedPaginator, Y as RelationName, Yt as PageParamsOf, Z as RelationPaginator, Zt as TypedPage, _ as HANDLE_RESERVED, _n as StrategyDescriptor, _t as AtomicResult, a as Validator, an as Cardinality, at as SortToken, b as JsonApiTransport, bt as AtomicUpdateInput, c as resolveValidator, cn as MenuDescriptor, ct as TypedReadQuery, d as JsonApiContext, dn as PaginatorRole, dt as AtomicCreateHandle, en as ActionInput, et as ResourceAccessors, f as JsonApiRequest, fn as PaginatorStrategy, ft as AtomicCreateInput, g as ClientOptions, gn as ResourceDescriptor, gt as AtomicRef, h as serializeQuery, hn as RelationMutations, ht as AtomicRecorder, i as ValidationOption, in as AtomicDescriptor, it as SortQuery, j as DefaultAttributes, jt as Edge, k as CreateInput, kt as ArrayEnvelope, l as validateDocument, ln as PaginatorDescriptor, lt as UpdateInput, m as execute, mn as RelationDescriptor, mt as AtomicHandle, n as SchemaMap, nn as ActionScope, nt as ResourceObjectView, o as WireResource, on as ClientIdPolicy, ot as TypeAccessor, p as ReadQuery, pn as PivotDescriptor, pt as AtomicDeleteHandle, q as ReadResult, qt as PageOf, r as ValidationConfig, rn as ApiDescriptor, rt as SingleReadQuery, s as assertJsonApiDocument, sn as CountableDescriptor, st as TypeName, t as ResolvedValidator, tn as ActionOutput, tt as ResourceHandle, u as Document, un as PaginatorKind, ut as WriteOptions, v as HeadersInit, vt as AtomicResults, w as ActionsAccessor, wt as JSON_API_MEDIA_TYPE, x as TransportRequest, xt as runAtomic, y as createClient, yt as AtomicUpdateHandle, z as HydratedMember, zt as relatedPaginator } from "./validate-CJPivkqT.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/errors.d.ts
|
|
4
|
-
/**
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* A single JSON:API error object (spec: error objects).
|
|
6
|
+
*
|
|
7
|
+
* `C` is the server's documented error-code union (a generated client's `ErrorCode`). `code` is
|
|
8
|
+
* typed `C | (string & {})`: editors suggest the documented codes, yet any other string still
|
|
9
|
+
* fits, because the catalogue is open and a server may send a code it never documented.
|
|
10
|
+
*/
|
|
11
|
+
interface JsonApiErrorObject<C extends string = string> {
|
|
6
12
|
id?: string;
|
|
7
13
|
status?: string;
|
|
8
|
-
code?: string;
|
|
14
|
+
code?: C | (string & {});
|
|
9
15
|
title?: string;
|
|
10
16
|
detail?: string;
|
|
11
17
|
source?: {
|
|
@@ -40,11 +46,14 @@ declare class StructuralGuardError extends Error {
|
|
|
40
46
|
/**
|
|
41
47
|
* Thrown for any non-2xx JSON:API response. Carries the parsed error document plus
|
|
42
48
|
* expressive status matchers and pointer-grouping helpers.
|
|
49
|
+
*
|
|
50
|
+
* `C` types each error object's `code` (see {@link JsonApiErrorObject}). It is a compile-time
|
|
51
|
+
* hint only: the runtime never checks a code against it.
|
|
43
52
|
*/
|
|
44
|
-
declare class JsonApiError extends Error {
|
|
53
|
+
declare class JsonApiError<C extends string = string> extends Error {
|
|
45
54
|
readonly status: number;
|
|
46
|
-
readonly errors: JsonApiErrorObject[];
|
|
47
|
-
constructor(status: number, errors: JsonApiErrorObject[], message?: string);
|
|
55
|
+
readonly errors: JsonApiErrorObject<C>[];
|
|
56
|
+
constructor(status: number, errors: JsonApiErrorObject<C>[], message?: string);
|
|
48
57
|
hasStatus(status: number): boolean;
|
|
49
58
|
is4xx(): boolean;
|
|
50
59
|
is5xx(): boolean;
|
|
@@ -64,8 +73,21 @@ declare class JsonApiError extends Error {
|
|
|
64
73
|
* query parameter). The payoff for form/validation UX — 422 `source.pointer`s are
|
|
65
74
|
* remapped to the flat shape the caller actually supplied.
|
|
66
75
|
*/
|
|
67
|
-
byPath(): Record<string, JsonApiErrorObject[]>;
|
|
76
|
+
byPath(): Record<string, JsonApiErrorObject<C>[]>;
|
|
68
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* True when `err` is a {@link JsonApiError} and any of its error objects carries `code`. Takes
|
|
80
|
+
* any string, so it also matches codes the server never documented. A generated client exports a
|
|
81
|
+
* `hasErrorCode` bound to its server's `ErrorCode` union, which rejects a misspelt code at
|
|
82
|
+
* compile time; reach for this one only to match an undocumented code.
|
|
83
|
+
*/
|
|
84
|
+
declare function hasErrorCode(err: unknown, code: string): err is JsonApiError;
|
|
85
|
+
/**
|
|
86
|
+
* {@link hasErrorCode} restricted to one server's documented codes. A generated client binds it:
|
|
87
|
+
* `export const hasErrorCode = hasErrorCodeRuntime as ErrorCodeGuard<ErrorCode>`. The cast is
|
|
88
|
+
* needed because `JsonApiError<string>` doesn't assign to `JsonApiError<ErrorCode>`.
|
|
89
|
+
*/
|
|
90
|
+
type ErrorCodeGuard<C extends string> = (err: unknown, code: C) => err is JsonApiError<C>;
|
|
69
91
|
//#endregion
|
|
70
92
|
//#region src/serialize-write.d.ts
|
|
71
93
|
/**
|
|
@@ -194,5 +216,5 @@ declare function withRemappedRelationshipPaths(error: JsonApiError, rel: string,
|
|
|
194
216
|
*/
|
|
195
217
|
declare function withRemappedAtomicPaths(error: JsonApiError, descriptor: ApiDescriptor, typeForOp: (opIndex: number) => string | undefined): JsonApiError;
|
|
196
218
|
//#endregion
|
|
197
|
-
export { ATOMIC_EXT, ATOMIC_MEDIA_TYPE, ActionDescriptor, ActionInput, ActionOutput, ActionScope, ActionsAccessor, ApiDescriptor, ArrayEnvelope, AtomicCreateHandle, AtomicCreateInput, AtomicDeleteHandle, AtomicDescriptor, AtomicHandle, AtomicRecorder, AtomicRef, AtomicResult, AtomicResultOf, AtomicResults, AtomicUpdateHandle, AtomicUpdateInput, Cardinality, Client, ClientIdPolicy, ClientOptions, Collection, CountToken, CountableDescriptor, CreateInput, DefaultActionTypes, DefaultAttributes, DefaultWriteAttributes, Document, DocumentEnvelope, Edge, EdgeEnvelope, EdgeMembers, FieldSelectionMap, FieldsMap, FilterKey, FilterQuery, HANDLE_RESERVED, HeadersInit, HydratedMember, IdentifierMember, IncludePath, IncludedRelations, JSON_API_MEDIA_TYPE, JsonApiContext, JsonApiError, JsonApiErrorObject, JsonApiRequest, JsonApiTransport, LinkageRef, LocalIdentifier, MaterialiseContext, MediaTypeParams, MemberName, NavigateOptions, Page, PaginatorKind, PivotInput, ReadQuery, ReadResult, RelationDescriptor, RelationMutations, RelationName, RelationReadQuery, RelationView, RelationshipAccessor, RelationshipDocument, ResolvedValidator, ResourceAccessors, ResourceDescriptor, ResourceEnvelope, ResourceHandle, ResourceIdentifier, ResourceLinks, ResourceObjectView, SchemaMap, SingleReadQuery, SortQuery, SortToken, StructuralGuardError, ToDocumentOptions, TransportRequest, TransportResponse, TypeAccessor, TypeName, TypedReadQuery, UpdateInput, ValidationConfig, ValidationOption, Validator, WireResource, WriteDocument, WriteOptions, assertJsonApiDocument, createClient, execute, fetchTransport, materialise, mediaType, relatedPaginatorKind, remapPointer, remapRelationshipPointer, resolveValidator, runAtomic, serializeQuery, toDocument, toRelationshipDocument, validateDocument, withRemappedAtomicPaths, withRemappedPaths, withRemappedRelationshipPaths };
|
|
219
|
+
export { ATOMIC_EXT, ATOMIC_MEDIA_TYPE, ActionDescriptor, ActionInput, ActionOutput, ActionScope, ActionsAccessor, ApiDescriptor, ArrayEnvelope, AtomicCreateHandle, AtomicCreateInput, AtomicDeleteHandle, AtomicDescriptor, AtomicHandle, AtomicRecorder, AtomicRef, AtomicResult, AtomicResultOf, AtomicResults, AtomicUpdateHandle, AtomicUpdateInput, CANONICAL_PAGE_KEYS, Cardinality, Client, ClientIdPolicy, ClientOptions, Collection, CountToken, CountableDescriptor, CreateInput, DefaultActionTypes, DefaultAttributes, DefaultWriteAttributes, Document, DocumentEnvelope, Edge, EdgeEnvelope, EdgeMembers, ErrorCodeGuard, ErrorCodeOf, ExactPageParams, FieldSelectionMap, FieldsMap, FilterKey, FilterQuery, HANDLE_RESERVED, HeadersInit, HydratedMember, IdentifierMember, IncludePath, IncludedRelations, JSON_API_MEDIA_TYPE, JsonApiContext, JsonApiError, JsonApiErrorObject, JsonApiRequest, JsonApiTransport, LinkageRef, ListPageParams, LocalIdentifier, MaterialiseContext, MediaTypeParams, MemberName, MenuDescriptor, NavigateOptions, Page, PageKeys, PageLinks, PageMeta, PageOf, PageParams, PageParamsOf, PaginatorDescriptor, PaginatorKind, PaginatorRole, PaginatorStrategy, PivotDescriptor, PivotInput, ReadQuery, ReadResult, ReadableRelationName, RelationDescriptor, RelationMutations, RelationName, RelationPageParams, RelationPaginator, RelationReadQuery, RelationView, RelationshipAccessor, RelationshipDocument, ResolvedPaginator, ResolvedValidator, ResourceAccessors, ResourceDescriptor, ResourceEnvelope, ResourceHandle, ResourceIdentifier, ResourceLinks, ResourceObjectView, SchemaMap, SingleReadQuery, SortQuery, SortToken, StrategyDescriptor, StructuralGuardError, ToDocumentOptions, TransportRequest, TransportResponse, TypeAccessor, TypeName, TypedPage, TypedReadQuery, UpdateInput, ValidationConfig, ValidationOption, Validator, WireResource, WriteDocument, WriteOptions, assertJsonApiDocument, createClient, execute, fetchTransport, hasErrorCode, materialise, mediaType, relatedPaginator, relatedPaginatorKind, remapPointer, remapRelationshipPointer, resolvePaginator, resolveValidator, runAtomic, serializeQuery, toDocument, toRelationshipDocument, validateDocument, withRemappedAtomicPaths, withRemappedPaths, withRemappedRelationshipPaths };
|
|
198
220
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors.ts","../src/serialize-write.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors.ts","../src/serialize-write.ts"],"mappings":";;;;;;AAOA;;;;UAAiB,kBAAA;EACf,EAAA;EACA,MAAA;EACA,IAAA,GAAO,CAAA;EACP,KAAA;EACA,MAAA;EACA,MAAA;IAAW,OAAA;IAAkB,SAAA;IAAoB,MAAA;EAAA;EACjD,IAAA,GAAO,MAAM;EAAN;;;;AAYA;EANP,IAAA;EAgBgC;;;;;EAVhC,OAAA;AAAA;AAW2B;AAa7B;;;;;;AAb6B,cADhB,oBAAA,SAA6B,KAAK;cACjC,OAAA;AAAA;;;;;;;;cAaD,YAAA,oCAAgD,KAAA;EAAA,SAClD,MAAA;EAAA,SACA,MAAA,EAAQ,kBAAA,CAAmB,CAAA;cAExB,MAAA,UAAgB,MAAA,EAAQ,kBAAA,CAAmB,CAAA,KAAM,OAAA;EAO7D,SAAA,CAAU,MAAA;EAIV,KAAA;EAIA,KAAA;EAIA,YAAA;EAIA,cAAA;EAIA,WAAA;EAIA,UAAA;EAIA,eAAA;EAIA,UAAA;EAIA,sBAAA;EAIA,eAAA;EApBA;EAyBA,iBAAA;EAIA,aAAA;EAjBA;;;;;EA0BA,MAAA,IAAU,MAAA,SAAe,kBAAA,CAAmB,CAAA;AAAA;;;;AAAC;AAgB/C;;iBAAgB,YAAA,CAAa,GAAA,WAAc,IAAA,WAAe,GAAA,IAAO,YAAY;;;;;;KASjE,cAAA,sBAAoC,GAAA,WAAc,IAAA,EAAM,CAAA,KAAM,GAAA,IAAO,YAAA,CAAa,CAAA;;;;;;;;UCpHpF,eAAA;EACR,IAAA;EACA,EAAA;EACA,GAAA;EACA,IAAA;IAAS,KAAA,EAAO,MAAA;EAAA,IAA4B,MAAM;AAAA;;UAInC,oBAAA;EACf,IAAA,EAAM,eAAA,GAAkB,eAAe;AAAA;;UAIxB,aAAA;EACf,IAAA;IACE,IAAA;IACA,EAAA;IACA,UAAA,GAAa,MAAA;IACb,aAAA,GAAgB,MAAA,SAAe,oBAAA;EAAA;AAAA;;UAKlB,iBAAA;EDoEU;;;;;EC9DzB,EAAE;AAAA;;;;;;;;;;;;;;;iBAiBY,UAAA,CACd,UAAA,EAAY,aAAA,EACZ,IAAA,UACA,KAAA,EAAO,MAAA,mBACP,IAAA,GAAO,iBAAA,GACN,aAAA;;;;;;;;;;;;;iBAgDa,sBAAA,CACd,IAAA,WACA,WAAA,mBACC,oBAAoB;;ADXwB;AAgB/C;;;;;;;;;AAA6E;AAS7E;;;;;;iBC6EgB,YAAA,CAAa,UAAA,EAAY,aAAa,EAAE,IAAA,UAAc,OAAA;;;;;;;;;;AD7EyB;;;;ACpI/B;;;;iBAiShD,wBAAA,CAAyB,GAAA,UAAa,QAAA,WAAmB,OAAA;;;;;;;iBAkBzD,iBAAA,CACd,KAAA,EAAO,YAAA,EACP,UAAA,EAAY,aAAA,EACZ,IAAA,WACC,YAAA;AAnSiD;AAIpD;;;;;;AAJoD,iBA8SpC,6BAAA,CACd,KAAA,EAAO,YAAA,EACP,GAAA,UACA,QAAA,YACC,YAAY;;AA7S0B;AAIzC;;;;;;;iBAsTgB,uBAAA,CACd,KAAA,EAAO,YAAA,EACP,UAAA,EAAY,aAAA,EACZ,SAAA,GAAY,OAAA,kCACX,YAAA"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as RelationshipAccessor, $t as ActionDescriptor, A as DefaultActionTypes, At as DocumentEnvelope, B as IdentifierMember, Bt as relatedPaginatorKind, C as fetchTransport, Ct as ATOMIC_MEDIA_TYPE, D as Collection, Dt as ResourceIdentifier, E as Client, Et as MediaTypeParams, F as FieldSelectionMap, Ft as RelationView, G as MemberName, Gt as PageLinks, H as IncludedRelations, Ht as ExactPageParams, I as FieldsMap, It as ResourceEnvelope, J as ReadableRelationName, Jt as PageParams, K as PivotInput, Kt as PageMeta, L as FilterKey, Lt as ResourceLinks, M as DefaultWriteAttributes, Mt as EdgeEnvelope, N as EdgeMembers, Nt as MaterialiseContext, O as CountToken, Ot as mediaType, P as ErrorCodeOf, Pt as NavigateOptions, Q as RelationReadQuery, Qt as resolvePaginator, R as FilterQuery, Rt as materialise, S as TransportResponse, St as ATOMIC_EXT, T as AtomicResultOf, Tt as LocalIdentifier, U as LinkageRef, Ut as Page, V as IncludePath, Vt as CANONICAL_PAGE_KEYS, W as ListPageParams, Wt as PageKeys, X as RelationPageParams, Xt as ResolvedPaginator, Y as RelationName, Yt as PageParamsOf, Z as RelationPaginator, Zt as TypedPage, _ as HANDLE_RESERVED, _n as StrategyDescriptor, _t as AtomicResult, a as Validator, an as Cardinality, at as SortToken, b as JsonApiTransport, bt as AtomicUpdateInput, c as resolveValidator, cn as MenuDescriptor, ct as TypedReadQuery, d as JsonApiContext, dn as PaginatorRole, dt as AtomicCreateHandle, en as ActionInput, et as ResourceAccessors, f as JsonApiRequest, fn as PaginatorStrategy, ft as AtomicCreateInput, g as ClientOptions, gn as ResourceDescriptor, gt as AtomicRef, h as serializeQuery, hn as RelationMutations, ht as AtomicRecorder, i as ValidationOption, in as AtomicDescriptor, it as SortQuery, j as DefaultAttributes, jt as Edge, k as CreateInput, kt as ArrayEnvelope, l as validateDocument, ln as PaginatorDescriptor, lt as UpdateInput, m as execute, mn as RelationDescriptor, mt as AtomicHandle, n as SchemaMap, nn as ActionScope, nt as ResourceObjectView, o as WireResource, on as ClientIdPolicy, ot as TypeAccessor, p as ReadQuery, pn as PivotDescriptor, pt as AtomicDeleteHandle, q as ReadResult, qt as PageOf, r as ValidationConfig, rn as ApiDescriptor, rt as SingleReadQuery, s as assertJsonApiDocument, sn as CountableDescriptor, st as TypeName, t as ResolvedValidator, tn as ActionOutput, tt as ResourceHandle, u as Document, un as PaginatorKind, ut as WriteOptions, v as HeadersInit, vt as AtomicResults, w as ActionsAccessor, wt as JSON_API_MEDIA_TYPE, x as TransportRequest, xt as runAtomic, y as createClient, yt as AtomicUpdateHandle, z as HydratedMember, zt as relatedPaginator } from "./validate-CJPivkqT.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/errors.d.ts
|
|
4
|
-
/**
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* A single JSON:API error object (spec: error objects).
|
|
6
|
+
*
|
|
7
|
+
* `C` is the server's documented error-code union (a generated client's `ErrorCode`). `code` is
|
|
8
|
+
* typed `C | (string & {})`: editors suggest the documented codes, yet any other string still
|
|
9
|
+
* fits, because the catalogue is open and a server may send a code it never documented.
|
|
10
|
+
*/
|
|
11
|
+
interface JsonApiErrorObject<C extends string = string> {
|
|
6
12
|
id?: string;
|
|
7
13
|
status?: string;
|
|
8
|
-
code?: string;
|
|
14
|
+
code?: C | (string & {});
|
|
9
15
|
title?: string;
|
|
10
16
|
detail?: string;
|
|
11
17
|
source?: {
|
|
@@ -40,11 +46,14 @@ declare class StructuralGuardError extends Error {
|
|
|
40
46
|
/**
|
|
41
47
|
* Thrown for any non-2xx JSON:API response. Carries the parsed error document plus
|
|
42
48
|
* expressive status matchers and pointer-grouping helpers.
|
|
49
|
+
*
|
|
50
|
+
* `C` types each error object's `code` (see {@link JsonApiErrorObject}). It is a compile-time
|
|
51
|
+
* hint only: the runtime never checks a code against it.
|
|
43
52
|
*/
|
|
44
|
-
declare class JsonApiError extends Error {
|
|
53
|
+
declare class JsonApiError<C extends string = string> extends Error {
|
|
45
54
|
readonly status: number;
|
|
46
|
-
readonly errors: JsonApiErrorObject[];
|
|
47
|
-
constructor(status: number, errors: JsonApiErrorObject[], message?: string);
|
|
55
|
+
readonly errors: JsonApiErrorObject<C>[];
|
|
56
|
+
constructor(status: number, errors: JsonApiErrorObject<C>[], message?: string);
|
|
48
57
|
hasStatus(status: number): boolean;
|
|
49
58
|
is4xx(): boolean;
|
|
50
59
|
is5xx(): boolean;
|
|
@@ -64,8 +73,21 @@ declare class JsonApiError extends Error {
|
|
|
64
73
|
* query parameter). The payoff for form/validation UX — 422 `source.pointer`s are
|
|
65
74
|
* remapped to the flat shape the caller actually supplied.
|
|
66
75
|
*/
|
|
67
|
-
byPath(): Record<string, JsonApiErrorObject[]>;
|
|
76
|
+
byPath(): Record<string, JsonApiErrorObject<C>[]>;
|
|
68
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* True when `err` is a {@link JsonApiError} and any of its error objects carries `code`. Takes
|
|
80
|
+
* any string, so it also matches codes the server never documented. A generated client exports a
|
|
81
|
+
* `hasErrorCode` bound to its server's `ErrorCode` union, which rejects a misspelt code at
|
|
82
|
+
* compile time; reach for this one only to match an undocumented code.
|
|
83
|
+
*/
|
|
84
|
+
declare function hasErrorCode(err: unknown, code: string): err is JsonApiError;
|
|
85
|
+
/**
|
|
86
|
+
* {@link hasErrorCode} restricted to one server's documented codes. A generated client binds it:
|
|
87
|
+
* `export const hasErrorCode = hasErrorCodeRuntime as ErrorCodeGuard<ErrorCode>`. The cast is
|
|
88
|
+
* needed because `JsonApiError<string>` doesn't assign to `JsonApiError<ErrorCode>`.
|
|
89
|
+
*/
|
|
90
|
+
type ErrorCodeGuard<C extends string> = (err: unknown, code: C) => err is JsonApiError<C>;
|
|
69
91
|
//#endregion
|
|
70
92
|
//#region src/serialize-write.d.ts
|
|
71
93
|
/**
|
|
@@ -194,5 +216,5 @@ declare function withRemappedRelationshipPaths(error: JsonApiError, rel: string,
|
|
|
194
216
|
*/
|
|
195
217
|
declare function withRemappedAtomicPaths(error: JsonApiError, descriptor: ApiDescriptor, typeForOp: (opIndex: number) => string | undefined): JsonApiError;
|
|
196
218
|
//#endregion
|
|
197
|
-
export { ATOMIC_EXT, ATOMIC_MEDIA_TYPE, ActionDescriptor, ActionInput, ActionOutput, ActionScope, ActionsAccessor, ApiDescriptor, ArrayEnvelope, AtomicCreateHandle, AtomicCreateInput, AtomicDeleteHandle, AtomicDescriptor, AtomicHandle, AtomicRecorder, AtomicRef, AtomicResult, AtomicResultOf, AtomicResults, AtomicUpdateHandle, AtomicUpdateInput, Cardinality, Client, ClientIdPolicy, ClientOptions, Collection, CountToken, CountableDescriptor, CreateInput, DefaultActionTypes, DefaultAttributes, DefaultWriteAttributes, Document, DocumentEnvelope, Edge, EdgeEnvelope, EdgeMembers, FieldSelectionMap, FieldsMap, FilterKey, FilterQuery, HANDLE_RESERVED, HeadersInit, HydratedMember, IdentifierMember, IncludePath, IncludedRelations, JSON_API_MEDIA_TYPE, JsonApiContext, JsonApiError, JsonApiErrorObject, JsonApiRequest, JsonApiTransport, LinkageRef, LocalIdentifier, MaterialiseContext, MediaTypeParams, MemberName, NavigateOptions, Page, PaginatorKind, PivotInput, ReadQuery, ReadResult, RelationDescriptor, RelationMutations, RelationName, RelationReadQuery, RelationView, RelationshipAccessor, RelationshipDocument, ResolvedValidator, ResourceAccessors, ResourceDescriptor, ResourceEnvelope, ResourceHandle, ResourceIdentifier, ResourceLinks, ResourceObjectView, SchemaMap, SingleReadQuery, SortQuery, SortToken, StructuralGuardError, ToDocumentOptions, TransportRequest, TransportResponse, TypeAccessor, TypeName, TypedReadQuery, UpdateInput, ValidationConfig, ValidationOption, Validator, WireResource, WriteDocument, WriteOptions, assertJsonApiDocument, createClient, execute, fetchTransport, materialise, mediaType, relatedPaginatorKind, remapPointer, remapRelationshipPointer, resolveValidator, runAtomic, serializeQuery, toDocument, toRelationshipDocument, validateDocument, withRemappedAtomicPaths, withRemappedPaths, withRemappedRelationshipPaths };
|
|
219
|
+
export { ATOMIC_EXT, ATOMIC_MEDIA_TYPE, ActionDescriptor, ActionInput, ActionOutput, ActionScope, ActionsAccessor, ApiDescriptor, ArrayEnvelope, AtomicCreateHandle, AtomicCreateInput, AtomicDeleteHandle, AtomicDescriptor, AtomicHandle, AtomicRecorder, AtomicRef, AtomicResult, AtomicResultOf, AtomicResults, AtomicUpdateHandle, AtomicUpdateInput, CANONICAL_PAGE_KEYS, Cardinality, Client, ClientIdPolicy, ClientOptions, Collection, CountToken, CountableDescriptor, CreateInput, DefaultActionTypes, DefaultAttributes, DefaultWriteAttributes, Document, DocumentEnvelope, Edge, EdgeEnvelope, EdgeMembers, ErrorCodeGuard, ErrorCodeOf, ExactPageParams, FieldSelectionMap, FieldsMap, FilterKey, FilterQuery, HANDLE_RESERVED, HeadersInit, HydratedMember, IdentifierMember, IncludePath, IncludedRelations, JSON_API_MEDIA_TYPE, JsonApiContext, JsonApiError, JsonApiErrorObject, JsonApiRequest, JsonApiTransport, LinkageRef, ListPageParams, LocalIdentifier, MaterialiseContext, MediaTypeParams, MemberName, MenuDescriptor, NavigateOptions, Page, PageKeys, PageLinks, PageMeta, PageOf, PageParams, PageParamsOf, PaginatorDescriptor, PaginatorKind, PaginatorRole, PaginatorStrategy, PivotDescriptor, PivotInput, ReadQuery, ReadResult, ReadableRelationName, RelationDescriptor, RelationMutations, RelationName, RelationPageParams, RelationPaginator, RelationReadQuery, RelationView, RelationshipAccessor, RelationshipDocument, ResolvedPaginator, ResolvedValidator, ResourceAccessors, ResourceDescriptor, ResourceEnvelope, ResourceHandle, ResourceIdentifier, ResourceLinks, ResourceObjectView, SchemaMap, SingleReadQuery, SortQuery, SortToken, StrategyDescriptor, StructuralGuardError, ToDocumentOptions, TransportRequest, TransportResponse, TypeAccessor, TypeName, TypedPage, TypedReadQuery, UpdateInput, ValidationConfig, ValidationOption, Validator, WireResource, WriteDocument, WriteOptions, assertJsonApiDocument, createClient, execute, fetchTransport, hasErrorCode, materialise, mediaType, relatedPaginator, relatedPaginatorKind, remapPointer, remapRelationshipPointer, resolvePaginator, resolveValidator, runAtomic, serializeQuery, toDocument, toRelationshipDocument, validateDocument, withRemappedAtomicPaths, withRemappedPaths, withRemappedRelationshipPaths };
|
|
198
220
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/errors.ts","../src/serialize-write.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/errors.ts","../src/serialize-write.ts"],"mappings":";;;;;;AAOA;;;;UAAiB,kBAAA;EACf,EAAA;EACA,MAAA;EACA,IAAA,GAAO,CAAA;EACP,KAAA;EACA,MAAA;EACA,MAAA;IAAW,OAAA;IAAkB,SAAA;IAAoB,MAAA;EAAA;EACjD,IAAA,GAAO,MAAM;EAAN;;;;AAYA;EANP,IAAA;EAgBgC;;;;;EAVhC,OAAA;AAAA;AAW2B;AAa7B;;;;;;AAb6B,cADhB,oBAAA,SAA6B,KAAK;cACjC,OAAA;AAAA;;;;;;;;cAaD,YAAA,oCAAgD,KAAA;EAAA,SAClD,MAAA;EAAA,SACA,MAAA,EAAQ,kBAAA,CAAmB,CAAA;cAExB,MAAA,UAAgB,MAAA,EAAQ,kBAAA,CAAmB,CAAA,KAAM,OAAA;EAO7D,SAAA,CAAU,MAAA;EAIV,KAAA;EAIA,KAAA;EAIA,YAAA;EAIA,cAAA;EAIA,WAAA;EAIA,UAAA;EAIA,eAAA;EAIA,UAAA;EAIA,sBAAA;EAIA,eAAA;EApBA;EAyBA,iBAAA;EAIA,aAAA;EAjBA;;;;;EA0BA,MAAA,IAAU,MAAA,SAAe,kBAAA,CAAmB,CAAA;AAAA;;;;AAAC;AAgB/C;;iBAAgB,YAAA,CAAa,GAAA,WAAc,IAAA,WAAe,GAAA,IAAO,YAAY;;;;;;KASjE,cAAA,sBAAoC,GAAA,WAAc,IAAA,EAAM,CAAA,KAAM,GAAA,IAAO,YAAA,CAAa,CAAA;;;;;;;;UCpHpF,eAAA;EACR,IAAA;EACA,EAAA;EACA,GAAA;EACA,IAAA;IAAS,KAAA,EAAO,MAAA;EAAA,IAA4B,MAAM;AAAA;;UAInC,oBAAA;EACf,IAAA,EAAM,eAAA,GAAkB,eAAe;AAAA;;UAIxB,aAAA;EACf,IAAA;IACE,IAAA;IACA,EAAA;IACA,UAAA,GAAa,MAAA;IACb,aAAA,GAAgB,MAAA,SAAe,oBAAA;EAAA;AAAA;;UAKlB,iBAAA;EDoEU;;;;;EC9DzB,EAAE;AAAA;;;;;;;;;;;;;;;iBAiBY,UAAA,CACd,UAAA,EAAY,aAAA,EACZ,IAAA,UACA,KAAA,EAAO,MAAA,mBACP,IAAA,GAAO,iBAAA,GACN,aAAA;;;;;;;;;;;;;iBAgDa,sBAAA,CACd,IAAA,WACA,WAAA,mBACC,oBAAoB;;ADXwB;AAgB/C;;;;;;;;;AAA6E;AAS7E;;;;;;iBC6EgB,YAAA,CAAa,UAAA,EAAY,aAAa,EAAE,IAAA,UAAc,OAAA;;;;;;;;;;AD7EyB;;;;ACpI/B;;;;iBAiShD,wBAAA,CAAyB,GAAA,UAAa,QAAA,WAAmB,OAAA;;;;;;;iBAkBzD,iBAAA,CACd,KAAA,EAAO,YAAA,EACP,UAAA,EAAY,aAAA,EACZ,IAAA,WACC,YAAA;AAnSiD;AAIpD;;;;;;AAJoD,iBA8SpC,6BAAA,CACd,KAAA,EAAO,YAAA,EACP,GAAA,UACA,QAAA,YACC,YAAY;;AA7S0B;AAIzC;;;;;;;iBAsTgB,uBAAA,CACd,KAAA,EAAO,YAAA,EACP,UAAA,EAAY,aAAA,EACZ,SAAA,GAAY,OAAA,kCACX,YAAA"}
|