@haddowg/json-api-client 1.3.0 → 1.4.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 +6 -0
- package/dist/ajv.d.cts +1 -1
- package/dist/ajv.d.mts +1 -1
- package/dist/index.cjs +199 -28
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +199 -29
- package/dist/index.mjs.map +1 -1
- package/dist/{validate-CJPivkqT.d.cts → validate-CQv5lmqO.d.cts} +218 -21
- package/dist/validate-CQv5lmqO.d.cts.map +1 -0
- package/dist/{validate-CJPivkqT.d.mts → validate-CQv5lmqO.d.mts} +218 -21
- package/dist/validate-CQv5lmqO.d.mts.map +1 -0
- package/package.json +1 -1
- package/dist/validate-CJPivkqT.d.cts.map +0 -1
- package/dist/validate-CJPivkqT.d.mts.map +0 -1
package/README.md
CHANGED
|
@@ -297,6 +297,12 @@ Retries are deliberately out of scope here — the transport (or the TanStack la
|
|
|
297
297
|
or `$next({ signal })`). Forward it to your HTTP library so the request can be cancelled; the
|
|
298
298
|
default `fetch` transport passes it to `fetch`.
|
|
299
299
|
|
|
300
|
+
Two optional members matter only for custom actions with non-JSON:API media types. Send
|
|
301
|
+
`req.rawBody` as is when it's set: a binary, `FormData` or `URLSearchParams` body in place of
|
|
302
|
+
`req.body`. When `req.responseType` is `'blob'` or `'arraybuffer'`, read a successful response
|
|
303
|
+
into `binary` as that type and leave `body` empty; read an error response as text in `body` as
|
|
304
|
+
usual. The `fetch` transport does both.
|
|
305
|
+
|
|
300
306
|
## Opt-in validation
|
|
301
307
|
|
|
302
308
|
The core runtime trusts the wire (you own both ends; the envelope is invariant) and only runs the
|
package/dist/ajv.d.cts
CHANGED
package/dist/ajv.d.mts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -540,18 +540,37 @@ const ATOMIC_MEDIA_TYPE = mediaType({ ext: [ATOMIC_EXT] });
|
|
|
540
540
|
//#region src/request.ts
|
|
541
541
|
const isAbsolute = (path) => /^https?:\/\//i.test(path);
|
|
542
542
|
const RELATIVE_ORIGIN = "http://relative.invalid";
|
|
543
|
-
/**
|
|
543
|
+
/**
|
|
544
|
+
* Resolve a server link against `baseUrl` per RFC 3986 and check where it lands. A link on the
|
|
545
|
+
* base's origin is followed; a relative base (e.g. `/api`) takes the page's origin in a browser and
|
|
546
|
+
* otherwise only accepts a link that keeps the host. Anything that isn't plain http(s) is refused.
|
|
547
|
+
*/
|
|
544
548
|
function resolveLink(link, baseUrl) {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
+
let normalised = link.replace(/[\t\n\r]/g, "");
|
|
550
|
+
let start = 0;
|
|
551
|
+
while (start < normalised.length && normalised.charCodeAt(start) <= 32) start++;
|
|
552
|
+
normalised = normalised.slice(start);
|
|
553
|
+
const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(normalised)?.[1]?.toLowerCase();
|
|
554
|
+
if (scheme !== void 0 && scheme !== "http" && scheme !== "https") throw new Error(`Refusing to follow link "${link}": only http(s) links are followed`);
|
|
555
|
+
const relativeBase = !isAbsolute(baseUrl);
|
|
556
|
+
const page = globalThis.location?.href;
|
|
557
|
+
const base = new URL(baseUrl, relativeBase ? typeof page === "string" ? page : RELATIVE_ORIGIN : void 0);
|
|
558
|
+
const resolved = new URL(link, base);
|
|
559
|
+
const sameOrigin = resolved.origin === base.origin && (scheme === void 0 || /^https?:\/\//i.test(normalised));
|
|
560
|
+
if (!sameOrigin) return {
|
|
561
|
+
url: resolved.href,
|
|
562
|
+
sameOrigin
|
|
563
|
+
};
|
|
564
|
+
return {
|
|
565
|
+
url: relativeBase ? resolved.pathname + resolved.search + resolved.hash : resolved.href,
|
|
566
|
+
sameOrigin
|
|
567
|
+
};
|
|
549
568
|
}
|
|
550
569
|
const append = (parts, key, value) => {
|
|
551
570
|
if (value === void 0 || value === null || value === "") return;
|
|
552
571
|
parts.push(`${key}=${encodeURIComponent(String(value))}`);
|
|
553
572
|
};
|
|
554
|
-
const isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
573
|
+
const isPlainObject$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
555
574
|
/**
|
|
556
575
|
* Append a filter value under its (already-bracketed) key. A plain object is a STRUCTURED filter
|
|
557
576
|
* value — a `Range`/`DateRange` deepObject (`{ min, max }`) — and recurses into nested bracketed
|
|
@@ -560,7 +579,7 @@ const isPlainObject = (value) => typeof value === "object" && value !== null &&
|
|
|
560
579
|
* wire as `filter[k]=[object Object]` and be silently ignored by the server (D23).
|
|
561
580
|
*/
|
|
562
581
|
const appendFilterValue = (parts, key, value) => {
|
|
563
|
-
if (isPlainObject(value)) {
|
|
582
|
+
if (isPlainObject$1(value)) {
|
|
564
583
|
for (const [subKey, subValue] of Object.entries(value)) appendFilterValue(parts, `${key}[${subKey}]`, subValue);
|
|
565
584
|
return;
|
|
566
585
|
}
|
|
@@ -583,14 +602,37 @@ function serializeQuery(query) {
|
|
|
583
602
|
return parts.join("&");
|
|
584
603
|
}
|
|
585
604
|
/**
|
|
586
|
-
* Execute a request: build the URL (a server link resolved against `baseUrl
|
|
587
|
-
* verbatim, else `baseUrl + path`), apply content negotiation and any async per-request headers,
|
|
605
|
+
* Execute a request: build the URL (a server link resolved against `baseUrl` and held to its
|
|
606
|
+
* origin, an absolute path verbatim, else `baseUrl + path`), apply content negotiation and any async per-request headers,
|
|
588
607
|
* then drive the transport. A 2xx with a body parses to a {@link Document}; an empty /
|
|
589
608
|
* 204 body resolves to `undefined`. A non-2xx throws a {@link JsonApiError} carrying the
|
|
590
609
|
* parsed error objects (tolerating a non-JSON error body with an empty list).
|
|
591
610
|
*/
|
|
592
611
|
async function execute(ctx, req) {
|
|
593
|
-
|
|
612
|
+
return parseDocument((await send(ctx, req)).body);
|
|
613
|
+
}
|
|
614
|
+
async function executeRaw(ctx, req, as) {
|
|
615
|
+
const res = await send(ctx, req, as === "text" ? void 0 : as);
|
|
616
|
+
if (as === "text") return res.body === "" ? void 0 : res.body;
|
|
617
|
+
if (res.status === 204) return;
|
|
618
|
+
if (res.binary === void 0) throw new Error("The transport returned no binary body for a request that asked for one; a custom transport must read the response as binary when the request sets responseType.");
|
|
619
|
+
return res.binary;
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Build the URL (a server link resolved against `baseUrl` and held to its origin, an absolute
|
|
623
|
+
* path verbatim, else `baseUrl + path`), apply content negotiation and any async per-request
|
|
624
|
+
* headers, then drive the transport. A non-2xx throws a {@link JsonApiError} carrying the parsed
|
|
625
|
+
* error objects (tolerating a non-JSON error body with an empty list).
|
|
626
|
+
*/
|
|
627
|
+
async function send(ctx, req, responseType) {
|
|
628
|
+
let url;
|
|
629
|
+
let sendHeaders = true;
|
|
630
|
+
if (req.link) {
|
|
631
|
+
const link = resolveLink(req.path, ctx.baseUrl);
|
|
632
|
+
if (!link.sameOrigin && ctx.allowCrossOriginLinks !== true) throw new Error(`Refusing to follow link "${req.path}": it leaves the base URL's origin (set allowCrossOriginLinks to follow it without the configured headers)`);
|
|
633
|
+
url = link.url;
|
|
634
|
+
sendHeaders = link.sameOrigin;
|
|
635
|
+
} else url = isAbsolute(req.path) ? req.path : ctx.baseUrl + req.path;
|
|
594
636
|
if (req.query) {
|
|
595
637
|
const qs = serializeQuery(req.query);
|
|
596
638
|
if (qs) url += (url.includes("?") ? "&" : "?") + qs;
|
|
@@ -606,15 +648,23 @@ async function execute(ctx, req) {
|
|
|
606
648
|
headers
|
|
607
649
|
};
|
|
608
650
|
if (req.signal !== void 0) transportReq.signal = req.signal;
|
|
609
|
-
if (
|
|
610
|
-
|
|
611
|
-
|
|
651
|
+
if (responseType !== void 0) transportReq.responseType = responseType;
|
|
652
|
+
if (req.body !== void 0 || req.method.toUpperCase() === "POST") {
|
|
653
|
+
const contentType = req.contentType === void 0 ? negotiated : req.contentType;
|
|
654
|
+
if (contentType !== null) headers["Content-Type"] = contentType;
|
|
612
655
|
}
|
|
613
|
-
if (
|
|
656
|
+
if (typeof req.body === "string" && req.raw) transportReq.body = req.body;
|
|
657
|
+
else if (req.raw && isRawBody(req.body)) transportReq.rawBody = req.body;
|
|
658
|
+
else if (req.body !== void 0) transportReq.body = JSON.stringify(req.body);
|
|
659
|
+
if (ctx.headers && sendHeaders) mergeHeaders(headers, await ctx.headers());
|
|
614
660
|
const res = await ctx.transport(transportReq);
|
|
615
|
-
if (res.status >= 200 && res.status < 300) return
|
|
661
|
+
if (res.status >= 200 && res.status < 300) return res;
|
|
616
662
|
throw new JsonApiError(res.status, parseErrors(res.body));
|
|
617
663
|
}
|
|
664
|
+
/** Whether a raw body goes to the transport as is rather than through `JSON.stringify`. */
|
|
665
|
+
function isRawBody(body) {
|
|
666
|
+
return typeof Blob !== "undefined" && body instanceof Blob || body instanceof ArrayBuffer || ArrayBuffer.isView(body) || typeof FormData !== "undefined" && body instanceof FormData || typeof URLSearchParams !== "undefined" && body instanceof URLSearchParams;
|
|
667
|
+
}
|
|
618
668
|
/**
|
|
619
669
|
* Merge a `HeadersInit` (object / tuple array / `Headers`) into the outgoing map,
|
|
620
670
|
* preserving the caller's casing (unlike the WHATWG `Headers`, which lowercases). The
|
|
@@ -1002,13 +1052,23 @@ const fetchTransport = async (req) => {
|
|
|
1002
1052
|
method: req.method,
|
|
1003
1053
|
headers: req.headers
|
|
1004
1054
|
};
|
|
1005
|
-
if (req.
|
|
1055
|
+
if (req.rawBody !== void 0) init.body = req.rawBody;
|
|
1056
|
+
else if (req.body !== void 0) init.body = req.body;
|
|
1006
1057
|
if (req.signal !== void 0) init.signal = req.signal;
|
|
1007
1058
|
const res = await fetch(req.url, init);
|
|
1008
1059
|
const headers = {};
|
|
1009
1060
|
res.headers.forEach((value, key) => {
|
|
1010
1061
|
headers[key] = value;
|
|
1011
1062
|
});
|
|
1063
|
+
if (req.responseType !== void 0 && res.ok) {
|
|
1064
|
+
const binary = req.responseType === "blob" ? await res.blob() : await res.arrayBuffer();
|
|
1065
|
+
return {
|
|
1066
|
+
status: res.status,
|
|
1067
|
+
headers,
|
|
1068
|
+
body: "",
|
|
1069
|
+
binary
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1012
1072
|
return {
|
|
1013
1073
|
status: res.status,
|
|
1014
1074
|
headers,
|
|
@@ -1119,36 +1179,145 @@ async function runWrite(ctx, spec) {
|
|
|
1119
1179
|
* - `raw` — the caller's payload, sent with the action's declared media type (e.g.
|
|
1120
1180
|
* `application/octet-stream`), falling back to a wildcard when the spec declared none.
|
|
1121
1181
|
*
|
|
1182
|
+
* An action listing several request media types (`inputMedia`) sends the one the caller picks
|
|
1183
|
+
* with `options.contentType`, or JSON:API when listed, else the first.
|
|
1184
|
+
*
|
|
1122
1185
|
* The response is shaped by the action's `output`: `document` materialises into the resource /
|
|
1123
1186
|
* collection view, `meta` returns the document's top-level `meta`, `none` resolves `undefined` (a
|
|
1124
|
-
* `204` / no body).
|
|
1187
|
+
* `204` / no body). An action declaring `rawOutput` answers in the media type the caller picks
|
|
1188
|
+
* with `options.accept`: JSON:API as above, or a `string`, a `Blob` or `ArrayBuffer`, or parsed
|
|
1189
|
+
* JSON by the media type's kind.
|
|
1125
1190
|
*/
|
|
1126
|
-
async function runAction(ctx, action, vars, input) {
|
|
1191
|
+
async function runAction(ctx, action, vars, input, options = {}) {
|
|
1127
1192
|
const req = {
|
|
1128
1193
|
method: action.method ?? "POST",
|
|
1129
1194
|
path: fill(action.path, vars)
|
|
1130
1195
|
};
|
|
1196
|
+
if (options.signal !== void 0) req.signal = options.signal;
|
|
1131
1197
|
let remap;
|
|
1132
|
-
|
|
1198
|
+
const media = requestMedia(action, options.contentType);
|
|
1199
|
+
if (media !== void 0 && media.kind !== "document") {
|
|
1200
|
+
req.body = encodeFields(media.mediaType, media.kind, input);
|
|
1201
|
+
req.raw = true;
|
|
1202
|
+
req.contentType = sentContentType(media.mediaType, media.kind, req.body);
|
|
1203
|
+
} else if (action.input === "document") if (action.inputType !== void 0) {
|
|
1133
1204
|
const inputType = action.inputType;
|
|
1134
1205
|
req.body = toDocument(ctx.descriptor, inputType, input ?? {});
|
|
1135
1206
|
remap = (error) => withRemappedPaths(error, ctx.descriptor, inputType);
|
|
1136
1207
|
} else req.body = input;
|
|
1137
1208
|
else if (action.input === "raw") {
|
|
1138
|
-
req.body = input;
|
|
1139
|
-
req.contentType = action.contentType ?? "*/*";
|
|
1209
|
+
req.body = encodeFields(action.contentType ?? "*/*", void 0, input);
|
|
1210
|
+
req.contentType = sentContentType(action.contentType ?? "*/*", void 0, req.body);
|
|
1140
1211
|
req.raw = true;
|
|
1141
1212
|
}
|
|
1142
|
-
|
|
1213
|
+
const raw = responseMedia(action, options.accept);
|
|
1143
1214
|
try {
|
|
1144
|
-
|
|
1215
|
+
if (raw !== void 0) {
|
|
1216
|
+
req.accept = raw.mediaType;
|
|
1217
|
+
if (raw.kind === "binary") return await executeRaw(ctx.request, req, options.responseType === "arrayBuffer" ? "arraybuffer" : "blob");
|
|
1218
|
+
const text = await executeRaw(ctx.request, req, "text");
|
|
1219
|
+
return raw.kind === "json" && text !== void 0 ? JSON.parse(text) : text;
|
|
1220
|
+
}
|
|
1221
|
+
const doc = await execute(ctx.request, req);
|
|
1222
|
+
if (action.output === "none" || doc === void 0) return;
|
|
1223
|
+
if (action.output === "meta") return doc.meta;
|
|
1224
|
+
return materialise(doc, ctx.materialise);
|
|
1145
1225
|
} catch (error) {
|
|
1146
1226
|
if (remap !== void 0 && error instanceof JsonApiError) throw remap(error);
|
|
1147
1227
|
throw error;
|
|
1148
1228
|
}
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1229
|
+
}
|
|
1230
|
+
/**
|
|
1231
|
+
* The request media type an action with several (`inputMedia`) sends: the caller's pick, matched
|
|
1232
|
+
* exactly or through a declared wildcard such as `image/*`, else JSON:API when listed, else the
|
|
1233
|
+
* first. `undefined` for an action with a single request media type.
|
|
1234
|
+
*/
|
|
1235
|
+
function requestMedia(action, picked) {
|
|
1236
|
+
const listed = action.inputMedia;
|
|
1237
|
+
if (listed === void 0 || listed.length === 0) {
|
|
1238
|
+
if (picked !== void 0) throw new Error(`This action declares no request media types to choose "${picked}" from.`);
|
|
1239
|
+
return;
|
|
1240
|
+
}
|
|
1241
|
+
if (picked === void 0) {
|
|
1242
|
+
const media = listed.find((entry) => entry.mediaType === "application/vnd.api+json") ?? listed[0];
|
|
1243
|
+
return {
|
|
1244
|
+
mediaType: media.mediaType,
|
|
1245
|
+
kind: media.kind
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
const essence = picked.split(";")[0].trim().toLowerCase();
|
|
1249
|
+
const match = listed.find((entry) => entry.mediaType === essence) ?? listed.find((entry) => entry.mediaType === `${essence.split("/")[0]}/*`) ?? listed.find((entry) => entry.mediaType === "*/*");
|
|
1250
|
+
if (match === void 0) throw new Error(`This action does not accept "${picked}"; it accepts ${listed.map((entry) => entry.mediaType).join(", ")}.`);
|
|
1251
|
+
return {
|
|
1252
|
+
mediaType: picked,
|
|
1253
|
+
kind: match.kind
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
/**
|
|
1257
|
+
* A multipart or URL-encoded body given as a plain object of fields, encoded into a `FormData` or
|
|
1258
|
+
* `URLSearchParams`. Any other body, a ready `FormData` included, is sent as it is.
|
|
1259
|
+
*/
|
|
1260
|
+
function encodeFields(mediaType, kind, body) {
|
|
1261
|
+
const multipart = kind === "multipart" || mediaType.startsWith("multipart/");
|
|
1262
|
+
if (!multipart && !(kind === "form" || mediaType === "application/x-www-form-urlencoded") || !isPlainObject(body)) return body;
|
|
1263
|
+
return multipart ? toFormData(body) : toSearchParams(body);
|
|
1264
|
+
}
|
|
1265
|
+
/** Whether a body is a plain object of fields rather than a ready payload. */
|
|
1266
|
+
function isPlainObject(value) {
|
|
1267
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
1268
|
+
const proto = Object.getPrototypeOf(value);
|
|
1269
|
+
return proto === Object.prototype || proto === null;
|
|
1270
|
+
}
|
|
1271
|
+
/**
|
|
1272
|
+
* The entries a field contributes: nothing for `null` or `undefined`, one `name[]` entry per item
|
|
1273
|
+
* for an array (the bracket suffix is how PHP servers read a repeated field as a list), else one
|
|
1274
|
+
* `name` entry.
|
|
1275
|
+
*/
|
|
1276
|
+
function fieldEntries(name, value) {
|
|
1277
|
+
if (value === null || value === void 0) return [];
|
|
1278
|
+
if (Array.isArray(value)) return value.filter((item) => item !== null && item !== void 0).map((item) => [`${name}[]`, item]);
|
|
1279
|
+
return [[name, value]];
|
|
1280
|
+
}
|
|
1281
|
+
/** A field's text value: booleans as `true` or `false`, everything else through `String`. */
|
|
1282
|
+
function fieldText(value) {
|
|
1283
|
+
return typeof value === "boolean" ? value ? "true" : "false" : String(value);
|
|
1284
|
+
}
|
|
1285
|
+
/** A multipart body from fields. A `File` keeps its name; a bare `Blob` is named after its field. */
|
|
1286
|
+
function toFormData(fields) {
|
|
1287
|
+
const data = new FormData();
|
|
1288
|
+
for (const [field, value] of Object.entries(fields)) for (const [name, item] of fieldEntries(field, value)) if (typeof Blob !== "undefined" && item instanceof Blob) {
|
|
1289
|
+
const fileName = typeof File !== "undefined" && item instanceof File && item.name !== "" ? item.name : field;
|
|
1290
|
+
data.append(name, item, fileName);
|
|
1291
|
+
} else data.append(name, fieldText(item));
|
|
1292
|
+
return data;
|
|
1293
|
+
}
|
|
1294
|
+
/** A URL-encoded body from fields. */
|
|
1295
|
+
function toSearchParams(fields) {
|
|
1296
|
+
const params = new URLSearchParams();
|
|
1297
|
+
for (const [field, value] of Object.entries(fields)) for (const [name, item] of fieldEntries(field, value)) params.append(name, fieldText(item));
|
|
1298
|
+
return params;
|
|
1299
|
+
}
|
|
1300
|
+
/**
|
|
1301
|
+
* The `Content-Type` for a non-JSON:API body. A multipart `FormData` body gets none, so the
|
|
1302
|
+
* transport writes the boundary. A wildcard media type takes a `Blob` body's own type.
|
|
1303
|
+
*/
|
|
1304
|
+
function sentContentType(mediaType, kind, body) {
|
|
1305
|
+
if ((kind === "multipart" || mediaType.startsWith("multipart/")) && typeof FormData !== "undefined" && body instanceof FormData) return null;
|
|
1306
|
+
if (mediaType.includes("*") && typeof Blob !== "undefined" && body instanceof Blob) return body.type === "" ? mediaType : body.type;
|
|
1307
|
+
return mediaType;
|
|
1308
|
+
}
|
|
1309
|
+
/**
|
|
1310
|
+
* The non-JSON:API media type an action is asked to answer in: the caller's `accept` when it isn't
|
|
1311
|
+
* JSON:API, else, with no `accept`, the first raw media type of an action that answers in no
|
|
1312
|
+
* JSON:API document. `undefined` means a JSON:API response.
|
|
1313
|
+
*/
|
|
1314
|
+
function responseMedia(action, accept) {
|
|
1315
|
+
const raw = action.rawOutput ?? [];
|
|
1316
|
+
if (accept === void 0) return action.output === "none" ? raw[0] : void 0;
|
|
1317
|
+
if (accept === "application/vnd.api+json") return;
|
|
1318
|
+
const media = raw.find((entry) => entry.mediaType === accept);
|
|
1319
|
+
if (media === void 0) throw new Error(`This action does not answer in "${accept}"; it answers in ${[...action.output === "none" ? [] : [JSON_API_MEDIA_TYPE], ...raw.map((entry) => entry.mediaType)].join(", ")}.`);
|
|
1320
|
+
return media;
|
|
1152
1321
|
}
|
|
1153
1322
|
/**
|
|
1154
1323
|
* Build the typed `.actions` accessor at one scope: a plain object exposing exactly the
|
|
@@ -1160,7 +1329,7 @@ async function runAction(ctx, action, vars, input) {
|
|
|
1160
1329
|
function actionsAccessor(ctx, type, scope, vars) {
|
|
1161
1330
|
const actions = ctx.descriptor[type]?.actions ?? {};
|
|
1162
1331
|
const out = {};
|
|
1163
|
-
for (const [name, action] of Object.entries(actions)) if (action.scope === scope) out[name] = (
|
|
1332
|
+
for (const [name, action] of Object.entries(actions)) if (action.scope === scope) out[name] = (...args) => action.input === "none" ? runAction(ctx, action, vars, void 0, args[0]) : runAction(ctx, action, vars, args[0], args[1]);
|
|
1164
1333
|
return out;
|
|
1165
1334
|
}
|
|
1166
1335
|
/**
|
|
@@ -1280,7 +1449,8 @@ function createClient(descriptor, options) {
|
|
|
1280
1449
|
const request = {
|
|
1281
1450
|
baseUrl: options.baseUrl,
|
|
1282
1451
|
transport: options.transport ?? fetchTransport,
|
|
1283
|
-
...options.headers !== void 0 ? { headers: options.headers } : {}
|
|
1452
|
+
...options.headers !== void 0 ? { headers: options.headers } : {},
|
|
1453
|
+
...options.allowCrossOriginLinks !== void 0 ? { allowCrossOriginLinks: options.allowCrossOriginLinks } : {}
|
|
1284
1454
|
};
|
|
1285
1455
|
const validator = resolveValidator(options.validate);
|
|
1286
1456
|
const ctx = {
|
|
@@ -1333,6 +1503,7 @@ exports.StructuralGuardError = StructuralGuardError;
|
|
|
1333
1503
|
exports.assertJsonApiDocument = assertJsonApiDocument;
|
|
1334
1504
|
exports.createClient = createClient;
|
|
1335
1505
|
exports.execute = execute;
|
|
1506
|
+
exports.executeRaw = executeRaw;
|
|
1336
1507
|
exports.fetchTransport = fetchTransport;
|
|
1337
1508
|
exports.hasErrorCode = hasErrorCode;
|
|
1338
1509
|
exports.materialise = materialise;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as ReadResult, $t as PageOf, A as BinaryBody, At as JSON_API_MEDIA_TYPE, B as ErrorCodeOf, Bt as NavigateOptions, C as TransportRawBody, Cn as RawOutputMedia, Ct as AtomicResult, D as ActionCallOptions, Dn as StrategyDescriptor, Dt as runAtomic, E as fetchTransport, En as ResourceDescriptor, Et as AtomicUpdateInput, F as CreateInput, Ft as ArrayEnvelope, G as HydratedMember, Gt as relatedPaginator, H as FieldsMap, Ht as ResourceEnvelope, I as DefaultActionTypes, It as DocumentEnvelope, J as IncludedRelations, Jt as ExactPageParams, K as IdentifierMember, Kt as relatedPaginatorKind, L as DefaultAttributes, Lt as Edge, M as Client, Mt as MediaTypeParams, N as Collection, Nt as ResourceIdentifier, O as ActionsAccessor, Ot as ATOMIC_EXT, P as CountToken, Pt as mediaType, Q as PivotInput, Qt as PageMeta, R as DefaultWriteAttributes, Rt as EdgeEnvelope, S as JsonApiTransport, Sn as RawMediaKind, St as AtomicRef, T as TransportResponse, Tn as RelationMutations, Tt as AtomicUpdateHandle, U as FilterKey, Ut as ResourceLinks, V as FieldSelectionMap, Vt as RelationView, W as FilterQuery, Wt as materialise, X as ListPageParams, Xt as PageKeys, Y as LinkageRef, Yt as Page, Z as MemberName, Zt as PageLinks, _ as serializeQuery, _n as PaginatorDescriptor, _t as AtomicCreateHandle, a as Validator, an as ActionDescriptor, at as RelationshipAccessor, b as HeadersInit, bn as PaginatorStrategy, bt as AtomicHandle, c as resolveValidator, cn as ActionScope, ct as ResourceObjectView, d as JsonApiContext, dn as Cardinality, dt as SortToken, en as PageParams, et as ReadableRelationName, f as JsonApiRequest, fn as ClientIdPolicy, ft as TypeAccessor, g as executeRaw, gn as MenuDescriptor, gt as WriteOptions, h as execute, hn as InputMediaKind, ht as UpdateInput, i as ValidationOption, in as resolvePaginator, it as RelationReadQuery, j as BinaryResponseType, jt as LocalIdentifier, k as AtomicResultOf, kt as ATOMIC_MEDIA_TYPE, l as validateDocument, ln as ApiDescriptor, lt as SingleReadQuery, m as ReadQuery, mn as InputMedia, mt as TypedReadQuery, n as SchemaMap, nn as ResolvedPaginator, nt as RelationPageParams, o as WireResource, on as ActionInput, ot as ResourceAccessors, p as RawResponseType, pn as CountableDescriptor, pt as TypeName, q as IncludePath, qt as CANONICAL_PAGE_KEYS, r as ValidationConfig, rn as TypedPage, rt as RelationPaginator, s as assertJsonApiDocument, sn as ActionOutput, st as ResourceHandle, t as ResolvedValidator, tn as PageParamsOf, tt as RelationName, u as Document, un as AtomicDescriptor, ut as SortQuery, v as ClientOptions, vn as PaginatorKind, vt as AtomicCreateInput, w as TransportRequest, wn as RelationDescriptor, wt as AtomicResults, x as createClient, xn as PivotDescriptor, xt as AtomicRecorder, y as HANDLE_RESERVED, yn as PaginatorRole, yt as AtomicDeleteHandle, z as EdgeMembers, zt as MaterialiseContext } from "./validate-CQv5lmqO.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/errors.d.ts
|
|
4
4
|
/**
|
|
@@ -216,5 +216,5 @@ declare function withRemappedRelationshipPaths(error: JsonApiError, rel: string,
|
|
|
216
216
|
*/
|
|
217
217
|
declare function withRemappedAtomicPaths(error: JsonApiError, descriptor: ApiDescriptor, typeForOp: (opIndex: number) => string | undefined): JsonApiError;
|
|
218
218
|
//#endregion
|
|
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 };
|
|
219
|
+
export { ATOMIC_EXT, ATOMIC_MEDIA_TYPE, ActionCallOptions, ActionDescriptor, ActionInput, ActionOutput, ActionScope, ActionsAccessor, ApiDescriptor, ArrayEnvelope, AtomicCreateHandle, AtomicCreateInput, AtomicDeleteHandle, AtomicDescriptor, AtomicHandle, AtomicRecorder, AtomicRef, AtomicResult, AtomicResultOf, AtomicResults, AtomicUpdateHandle, AtomicUpdateInput, BinaryBody, BinaryResponseType, 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, InputMedia, InputMediaKind, 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, RawMediaKind, RawOutputMedia, RawResponseType, 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, TransportRawBody, TransportRequest, TransportResponse, TypeAccessor, TypeName, TypedPage, TypedReadQuery, UpdateInput, ValidationConfig, ValidationOption, Validator, WireResource, WriteDocument, WriteOptions, assertJsonApiDocument, createClient, execute, executeRaw, fetchTransport, hasErrorCode, materialise, mediaType, relatedPaginator, relatedPaginatorKind, remapPointer, remapRelationshipPointer, resolvePaginator, resolveValidator, runAtomic, serializeQuery, toDocument, toRelationshipDocument, validateDocument, withRemappedAtomicPaths, withRemappedPaths, withRemappedRelationshipPaths };
|
|
220
220
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as ReadResult, $t as PageOf, A as BinaryBody, At as JSON_API_MEDIA_TYPE, B as ErrorCodeOf, Bt as NavigateOptions, C as TransportRawBody, Cn as RawOutputMedia, Ct as AtomicResult, D as ActionCallOptions, Dn as StrategyDescriptor, Dt as runAtomic, E as fetchTransport, En as ResourceDescriptor, Et as AtomicUpdateInput, F as CreateInput, Ft as ArrayEnvelope, G as HydratedMember, Gt as relatedPaginator, H as FieldsMap, Ht as ResourceEnvelope, I as DefaultActionTypes, It as DocumentEnvelope, J as IncludedRelations, Jt as ExactPageParams, K as IdentifierMember, Kt as relatedPaginatorKind, L as DefaultAttributes, Lt as Edge, M as Client, Mt as MediaTypeParams, N as Collection, Nt as ResourceIdentifier, O as ActionsAccessor, Ot as ATOMIC_EXT, P as CountToken, Pt as mediaType, Q as PivotInput, Qt as PageMeta, R as DefaultWriteAttributes, Rt as EdgeEnvelope, S as JsonApiTransport, Sn as RawMediaKind, St as AtomicRef, T as TransportResponse, Tn as RelationMutations, Tt as AtomicUpdateHandle, U as FilterKey, Ut as ResourceLinks, V as FieldSelectionMap, Vt as RelationView, W as FilterQuery, Wt as materialise, X as ListPageParams, Xt as PageKeys, Y as LinkageRef, Yt as Page, Z as MemberName, Zt as PageLinks, _ as serializeQuery, _n as PaginatorDescriptor, _t as AtomicCreateHandle, a as Validator, an as ActionDescriptor, at as RelationshipAccessor, b as HeadersInit, bn as PaginatorStrategy, bt as AtomicHandle, c as resolveValidator, cn as ActionScope, ct as ResourceObjectView, d as JsonApiContext, dn as Cardinality, dt as SortToken, en as PageParams, et as ReadableRelationName, f as JsonApiRequest, fn as ClientIdPolicy, ft as TypeAccessor, g as executeRaw, gn as MenuDescriptor, gt as WriteOptions, h as execute, hn as InputMediaKind, ht as UpdateInput, i as ValidationOption, in as resolvePaginator, it as RelationReadQuery, j as BinaryResponseType, jt as LocalIdentifier, k as AtomicResultOf, kt as ATOMIC_MEDIA_TYPE, l as validateDocument, ln as ApiDescriptor, lt as SingleReadQuery, m as ReadQuery, mn as InputMedia, mt as TypedReadQuery, n as SchemaMap, nn as ResolvedPaginator, nt as RelationPageParams, o as WireResource, on as ActionInput, ot as ResourceAccessors, p as RawResponseType, pn as CountableDescriptor, pt as TypeName, q as IncludePath, qt as CANONICAL_PAGE_KEYS, r as ValidationConfig, rn as TypedPage, rt as RelationPaginator, s as assertJsonApiDocument, sn as ActionOutput, st as ResourceHandle, t as ResolvedValidator, tn as PageParamsOf, tt as RelationName, u as Document, un as AtomicDescriptor, ut as SortQuery, v as ClientOptions, vn as PaginatorKind, vt as AtomicCreateInput, w as TransportRequest, wn as RelationDescriptor, wt as AtomicResults, x as createClient, xn as PivotDescriptor, xt as AtomicRecorder, y as HANDLE_RESERVED, yn as PaginatorRole, yt as AtomicDeleteHandle, z as EdgeMembers, zt as MaterialiseContext } from "./validate-CQv5lmqO.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/errors.d.ts
|
|
4
4
|
/**
|
|
@@ -216,5 +216,5 @@ declare function withRemappedRelationshipPaths(error: JsonApiError, rel: string,
|
|
|
216
216
|
*/
|
|
217
217
|
declare function withRemappedAtomicPaths(error: JsonApiError, descriptor: ApiDescriptor, typeForOp: (opIndex: number) => string | undefined): JsonApiError;
|
|
218
218
|
//#endregion
|
|
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 };
|
|
219
|
+
export { ATOMIC_EXT, ATOMIC_MEDIA_TYPE, ActionCallOptions, ActionDescriptor, ActionInput, ActionOutput, ActionScope, ActionsAccessor, ApiDescriptor, ArrayEnvelope, AtomicCreateHandle, AtomicCreateInput, AtomicDeleteHandle, AtomicDescriptor, AtomicHandle, AtomicRecorder, AtomicRef, AtomicResult, AtomicResultOf, AtomicResults, AtomicUpdateHandle, AtomicUpdateInput, BinaryBody, BinaryResponseType, 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, InputMedia, InputMediaKind, 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, RawMediaKind, RawOutputMedia, RawResponseType, 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, TransportRawBody, TransportRequest, TransportResponse, TypeAccessor, TypeName, TypedPage, TypedReadQuery, UpdateInput, ValidationConfig, ValidationOption, Validator, WireResource, WriteDocument, WriteOptions, assertJsonApiDocument, createClient, execute, executeRaw, fetchTransport, hasErrorCode, materialise, mediaType, relatedPaginator, relatedPaginatorKind, remapPointer, remapRelationshipPointer, resolvePaginator, resolveValidator, runAtomic, serializeQuery, toDocument, toRelationshipDocument, validateDocument, withRemappedAtomicPaths, withRemappedPaths, withRemappedRelationshipPaths };
|
|
220
220
|
//# sourceMappingURL=index.d.mts.map
|