@relyio/sdk 0.12.0 → 0.14.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/CHANGELOG.md +228 -0
- package/dist/{chunk-3DRDHXLY.js → chunk-5UMY6CS4.js} +435 -23
- package/dist/{chunk-FRJEUAAF.js → chunk-DBBZVZOS.js} +968 -2670
- package/dist/{chunk-DXCVO6M5.cjs → chunk-GUPV2M3X.cjs} +969 -2680
- package/dist/{chunk-POEEDYFM.js → chunk-PCFTJLEP.js} +543 -260
- package/dist/{chunk-FI5VIF4M.cjs → chunk-RSHMA4KT.cjs} +442 -22
- package/dist/{chunk-3MSFWXQL.cjs → chunk-X4KSS7PP.cjs} +542 -260
- package/dist/client/index.cjs +3 -3
- package/dist/client/index.d.cts +4 -5
- package/dist/client/index.d.ts +4 -5
- package/dist/client/index.js +1 -1
- package/dist/{include-paths-CL4gHv6I.d.cts → define-content-type-BUZeWtpk.d.cts} +4458 -1312
- package/dist/{include-paths-CrJNTsMl.d.ts → define-content-type-DOrZb_a_.d.ts} +4458 -1312
- package/dist/define-schema-5aHmsA8j.d.ts +699 -0
- package/dist/define-schema-nCfZeboB.d.cts +699 -0
- package/dist/index-B97ZDj44.d.ts +507 -0
- package/dist/index-C-pcllqY.d.cts +507 -0
- package/dist/index-DOhFQbv7.d.ts +3065 -0
- package/dist/index-DgVV5Nj7.d.cts +3065 -0
- package/dist/index.cjs +114 -147
- package/dist/index.d.cts +49 -87
- package/dist/index.d.ts +49 -87
- package/dist/index.js +5 -29
- package/dist/markdown/index.cjs +13750 -0
- package/dist/markdown/index.d.cts +111 -0
- package/dist/markdown/index.d.ts +111 -0
- package/dist/markdown/index.js +13742 -0
- package/dist/rich-text/index.cjs +26 -6
- package/dist/rich-text/index.d.cts +3 -148
- package/dist/rich-text/index.d.ts +3 -148
- package/dist/rich-text/index.js +1 -1
- package/dist/rich-text.d-BWc-5gX1.d.cts +326 -0
- package/dist/rich-text.d-BWc-5gX1.d.ts +326 -0
- package/dist/schema/index.cjs +33 -37
- package/dist/schema/index.d.cts +37 -191
- package/dist/schema/index.d.ts +37 -191
- package/dist/schema/index.js +1 -1
- package/dist/types/index.d.cts +2 -3
- package/dist/types/index.d.ts +2 -3
- package/package.json +14 -3
- package/dist/define-schema-DgctHlI2.d.cts +0 -1034
- package/dist/define-schema-mrEZbY1h.d.ts +0 -1034
- package/dist/index-B9RfZVF1.d.ts +0 -861
- package/dist/index-BrvEg6-A.d.cts +0 -3729
- package/dist/index-Pw0onkJe.d.ts +0 -3729
- package/dist/index-b-AkfTUv.d.cts +0 -861
- package/dist/rich-text.d-rKmpgdGd.d.cts +0 -200
- package/dist/rich-text.d-rKmpgdGd.d.ts +0 -200
|
@@ -304,6 +304,10 @@ function isResourceNotFound(error) {
|
|
|
304
304
|
return error instanceof ResourceNotFoundError;
|
|
305
305
|
}
|
|
306
306
|
chunkMWMSFIWN_cjs.__name(isResourceNotFound, "isResourceNotFound");
|
|
307
|
+
function isMissingEntry(error) {
|
|
308
|
+
return error instanceof ResourceNotFoundError && error.context?.resourceType === "entry";
|
|
309
|
+
}
|
|
310
|
+
chunkMWMSFIWN_cjs.__name(isMissingEntry, "isMissingEntry");
|
|
307
311
|
|
|
308
312
|
// src/errors/network-errors.ts
|
|
309
313
|
var _NetworkError = class _NetworkError extends SDKError {
|
|
@@ -463,9 +467,12 @@ chunkMWMSFIWN_cjs.__name(refuseMismatchedAlternate, "refuseMismatchedAlternate")
|
|
|
463
467
|
|
|
464
468
|
// ../../platform/api-contract/dist/index.js
|
|
465
469
|
var HEADER_RETRY_AFTER = { name: "Retry-After" };
|
|
466
|
-
var HEADER_ENTITY_TAG = { name: "X-Entity-Tag" };
|
|
467
470
|
var HEADER_IF_MATCH = {
|
|
468
471
|
name: "If-Match"};
|
|
472
|
+
function entityTag(parts) {
|
|
473
|
+
return `"${parts.entryUid}:${parts.locale}:${parts.version}:${parts.sharedVersion}"`;
|
|
474
|
+
}
|
|
475
|
+
chunkMWMSFIWN_cjs.__name(entityTag, "entityTag");
|
|
469
476
|
var HEADER_IDEMPOTENCY_KEY = {
|
|
470
477
|
name: "Idempotency-Key"};
|
|
471
478
|
var FRESH_PARAMETER = "_fresh";
|
|
@@ -700,6 +707,7 @@ function parseRetryAfterMs(value, nowMs) {
|
|
|
700
707
|
chunkMWMSFIWN_cjs.__name(parseRetryAfterMs, "parseRetryAfterMs");
|
|
701
708
|
|
|
702
709
|
// src/errors/error-mapper.ts
|
|
710
|
+
var STALE_VERSION_GUIDANCE = "The entry changed since it was read: re-read it with `fresh: true` and retry the write with what that read returns.";
|
|
703
711
|
var _ErrorMapper = class _ErrorMapper {
|
|
704
712
|
/** Map a non-2xx response to an SDK error. */
|
|
705
713
|
static mapHttpError(response, requestContext) {
|
|
@@ -767,10 +775,16 @@ var _ErrorMapper = class _ErrorMapper {
|
|
|
767
775
|
});
|
|
768
776
|
}
|
|
769
777
|
case "RESOURCE_CONFLICT": {
|
|
770
|
-
|
|
778
|
+
const expectedVersion = detailNumber(refusal, "expectedVersion");
|
|
779
|
+
const guidance = expectedVersion === void 0 ? message : `${message.endsWith(".") ? message : `${message}.`} ${STALE_VERSION_GUIDANCE}`;
|
|
780
|
+
return new ResourceConflictError(guidance, 409, void 0, {
|
|
771
781
|
...context,
|
|
772
|
-
expectedVersion
|
|
773
|
-
actualVersion: detailNumber(refusal, "actualVersion")
|
|
782
|
+
expectedVersion,
|
|
783
|
+
actualVersion: detailNumber(refusal, "actualVersion"),
|
|
784
|
+
// The shared fields' counter, which the `If-Match` tag carries beside the locale's and a
|
|
785
|
+
// write that changes a shared field is checked against (REL-2363).
|
|
786
|
+
expectedSharedVersion: detailNumber(refusal, "expectedSharedVersion"),
|
|
787
|
+
actualSharedVersion: detailNumber(refusal, "actualSharedVersion")
|
|
774
788
|
});
|
|
775
789
|
}
|
|
776
790
|
case "RESOURCE_EXPIRED": {
|
|
@@ -932,6 +946,7 @@ var DECLARED_PATHS = {
|
|
|
932
946
|
"/v1/meta/schema/{contentType}": true,
|
|
933
947
|
"/v1/meta/schema/{contentType}/fields": true,
|
|
934
948
|
"/v1/project": true,
|
|
949
|
+
"/v1/queries/{name}": true,
|
|
935
950
|
"/v1/query": true,
|
|
936
951
|
"/v1/search": true,
|
|
937
952
|
"/v1/search/autocomplete": true,
|
|
@@ -1094,9 +1109,27 @@ var _HttpClient = class _HttpClient {
|
|
|
1094
1109
|
constructor(config) {
|
|
1095
1110
|
/** What every request reads off the configuration, derived by {@link configure} and nowhere else. */
|
|
1096
1111
|
chunkMWMSFIWN_cjs.__publicField(this, "connection");
|
|
1112
|
+
/**
|
|
1113
|
+
* Set on a view {@link withHeaders} made: the client every request is sent through, and the
|
|
1114
|
+
* headers laid beneath each request's own. A view keeps no connection of its own that matters —
|
|
1115
|
+
* everything it is asked to change, it changes on that client.
|
|
1116
|
+
*/
|
|
1117
|
+
chunkMWMSFIWN_cjs.__publicField(this, "view");
|
|
1097
1118
|
this.connection = connectionFor(config);
|
|
1098
1119
|
this.announce();
|
|
1099
1120
|
}
|
|
1121
|
+
/**
|
|
1122
|
+
* A view of this client that sends every request through it with `headers` added — beneath the
|
|
1123
|
+
* request's own, over this client's — and changes nothing else: its key, base URL, timeout,
|
|
1124
|
+
* retries and `fetch` are this client's as they are when each request is sent, so a later
|
|
1125
|
+
* `configure()` or `setApiKey()` on this client reaches the view, and one on the view reaches
|
|
1126
|
+
* this client. `client.with({ dataset })` is one (REL-2417).
|
|
1127
|
+
*/
|
|
1128
|
+
withHeaders(headers) {
|
|
1129
|
+
const view = new _HttpClient(this.connection.config);
|
|
1130
|
+
view.view = { client: this, headers: { ...headers } };
|
|
1131
|
+
return view;
|
|
1132
|
+
}
|
|
1100
1133
|
/**
|
|
1101
1134
|
* Run on `config` from now on: every later request — whoever holds this client — is sent to its
|
|
1102
1135
|
* `baseUrl`, with its headers, key and dataset, its timeout and retries, through its `fetch`, and
|
|
@@ -1108,6 +1141,7 @@ var _HttpClient = class _HttpClient {
|
|
|
1108
1141
|
* replaced by what `config` says.
|
|
1109
1142
|
*/
|
|
1110
1143
|
configure(config) {
|
|
1144
|
+
if (this.view !== void 0) return this.view.client.configure(config);
|
|
1111
1145
|
this.connection = connectionFor(config);
|
|
1112
1146
|
this.announce();
|
|
1113
1147
|
}
|
|
@@ -1166,6 +1200,12 @@ var _HttpClient = class _HttpClient {
|
|
|
1166
1200
|
* given none.
|
|
1167
1201
|
*/
|
|
1168
1202
|
async request(config) {
|
|
1203
|
+
if (this.view !== void 0) {
|
|
1204
|
+
return this.view.client.request({
|
|
1205
|
+
...config,
|
|
1206
|
+
headers: layerHeaders(this.view.headers, config.headers)
|
|
1207
|
+
});
|
|
1208
|
+
}
|
|
1169
1209
|
if (config.timeout !== void 0) assertRequestTimeout(config.timeout);
|
|
1170
1210
|
const mergedConfig = this.mergeRequestConfig(config);
|
|
1171
1211
|
if (presentKey(headerValue(mergedConfig.headers, API_KEY_HEADER)) === void 0) {
|
|
@@ -1276,6 +1316,7 @@ var _HttpClient = class _HttpClient {
|
|
|
1276
1316
|
* matched without regard to case — until the client is next configured.
|
|
1277
1317
|
*/
|
|
1278
1318
|
setDefaultHeaders(headers) {
|
|
1319
|
+
if (this.view !== void 0) return this.view.client.setDefaultHeaders(headers);
|
|
1279
1320
|
this.connection = {
|
|
1280
1321
|
...this.connection,
|
|
1281
1322
|
defaultHeaders: layerHeaders(this.connection.defaultHeaders, headers)
|
|
@@ -1299,6 +1340,7 @@ var _HttpClient = class _HttpClient {
|
|
|
1299
1340
|
* never touched: the API reads `X-API-Key` first, so the old key was the one used (REL-1385).
|
|
1300
1341
|
*/
|
|
1301
1342
|
setApiKey(apiKey) {
|
|
1343
|
+
if (this.view !== void 0) return this.view.client.setApiKey(apiKey);
|
|
1302
1344
|
const { config } = this.connection;
|
|
1303
1345
|
config.apiKey = apiKey;
|
|
1304
1346
|
config.headers = layerHeaders(config.headers, { [API_KEY_HEADER]: null });
|
|
@@ -1313,18 +1355,23 @@ var _HttpClient = class _HttpClient {
|
|
|
1313
1355
|
* Get current default headers
|
|
1314
1356
|
*/
|
|
1315
1357
|
getDefaultHeaders() {
|
|
1358
|
+
if (this.view !== void 0) {
|
|
1359
|
+
return layerHeaders(this.view.client.getDefaultHeaders(), this.view.headers);
|
|
1360
|
+
}
|
|
1316
1361
|
return { ...this.connection.defaultHeaders };
|
|
1317
1362
|
}
|
|
1318
1363
|
/**
|
|
1319
1364
|
* Update base URL
|
|
1320
1365
|
*/
|
|
1321
1366
|
setBaseUrl(baseUrl) {
|
|
1367
|
+
if (this.view !== void 0) return this.view.client.setBaseUrl(baseUrl);
|
|
1322
1368
|
this.connection = { ...this.connection, baseUrl };
|
|
1323
1369
|
}
|
|
1324
1370
|
/**
|
|
1325
1371
|
* Get current base URL
|
|
1326
1372
|
*/
|
|
1327
1373
|
getBaseUrl() {
|
|
1374
|
+
if (this.view !== void 0) return this.view.client.getBaseUrl();
|
|
1328
1375
|
return this.connection.baseUrl;
|
|
1329
1376
|
}
|
|
1330
1377
|
/**
|
|
@@ -1592,6 +1639,31 @@ function credentialsModeFor(includeCredentials) {
|
|
|
1592
1639
|
}
|
|
1593
1640
|
chunkMWMSFIWN_cjs.__name(credentialsModeFor, "credentialsModeFor");
|
|
1594
1641
|
|
|
1642
|
+
// src/http/write-options.ts
|
|
1643
|
+
function versionCheckOf(entry) {
|
|
1644
|
+
const { id, locale, version, sharedVersion } = entry._metadata;
|
|
1645
|
+
return { id, locale, ifMatch: entityTag({ entryUid: id, locale, version, sharedVersion }) };
|
|
1646
|
+
}
|
|
1647
|
+
chunkMWMSFIWN_cjs.__name(versionCheckOf, "versionCheckOf");
|
|
1648
|
+
function mintIdempotencyKey() {
|
|
1649
|
+
const webCrypto = globalThis.crypto;
|
|
1650
|
+
if (typeof webCrypto?.randomUUID !== "function") return void 0;
|
|
1651
|
+
return webCrypto.randomUUID();
|
|
1652
|
+
}
|
|
1653
|
+
chunkMWMSFIWN_cjs.__name(mintIdempotencyKey, "mintIdempotencyKey");
|
|
1654
|
+
function writeHeaders(options) {
|
|
1655
|
+
const headers = {};
|
|
1656
|
+
if (options?.ifMatch !== void 0) {
|
|
1657
|
+
headers[HEADER_IF_MATCH.name] = options.ifMatch;
|
|
1658
|
+
}
|
|
1659
|
+
const idempotencyKey = options?.idempotencyKey ?? mintIdempotencyKey();
|
|
1660
|
+
if (idempotencyKey !== void 0) {
|
|
1661
|
+
headers[HEADER_IDEMPOTENCY_KEY.name] = idempotencyKey;
|
|
1662
|
+
}
|
|
1663
|
+
return Object.keys(headers).length > 0 ? headers : void 0;
|
|
1664
|
+
}
|
|
1665
|
+
chunkMWMSFIWN_cjs.__name(writeHeaders, "writeHeaders");
|
|
1666
|
+
|
|
1595
1667
|
// src/content/client-locale.ts
|
|
1596
1668
|
function callLocale(named, clientLocale) {
|
|
1597
1669
|
if (named !== void 0) return named;
|
|
@@ -1603,7 +1675,12 @@ function readClientLocale(locale) {
|
|
|
1603
1675
|
}
|
|
1604
1676
|
chunkMWMSFIWN_cjs.__name(readClientLocale, "readClientLocale");
|
|
1605
1677
|
|
|
1606
|
-
// src/content/
|
|
1678
|
+
// src/content/read-terms.ts
|
|
1679
|
+
function writeChildrenQuery(params, options) {
|
|
1680
|
+
params.children = options.depth === void 0 ? "true" : `${options.depth}`;
|
|
1681
|
+
if (options.limit !== void 0) params.childrenLimit = options.limit;
|
|
1682
|
+
}
|
|
1683
|
+
chunkMWMSFIWN_cjs.__name(writeChildrenQuery, "writeChildrenQuery");
|
|
1607
1684
|
function namesMetadata(key) {
|
|
1608
1685
|
return key === "_metadata" || key.startsWith("_metadata.");
|
|
1609
1686
|
}
|
|
@@ -1621,887 +1698,309 @@ function refuseMetadataConditions(conditions) {
|
|
|
1621
1698
|
);
|
|
1622
1699
|
}
|
|
1623
1700
|
chunkMWMSFIWN_cjs.__name(refuseMetadataConditions, "refuseMetadataConditions");
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
this.contentType = contentType;
|
|
1632
|
-
chunkMWMSFIWN_cjs.__publicField(this, "queryOptions", {});
|
|
1633
|
-
chunkMWMSFIWN_cjs.__publicField(this, "localeValue");
|
|
1634
|
-
chunkMWMSFIWN_cjs.__publicField(this, "localesArray");
|
|
1635
|
-
chunkMWMSFIWN_cjs.__publicField(this, "fetchAllLocales", false);
|
|
1636
|
-
chunkMWMSFIWN_cjs.__publicField(this, "fieldsProjection");
|
|
1637
|
-
chunkMWMSFIWN_cjs.__publicField(this, "childrenOptions");
|
|
1638
|
-
chunkMWMSFIWN_cjs.__publicField(this, "pageNumber");
|
|
1639
|
-
chunkMWMSFIWN_cjs.__publicField(this, "pageSizeValue");
|
|
1640
|
-
chunkMWMSFIWN_cjs.__publicField(this, "requestHeaders");
|
|
1641
|
-
/** The client's locale, asked when the query is sent rather than copied when it was built. */
|
|
1642
|
-
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
1643
|
-
chunkMWMSFIWN_cjs.__publicField(this, "freshValue");
|
|
1644
|
-
this.clientLocale = readClientLocale(locale);
|
|
1645
|
-
}
|
|
1646
|
-
/**
|
|
1647
|
-
* The feed position this read follows — a change's `fresh` (`FeedChange`), or a resync's. Sent as
|
|
1648
|
-
* `?_fresh`, the one term the API declares for it: no cache — the Content API's edge or the
|
|
1649
|
-
* browser's own — holds an answer for that position from before it, so the read is answered after
|
|
1650
|
-
* the change, and every read naming the same position shares that answer. The answer is the
|
|
1651
|
-
* read's own; omit it for a read no change prompted.
|
|
1652
|
-
*/
|
|
1653
|
-
fresh(position) {
|
|
1654
|
-
this.freshValue = position;
|
|
1655
|
-
return this;
|
|
1656
|
-
}
|
|
1657
|
-
/**
|
|
1658
|
-
* Headers this query adds to the client's own, e.g. `X-RelyIO-Dataset` to list another dataset
|
|
1659
|
-
* the key can see. A name the client already sends is replaced for this query only; the client
|
|
1660
|
-
* is not changed.
|
|
1661
|
-
*/
|
|
1662
|
-
headers(headers) {
|
|
1663
|
-
this.requestHeaders = headers;
|
|
1664
|
-
return this;
|
|
1665
|
-
}
|
|
1666
|
-
/**
|
|
1667
|
-
* Add where conditions to the query: conditions on the fields the content type declares. A
|
|
1668
|
-
* condition on `_metadata` is refused here, before anything is sent (`refuseMetadataConditions`).
|
|
1669
|
-
*/
|
|
1670
|
-
where(conditions) {
|
|
1671
|
-
refuseMetadataConditions(conditions);
|
|
1672
|
-
this.queryOptions.where = {
|
|
1673
|
-
...this.queryOptions.where,
|
|
1674
|
-
...conditions
|
|
1675
|
-
};
|
|
1676
|
-
return this;
|
|
1677
|
-
}
|
|
1678
|
-
/**
|
|
1679
|
-
* Select specific fields to return
|
|
1680
|
-
*/
|
|
1681
|
-
select(fields) {
|
|
1682
|
-
this.queryOptions.select = fields;
|
|
1683
|
-
return this;
|
|
1684
|
-
}
|
|
1685
|
-
/**
|
|
1686
|
-
* Expand references into the entries they point at: one include path per element (REL-1801).
|
|
1687
|
-
* A path names fields through lists, page builders, objects and references —
|
|
1688
|
-
* `'sections.features'`, `'sections.customers.logo'` — and may pick the fields each entry returns,
|
|
1689
|
-
* `'sections.features(name,slug)'`. Each is checked against the schema: a path that holds no
|
|
1690
|
-
* reference does not compile, and the read's type follows the paths — an expanded reference is the
|
|
1691
|
-
* entry, every other one its id.
|
|
1692
|
-
*/
|
|
1693
|
-
include(paths) {
|
|
1694
|
-
this.queryOptions.include = [
|
|
1695
|
-
...this.queryOptions.include ?? [],
|
|
1696
|
-
...paths
|
|
1697
|
-
];
|
|
1698
|
-
return this;
|
|
1701
|
+
|
|
1702
|
+
// src/content/read-options.ts
|
|
1703
|
+
function listQuery(options, clientLocale) {
|
|
1704
|
+
const query = {};
|
|
1705
|
+
if (options.where !== void 0) {
|
|
1706
|
+
refuseMetadataConditions(options.where);
|
|
1707
|
+
if (Object.keys(options.where).length > 0) query.filters = JSON.stringify(options.where);
|
|
1699
1708
|
}
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
this.queryOptions.sort = {
|
|
1703
|
-
...this.queryOptions.sort,
|
|
1704
|
-
[fieldOrOptions]: direction ?? "asc"
|
|
1705
|
-
};
|
|
1706
|
-
} else {
|
|
1707
|
-
this.queryOptions.sort = {
|
|
1708
|
-
...this.queryOptions.sort,
|
|
1709
|
-
...fieldOrOptions
|
|
1710
|
-
};
|
|
1711
|
-
}
|
|
1712
|
-
return this;
|
|
1709
|
+
if (options.select !== void 0 && options.select.length > 0) {
|
|
1710
|
+
query.fields = options.select.join(",");
|
|
1713
1711
|
}
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1712
|
+
if (options.sort !== void 0) {
|
|
1713
|
+
const order = Object.entries(options.sort).flatMap(
|
|
1714
|
+
([key, direction]) => direction === void 0 ? [] : [`${key}:${direction}`]
|
|
1715
|
+
);
|
|
1716
|
+
if (order.length > 0) query.sort = order.join(",");
|
|
1719
1717
|
}
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1718
|
+
if (options.limit !== void 0) query.limit = options.limit;
|
|
1719
|
+
if (options.cursor !== void 0) query.cursor = options.cursor;
|
|
1720
|
+
if (options.page !== void 0) query.page = options.page;
|
|
1721
|
+
writeReadTerms(query, options, clientLocale);
|
|
1722
|
+
return query;
|
|
1723
|
+
}
|
|
1724
|
+
chunkMWMSFIWN_cjs.__name(listQuery, "listQuery");
|
|
1725
|
+
function entryQuery(options, clientLocale) {
|
|
1726
|
+
const query = {};
|
|
1727
|
+
writeReadTerms(query, options, clientLocale);
|
|
1728
|
+
return query;
|
|
1729
|
+
}
|
|
1730
|
+
chunkMWMSFIWN_cjs.__name(entryQuery, "entryQuery");
|
|
1731
|
+
function documentQuery(options, clientLocale) {
|
|
1732
|
+
const query = {};
|
|
1733
|
+
writeDocumentTerms(query, options, clientLocale);
|
|
1734
|
+
return query;
|
|
1735
|
+
}
|
|
1736
|
+
chunkMWMSFIWN_cjs.__name(documentQuery, "documentQuery");
|
|
1737
|
+
function writeReadTerms(query, options, clientLocale) {
|
|
1738
|
+
writeDocumentTerms(query, options, clientLocale);
|
|
1739
|
+
if (options.children !== void 0) {
|
|
1740
|
+
writeChildrenQuery(query, options.children === true ? {} : options.children);
|
|
1725
1741
|
}
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
return this;
|
|
1742
|
+
}
|
|
1743
|
+
chunkMWMSFIWN_cjs.__name(writeReadTerms, "writeReadTerms");
|
|
1744
|
+
function writeDocumentTerms(query, options, clientLocale) {
|
|
1745
|
+
if (options.include !== void 0 && options.include.length > 0) {
|
|
1746
|
+
query.include = options.include.join(",");
|
|
1732
1747
|
}
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1748
|
+
writeLocale(query, options.locale ?? clientLocale);
|
|
1749
|
+
if (typeof options.fresh === "string") query[FRESH_PARAMETER] = options.fresh;
|
|
1750
|
+
}
|
|
1751
|
+
chunkMWMSFIWN_cjs.__name(writeDocumentTerms, "writeDocumentTerms");
|
|
1752
|
+
function writeLocale(query, locale) {
|
|
1753
|
+
if (locale === void 0) return;
|
|
1754
|
+
if (typeof locale === "string") {
|
|
1755
|
+
if (locale !== "") query.locale = locale;
|
|
1756
|
+
return;
|
|
1757
|
+
}
|
|
1758
|
+
if (locale.length === 0) {
|
|
1759
|
+
throw new ValidationError(
|
|
1760
|
+
"`locale` is an empty list, which names no locale to read. Name one code, a list of codes or '*'.",
|
|
1761
|
+
[{ field: "locale", code: "EMPTY_LOCALE_LIST", message: "locale names no code" }]
|
|
1762
|
+
);
|
|
1739
1763
|
}
|
|
1764
|
+
query.locales = locale.join(",");
|
|
1765
|
+
}
|
|
1766
|
+
chunkMWMSFIWN_cjs.__name(writeLocale, "writeLocale");
|
|
1767
|
+
function readHeaders(options) {
|
|
1768
|
+
const headers = {};
|
|
1769
|
+
if (options.dataset !== void 0) headers[DATASET_HEADER] = options.dataset;
|
|
1770
|
+
if (options.fresh === true) headers["Cache-Control"] = "no-cache";
|
|
1771
|
+
return Object.keys(headers).length > 0 ? headers : void 0;
|
|
1772
|
+
}
|
|
1773
|
+
chunkMWMSFIWN_cjs.__name(readHeaders, "readHeaders");
|
|
1774
|
+
|
|
1775
|
+
// src/content/entry-handle.ts
|
|
1776
|
+
var _EntryHandle = class _EntryHandle {
|
|
1740
1777
|
/**
|
|
1741
|
-
*
|
|
1778
|
+
* @param typeName - The content or asset type the routes are addressed by
|
|
1779
|
+
* @param locale - The client's locale: the function `TypedRelyIOClient` hands over, asked on
|
|
1780
|
+
* every call
|
|
1742
1781
|
*/
|
|
1743
|
-
|
|
1744
|
-
this.
|
|
1745
|
-
|
|
1782
|
+
constructor(httpClient, typeName, locale) {
|
|
1783
|
+
this.httpClient = httpClient;
|
|
1784
|
+
this.typeName = typeName;
|
|
1785
|
+
/** The client's locale, asked on every call rather than copied when this handle was taken. */
|
|
1786
|
+
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
1787
|
+
this.clientLocale = readClientLocale(locale);
|
|
1746
1788
|
}
|
|
1747
1789
|
/**
|
|
1748
|
-
*
|
|
1749
|
-
* @param locale - Locale code (e.g., 'en-US', 'de-DE', 'fr-FR')
|
|
1790
|
+
* One page of this type's entries: the API's own `{ data, page }`, as it answered (REL-2415).
|
|
1750
1791
|
*
|
|
1751
|
-
*
|
|
1752
|
-
*
|
|
1753
|
-
*
|
|
1754
|
-
* .locale('es-ES')
|
|
1755
|
-
* ```
|
|
1756
|
-
*/
|
|
1757
|
-
locale(locale) {
|
|
1758
|
-
this.localeValue = locale;
|
|
1759
|
-
this.localesArray = void 0;
|
|
1760
|
-
this.fetchAllLocales = false;
|
|
1761
|
-
return this;
|
|
1762
|
-
}
|
|
1763
|
-
/**
|
|
1764
|
-
* Fetch content in multiple specific locales
|
|
1765
|
-
* Returns primary locale at top level, others in _metadata.localizations
|
|
1792
|
+
* Page by `cursor` — the `page.nextCursor` a page handed back — to walk, or by `page` number for an
|
|
1793
|
+
* archive page like `/blog/page/3`; `limit` is the page size for both. The page is the cursor
|
|
1794
|
+
* dialect's `{ nextCursor, hasMore }`: a list carries no total.
|
|
1766
1795
|
*
|
|
1767
|
-
*
|
|
1796
|
+
* The rest of the options have one name per concern (REL-2417): `select` the entry's own Fields,
|
|
1797
|
+
* `sort` an order whose key order is the priority, `locale` a code, a list of codes or `'*'`,
|
|
1798
|
+
* `dataset` this read's dataset, `fresh` how fresh the answer must be, `children` the children to
|
|
1799
|
+
* embed. See `ListReadOptions`.
|
|
1768
1800
|
*
|
|
1769
1801
|
* @example
|
|
1770
1802
|
* ```typescript
|
|
1771
|
-
* const
|
|
1772
|
-
*
|
|
1773
|
-
*
|
|
1774
|
-
*
|
|
1775
|
-
*
|
|
1776
|
-
*
|
|
1777
|
-
*
|
|
1803
|
+
* const { data, page } = await relyio.content('post').list({
|
|
1804
|
+
* where: { category: 'news' },
|
|
1805
|
+
* include: ['author'],
|
|
1806
|
+
* select: ['title', 'slug'],
|
|
1807
|
+
* sort: { featured: 'desc', publishedAt: 'desc' },
|
|
1808
|
+
* limit: 10,
|
|
1809
|
+
* page: 3,
|
|
1810
|
+
* })
|
|
1778
1811
|
* ```
|
|
1779
1812
|
*/
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1813
|
+
async list(options = {}) {
|
|
1814
|
+
const response = await this.httpClient.send(
|
|
1815
|
+
"/v1/{contentType}",
|
|
1816
|
+
"get",
|
|
1817
|
+
{
|
|
1818
|
+
path: { contentType: this.typeName },
|
|
1819
|
+
query: listQuery(options, this.clientLocale()),
|
|
1820
|
+
headers: readHeaders(options)
|
|
1821
|
+
}
|
|
1822
|
+
);
|
|
1823
|
+
return response.body;
|
|
1785
1824
|
}
|
|
1786
1825
|
/**
|
|
1787
|
-
*
|
|
1788
|
-
*
|
|
1789
|
-
*
|
|
1790
|
-
*
|
|
1791
|
-
* ```typescript
|
|
1792
|
-
* const product = await client.content('product')
|
|
1793
|
-
* .findById('prod_123')
|
|
1794
|
-
* .allLocales()
|
|
1795
|
-
* .execute()
|
|
1826
|
+
* Every entry of this type that `where` keeps, page after page, as an async iterable: the walk
|
|
1827
|
+
* follows each page's cursor and stops where the API says there is no more (REL-2415).
|
|
1828
|
+
* `Array.fromAsync(relyio.content('post').listAll())` makes it an array. `limit` is how many each
|
|
1829
|
+
* request reads; every other option is a list's, sent with each page.
|
|
1796
1830
|
*
|
|
1797
|
-
*
|
|
1798
|
-
*
|
|
1799
|
-
* // Access: product._metadata.availableLocales
|
|
1800
|
-
* ```
|
|
1831
|
+
* Iterating throws when a page says there is more and hands back no cursor to read it by, rather
|
|
1832
|
+
* than ending the walk short.
|
|
1801
1833
|
*/
|
|
1802
|
-
|
|
1803
|
-
this.
|
|
1804
|
-
this.localeValue = void 0;
|
|
1805
|
-
this.localesArray = void 0;
|
|
1806
|
-
return this;
|
|
1834
|
+
listAll(options = {}) {
|
|
1835
|
+
return this.walk(options);
|
|
1807
1836
|
}
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1837
|
+
async *walk(options) {
|
|
1838
|
+
let cursor;
|
|
1839
|
+
for (; ; ) {
|
|
1840
|
+
const { data, page } = await this.list(
|
|
1841
|
+
cursor === void 0 ? options : { ...options, cursor }
|
|
1842
|
+
);
|
|
1843
|
+
yield* data;
|
|
1844
|
+
if (!page.hasMore) return;
|
|
1845
|
+
if (page.nextCursor === null) {
|
|
1846
|
+
throw new Error(
|
|
1847
|
+
`${this.typeName}: a page of the list says there is more and hands back no cursor to read it by`
|
|
1848
|
+
);
|
|
1849
|
+
}
|
|
1850
|
+
cursor = page.nextCursor;
|
|
1851
|
+
}
|
|
1820
1852
|
}
|
|
1821
1853
|
/**
|
|
1822
|
-
*
|
|
1823
|
-
*
|
|
1854
|
+
* One entry by its id or slug, or `null` when there is no such entry (REL-2415).
|
|
1855
|
+
*
|
|
1856
|
+
* `null` only for a missing **entry**: a type the schema does not declare, or a dataset with no
|
|
1857
|
+
* schema deployed, throws `ResourceNotFoundError` naming which (`context.resourceType`), so an
|
|
1858
|
+
* undeployed type never reads as a missing page.
|
|
1859
|
+
*
|
|
1860
|
+
* It takes the options of a list that are not about which entries or in what order — `include`,
|
|
1861
|
+
* `locale`, `dataset`, `fresh`, `children` (REL-2417). The route declares no `fields`, so there is
|
|
1862
|
+
* no `select`.
|
|
1824
1863
|
*
|
|
1825
1864
|
* @example
|
|
1826
1865
|
* ```typescript
|
|
1827
|
-
*
|
|
1828
|
-
*
|
|
1829
|
-
*
|
|
1830
|
-
* // Include with options
|
|
1831
|
-
* .children({ contentTypes: ['variant'], limit: 10 })
|
|
1866
|
+
* const post = await relyio.content('post').get('hello-world', { include: ['author'] })
|
|
1867
|
+
* if (post === null) return notFound()
|
|
1832
1868
|
* ```
|
|
1833
1869
|
*/
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
this.
|
|
1837
|
-
|
|
1838
|
-
|
|
1870
|
+
async get(idOrSlug, options = {}) {
|
|
1871
|
+
try {
|
|
1872
|
+
return await this.httpClient.fetchPayload("/v1/{contentType}/{id}", "get", {
|
|
1873
|
+
path: { contentType: this.typeName, id: idOrSlug },
|
|
1874
|
+
query: entryQuery(options, this.clientLocale()),
|
|
1875
|
+
headers: readHeaders(options)
|
|
1876
|
+
});
|
|
1877
|
+
} catch (error) {
|
|
1878
|
+
if (isMissingEntry(error)) return null;
|
|
1879
|
+
throw error;
|
|
1839
1880
|
}
|
|
1840
|
-
return this;
|
|
1841
|
-
}
|
|
1842
|
-
/**
|
|
1843
|
-
* Set page number for page-based pagination
|
|
1844
|
-
* @param pageNum - Page number (1-based)
|
|
1845
|
-
*/
|
|
1846
|
-
page(pageNum) {
|
|
1847
|
-
this.pageNumber = pageNum;
|
|
1848
|
-
return this;
|
|
1849
1881
|
}
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1882
|
+
async update(target, data, options) {
|
|
1883
|
+
const { idempotencyKey, locale, ...placement } = options ?? {};
|
|
1884
|
+
const write = typeof target === "string" ? { id: target, locale: callLocale(locale, this.clientLocale()), ifMatch: void 0 } : versionCheckOf(target);
|
|
1885
|
+
return this.httpClient.fetchPayload(
|
|
1886
|
+
"/v1/{contentType}/{id}",
|
|
1887
|
+
"patch",
|
|
1888
|
+
{
|
|
1889
|
+
path: { contentType: this.typeName, id: write.id },
|
|
1890
|
+
body: {
|
|
1891
|
+
content: data,
|
|
1892
|
+
...placement,
|
|
1893
|
+
...write.locale === void 0 ? {} : { locale: write.locale }
|
|
1894
|
+
},
|
|
1895
|
+
headers: writeHeaders({ idempotencyKey, ifMatch: write.ifMatch })
|
|
1896
|
+
}
|
|
1897
|
+
);
|
|
1857
1898
|
}
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1899
|
+
async delete(target, options) {
|
|
1900
|
+
const write = typeof target === "string" ? { id: target, ifMatch: void 0 } : versionCheckOf(target);
|
|
1901
|
+
await this.httpClient.send("/v1/{contentType}/{id}", "delete", {
|
|
1902
|
+
path: { contentType: this.typeName, id: write.id },
|
|
1903
|
+
headers: writeHeaders({ idempotencyKey: options?.idempotencyKey, ifMatch: write.ifMatch })
|
|
1904
|
+
});
|
|
1863
1905
|
}
|
|
1906
|
+
};
|
|
1907
|
+
chunkMWMSFIWN_cjs.__name(_EntryHandle, "EntryHandle");
|
|
1908
|
+
var EntryHandle = _EntryHandle;
|
|
1909
|
+
|
|
1910
|
+
// src/content/content-client.ts
|
|
1911
|
+
var _ContentClient = class _ContentClient extends EntryHandle {
|
|
1864
1912
|
/**
|
|
1865
|
-
*
|
|
1866
|
-
*
|
|
1913
|
+
* Create a new content entry.
|
|
1914
|
+
*
|
|
1915
|
+
* `locale` defaults to the client's own, and `dataset` to the client's (`client.with({ dataset })`
|
|
1916
|
+
* sets it for every call).
|
|
1917
|
+
*
|
|
1918
|
+
* @example
|
|
1919
|
+
* ```typescript
|
|
1920
|
+
* const post = await relyio.content('post').create({ title: 'Hello' }, { slug: 'hello' })
|
|
1921
|
+
* ```
|
|
1867
1922
|
*/
|
|
1868
|
-
async
|
|
1869
|
-
const
|
|
1923
|
+
async create(data, options = {}) {
|
|
1924
|
+
const { idempotencyKey, dataset, locale, ...body } = options;
|
|
1925
|
+
const sent = callLocale(locale, this.clientLocale());
|
|
1926
|
+
return this.httpClient.fetchPayload(
|
|
1870
1927
|
"/v1/{contentType}",
|
|
1871
|
-
"
|
|
1928
|
+
"post",
|
|
1872
1929
|
{
|
|
1873
|
-
path: { contentType: this.
|
|
1874
|
-
|
|
1875
|
-
headers:
|
|
1930
|
+
path: { contentType: this.typeName },
|
|
1931
|
+
body: { content: data, ...body, ...sent === void 0 ? {} : { locale: sent } },
|
|
1932
|
+
headers: { ...readHeaders({ dataset }), ...writeHeaders({ idempotencyKey }) }
|
|
1876
1933
|
}
|
|
1877
1934
|
);
|
|
1878
|
-
return response.body;
|
|
1879
|
-
}
|
|
1880
|
-
/**
|
|
1881
|
-
* Execute the query and return a single result (first match)
|
|
1882
|
-
*/
|
|
1883
|
-
async first() {
|
|
1884
|
-
const originalLimit = this.queryOptions.limit;
|
|
1885
|
-
this.limit(1);
|
|
1886
|
-
try {
|
|
1887
|
-
const results = await this.execute();
|
|
1888
|
-
return results.length > 0 ? results[0] ?? null : null;
|
|
1889
|
-
} finally {
|
|
1890
|
-
if (originalLimit !== void 0) {
|
|
1891
|
-
this.queryOptions.limit = originalLimit;
|
|
1892
|
-
} else {
|
|
1893
|
-
delete this.queryOptions.limit;
|
|
1894
|
-
}
|
|
1895
|
-
}
|
|
1896
|
-
}
|
|
1897
|
-
/**
|
|
1898
|
-
* Get paginated results
|
|
1899
|
-
*/
|
|
1900
|
-
async paginate(limit = 20) {
|
|
1901
|
-
return this.limit(limit).executeWithMeta();
|
|
1902
1935
|
}
|
|
1903
1936
|
/**
|
|
1904
|
-
*
|
|
1937
|
+
* Get version history for one locale of an entry.
|
|
1938
|
+
*
|
|
1939
|
+
* Versions are numbered per locale, so this is one locale's timeline: `locale` defaults to the
|
|
1940
|
+
* client's own, else the schema default; no fallback is applied, and a locale
|
|
1941
|
+
* with no history returns an empty array rather than another locale's rows. Every row names the
|
|
1942
|
+
* locale it belongs to.
|
|
1905
1943
|
*/
|
|
1906
|
-
async
|
|
1907
|
-
const
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
}
|
|
1914
|
-
const result = await this.limit(limit).executeWithMeta();
|
|
1915
|
-
for (const item of readPayload(result)) {
|
|
1916
|
-
yield item;
|
|
1944
|
+
async versions(id, options) {
|
|
1945
|
+
const locale = callLocale(options?.locale, this.clientLocale());
|
|
1946
|
+
return this.httpClient.fetchPayload("/v1/{contentType}/{id}/versions", "get", {
|
|
1947
|
+
path: { contentType: this.typeName, id },
|
|
1948
|
+
query: {
|
|
1949
|
+
limit: options?.limit ?? 10,
|
|
1950
|
+
...locale === void 0 ? {} : { locale }
|
|
1917
1951
|
}
|
|
1918
|
-
|
|
1919
|
-
cursor = result.page.nextCursor ?? void 0;
|
|
1920
|
-
}
|
|
1921
|
-
}
|
|
1922
|
-
/**
|
|
1923
|
-
* Execute the query and return all results as an array (for large datasets)
|
|
1924
|
-
*/
|
|
1925
|
-
async all() {
|
|
1926
|
-
const allItems = [];
|
|
1927
|
-
for await (const item of this) {
|
|
1928
|
-
allItems.push(item);
|
|
1929
|
-
}
|
|
1930
|
-
return allItems;
|
|
1952
|
+
});
|
|
1931
1953
|
}
|
|
1932
1954
|
/**
|
|
1933
|
-
*
|
|
1955
|
+
* One version of an entry: `version(id, { version, locale })`.
|
|
1956
|
+
*
|
|
1957
|
+
* `locale` defaults to the client's own, else the schema default. Version numbers are per locale,
|
|
1958
|
+
* so version 2 is different content in each one.
|
|
1959
|
+
*
|
|
1960
|
+
* There is no `null`: a version the locale does not have, an entry that is not there, a type the
|
|
1961
|
+
* schema does not declare and a dataset with no schema all throw `ResourceNotFoundError`, its
|
|
1962
|
+
* `context.resourceType` naming which (REL-2409 Q12).
|
|
1934
1963
|
*/
|
|
1935
|
-
|
|
1936
|
-
const
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
cloned.fieldsProjection = this.fieldsProjection ? [...this.fieldsProjection] : void 0;
|
|
1946
|
-
cloned.pageNumber = this.pageNumber;
|
|
1947
|
-
cloned.pageSizeValue = this.pageSizeValue;
|
|
1948
|
-
cloned.requestHeaders = this.requestHeaders ? { ...this.requestHeaders } : void 0;
|
|
1949
|
-
cloned.freshValue = this.freshValue;
|
|
1950
|
-
return cloned;
|
|
1964
|
+
async version(id, options) {
|
|
1965
|
+
const locale = callLocale(options.locale, this.clientLocale());
|
|
1966
|
+
return this.httpClient.fetchPayload("/v1/{contentType}/{id}/versions/{versionNumber}", "get", {
|
|
1967
|
+
path: {
|
|
1968
|
+
contentType: this.typeName,
|
|
1969
|
+
id,
|
|
1970
|
+
versionNumber: String(options.version)
|
|
1971
|
+
},
|
|
1972
|
+
query: locale === void 0 ? void 0 : { locale }
|
|
1973
|
+
});
|
|
1951
1974
|
}
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1975
|
+
async restore(target, options) {
|
|
1976
|
+
const { version, locale, idempotencyKey } = options;
|
|
1977
|
+
const write = typeof target === "string" ? { id: target, locale, ifMatch: void 0 } : versionCheckOf(target);
|
|
1978
|
+
return this.httpClient.fetchPayload("/v1/{contentType}/{id}/versions/{versionNumber}/restore", "post", {
|
|
1979
|
+
path: {
|
|
1980
|
+
contentType: this.typeName,
|
|
1981
|
+
id: write.id,
|
|
1982
|
+
versionNumber: String(version)
|
|
1983
|
+
},
|
|
1984
|
+
body: { locale: write.locale },
|
|
1985
|
+
headers: writeHeaders({ idempotencyKey, ifMatch: write.ifMatch })
|
|
1986
|
+
});
|
|
1957
1987
|
}
|
|
1958
1988
|
/**
|
|
1959
|
-
*
|
|
1989
|
+
* The direct children of a hierarchical entry, each read as `get` reads an entry.
|
|
1960
1990
|
*
|
|
1961
|
-
*
|
|
1962
|
-
*
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
return this.executeWithMeta();
|
|
1966
|
-
}
|
|
1967
|
-
/**
|
|
1968
|
-
* `count()` and `exists()` are gone, and their absence is the honest answer
|
|
1969
|
-
* rather than an omission (`INV-RD-CAPABILITY-IS-HONEST`).
|
|
1991
|
+
* It takes `get`'s options — `include` (checked against the type), `locale` (a code, a list or
|
|
1992
|
+
* `'*'`), `dataset`, `fresh` and `children` — the terms its route declares as the entry route
|
|
1993
|
+
* does, sent the same way. The route lists one level and takes no depth (REL-2195); a tree nested
|
|
1994
|
+
* under each child is the `children` option.
|
|
1970
1995
|
*
|
|
1971
|
-
*
|
|
1972
|
-
* customer list onto the **cursor** dialect, whose page facts are
|
|
1973
|
-
* `{ nextCursor, hasMore }` and nothing else, so no total reaches this
|
|
1974
|
-
* surface at all. Keeping the method would have meant either a request that
|
|
1975
|
-
* always throws or a number assembled from a page the caller happened to
|
|
1976
|
-
* fetch — a count of what was returned, presented as a count of what matched
|
|
1977
|
-
* (rule 6). The plan's §3.3 listed `count` among six methods a type would
|
|
1978
|
-
* repair; what the type actually shows is that the capability is no longer
|
|
1979
|
-
* there. A caller that wants "is there at least one" fetches one and looks at
|
|
1980
|
-
* `data.length`; a caller that wants a true total uses `POST /v1/search`,
|
|
1981
|
-
* which is the offset dialect precisely because a facet-bearing result wants
|
|
1982
|
-
* one (Decision 5).
|
|
1983
|
-
*/
|
|
1984
|
-
/**
|
|
1985
|
-
* Build query parameters for the HTTP request
|
|
1996
|
+
* @param id - Parent entry ID
|
|
1986
1997
|
*/
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
params.fields = this.queryOptions.select.join(",");
|
|
1994
|
-
}
|
|
1995
|
-
if (this.fieldsProjection) {
|
|
1996
|
-
params.fields = this.fieldsProjection.join(",");
|
|
1997
|
-
}
|
|
1998
|
-
if (this.queryOptions.include) {
|
|
1999
|
-
params.include = this.queryOptions.include.join(",");
|
|
2000
|
-
}
|
|
2001
|
-
if (this.queryOptions.sort) {
|
|
2002
|
-
const sortArray = Object.entries(this.queryOptions.sort).map(
|
|
2003
|
-
([field, direction]) => `${field}:${direction}`
|
|
2004
|
-
);
|
|
2005
|
-
params.sort = sortArray.join(",");
|
|
2006
|
-
}
|
|
2007
|
-
if (this.queryOptions.limit !== void 0) {
|
|
2008
|
-
params.limit = this.queryOptions.limit;
|
|
2009
|
-
}
|
|
2010
|
-
if (this.queryOptions.offset !== void 0) {
|
|
2011
|
-
params.offset = this.queryOptions.offset;
|
|
2012
|
-
}
|
|
2013
|
-
if (this.queryOptions.cursor !== void 0) {
|
|
2014
|
-
params.cursor = this.queryOptions.cursor;
|
|
2015
|
-
}
|
|
2016
|
-
const clientLocale = this.clientLocale();
|
|
2017
|
-
if (this.localeValue != null && this.localeValue !== "") {
|
|
2018
|
-
params.locale = this.localeValue;
|
|
2019
|
-
} else if (this.fetchAllLocales) {
|
|
2020
|
-
params.locale = "*";
|
|
2021
|
-
} else if (this.localesArray && this.localesArray.length > 0) {
|
|
2022
|
-
params.locales = this.localesArray.join(",");
|
|
2023
|
-
} else if (clientLocale != null && clientLocale !== "") {
|
|
2024
|
-
params.locale = clientLocale;
|
|
2025
|
-
}
|
|
2026
|
-
if (this.pageNumber !== void 0) {
|
|
2027
|
-
params.page = this.pageNumber;
|
|
2028
|
-
}
|
|
2029
|
-
if (this.pageSizeValue !== void 0) {
|
|
2030
|
-
params.pageSize = this.pageSizeValue;
|
|
2031
|
-
}
|
|
2032
|
-
if (this.childrenOptions) {
|
|
2033
|
-
if (this.childrenOptions.contentTypes) {
|
|
2034
|
-
params.children = this.childrenOptions.contentTypes.join(",");
|
|
2035
|
-
} else {
|
|
2036
|
-
params.children = "true";
|
|
2037
|
-
}
|
|
2038
|
-
if (this.childrenOptions.limit !== void 0) {
|
|
2039
|
-
params.childrenLimit = this.childrenOptions.limit;
|
|
2040
|
-
}
|
|
2041
|
-
}
|
|
2042
|
-
if (this.freshValue !== void 0) {
|
|
2043
|
-
params[FRESH_PARAMETER] = this.freshValue;
|
|
2044
|
-
}
|
|
2045
|
-
return params;
|
|
2046
|
-
}
|
|
2047
|
-
};
|
|
2048
|
-
chunkMWMSFIWN_cjs.__name(_ContentQueryBuilder, "ContentQueryBuilder");
|
|
2049
|
-
var ContentQueryBuilder = _ContentQueryBuilder;
|
|
2050
|
-
var _ContentByIdBuilder = class _ContentByIdBuilder {
|
|
2051
|
-
/**
|
|
2052
|
-
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent when the
|
|
2053
|
-
* read names none: the function `TypedRelyIOClient` hands over, or a locale fixed for it
|
|
2054
|
-
*/
|
|
2055
|
-
constructor(httpClient, contentType, id, locale) {
|
|
2056
|
-
this.httpClient = httpClient;
|
|
2057
|
-
this.contentType = contentType;
|
|
2058
|
-
this.id = id;
|
|
2059
|
-
chunkMWMSFIWN_cjs.__publicField(this, "includeRelations");
|
|
2060
|
-
chunkMWMSFIWN_cjs.__publicField(this, "localeValue");
|
|
2061
|
-
chunkMWMSFIWN_cjs.__publicField(this, "localesArray");
|
|
2062
|
-
chunkMWMSFIWN_cjs.__publicField(this, "fetchAllLocales", false);
|
|
2063
|
-
chunkMWMSFIWN_cjs.__publicField(this, "childrenOptions");
|
|
2064
|
-
chunkMWMSFIWN_cjs.__publicField(this, "requestHeaders");
|
|
2065
|
-
/** The client's locale, asked when the read is sent rather than copied when it was built. */
|
|
2066
|
-
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
2067
|
-
chunkMWMSFIWN_cjs.__publicField(this, "freshValue");
|
|
2068
|
-
this.clientLocale = readClientLocale(locale);
|
|
2069
|
-
}
|
|
2070
|
-
/**
|
|
2071
|
-
* The feed position this read follows — a change's `fresh` (`FeedChange`), or a resync's. Sent as
|
|
2072
|
-
* `?_fresh`, the one term the API declares for it: no cache — the Content API's edge or the
|
|
2073
|
-
* browser's own — holds an answer for that position from before it, so the read is answered after
|
|
2074
|
-
* the change, and every read naming the same position shares that answer. The answer is the
|
|
2075
|
-
* read's own; omit it for a read no change prompted.
|
|
2076
|
-
*/
|
|
2077
|
-
fresh(position) {
|
|
2078
|
-
this.freshValue = position;
|
|
2079
|
-
return this;
|
|
2080
|
-
}
|
|
2081
|
-
/**
|
|
2082
|
-
* Expand references into the entries they point at: one include path per element (REL-1801).
|
|
2083
|
-
* A path names fields through lists, page builders, objects and references —
|
|
2084
|
-
* `'sections.features'`, `'sections.customers.logo'` — and may pick the fields each entry returns,
|
|
2085
|
-
* `'sections.features(name,slug)'`. Each is checked against the schema: a path that holds no
|
|
2086
|
-
* reference does not compile, and the read's type follows the paths — an expanded reference is the
|
|
2087
|
-
* entry, every other one its id. A second call adds to the first.
|
|
2088
|
-
*/
|
|
2089
|
-
include(paths) {
|
|
2090
|
-
this.includeRelations = [...this.includeRelations ?? [], ...paths];
|
|
2091
|
-
return this;
|
|
2092
|
-
}
|
|
2093
|
-
/**
|
|
2094
|
-
* Set locale for localized content
|
|
2095
|
-
* @param locale - Locale code (e.g., 'en-US', 'de-DE', 'fr-FR')
|
|
2096
|
-
*/
|
|
2097
|
-
locale(locale) {
|
|
2098
|
-
this.localeValue = locale;
|
|
2099
|
-
this.localesArray = void 0;
|
|
2100
|
-
this.fetchAllLocales = false;
|
|
2101
|
-
return this;
|
|
2102
|
-
}
|
|
2103
|
-
/**
|
|
2104
|
-
* Fetch content in multiple specific locales
|
|
2105
|
-
* Returns primary locale at top level, others in _metadata.localizations
|
|
2106
|
-
*
|
|
2107
|
-
* @param localeCodes - Array of locale codes to fetch
|
|
2108
|
-
*/
|
|
2109
|
-
locales(localeCodes) {
|
|
2110
|
-
this.localesArray = localeCodes;
|
|
2111
|
-
this.localeValue = void 0;
|
|
2112
|
-
this.fetchAllLocales = false;
|
|
2113
|
-
return this;
|
|
2114
|
-
}
|
|
2115
|
-
/**
|
|
2116
|
-
* Headers this one read adds to the client's own, e.g. `X-RelyIO-Dataset` to read another dataset
|
|
2117
|
-
* the key can see. A name the client already sends is replaced for this request only; the client
|
|
2118
|
-
* is not changed.
|
|
2119
|
-
*/
|
|
2120
|
-
headers(headers) {
|
|
2121
|
-
this.requestHeaders = headers;
|
|
2122
|
-
return this;
|
|
2123
|
-
}
|
|
2124
|
-
/**
|
|
2125
|
-
* Fetch content in all available locales
|
|
2126
|
-
* Returns default locale at top level, others in _metadata.localizations
|
|
2127
|
-
*/
|
|
2128
|
-
allLocales() {
|
|
2129
|
-
this.fetchAllLocales = true;
|
|
2130
|
-
this.localeValue = void 0;
|
|
2131
|
-
this.localesArray = void 0;
|
|
2132
|
-
return this;
|
|
2133
|
-
}
|
|
2134
|
-
/**
|
|
2135
|
-
* Include children in results (for hierarchical content)
|
|
2136
|
-
* @param options - Children options or boolean to enable with defaults
|
|
2137
|
-
*/
|
|
2138
|
-
children(options) {
|
|
2139
|
-
if (typeof options === "boolean") {
|
|
2140
|
-
this.childrenOptions = options ? {} : void 0;
|
|
2141
|
-
} else {
|
|
2142
|
-
this.childrenOptions = options;
|
|
2143
|
-
}
|
|
2144
|
-
return this;
|
|
2145
|
-
}
|
|
2146
|
-
/**
|
|
2147
|
-
* Execute the query and return the content item
|
|
2148
|
-
*/
|
|
2149
|
-
async execute() {
|
|
2150
|
-
const params = {};
|
|
2151
|
-
if (this.includeRelations != null) {
|
|
2152
|
-
params.include = this.includeRelations.join(",");
|
|
2153
|
-
}
|
|
2154
|
-
const clientLocale = this.clientLocale();
|
|
2155
|
-
if (this.localeValue != null && this.localeValue !== "") {
|
|
2156
|
-
params.locale = this.localeValue;
|
|
2157
|
-
} else if (this.fetchAllLocales) {
|
|
2158
|
-
params.locale = "*";
|
|
2159
|
-
} else if (this.localesArray && this.localesArray.length > 0) {
|
|
2160
|
-
params.locales = this.localesArray.join(",");
|
|
2161
|
-
} else if (clientLocale != null && clientLocale !== "") {
|
|
2162
|
-
params.locale = clientLocale;
|
|
2163
|
-
}
|
|
2164
|
-
if (this.childrenOptions != null) {
|
|
2165
|
-
if (this.childrenOptions.contentTypes) {
|
|
2166
|
-
params.children = this.childrenOptions.contentTypes.join(",");
|
|
2167
|
-
} else {
|
|
2168
|
-
params.children = "true";
|
|
2169
|
-
}
|
|
2170
|
-
if (this.childrenOptions.limit !== void 0) {
|
|
2171
|
-
params.childrenLimit = this.childrenOptions.limit;
|
|
2172
|
-
}
|
|
2173
|
-
}
|
|
2174
|
-
if (this.freshValue !== void 0) {
|
|
2175
|
-
params[FRESH_PARAMETER] = this.freshValue;
|
|
2176
|
-
}
|
|
2177
|
-
try {
|
|
2178
|
-
return await this.httpClient.fetchPayload(
|
|
2179
|
-
"/v1/{contentType}/{id}",
|
|
2180
|
-
"get",
|
|
2181
|
-
{
|
|
2182
|
-
path: { contentType: this.contentType, id: this.id },
|
|
2183
|
-
query: params,
|
|
2184
|
-
headers: this.requestHeaders
|
|
2185
|
-
}
|
|
2186
|
-
);
|
|
2187
|
-
} catch (error) {
|
|
2188
|
-
if (isResourceNotFound(error)) return null;
|
|
2189
|
-
throw error;
|
|
2190
|
-
}
|
|
2191
|
-
}
|
|
2192
|
-
};
|
|
2193
|
-
chunkMWMSFIWN_cjs.__name(_ContentByIdBuilder, "ContentByIdBuilder");
|
|
2194
|
-
var ContentByIdBuilder = _ContentByIdBuilder;
|
|
2195
|
-
|
|
2196
|
-
// src/http/write-options.ts
|
|
2197
|
-
function mintIdempotencyKey() {
|
|
2198
|
-
const webCrypto = globalThis.crypto;
|
|
2199
|
-
if (typeof webCrypto?.randomUUID !== "function") return void 0;
|
|
2200
|
-
return webCrypto.randomUUID();
|
|
2201
|
-
}
|
|
2202
|
-
chunkMWMSFIWN_cjs.__name(mintIdempotencyKey, "mintIdempotencyKey");
|
|
2203
|
-
function writeHeaders(options) {
|
|
2204
|
-
const headers = {};
|
|
2205
|
-
if (options !== void 0 && "ifMatch" in options && options.ifMatch !== void 0) {
|
|
2206
|
-
headers[HEADER_IF_MATCH.name] = options.ifMatch;
|
|
2207
|
-
}
|
|
2208
|
-
const idempotencyKey = options?.idempotencyKey ?? mintIdempotencyKey();
|
|
2209
|
-
if (idempotencyKey !== void 0) {
|
|
2210
|
-
headers[HEADER_IDEMPOTENCY_KEY.name] = idempotencyKey;
|
|
2211
|
-
}
|
|
2212
|
-
return Object.keys(headers).length > 0 ? headers : void 0;
|
|
2213
|
-
}
|
|
2214
|
-
chunkMWMSFIWN_cjs.__name(writeHeaders, "writeHeaders");
|
|
2215
|
-
function requestHeaders(headers, typed) {
|
|
2216
|
-
if (headers === void 0) return typed;
|
|
2217
|
-
if (typed === void 0) return headers;
|
|
2218
|
-
const typedNames = new Set(Object.keys(typed).map((name) => name.toLowerCase()));
|
|
2219
|
-
const own = Object.entries(headers).filter(([name]) => !typedNames.has(name.toLowerCase()));
|
|
2220
|
-
return { ...Object.fromEntries(own), ...typed };
|
|
2221
|
-
}
|
|
2222
|
-
chunkMWMSFIWN_cjs.__name(requestHeaders, "requestHeaders");
|
|
2223
|
-
function entityTagOf(response) {
|
|
2224
|
-
return headerValue(response.headers, HEADER_ENTITY_TAG.name);
|
|
2225
|
-
}
|
|
2226
|
-
chunkMWMSFIWN_cjs.__name(entityTagOf, "entityTagOf");
|
|
2227
|
-
|
|
2228
|
-
// src/content/content-client.ts
|
|
2229
|
-
var _ContentClient = class _ContentClient {
|
|
2230
|
-
/**
|
|
2231
|
-
* @param locale - The client's locale: the function `TypedRelyIOClient` hands over, asked on
|
|
2232
|
-
* every call, or a locale fixed for this client
|
|
2233
|
-
*/
|
|
2234
|
-
constructor(httpClient, contentType, locale) {
|
|
2235
|
-
this.httpClient = httpClient;
|
|
2236
|
-
this.contentType = contentType;
|
|
2237
|
-
/** The client's locale, asked on every call rather than copied when this client was taken. */
|
|
2238
|
-
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
2239
|
-
this.clientLocale = readClientLocale(locale);
|
|
2240
|
-
}
|
|
2241
|
-
/**
|
|
2242
|
-
* Create a new query builder for this content type
|
|
2243
|
-
*/
|
|
2244
|
-
query() {
|
|
2245
|
-
return new ContentQueryBuilder(this.httpClient, this.contentType, this.clientLocale);
|
|
2246
|
-
}
|
|
2247
|
-
/**
|
|
2248
|
-
* Find content by ID with fluent options
|
|
2249
|
-
*/
|
|
2250
|
-
findById(id) {
|
|
2251
|
-
return new ContentByIdBuilder(this.httpClient, this.contentType, id, this.clientLocale);
|
|
2252
|
-
}
|
|
2253
|
-
/**
|
|
2254
|
-
* Fetch all content items
|
|
2255
|
-
* @param locale - Optional locale for localized content
|
|
2256
|
-
*/
|
|
2257
|
-
async fetchAll(locale) {
|
|
2258
|
-
const builder = this.query();
|
|
2259
|
-
if (locale != null && locale !== "") {
|
|
2260
|
-
builder.locale(locale);
|
|
2261
|
-
}
|
|
2262
|
-
return builder.execute();
|
|
2263
|
-
}
|
|
2264
|
-
async fetch(options) {
|
|
2265
|
-
const builder = this.query();
|
|
2266
|
-
if (options?.where) {
|
|
2267
|
-
builder.where(options.where);
|
|
2268
|
-
}
|
|
2269
|
-
if (options?.limit != null) {
|
|
2270
|
-
builder.limit(options.limit);
|
|
2271
|
-
}
|
|
2272
|
-
if (options?.offset != null) {
|
|
2273
|
-
builder.offset(options.offset);
|
|
2274
|
-
}
|
|
2275
|
-
if (options?.sort) {
|
|
2276
|
-
builder.sort(options.sort);
|
|
2277
|
-
}
|
|
2278
|
-
if (options?.include) {
|
|
2279
|
-
builder.include([...options.include]);
|
|
2280
|
-
}
|
|
2281
|
-
if (options?.locale != null && options.locale !== "") {
|
|
2282
|
-
builder.locale(options.locale);
|
|
2283
|
-
}
|
|
2284
|
-
if (options?.fields != null) {
|
|
2285
|
-
builder.fields(options.fields);
|
|
2286
|
-
}
|
|
2287
|
-
if (options?.children != null) {
|
|
2288
|
-
builder.children(options.children);
|
|
2289
|
-
}
|
|
2290
|
-
return builder.execute();
|
|
2291
|
-
}
|
|
2292
|
-
async fetchOne(id, options) {
|
|
2293
|
-
const builder = this.findById(id);
|
|
2294
|
-
if (options?.include != null) {
|
|
2295
|
-
builder.include([...options.include]);
|
|
2296
|
-
}
|
|
2297
|
-
if (options?.locale != null && options.locale !== "") {
|
|
2298
|
-
builder.locale(options.locale);
|
|
2299
|
-
}
|
|
2300
|
-
if (options?.headers != null) {
|
|
2301
|
-
builder.headers(options.headers);
|
|
2302
|
-
}
|
|
2303
|
-
return builder.execute();
|
|
2304
|
-
}
|
|
2305
|
-
async fetchOneWithTag(id, options) {
|
|
2306
|
-
const query = {};
|
|
2307
|
-
if (options?.include != null) {
|
|
2308
|
-
query.include = options.include.join(",");
|
|
2309
|
-
}
|
|
2310
|
-
const locale = options?.locale ?? this.clientLocale();
|
|
2311
|
-
if (locale != null && locale !== "") query.locale = locale;
|
|
2312
|
-
const response = await this.httpClient.send(
|
|
2313
|
-
"/v1/{contentType}/{id}",
|
|
2314
|
-
"get",
|
|
2315
|
-
{ path: { contentType: this.contentType, id }, query, headers: options?.headers }
|
|
2316
|
-
);
|
|
2317
|
-
return { entry: readPayload(response.body), entityTag: entityTagOf(response) };
|
|
2318
|
-
}
|
|
2319
|
-
/**
|
|
2320
|
-
* Fetch the first content item matching the conditions
|
|
2321
|
-
* @param where - Filter conditions
|
|
2322
|
-
* @param locale - Optional locale
|
|
2323
|
-
*/
|
|
2324
|
-
async fetchFirst(where, locale) {
|
|
2325
|
-
const builder = this.query();
|
|
2326
|
-
if (where != null) {
|
|
2327
|
-
builder.where(where);
|
|
2328
|
-
}
|
|
2329
|
-
if (locale != null && locale !== "") {
|
|
2330
|
-
builder.locale(locale);
|
|
2331
|
-
}
|
|
2332
|
-
return builder.first();
|
|
2333
|
-
}
|
|
2334
|
-
/**
|
|
2335
|
-
* Create a new content item
|
|
2336
|
-
* @param data - Content data
|
|
2337
|
-
* @param options - Create options (slug, locale, parentId, sortOrder), and `headers` this one
|
|
2338
|
-
* request adds — e.g. `{ 'X-RelyIO-Dataset': 'staging' }` to write a dataset other than the
|
|
2339
|
-
* client's. They are sent, never put in the body; `idempotencyKey` still wins over an
|
|
2340
|
-
* `Idempotency-Key` among them. `locale` defaults to the client's own (`withLocale()`).
|
|
2341
|
-
*/
|
|
2342
|
-
async create(data, options) {
|
|
2343
|
-
const { idempotencyKey, headers, locale, ...body } = options ?? {};
|
|
2344
|
-
const sent = callLocale(locale, this.clientLocale());
|
|
2345
|
-
return this.httpClient.fetchPayload(
|
|
2346
|
-
"/v1/{contentType}",
|
|
2347
|
-
"post",
|
|
2348
|
-
{
|
|
2349
|
-
path: { contentType: this.contentType },
|
|
2350
|
-
body: { content: data, ...body, ...sent === void 0 ? {} : { locale: sent } },
|
|
2351
|
-
headers: requestHeaders(headers, writeHeaders({ idempotencyKey }))
|
|
2352
|
-
}
|
|
2353
|
-
);
|
|
2354
|
-
}
|
|
2355
|
-
/**
|
|
2356
|
-
* Update a content item by ID (partial update)
|
|
2357
|
-
* @param id - Entry ID
|
|
2358
|
-
* @param data - Fields to update
|
|
2359
|
-
* @param options - Update options (slug, locale, parentId, sortOrder), and `headers` this one
|
|
2360
|
-
* request adds, as for {@link create}. `ifMatch` and `idempotencyKey` win over the same
|
|
2361
|
-
* header among them. `locale` defaults to the client's own, the locale whose entity tag
|
|
2362
|
-
* {@link fetchOneWithTag} reads, so the tag it hands back is checked against the same locale.
|
|
2363
|
-
*/
|
|
2364
|
-
async update(id, data, options) {
|
|
2365
|
-
const { idempotencyKey, ifMatch, headers, locale, ...body } = options ?? {};
|
|
2366
|
-
const sent = callLocale(locale, this.clientLocale());
|
|
2367
|
-
return this.httpClient.fetchPayload(
|
|
2368
|
-
"/v1/{contentType}/{id}",
|
|
2369
|
-
"patch",
|
|
2370
|
-
{
|
|
2371
|
-
path: { contentType: this.contentType, id },
|
|
2372
|
-
body: { content: data, ...body, ...sent === void 0 ? {} : { locale: sent } },
|
|
2373
|
-
headers: requestHeaders(headers, writeHeaders({ idempotencyKey, ifMatch }))
|
|
2374
|
-
}
|
|
2375
|
-
);
|
|
2376
|
-
}
|
|
2377
|
-
/**
|
|
2378
|
-
* Delete a content item by ID
|
|
2379
|
-
*/
|
|
2380
|
-
async delete(id, options) {
|
|
2381
|
-
await this.httpClient.send("/v1/{contentType}/{id}", "delete", {
|
|
2382
|
-
path: { contentType: this.contentType, id },
|
|
2383
|
-
headers: writeHeaders(options)
|
|
2384
|
-
});
|
|
2385
|
-
}
|
|
2386
|
-
/**
|
|
2387
|
-
* Check if content exists by ID
|
|
2388
|
-
*/
|
|
2389
|
-
async exists(id) {
|
|
2390
|
-
try {
|
|
2391
|
-
const item = await this.fetchOne(id);
|
|
2392
|
-
return item !== null;
|
|
2393
|
-
} catch (error) {
|
|
2394
|
-
if (error instanceof ResourceNotFoundError) {
|
|
2395
|
-
return false;
|
|
2396
|
-
}
|
|
2397
|
-
throw error;
|
|
2398
|
-
}
|
|
2399
|
-
}
|
|
2400
|
-
/**
|
|
2401
|
-
* Get version history for one locale of an entry.
|
|
2402
|
-
*
|
|
2403
|
-
* Versions are numbered per locale, so this is one locale's timeline: `locale` defaults to the
|
|
2404
|
-
* client's own (`withLocale()`), else the schema default; no fallback is applied, and a locale
|
|
2405
|
-
* with no history returns an empty array rather than another locale's rows. Every row names the
|
|
2406
|
-
* locale it belongs to.
|
|
2407
|
-
*/
|
|
2408
|
-
async versions(id, options) {
|
|
2409
|
-
const locale = callLocale(options?.locale, this.clientLocale());
|
|
2410
|
-
return this.httpClient.fetchPayload("/v1/{contentType}/{id}/versions", "get", {
|
|
2411
|
-
path: { contentType: this.contentType, id },
|
|
2412
|
-
query: {
|
|
2413
|
-
limit: options?.limit ?? 10,
|
|
2414
|
-
...locale === void 0 ? {} : { locale }
|
|
2415
|
-
}
|
|
2416
|
-
});
|
|
2417
|
-
}
|
|
2418
|
-
/**
|
|
2419
|
-
* Get a specific version of an entry.
|
|
2420
|
-
*
|
|
2421
|
-
* `locale` defaults to the client's own (`withLocale()`), else the schema default. Version
|
|
2422
|
-
* numbers are per locale, so version 2 is different content in each one.
|
|
2423
|
-
*/
|
|
2424
|
-
async version(id, versionNumber, options) {
|
|
2425
|
-
const locale = callLocale(options?.locale, this.clientLocale());
|
|
2426
|
-
return this.httpClient.fetchPayload("/v1/{contentType}/{id}/versions/{versionNumber}", "get", {
|
|
2427
|
-
path: {
|
|
2428
|
-
contentType: this.contentType,
|
|
2429
|
-
id,
|
|
2430
|
-
versionNumber: String(versionNumber)
|
|
2431
|
-
},
|
|
2432
|
-
query: locale === void 0 ? void 0 : { locale }
|
|
2433
|
-
});
|
|
2434
|
-
}
|
|
2435
|
-
/**
|
|
2436
|
-
* Revert one locale of an entry to a previous version.
|
|
2437
|
-
*
|
|
2438
|
-
* `locale` is **required**, and that is not a convention: versions are numbered per locale, so
|
|
2439
|
-
* `versionNumber` alone is ambiguous, and defaulting it would silently revert the wrong
|
|
2440
|
-
* translation. Only that locale's fields change — shared fields and every other locale are left
|
|
2441
|
-
* untouched.
|
|
2442
|
-
*
|
|
2443
|
-
* The restore is validated as strictly as a publish, so it cannot publish invalid content, and it
|
|
2444
|
-
* records a new version of its own rather than rewinding the counter — so the revert is auditable
|
|
2445
|
-
* and itself reversible.
|
|
2446
|
-
*/
|
|
2447
|
-
async restore(id, versionNumber, locale, options) {
|
|
2448
|
-
return this.httpClient.fetchPayload("/v1/{contentType}/{id}/versions/{versionNumber}/restore", "post", {
|
|
2449
|
-
path: {
|
|
2450
|
-
contentType: this.contentType,
|
|
2451
|
-
id,
|
|
2452
|
-
versionNumber: String(versionNumber)
|
|
2453
|
-
},
|
|
2454
|
-
body: { locale },
|
|
2455
|
-
headers: writeHeaders(options)
|
|
2456
|
-
});
|
|
2457
|
-
}
|
|
2458
|
-
/**
|
|
2459
|
-
* Get children of a hierarchical entry
|
|
2460
|
-
* @param id - Parent entry ID
|
|
2461
|
-
* @param options - Fetch options
|
|
2462
|
-
*/
|
|
2463
|
-
async children(id, options) {
|
|
2464
|
-
const params = {};
|
|
2465
|
-
if (options?.depth != null) {
|
|
2466
|
-
params.depth = options.depth;
|
|
2467
|
-
}
|
|
2468
|
-
if (options?.include != null) {
|
|
2469
|
-
params.include = options.include.join(",");
|
|
2470
|
-
}
|
|
2471
|
-
const locale = options?.locale ?? this.clientLocale();
|
|
2472
|
-
if (locale != null && locale !== "") {
|
|
2473
|
-
params.locale = locale;
|
|
2474
|
-
}
|
|
2475
|
-
return this.httpClient.fetchPayload(
|
|
2476
|
-
"/v1/{contentType}/{id}/children",
|
|
2477
|
-
"get",
|
|
2478
|
-
{ path: { contentType: this.contentType, id }, query: params }
|
|
2479
|
-
);
|
|
2480
|
-
}
|
|
2481
|
-
/**
|
|
2482
|
-
* Get the content type name
|
|
2483
|
-
*/
|
|
2484
|
-
getContentType() {
|
|
2485
|
-
return this.contentType;
|
|
2486
|
-
}
|
|
2487
|
-
/**
|
|
2488
|
-
* Create a new ContentClient for a different content type
|
|
2489
|
-
*/
|
|
2490
|
-
ofType(contentType) {
|
|
2491
|
-
return new _ContentClient(this.httpClient, contentType, this.clientLocale);
|
|
2492
|
-
}
|
|
2493
|
-
/**
|
|
2494
|
-
* Create a new ContentClient with a different default locale, fixed: an update of the client's
|
|
2495
|
-
* locale (`updateConfig({ locale })`) does not reach it
|
|
2496
|
-
*/
|
|
2497
|
-
withLocale(locale) {
|
|
2498
|
-
return new _ContentClient(this.httpClient, this.contentType, locale);
|
|
2499
|
-
}
|
|
2500
|
-
/**
|
|
2501
|
-
* Get the default locale as it is now: the client's, or the one `withLocale()` fixed
|
|
2502
|
-
*/
|
|
2503
|
-
getDefaultLocale() {
|
|
2504
|
-
return this.clientLocale();
|
|
1998
|
+
async children(id, options = {}) {
|
|
1999
|
+
return this.httpClient.fetchPayload("/v1/{contentType}/{id}/children", "get", {
|
|
2000
|
+
path: { contentType: this.typeName, id },
|
|
2001
|
+
query: entryQuery(options, this.clientLocale()),
|
|
2002
|
+
headers: readHeaders(options)
|
|
2003
|
+
});
|
|
2505
2004
|
}
|
|
2506
2005
|
};
|
|
2507
2006
|
chunkMWMSFIWN_cjs.__name(_ContentClient, "ContentClient");
|
|
@@ -2640,16 +2139,16 @@ var _AssetFileBuilder = class _AssetFileBuilder {
|
|
|
2640
2139
|
get target() {
|
|
2641
2140
|
return { contentType: this.assetType, id: this.entryUid };
|
|
2642
2141
|
}
|
|
2643
|
-
|
|
2142
|
+
localeOf(locale) {
|
|
2644
2143
|
return locale ?? this.clientLocale();
|
|
2645
2144
|
}
|
|
2646
2145
|
/**
|
|
2647
2146
|
* The `locale` body field of a multipart call: the session's, else the client's. The API finds
|
|
2648
|
-
* the binding by it, so a session a `
|
|
2147
|
+
* the binding by it, so a session a `with({ locale })` client opened must name the same locale on
|
|
2649
2148
|
* every later call or its `objectKey` is refused as another binding's.
|
|
2650
2149
|
*/
|
|
2651
2150
|
localeField(locale) {
|
|
2652
|
-
const sent = this.
|
|
2151
|
+
const sent = this.localeOf(locale);
|
|
2653
2152
|
return hasText(sent) ? { locale: sent } : {};
|
|
2654
2153
|
}
|
|
2655
2154
|
/**
|
|
@@ -2657,7 +2156,7 @@ var _AssetFileBuilder = class _AssetFileBuilder {
|
|
|
2657
2156
|
* Cloudflare Stream direct-creator URL (video). Resumable multipart is plan 17.
|
|
2658
2157
|
*/
|
|
2659
2158
|
async presign(input) {
|
|
2660
|
-
const locale = this.
|
|
2159
|
+
const locale = this.localeOf(input.locale);
|
|
2661
2160
|
return this.httpClient.fetchPayload("/v1/{contentType}/{id}/file/presign", "post", {
|
|
2662
2161
|
path: this.target,
|
|
2663
2162
|
body: {
|
|
@@ -2674,7 +2173,7 @@ var _AssetFileBuilder = class _AssetFileBuilder {
|
|
|
2674
2173
|
* R2; a no-op for Stream, whose readiness is webhook-driven).
|
|
2675
2174
|
*/
|
|
2676
2175
|
async confirm(input = {}) {
|
|
2677
|
-
const locale = this.
|
|
2176
|
+
const locale = this.localeOf(input.locale);
|
|
2678
2177
|
return this.httpClient.fetchPayload("/v1/{contentType}/{id}/file/confirm", "post", {
|
|
2679
2178
|
path: this.target,
|
|
2680
2179
|
body: {
|
|
@@ -2689,7 +2188,7 @@ var _AssetFileBuilder = class _AssetFileBuilder {
|
|
|
2689
2188
|
// ──────────────────────────────────────────────────────────────────────────
|
|
2690
2189
|
/** Open an R2 multipart session for a large file (standalone of `presign`). */
|
|
2691
2190
|
async createMultipart(input) {
|
|
2692
|
-
const locale = this.
|
|
2191
|
+
const locale = this.localeOf(input.locale);
|
|
2693
2192
|
return this.httpClient.fetchPayload("/v1/{contentType}/{id}/file/multipart/create", "post", {
|
|
2694
2193
|
path: this.target,
|
|
2695
2194
|
body: {
|
|
@@ -2754,7 +2253,7 @@ var _AssetFileBuilder = class _AssetFileBuilder {
|
|
|
2754
2253
|
*/
|
|
2755
2254
|
async url(input = {}) {
|
|
2756
2255
|
const params = {};
|
|
2757
|
-
const locale = this.
|
|
2256
|
+
const locale = this.localeOf(input.locale);
|
|
2758
2257
|
if (hasText(locale)) params.locale = locale;
|
|
2759
2258
|
if (hasText(input.variantId)) params.variantId = input.variantId;
|
|
2760
2259
|
if (input.purpose !== void 0) params.purpose = input.purpose;
|
|
@@ -2775,7 +2274,7 @@ var _AssetFileBuilder = class _AssetFileBuilder {
|
|
|
2775
2274
|
*/
|
|
2776
2275
|
async status(options = {}) {
|
|
2777
2276
|
const params = {};
|
|
2778
|
-
const locale = this.
|
|
2277
|
+
const locale = this.localeOf(options.locale);
|
|
2779
2278
|
if (hasText(locale)) params.locale = locale;
|
|
2780
2279
|
return this.httpClient.fetchPayload(
|
|
2781
2280
|
"/v1/{contentType}/{id}/file",
|
|
@@ -2788,7 +2287,7 @@ var _AssetFileBuilder = class _AssetFileBuilder {
|
|
|
2788
2287
|
* a downgrade purges the gateway cache). Returns the refreshed asset entry.
|
|
2789
2288
|
*/
|
|
2790
2289
|
async updateVisibility(visibility, options = {}) {
|
|
2791
|
-
const locale = this.
|
|
2290
|
+
const locale = this.localeOf(options.locale);
|
|
2792
2291
|
return this.httpClient.fetchPayload("/v1/{contentType}/{id}/file", "patch", {
|
|
2793
2292
|
path: this.target,
|
|
2794
2293
|
body: { visibility, ...hasText(locale) ? { locale } : {} }
|
|
@@ -2801,7 +2300,7 @@ var _AssetFileBuilder = class _AssetFileBuilder {
|
|
|
2801
2300
|
* refreshed asset entry.
|
|
2802
2301
|
*/
|
|
2803
2302
|
async setFocalPoint(focalPoint, options = {}) {
|
|
2804
|
-
const locale = this.
|
|
2303
|
+
const locale = this.localeOf(options.locale);
|
|
2805
2304
|
return this.httpClient.fetchPayload("/v1/{contentType}/{id}/file", "patch", {
|
|
2806
2305
|
path: this.target,
|
|
2807
2306
|
body: { focalPoint, ...hasText(locale) ? { locale } : {} }
|
|
@@ -2813,7 +2312,7 @@ var _AssetFileBuilder = class _AssetFileBuilder {
|
|
|
2813
2312
|
*/
|
|
2814
2313
|
async delete(options = {}) {
|
|
2815
2314
|
const params = {};
|
|
2816
|
-
const locale = this.
|
|
2315
|
+
const locale = this.localeOf(options.locale);
|
|
2817
2316
|
if (hasText(locale)) params.locale = locale;
|
|
2818
2317
|
await this.httpClient.send("/v1/{contentType}/{id}/file", "delete", {
|
|
2819
2318
|
path: this.target,
|
|
@@ -2839,22 +2338,27 @@ var _AssetFileBuilder = class _AssetFileBuilder {
|
|
|
2839
2338
|
* @throws {ReadOnlyKeyError} When the key's lens does not show the asset and the key may not read
|
|
2840
2339
|
* its binding either: nothing it can read would ever report the file.
|
|
2841
2340
|
*/
|
|
2341
|
+
/** The asset entry through the key's lens, or `null` where that lens finds none. */
|
|
2342
|
+
async readEntry(locale) {
|
|
2343
|
+
try {
|
|
2344
|
+
return await this.httpClient.fetchPayload("/v1/{contentType}/{id}", "get", {
|
|
2345
|
+
path: this.target,
|
|
2346
|
+
query: hasText(locale) ? { locale } : {}
|
|
2347
|
+
});
|
|
2348
|
+
} catch (error) {
|
|
2349
|
+
if (isResourceNotFound(error)) return null;
|
|
2350
|
+
throw error;
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2842
2353
|
async waitUntilReady(options = {}) {
|
|
2843
2354
|
assertWaitOptions(options);
|
|
2844
2355
|
const timeoutMs = options.timeoutMs ?? 6e4;
|
|
2845
2356
|
const pollIntervalMs = options.pollIntervalMs ?? 1500;
|
|
2846
|
-
const locale = this.
|
|
2357
|
+
const locale = this.localeOf(options.locale);
|
|
2847
2358
|
const deadline = Date.now() + timeoutMs;
|
|
2848
2359
|
const subject = `${this.assetType}/${this.entryUid}`;
|
|
2849
2360
|
for (; ; ) {
|
|
2850
|
-
const
|
|
2851
|
-
this.httpClient,
|
|
2852
|
-
this.assetType,
|
|
2853
|
-
this.entryUid,
|
|
2854
|
-
locale
|
|
2855
|
-
);
|
|
2856
|
-
if (hasText(locale)) builder.locale(locale);
|
|
2857
|
-
const entry = await builder.execute();
|
|
2361
|
+
const entry = await this.readEntry(locale);
|
|
2858
2362
|
let status;
|
|
2859
2363
|
if (entry === null) {
|
|
2860
2364
|
const binding = await this.status({ ...hasText(locale) ? { locale } : {} });
|
|
@@ -3137,56 +2641,12 @@ var _AssetUploadBuilder = class _AssetUploadBuilder {
|
|
|
3137
2641
|
};
|
|
3138
2642
|
chunkMWMSFIWN_cjs.__name(_AssetUploadBuilder, "AssetUploadBuilder");
|
|
3139
2643
|
var AssetUploadBuilder = _AssetUploadBuilder;
|
|
3140
|
-
var _AssetClient = class _AssetClient {
|
|
3141
|
-
/**
|
|
3142
|
-
* @param locale - The client's locale: the function `TypedRelyIOClient` hands over, asked on
|
|
3143
|
-
* every call, or a locale fixed for this client
|
|
3144
|
-
*/
|
|
3145
|
-
constructor(httpClient, assetType, locale) {
|
|
3146
|
-
this.httpClient = httpClient;
|
|
3147
|
-
this.assetType = assetType;
|
|
3148
|
-
/** The client's locale, asked on every call rather than copied when this client was taken. */
|
|
3149
|
-
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
3150
|
-
this.clientLocale = readClientLocale(locale);
|
|
3151
|
-
}
|
|
3152
|
-
/**
|
|
3153
|
-
* Create a query builder for this asset type. It resolves asset reads; its conditions name the
|
|
3154
|
-
* asset type's fields, which the `file` and `urls` blocks are not.
|
|
3155
|
-
*/
|
|
3156
|
-
query() {
|
|
3157
|
-
return new ContentQueryBuilder(
|
|
3158
|
-
this.httpClient,
|
|
3159
|
-
this.assetType,
|
|
3160
|
-
this.clientLocale
|
|
3161
|
-
);
|
|
3162
|
-
}
|
|
3163
|
-
/** Find an asset entry by id (or slug) with fluent options. */
|
|
3164
|
-
findById(id) {
|
|
3165
|
-
return new ContentByIdBuilder(
|
|
3166
|
-
this.httpClient,
|
|
3167
|
-
this.assetType,
|
|
3168
|
-
id,
|
|
3169
|
-
this.clientLocale
|
|
3170
|
-
);
|
|
3171
|
-
}
|
|
3172
|
-
async fetchOne(id, options) {
|
|
3173
|
-
const builder = this.findById(id);
|
|
3174
|
-
if (options?.include != null) builder.include([...options.include]);
|
|
3175
|
-
if (options?.locale != null && options.locale !== "") builder.locale(options.locale);
|
|
3176
|
-
return builder.execute();
|
|
3177
|
-
}
|
|
3178
|
-
/** Fetch the first asset entry matching the conditions, or `null`. */
|
|
3179
|
-
async fetchFirst(where, locale) {
|
|
3180
|
-
const builder = this.query();
|
|
3181
|
-
if (where != null) builder.where(where);
|
|
3182
|
-
if (locale != null && locale !== "") builder.locale(locale);
|
|
3183
|
-
return builder.first();
|
|
3184
|
-
}
|
|
2644
|
+
var _AssetClient = class _AssetClient extends EntryHandle {
|
|
3185
2645
|
/**
|
|
3186
2646
|
* Create a new asset entry as a draft. The binary is uploaded separately via
|
|
3187
2647
|
* `file(uid)` (or use the high-level `upload()` helper), and the entry
|
|
3188
2648
|
* auto-publishes when its file becomes ready (unless `publish: false`).
|
|
3189
|
-
* `locale` defaults to the client's own
|
|
2649
|
+
* `locale` defaults to the client's own.
|
|
3190
2650
|
*/
|
|
3191
2651
|
async create(data, options) {
|
|
3192
2652
|
const { idempotencyKey, locale, ...rest } = options ?? {};
|
|
@@ -3195,58 +2655,19 @@ var _AssetClient = class _AssetClient {
|
|
|
3195
2655
|
"/v1/{contentType}",
|
|
3196
2656
|
"post",
|
|
3197
2657
|
{
|
|
3198
|
-
path: { contentType: this.
|
|
2658
|
+
path: { contentType: this.typeName },
|
|
3199
2659
|
body: { content: data, ...rest, ...sent === void 0 ? {} : { locale: sent } },
|
|
3200
2660
|
headers: writeHeaders({ idempotencyKey })
|
|
3201
2661
|
}
|
|
3202
2662
|
);
|
|
3203
2663
|
}
|
|
3204
|
-
/**
|
|
3205
|
-
* Update an asset entry's metadata fields (and/or slug). `locale` defaults to the client's own
|
|
3206
|
-
* (`withLocale()`).
|
|
3207
|
-
*/
|
|
3208
|
-
async update(id, data, options) {
|
|
3209
|
-
const { idempotencyKey, ifMatch, locale, ...rest } = options ?? {};
|
|
3210
|
-
const sent = callLocale(locale, this.clientLocale());
|
|
3211
|
-
return this.httpClient.fetchPayload(
|
|
3212
|
-
"/v1/{contentType}/{id}",
|
|
3213
|
-
"patch",
|
|
3214
|
-
{
|
|
3215
|
-
path: { contentType: this.assetType, id },
|
|
3216
|
-
body: { content: data, ...rest, ...sent === void 0 ? {} : { locale: sent } },
|
|
3217
|
-
headers: writeHeaders({ idempotencyKey, ifMatch })
|
|
3218
|
-
}
|
|
3219
|
-
);
|
|
3220
|
-
}
|
|
3221
|
-
/** Delete an asset entry (cascades file-byte cleanup + gateway purge). */
|
|
3222
|
-
async delete(id, options) {
|
|
3223
|
-
await this.httpClient.send("/v1/{contentType}/{id}", "delete", {
|
|
3224
|
-
path: { contentType: this.assetType, id },
|
|
3225
|
-
headers: writeHeaders(options)
|
|
3226
|
-
});
|
|
3227
|
-
}
|
|
3228
2664
|
/** Get the file sub-resource builder for a specific asset entry. */
|
|
3229
2665
|
file(entryUid) {
|
|
3230
|
-
return new AssetFileBuilder(this.httpClient, this.
|
|
2666
|
+
return new AssetFileBuilder(this.httpClient, this.typeName, entryUid, this.clientLocale);
|
|
3231
2667
|
}
|
|
3232
2668
|
/** Start a high-level upload (create → presign → PUT → confirm). */
|
|
3233
2669
|
upload(file) {
|
|
3234
|
-
return new AssetUploadBuilder(this.httpClient, this.
|
|
3235
|
-
}
|
|
3236
|
-
/** Get the asset type id. */
|
|
3237
|
-
getAssetType() {
|
|
3238
|
-
return this.assetType;
|
|
3239
|
-
}
|
|
3240
|
-
/** Get the default locale as it is now: the client's, or the one `withLocale()` fixed. */
|
|
3241
|
-
getDefaultLocale() {
|
|
3242
|
-
return this.clientLocale();
|
|
3243
|
-
}
|
|
3244
|
-
/**
|
|
3245
|
-
* Create a new AssetClient for this type with a different default locale, fixed: an update of the
|
|
3246
|
-
* client's locale (`updateConfig({ locale })`) does not reach it.
|
|
3247
|
-
*/
|
|
3248
|
-
withLocale(locale) {
|
|
3249
|
-
return new _AssetClient(this.httpClient, this.assetType, locale);
|
|
2670
|
+
return new AssetUploadBuilder(this.httpClient, this.typeName, file, this.clientLocale);
|
|
3250
2671
|
}
|
|
3251
2672
|
};
|
|
3252
2673
|
chunkMWMSFIWN_cjs.__name(_AssetClient, "AssetClient");
|
|
@@ -3258,1539 +2679,222 @@ function isAssetEntry(entry) {
|
|
|
3258
2679
|
}
|
|
3259
2680
|
chunkMWMSFIWN_cjs.__name(isAssetEntry, "isAssetEntry");
|
|
3260
2681
|
|
|
3261
|
-
// src/content/
|
|
3262
|
-
var
|
|
2682
|
+
// src/content/document-handle.ts
|
|
2683
|
+
var _DocumentHandle = class _DocumentHandle {
|
|
3263
2684
|
/**
|
|
2685
|
+
* @param name - The singleton key or settings group id the routes are addressed by
|
|
3264
2686
|
* @param locale - The client's locale: the function `TypedRelyIOClient` hands over, asked on
|
|
3265
|
-
* every call
|
|
2687
|
+
* every call
|
|
3266
2688
|
*/
|
|
3267
|
-
constructor(httpClient,
|
|
2689
|
+
constructor(httpClient, name, locale) {
|
|
3268
2690
|
this.httpClient = httpClient;
|
|
3269
|
-
this.
|
|
3270
|
-
|
|
3271
|
-
chunkMWMSFIWN_cjs.__publicField(this, "localeValue");
|
|
3272
|
-
/** The client's locale, asked on every call rather than copied when this client was taken. */
|
|
2691
|
+
this.name = name;
|
|
2692
|
+
/** The client's locale, asked on every call rather than copied when this handle was taken. */
|
|
3273
2693
|
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
3274
2694
|
this.clientLocale = readClientLocale(locale);
|
|
3275
2695
|
}
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
* read's type follows the paths — an expanded reference is the entry, every other one its id. A
|
|
3282
|
-
* second call adds to the first.
|
|
3283
|
-
*/
|
|
3284
|
-
include(paths) {
|
|
3285
|
-
this.includeFields = [...this.includeFields ?? [], ...paths];
|
|
3286
|
-
return this;
|
|
3287
|
-
}
|
|
3288
|
-
/**
|
|
3289
|
-
* Set locale for localized content
|
|
3290
|
-
* @param locale - Locale code (e.g., 'en', 'de', 'fr')
|
|
3291
|
-
*/
|
|
3292
|
-
locale(locale) {
|
|
3293
|
-
this.localeValue = locale;
|
|
3294
|
-
return this;
|
|
3295
|
-
}
|
|
3296
|
-
async fetch(options) {
|
|
3297
|
-
try {
|
|
3298
|
-
return (await this.fetchWithTag(options)).content;
|
|
3299
|
-
} catch (error) {
|
|
3300
|
-
if (isResourceNotFound(error)) return null;
|
|
3301
|
-
throw error;
|
|
2696
|
+
async update(...args) {
|
|
2697
|
+
if (isCheckedUpdate(args)) {
|
|
2698
|
+
const [read, content2, options2] = args;
|
|
2699
|
+
const { locale, ifMatch } = versionCheckOf(read);
|
|
2700
|
+
return this.patch({ content: content2, locale, ifMatch }, options2);
|
|
3302
2701
|
}
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
*
|
|
3308
|
-
* `entityTag` is absent on a cache HIT: a cached body cannot know the current
|
|
3309
|
-
* version, and a stale tag would refuse the very next write.
|
|
3310
|
-
*/
|
|
3311
|
-
async fetchWithTag(options) {
|
|
3312
|
-
const query = {};
|
|
3313
|
-
const includeValue = this.includeFields === void 0 && options?.include === void 0 ? void 0 : [...this.includeFields ?? [], ...options?.include ?? []];
|
|
3314
|
-
const localeValueFinal = options?.locale ?? this.localeValue ?? this.clientLocale();
|
|
3315
|
-
if (includeValue) query.include = includeValue.join(",");
|
|
3316
|
-
if (localeValueFinal != null && localeValueFinal !== "") query.locale = localeValueFinal;
|
|
3317
|
-
if (options?.fresh !== void 0) query[FRESH_PARAMETER] = options.fresh;
|
|
3318
|
-
const response = await this.httpClient.send(
|
|
3319
|
-
"/v1/singletons/{key}",
|
|
3320
|
-
"get",
|
|
3321
|
-
{ path: { key: this.singletonKey }, query }
|
|
3322
|
-
);
|
|
3323
|
-
return { content: readPayload(response.body), entityTag: entityTagOf(response) };
|
|
3324
|
-
}
|
|
3325
|
-
/**
|
|
3326
|
-
* Update singleton content. The API auto-publishes on PATCH — there is no
|
|
3327
|
-
* separate publish route; calling `update()` writes and publishes.
|
|
3328
|
-
* @param data - The content fields to update
|
|
3329
|
-
* @param locale - Optional locale for localized content (overrides the fluent locale, which
|
|
3330
|
-
* overrides the client's own)
|
|
3331
|
-
* @param options - `If-Match` / `Idempotency-Key`, both declared on this route
|
|
3332
|
-
*/
|
|
3333
|
-
async update(data, locale, options) {
|
|
3334
|
-
const finalLocale = this.localeOf(locale);
|
|
3335
|
-
return this.httpClient.fetchPayload(
|
|
3336
|
-
"/v1/singletons/{key}",
|
|
3337
|
-
"patch",
|
|
3338
|
-
{
|
|
3339
|
-
path: { key: this.singletonKey },
|
|
3340
|
-
body: {
|
|
3341
|
-
content: data,
|
|
3342
|
-
...finalLocale != null && finalLocale !== "" && { locale: finalLocale }
|
|
3343
|
-
},
|
|
3344
|
-
headers: writeHeaders(options)
|
|
3345
|
-
}
|
|
2702
|
+
const [content, options] = args;
|
|
2703
|
+
return this.patch(
|
|
2704
|
+
{ content, locale: this.localeOf(options?.locale), ifMatch: void 0 },
|
|
2705
|
+
options
|
|
3346
2706
|
);
|
|
3347
2707
|
}
|
|
3348
2708
|
/**
|
|
3349
|
-
*
|
|
3350
|
-
*/
|
|
3351
|
-
async exists() {
|
|
3352
|
-
try {
|
|
3353
|
-
const result = await this.fetch();
|
|
3354
|
-
return result !== null;
|
|
3355
|
-
} catch {
|
|
3356
|
-
return false;
|
|
3357
|
-
}
|
|
3358
|
-
}
|
|
3359
|
-
/**
|
|
3360
|
-
* Get version history for one locale of the singleton.
|
|
2709
|
+
* Version history for one locale of the document.
|
|
3361
2710
|
*
|
|
3362
2711
|
* Versions are numbered per locale, so this is one locale's timeline: `locale` defaults to the
|
|
3363
|
-
*
|
|
3364
|
-
*
|
|
3365
|
-
*
|
|
3366
|
-
*/
|
|
3367
|
-
async versions(options) {
|
|
3368
|
-
const locale = this.localeOf(options
|
|
3369
|
-
const payload = await this.
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
limit: options?.limit ?? 10,
|
|
3373
|
-
...locale === void 0 ? {} : { locale }
|
|
3374
|
-
}
|
|
2712
|
+
* client's own, then the schema default; no fallback is applied, and a locale with no history
|
|
2713
|
+
* returns an empty array rather than another locale's rows. Every row names the locale it belongs
|
|
2714
|
+
* to.
|
|
2715
|
+
*/
|
|
2716
|
+
async versions(options = {}) {
|
|
2717
|
+
const locale = this.localeOf(options.locale);
|
|
2718
|
+
const payload = await this.readVersions({
|
|
2719
|
+
limit: options.limit ?? 10,
|
|
2720
|
+
...locale === void 0 ? {} : { locale }
|
|
3375
2721
|
});
|
|
3376
2722
|
return payload.versions;
|
|
3377
2723
|
}
|
|
3378
2724
|
/**
|
|
3379
|
-
*
|
|
2725
|
+
* One version of the document: `version({ version, locale })`. `locale` defaults to the client's
|
|
2726
|
+
* own, then the schema default; version numbers are per locale, so version 2 is different content
|
|
2727
|
+
* in each one.
|
|
3380
2728
|
*
|
|
3381
|
-
* `
|
|
3382
|
-
* schema
|
|
2729
|
+
* There is no `null`: a version the locale does not have, a document nobody has written, one the
|
|
2730
|
+
* schema does not declare and a dataset with no schema all throw `ResourceNotFoundError`, its
|
|
2731
|
+
* `context.resourceType` naming which (REL-2409 Q12).
|
|
3383
2732
|
*/
|
|
3384
|
-
async version(
|
|
3385
|
-
const locale = this.localeOf(options
|
|
3386
|
-
|
|
3387
|
-
return await this.httpClient.fetchPayload("/v1/singletons/{key}/versions/{versionNumber}", "get", {
|
|
3388
|
-
path: { key: this.singletonKey, versionNumber: String(versionNumber) },
|
|
3389
|
-
query: locale === void 0 ? void 0 : { locale }
|
|
3390
|
-
});
|
|
3391
|
-
} catch (error) {
|
|
3392
|
-
if (isResourceNotFound(error)) return null;
|
|
3393
|
-
throw error;
|
|
3394
|
-
}
|
|
2733
|
+
async version(options) {
|
|
2734
|
+
const locale = this.localeOf(options.locale);
|
|
2735
|
+
return this.readVersion(String(options.version), locale === void 0 ? {} : { locale });
|
|
3395
2736
|
}
|
|
3396
|
-
/** The locale a write or history read sends: the call's,
|
|
2737
|
+
/** The locale a write or a history read sends: the call's, else the client's. */
|
|
3397
2738
|
localeOf(named) {
|
|
3398
|
-
return callLocale(named
|
|
3399
|
-
}
|
|
3400
|
-
/**
|
|
3401
|
-
* Get the singleton key
|
|
3402
|
-
*/
|
|
3403
|
-
getSingletonKey() {
|
|
3404
|
-
return this.singletonKey;
|
|
3405
|
-
}
|
|
3406
|
-
/**
|
|
3407
|
-
* Reset fluent options for reuse
|
|
3408
|
-
*/
|
|
3409
|
-
reset() {
|
|
3410
|
-
this.includeFields = void 0;
|
|
3411
|
-
this.localeValue = void 0;
|
|
3412
|
-
return this;
|
|
3413
|
-
}
|
|
3414
|
-
};
|
|
3415
|
-
chunkMWMSFIWN_cjs.__name(_SingletonClient, "SingletonClient");
|
|
3416
|
-
var SingletonClient = _SingletonClient;
|
|
3417
|
-
|
|
3418
|
-
// src/content/settings-client.ts
|
|
3419
|
-
var _SettingsClient = class _SettingsClient {
|
|
3420
|
-
/**
|
|
3421
|
-
* @param locale - The client's locale: the function `TypedRelyIOClient` hands over, asked on
|
|
3422
|
-
* every call, or a locale fixed for this client
|
|
3423
|
-
*/
|
|
3424
|
-
constructor(httpClient, groupId, locale) {
|
|
3425
|
-
this.httpClient = httpClient;
|
|
3426
|
-
this.groupId = groupId;
|
|
3427
|
-
chunkMWMSFIWN_cjs.__publicField(this, "includeFields");
|
|
3428
|
-
chunkMWMSFIWN_cjs.__publicField(this, "localeValue");
|
|
3429
|
-
/** The client's locale, asked on every call rather than copied when this client was taken. */
|
|
3430
|
-
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
3431
|
-
this.clientLocale = readClientLocale(locale);
|
|
3432
|
-
}
|
|
3433
|
-
/**
|
|
3434
|
-
* Expand references into the entries they point at: one include path per element (REL-1801).
|
|
3435
|
-
* A path names fields through lists, objects and references — `'hero.media.image'`,
|
|
3436
|
-
* `'featured.author'` — and may pick the fields each entry returns, `'featured(title,slug)'`.
|
|
3437
|
-
* Each is checked against the schema: a path that holds no reference does not compile, and the
|
|
3438
|
-
* read's type follows the paths — an expanded reference is the entry, every other one its id. A
|
|
3439
|
-
* second call adds to the first.
|
|
3440
|
-
*/
|
|
3441
|
-
include(paths) {
|
|
3442
|
-
this.includeFields = [...this.includeFields ?? [], ...paths];
|
|
3443
|
-
return this;
|
|
3444
|
-
}
|
|
3445
|
-
/**
|
|
3446
|
-
* Set locale for localized settings
|
|
3447
|
-
* @param locale - Locale code (e.g., 'en', 'de', 'fr')
|
|
3448
|
-
*/
|
|
3449
|
-
locale(locale) {
|
|
3450
|
-
this.localeValue = locale;
|
|
3451
|
-
return this;
|
|
3452
|
-
}
|
|
3453
|
-
async fetch(options) {
|
|
3454
|
-
try {
|
|
3455
|
-
return (await this.fetchWithTag(options)).settings;
|
|
3456
|
-
} catch (error) {
|
|
3457
|
-
if (isResourceNotFound(error)) return null;
|
|
3458
|
-
throw error;
|
|
3459
|
-
}
|
|
2739
|
+
return callLocale(named, this.clientLocale());
|
|
3460
2740
|
}
|
|
3461
|
-
/**
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
*
|
|
3467
|
-
* @param settings - The settings fields to update
|
|
3468
|
-
* @param locale - Optional locale for localized settings (overrides the fluent locale, which
|
|
3469
|
-
* overrides the client's own)
|
|
3470
|
-
*/
|
|
3471
|
-
async update(settings, locale, options) {
|
|
3472
|
-
const finalLocale = this.localeOf(locale);
|
|
3473
|
-
const body = {
|
|
3474
|
-
content: settings,
|
|
3475
|
-
...finalLocale != null && finalLocale !== "" ? { locale: finalLocale } : {}
|
|
2741
|
+
/** The write's body: its data, and the locale it names when it names one. */
|
|
2742
|
+
static bodyOf(write) {
|
|
2743
|
+
return {
|
|
2744
|
+
content: write.content,
|
|
2745
|
+
...write.locale === void 0 ? {} : { locale: write.locale }
|
|
3476
2746
|
};
|
|
3477
|
-
return this.httpClient.fetchPayload(
|
|
3478
|
-
"/v1/settings/{groupId}",
|
|
3479
|
-
"patch",
|
|
3480
|
-
{ path: { groupId: this.groupId }, body, headers: writeHeaders(options) }
|
|
3481
|
-
);
|
|
3482
|
-
}
|
|
3483
|
-
/**
|
|
3484
|
-
* Fetch the group **and the entity tag that read served**, which is what
|
|
3485
|
-
* `update`'s and `reset`'s `ifMatch` take
|
|
3486
|
-
* (`INV-API-CONDITIONAL-WRITE-IS-REACHABLE`).
|
|
3487
|
-
*/
|
|
3488
|
-
async fetchWithTag(options) {
|
|
3489
|
-
const query = {};
|
|
3490
|
-
const includeValue = this.includeFields === void 0 && options?.include === void 0 ? void 0 : [...this.includeFields ?? [], ...options?.include ?? []];
|
|
3491
|
-
const localeValueFinal = options?.locale ?? this.localeValue ?? this.clientLocale();
|
|
3492
|
-
if (includeValue) query.include = includeValue.join(",");
|
|
3493
|
-
if (localeValueFinal != null && localeValueFinal !== "") query.locale = localeValueFinal;
|
|
3494
|
-
const response = await this.httpClient.send(
|
|
3495
|
-
"/v1/settings/{groupId}",
|
|
3496
|
-
"get",
|
|
3497
|
-
{ path: { groupId: this.groupId }, query }
|
|
3498
|
-
);
|
|
3499
|
-
return { settings: readPayload(response.body), entityTag: entityTagOf(response) };
|
|
3500
|
-
}
|
|
3501
|
-
/**
|
|
3502
|
-
* Reset settings to default values
|
|
3503
|
-
*
|
|
3504
|
-
* The route reads its locale from `?locale=` and takes no body, so that is where it is sent.
|
|
3505
|
-
*
|
|
3506
|
-
* @param locale - Optional locale for localized settings (overrides the fluent locale, which
|
|
3507
|
-
* overrides the client's own)
|
|
3508
|
-
*/
|
|
3509
|
-
async reset(locale, options) {
|
|
3510
|
-
const finalLocale = this.localeOf(locale);
|
|
3511
|
-
return this.httpClient.fetchPayload(
|
|
3512
|
-
"/v1/settings/{groupId}/reset",
|
|
3513
|
-
"post",
|
|
3514
|
-
{
|
|
3515
|
-
path: { groupId: this.groupId },
|
|
3516
|
-
query: finalLocale != null && finalLocale !== "" ? { locale: finalLocale } : void 0,
|
|
3517
|
-
headers: writeHeaders(options)
|
|
3518
|
-
}
|
|
3519
|
-
);
|
|
3520
|
-
}
|
|
3521
|
-
/**
|
|
3522
|
-
* Get default settings for this group
|
|
3523
|
-
*/
|
|
3524
|
-
async getDefaults() {
|
|
3525
|
-
return this.httpClient.fetchPayload(
|
|
3526
|
-
"/v1/settings/{groupId}/defaults",
|
|
3527
|
-
"get",
|
|
3528
|
-
{ path: { groupId: this.groupId } }
|
|
3529
|
-
);
|
|
3530
|
-
}
|
|
3531
|
-
/**
|
|
3532
|
-
* Check if settings group exists
|
|
3533
|
-
*/
|
|
3534
|
-
async exists() {
|
|
3535
|
-
try {
|
|
3536
|
-
const result = await this.fetch();
|
|
3537
|
-
return result !== null;
|
|
3538
|
-
} catch (error) {
|
|
3539
|
-
if (isResourceNotFound(error)) return false;
|
|
3540
|
-
throw error;
|
|
3541
|
-
}
|
|
3542
|
-
}
|
|
3543
|
-
/**
|
|
3544
|
-
* Get version history for one locale of the settings group.
|
|
3545
|
-
*
|
|
3546
|
-
* Versions are numbered per locale, so this is one locale's timeline: `locale` defaults to the
|
|
3547
|
-
* fluent `.locale()`, then the client's own (`withLocale()`), then the schema default; no
|
|
3548
|
-
* fallback is applied, and a locale with no history returns an empty array rather than another
|
|
3549
|
-
* locale's rows. Every row names the locale it belongs to.
|
|
3550
|
-
*/
|
|
3551
|
-
async versions(options) {
|
|
3552
|
-
const locale = this.localeOf(options?.locale);
|
|
3553
|
-
const payload = await this.httpClient.fetchPayload("/v1/settings/{groupId}/versions", "get", {
|
|
3554
|
-
path: { groupId: this.groupId },
|
|
3555
|
-
query: {
|
|
3556
|
-
limit: options?.limit ?? 10,
|
|
3557
|
-
...locale === void 0 ? {} : { locale }
|
|
3558
|
-
}
|
|
3559
|
-
});
|
|
3560
|
-
return payload.versions;
|
|
3561
|
-
}
|
|
3562
|
-
/**
|
|
3563
|
-
* Get a specific version of the settings.
|
|
3564
|
-
*
|
|
3565
|
-
* `locale` defaults to the fluent `.locale()`, then the client's own (`withLocale()`), then the
|
|
3566
|
-
* schema default. Version numbers are per locale, so version 2 is different content in each one.
|
|
3567
|
-
*/
|
|
3568
|
-
async version(versionNumber, options) {
|
|
3569
|
-
const locale = this.localeOf(options?.locale);
|
|
3570
|
-
try {
|
|
3571
|
-
return await this.httpClient.fetchPayload("/v1/settings/{groupId}/versions/{versionNumber}", "get", {
|
|
3572
|
-
path: { groupId: this.groupId, versionNumber: String(versionNumber) },
|
|
3573
|
-
query: locale === void 0 ? void 0 : { locale }
|
|
3574
|
-
});
|
|
3575
|
-
} catch (error) {
|
|
3576
|
-
if (isResourceNotFound(error)) return null;
|
|
3577
|
-
throw error;
|
|
3578
|
-
}
|
|
3579
|
-
}
|
|
3580
|
-
/** The locale a write or history read sends: the call's, the fluent one, else the client's. */
|
|
3581
|
-
localeOf(named) {
|
|
3582
|
-
return callLocale(named ?? this.localeValue, this.clientLocale());
|
|
3583
|
-
}
|
|
3584
|
-
/**
|
|
3585
|
-
* Get the settings group ID
|
|
3586
|
-
*/
|
|
3587
|
-
getGroupId() {
|
|
3588
|
-
return this.groupId;
|
|
3589
2747
|
}
|
|
3590
|
-
/**
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
resetOptions() {
|
|
3594
|
-
this.includeFields = void 0;
|
|
3595
|
-
this.localeValue = void 0;
|
|
3596
|
-
return this;
|
|
2748
|
+
/** The two headers a write sends: its check, when it has one, and its `Idempotency-Key`. */
|
|
2749
|
+
static headersOf(write, options) {
|
|
2750
|
+
return writeHeaders({ idempotencyKey: options?.idempotencyKey, ifMatch: write.ifMatch });
|
|
3597
2751
|
}
|
|
3598
2752
|
};
|
|
3599
|
-
chunkMWMSFIWN_cjs.__name(
|
|
3600
|
-
var
|
|
2753
|
+
chunkMWMSFIWN_cjs.__name(_DocumentHandle, "DocumentHandle");
|
|
2754
|
+
var DocumentHandle = _DocumentHandle;
|
|
2755
|
+
function isCheckedUpdate(args) {
|
|
2756
|
+
return isRead(args[0]);
|
|
2757
|
+
}
|
|
2758
|
+
chunkMWMSFIWN_cjs.__name(isCheckedUpdate, "isCheckedUpdate");
|
|
2759
|
+
function isRead(value) {
|
|
2760
|
+
return "_metadata" in value && typeof value._metadata === "object" && value._metadata !== null;
|
|
2761
|
+
}
|
|
2762
|
+
chunkMWMSFIWN_cjs.__name(isRead, "isRead");
|
|
3601
2763
|
|
|
3602
|
-
// src/
|
|
3603
|
-
var
|
|
3604
|
-
/**
|
|
3605
|
-
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent when
|
|
3606
|
-
* `.locale()` names none: the function `TypedRelyIOClient` hands over, or a locale fixed for it
|
|
3607
|
-
*/
|
|
3608
|
-
constructor(httpClient, query, locale) {
|
|
3609
|
-
this.httpClient = httpClient;
|
|
3610
|
-
chunkMWMSFIWN_cjs.__publicField(this, "query");
|
|
3611
|
-
chunkMWMSFIWN_cjs.__publicField(this, "searchOptions", {});
|
|
3612
|
-
chunkMWMSFIWN_cjs.__publicField(this, "requestHeaders");
|
|
3613
|
-
chunkMWMSFIWN_cjs.__publicField(this, "freshValue");
|
|
3614
|
-
/** The client's locale, asked when the query is sent rather than copied when it was built. */
|
|
3615
|
-
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
3616
|
-
this.query = query;
|
|
3617
|
-
this.clientLocale = readClientLocale(locale);
|
|
3618
|
-
}
|
|
3619
|
-
/**
|
|
3620
|
-
* Headers this search adds to the client's own, e.g. `X-RelyIO-Dataset` to search another
|
|
3621
|
-
* dataset the key can see. A name the client already sends is replaced for this search only.
|
|
3622
|
-
*/
|
|
3623
|
-
headers(headers) {
|
|
3624
|
-
this.requestHeaders = headers;
|
|
3625
|
-
return this;
|
|
3626
|
-
}
|
|
3627
|
-
/**
|
|
3628
|
-
* The feed position this search follows — a change's `fresh` (`FeedChange`), or a resync's. Sent
|
|
3629
|
-
* as `?_fresh` on the query string beside the body: the edge keys a search on both, so no answer
|
|
3630
|
-
* it holds from before that position can answer it. The answer is the search's own.
|
|
3631
|
-
*/
|
|
3632
|
-
fresh(position) {
|
|
3633
|
-
this.freshValue = position;
|
|
3634
|
-
return this;
|
|
3635
|
-
}
|
|
3636
|
-
/**
|
|
3637
|
-
* Search within a single content type. Where a schema types the client, the name is one of its
|
|
3638
|
-
* content types and the results are that type's entries.
|
|
3639
|
-
* @param contentType - Content type to search in
|
|
3640
|
-
*/
|
|
3641
|
-
in(contentType) {
|
|
3642
|
-
this.searchOptions.contentType = contentType;
|
|
3643
|
-
this.searchOptions.contentTypes = void 0;
|
|
3644
|
-
return this;
|
|
3645
|
-
}
|
|
3646
|
-
/**
|
|
3647
|
-
* Search across multiple content types. Where a schema types the client, the names are its content
|
|
3648
|
-
* types and the results are a union of their entries — every type's, for `'*'`.
|
|
3649
|
-
* @param contentTypes - Array of content types or '*' for all
|
|
3650
|
-
*/
|
|
3651
|
-
across(contentTypes) {
|
|
3652
|
-
this.searchOptions.contentTypes = contentTypes;
|
|
3653
|
-
this.searchOptions.contentType = void 0;
|
|
3654
|
-
return this;
|
|
3655
|
-
}
|
|
3656
|
-
/**
|
|
3657
|
-
* Add filter conditions, on the fields the content types declare. A condition on `_metadata` is
|
|
3658
|
-
* refused here, before anything is sent.
|
|
3659
|
-
* @param conditions - Filter conditions
|
|
3660
|
-
*/
|
|
3661
|
-
where(conditions) {
|
|
3662
|
-
refuseMetadataConditions(conditions);
|
|
3663
|
-
this.searchOptions.where = {
|
|
3664
|
-
...this.searchOptions.where,
|
|
3665
|
-
...conditions
|
|
3666
|
-
};
|
|
3667
|
-
return this;
|
|
3668
|
-
}
|
|
3669
|
-
/**
|
|
3670
|
-
* Specify which fields to search in
|
|
3671
|
-
* @param fields - Field names to search
|
|
3672
|
-
*/
|
|
3673
|
-
searchFields(fields) {
|
|
3674
|
-
this.searchOptions.searchFields = fields;
|
|
3675
|
-
return this;
|
|
3676
|
-
}
|
|
3677
|
-
/**
|
|
3678
|
-
* Project specific fields in results
|
|
3679
|
-
* @param projection - Field mapping
|
|
3680
|
-
*/
|
|
3681
|
-
fields(projection) {
|
|
3682
|
-
this.searchOptions.fields = projection;
|
|
3683
|
-
return this;
|
|
3684
|
-
}
|
|
3685
|
-
/**
|
|
3686
|
-
* Order the results by a field instead of by relevance. Called again, it adds a tie-breaker.
|
|
3687
|
-
* `_score` names relevance itself.
|
|
3688
|
-
* @param field - Field path to sort by (e.g. `updatedAt`, `pricing.basePrice`)
|
|
3689
|
-
* @param direction - `asc` or `desc` (the route's default is `desc`)
|
|
3690
|
-
*/
|
|
3691
|
-
sort(field, direction = "desc") {
|
|
3692
|
-
this.searchOptions.sort = [...this.searchOptions.sort ?? [], { field, direction }];
|
|
3693
|
-
return this;
|
|
3694
|
-
}
|
|
3695
|
-
/**
|
|
3696
|
-
* Limit number of results
|
|
3697
|
-
* @param count - Maximum results
|
|
3698
|
-
*/
|
|
3699
|
-
limit(count) {
|
|
3700
|
-
this.searchOptions.limit = count;
|
|
3701
|
-
return this;
|
|
3702
|
-
}
|
|
3703
|
-
/**
|
|
3704
|
-
* Skip results for pagination
|
|
3705
|
-
* @param count - Number to skip
|
|
3706
|
-
*/
|
|
3707
|
-
offset(count) {
|
|
3708
|
-
this.searchOptions.offset = count;
|
|
3709
|
-
return this;
|
|
3710
|
-
}
|
|
3711
|
-
/**
|
|
3712
|
-
* Include relevance scores in results
|
|
3713
|
-
*/
|
|
3714
|
-
includeScore() {
|
|
3715
|
-
this.searchOptions.includeScore = true;
|
|
3716
|
-
return this;
|
|
3717
|
-
}
|
|
3718
|
-
/**
|
|
3719
|
-
* Include score breakdown explanation
|
|
3720
|
-
*/
|
|
3721
|
-
explain() {
|
|
3722
|
-
this.searchOptions.explain = true;
|
|
3723
|
-
return this;
|
|
3724
|
-
}
|
|
3725
|
-
/**
|
|
3726
|
-
* Set locale for localized content
|
|
3727
|
-
* @param locale - Locale code
|
|
3728
|
-
*/
|
|
3729
|
-
locale(locale) {
|
|
3730
|
-
this.searchOptions.locale = locale;
|
|
3731
|
-
return this;
|
|
3732
|
-
}
|
|
3733
|
-
/**
|
|
3734
|
-
* Execute the search query
|
|
3735
|
-
*/
|
|
3736
|
-
async execute() {
|
|
3737
|
-
const body = {
|
|
3738
|
-
q: this.query
|
|
3739
|
-
};
|
|
3740
|
-
if (this.searchOptions.contentType != null && this.searchOptions.contentType !== "") {
|
|
3741
|
-
body.contentType = this.searchOptions.contentType;
|
|
3742
|
-
}
|
|
3743
|
-
if (this.searchOptions.contentTypes != null) {
|
|
3744
|
-
body.contentTypes = this.searchOptions.contentTypes;
|
|
3745
|
-
}
|
|
3746
|
-
if (this.searchOptions.where && Object.keys(this.searchOptions.where).length > 0) {
|
|
3747
|
-
body.where = this.searchOptions.where;
|
|
3748
|
-
}
|
|
3749
|
-
if (this.searchOptions.searchFields) {
|
|
3750
|
-
body.searchFields = this.searchOptions.searchFields;
|
|
3751
|
-
}
|
|
3752
|
-
if (this.searchOptions.fields) {
|
|
3753
|
-
body.fields = this.searchOptions.fields;
|
|
3754
|
-
}
|
|
3755
|
-
if (this.searchOptions.sort) {
|
|
3756
|
-
body.sort = this.searchOptions.sort;
|
|
3757
|
-
}
|
|
3758
|
-
if (this.searchOptions.limit !== void 0) {
|
|
3759
|
-
body.limit = this.searchOptions.limit;
|
|
3760
|
-
}
|
|
3761
|
-
if (this.searchOptions.offset !== void 0) {
|
|
3762
|
-
body.offset = this.searchOptions.offset;
|
|
3763
|
-
}
|
|
3764
|
-
if (this.searchOptions.includeScore === true) {
|
|
3765
|
-
body.includeScore = true;
|
|
3766
|
-
}
|
|
3767
|
-
if (this.searchOptions.explain === true) {
|
|
3768
|
-
body.explain = true;
|
|
3769
|
-
}
|
|
3770
|
-
const locale = this.searchOptions.locale ?? this.clientLocale();
|
|
3771
|
-
if (locale != null && locale !== "") {
|
|
3772
|
-
body.locale = locale;
|
|
3773
|
-
}
|
|
3774
|
-
const response = await this.httpClient.send(
|
|
3775
|
-
"/v1/search",
|
|
3776
|
-
"post",
|
|
3777
|
-
{
|
|
3778
|
-
body,
|
|
3779
|
-
headers: this.requestHeaders,
|
|
3780
|
-
...this.freshValue === void 0 ? {} : { query: { [FRESH_PARAMETER]: this.freshValue } }
|
|
3781
|
-
}
|
|
3782
|
-
);
|
|
3783
|
-
return response.body;
|
|
3784
|
-
}
|
|
3785
|
-
/**
|
|
3786
|
-
* Execute and return just the items (convenience method)
|
|
3787
|
-
*/
|
|
3788
|
-
async items() {
|
|
3789
|
-
return readPayload(await this.execute());
|
|
3790
|
-
}
|
|
3791
|
-
/**
|
|
3792
|
-
* Get the first result
|
|
3793
|
-
*/
|
|
3794
|
-
async first() {
|
|
3795
|
-
return readPayload(await this.limit(1).execute())[0] ?? null;
|
|
3796
|
-
}
|
|
3797
|
-
};
|
|
3798
|
-
chunkMWMSFIWN_cjs.__name(_SearchBuilder, "SearchBuilder");
|
|
3799
|
-
var SearchBuilder = _SearchBuilder;
|
|
3800
|
-
var _AutocompleteBuilder = class _AutocompleteBuilder {
|
|
3801
|
-
/**
|
|
3802
|
-
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent when
|
|
3803
|
-
* `.locale()` names none: the function `TypedRelyIOClient` hands over, or a locale fixed for it
|
|
3804
|
-
*/
|
|
3805
|
-
constructor(httpClient, query, locale) {
|
|
3806
|
-
this.httpClient = httpClient;
|
|
3807
|
-
chunkMWMSFIWN_cjs.__publicField(this, "query");
|
|
3808
|
-
chunkMWMSFIWN_cjs.__publicField(this, "autocompleteOptions", {});
|
|
3809
|
-
/** The client's locale, asked when the query is sent rather than copied when it was built. */
|
|
3810
|
-
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
3811
|
-
this.query = query;
|
|
3812
|
-
this.clientLocale = readClientLocale(locale);
|
|
3813
|
-
}
|
|
3814
|
-
/**
|
|
3815
|
-
* Autocomplete within a content type
|
|
3816
|
-
* @param contentType - Content type to search
|
|
3817
|
-
*/
|
|
3818
|
-
in(contentType) {
|
|
3819
|
-
this.autocompleteOptions.contentType = contentType;
|
|
3820
|
-
return this;
|
|
3821
|
-
}
|
|
3822
|
-
/**
|
|
3823
|
-
* Field to autocomplete on
|
|
3824
|
-
* @param fieldName - Field name (supports nested like 'category.name')
|
|
3825
|
-
*/
|
|
3826
|
-
field(fieldName) {
|
|
3827
|
-
this.autocompleteOptions.field = fieldName;
|
|
3828
|
-
return this;
|
|
3829
|
-
}
|
|
3830
|
-
/**
|
|
3831
|
-
* Enable fuzzy matching for typo tolerance
|
|
3832
|
-
*/
|
|
3833
|
-
fuzzy() {
|
|
3834
|
-
this.autocompleteOptions.fuzzy = true;
|
|
3835
|
-
return this;
|
|
3836
|
-
}
|
|
3837
|
-
/**
|
|
3838
|
-
* Add filter conditions, on the fields the content types declare. A condition on `_metadata` is
|
|
3839
|
-
* refused here, before anything is sent.
|
|
3840
|
-
* @param conditions - Filter conditions
|
|
3841
|
-
*/
|
|
3842
|
-
where(conditions) {
|
|
3843
|
-
refuseMetadataConditions(conditions);
|
|
3844
|
-
this.autocompleteOptions.where = {
|
|
3845
|
-
...this.autocompleteOptions.where,
|
|
3846
|
-
...conditions
|
|
3847
|
-
};
|
|
3848
|
-
return this;
|
|
3849
|
-
}
|
|
3850
|
-
/**
|
|
3851
|
-
* Limit number of suggestions
|
|
3852
|
-
* @param count - Maximum suggestions
|
|
3853
|
-
*/
|
|
3854
|
-
limit(count) {
|
|
3855
|
-
this.autocompleteOptions.limit = count;
|
|
3856
|
-
return this;
|
|
3857
|
-
}
|
|
3858
|
-
/**
|
|
3859
|
-
* Set locale for localized content
|
|
3860
|
-
* @param locale - Locale code
|
|
3861
|
-
*/
|
|
3862
|
-
locale(locale) {
|
|
3863
|
-
this.autocompleteOptions.locale = locale;
|
|
3864
|
-
return this;
|
|
3865
|
-
}
|
|
3866
|
-
/**
|
|
3867
|
-
* Execute the autocomplete query
|
|
3868
|
-
*/
|
|
3869
|
-
async execute() {
|
|
3870
|
-
if (this.autocompleteOptions.contentType == null || this.autocompleteOptions.contentType === "") {
|
|
3871
|
-
throw new Error('Content type is required for autocomplete. Use .in("contentType")');
|
|
3872
|
-
}
|
|
3873
|
-
if (this.autocompleteOptions.field == null || this.autocompleteOptions.field === "") {
|
|
3874
|
-
throw new Error('Field is required for autocomplete. Use .field("fieldName")');
|
|
3875
|
-
}
|
|
3876
|
-
const body = {
|
|
3877
|
-
q: this.query,
|
|
3878
|
-
contentType: this.autocompleteOptions.contentType,
|
|
3879
|
-
field: this.autocompleteOptions.field
|
|
3880
|
-
};
|
|
3881
|
-
if (this.autocompleteOptions.fuzzy === true) {
|
|
3882
|
-
body.fuzzy = true;
|
|
3883
|
-
}
|
|
3884
|
-
if (this.autocompleteOptions.where && Object.keys(this.autocompleteOptions.where).length > 0) {
|
|
3885
|
-
body.where = this.autocompleteOptions.where;
|
|
3886
|
-
}
|
|
3887
|
-
if (this.autocompleteOptions.limit !== void 0) {
|
|
3888
|
-
body.limit = this.autocompleteOptions.limit;
|
|
3889
|
-
}
|
|
3890
|
-
const locale = this.autocompleteOptions.locale ?? this.clientLocale();
|
|
3891
|
-
if (locale != null && locale !== "") {
|
|
3892
|
-
body.locale = locale;
|
|
3893
|
-
}
|
|
3894
|
-
const response = await this.httpClient.send("/v1/search/autocomplete", "post", { body });
|
|
3895
|
-
return response.body;
|
|
3896
|
-
}
|
|
3897
|
-
/**
|
|
3898
|
-
* Get just the suggestion texts
|
|
3899
|
-
*/
|
|
3900
|
-
async texts() {
|
|
3901
|
-
return readPayload(await this.execute()).map((suggestion) => suggestion.text);
|
|
3902
|
-
}
|
|
3903
|
-
};
|
|
3904
|
-
chunkMWMSFIWN_cjs.__name(_AutocompleteBuilder, "AutocompleteBuilder");
|
|
3905
|
-
var AutocompleteBuilder = _AutocompleteBuilder;
|
|
3906
|
-
var _SimilarBuilder = class _SimilarBuilder {
|
|
3907
|
-
/**
|
|
3908
|
-
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent when
|
|
3909
|
-
* `.locale()` names none: the function `TypedRelyIOClient` hands over, or a locale fixed for it
|
|
3910
|
-
*/
|
|
3911
|
-
constructor(httpClient, sourceId, locale) {
|
|
3912
|
-
this.httpClient = httpClient;
|
|
3913
|
-
chunkMWMSFIWN_cjs.__publicField(this, "sourceId");
|
|
3914
|
-
chunkMWMSFIWN_cjs.__publicField(this, "similarOptions", {});
|
|
3915
|
-
chunkMWMSFIWN_cjs.__publicField(this, "requestHeaders");
|
|
3916
|
-
/** The client's locale, asked when the read is sent rather than copied when it was built. */
|
|
3917
|
-
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
3918
|
-
this.sourceId = sourceId;
|
|
3919
|
-
this.clientLocale = readClientLocale(locale);
|
|
3920
|
-
}
|
|
3921
|
-
/**
|
|
3922
|
-
* Headers this read adds to the client's own, e.g. `X-RelyIO-Dataset` to read another dataset
|
|
3923
|
-
* the key can see. A name the client already sends is replaced for this read only.
|
|
3924
|
-
*/
|
|
3925
|
-
headers(headers) {
|
|
3926
|
-
this.requestHeaders = headers;
|
|
3927
|
-
return this;
|
|
3928
|
-
}
|
|
3929
|
-
/**
|
|
3930
|
-
* Find similar content within a content type
|
|
3931
|
-
* @param contentType - Content type to search
|
|
3932
|
-
*/
|
|
3933
|
-
in(contentType) {
|
|
3934
|
-
this.similarOptions.contentType = contentType;
|
|
3935
|
-
this.similarOptions.contentTypes = void 0;
|
|
3936
|
-
return this;
|
|
3937
|
-
}
|
|
3938
|
-
/**
|
|
3939
|
-
* Find similar content across several content types, or `'*'` for every type
|
|
3940
|
-
* @param contentTypes - Array of content types or '*' for all
|
|
3941
|
-
*/
|
|
3942
|
-
across(contentTypes) {
|
|
3943
|
-
this.similarOptions.contentTypes = contentTypes;
|
|
3944
|
-
this.similarOptions.contentType = void 0;
|
|
3945
|
-
return this;
|
|
3946
|
-
}
|
|
3947
|
-
/*
|
|
3948
|
-
* No `where()` (REL-1452). Similar ranks from the source entry's stored vector, and the vector
|
|
3949
|
-
* index can pre-filter by content type and locale only — never by an entry field. The API used to
|
|
3950
|
-
* accept `where` here and apply nothing; it now refuses the property, so the builder does not
|
|
3951
|
-
* offer a filter that cannot be honoured. Narrow with `.in()`, `.across()` and `.locale()`.
|
|
3952
|
-
*/
|
|
3953
|
-
/**
|
|
3954
|
-
* Limit number of results
|
|
3955
|
-
* @param count - Maximum results
|
|
3956
|
-
*/
|
|
3957
|
-
limit(count) {
|
|
3958
|
-
this.similarOptions.limit = count;
|
|
3959
|
-
return this;
|
|
3960
|
-
}
|
|
3961
|
-
/**
|
|
3962
|
-
* Set locale for localized content
|
|
3963
|
-
* @param locale - Locale code
|
|
3964
|
-
*/
|
|
3965
|
-
locale(locale) {
|
|
3966
|
-
this.similarOptions.locale = locale;
|
|
3967
|
-
return this;
|
|
3968
|
-
}
|
|
3969
|
-
/**
|
|
3970
|
-
* Execute the similar query
|
|
3971
|
-
*/
|
|
3972
|
-
async execute() {
|
|
3973
|
-
const { contentType, contentTypes } = this.similarOptions;
|
|
3974
|
-
if ((contentType == null || contentType === "") && contentTypes == null) {
|
|
3975
|
-
throw new Error(
|
|
3976
|
-
'Content type is required for similar search. Use .in("contentType") or .across("*")'
|
|
3977
|
-
);
|
|
3978
|
-
}
|
|
3979
|
-
const body = { source: this.sourceId };
|
|
3980
|
-
if (contentType != null && contentType !== "") {
|
|
3981
|
-
body.contentType = contentType;
|
|
3982
|
-
}
|
|
3983
|
-
if (contentTypes != null) {
|
|
3984
|
-
body.contentTypes = contentTypes;
|
|
3985
|
-
}
|
|
3986
|
-
if (this.similarOptions.limit !== void 0) {
|
|
3987
|
-
body.limit = this.similarOptions.limit;
|
|
3988
|
-
}
|
|
3989
|
-
const locale = this.similarOptions.locale ?? this.clientLocale();
|
|
3990
|
-
if (locale != null && locale !== "") {
|
|
3991
|
-
body.locale = locale;
|
|
3992
|
-
}
|
|
3993
|
-
const response = await this.httpClient.send(
|
|
3994
|
-
"/v1/search/similar",
|
|
3995
|
-
"post",
|
|
3996
|
-
{ body, headers: this.requestHeaders }
|
|
3997
|
-
);
|
|
3998
|
-
return response.body;
|
|
3999
|
-
}
|
|
4000
|
-
/**
|
|
4001
|
-
* Get just the similar items
|
|
4002
|
-
*/
|
|
4003
|
-
async items() {
|
|
4004
|
-
return readPayload(await this.execute());
|
|
4005
|
-
}
|
|
4006
|
-
/**
|
|
4007
|
-
* Get the most similar item
|
|
4008
|
-
*/
|
|
4009
|
-
async first() {
|
|
4010
|
-
return readPayload(await this.limit(1).execute())[0] ?? null;
|
|
4011
|
-
}
|
|
4012
|
-
};
|
|
4013
|
-
chunkMWMSFIWN_cjs.__name(_SimilarBuilder, "SimilarBuilder");
|
|
4014
|
-
var SimilarBuilder = _SimilarBuilder;
|
|
4015
|
-
var _SearchClient = class _SearchClient {
|
|
4016
|
-
/**
|
|
4017
|
-
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`): every builder
|
|
4018
|
-
* here sends it when the query names none, as `content()`'s reads do — the function
|
|
4019
|
-
* `TypedRelyIOClient` hands over, or a locale fixed for this client
|
|
4020
|
-
*/
|
|
4021
|
-
constructor(httpClient, locale) {
|
|
4022
|
-
this.httpClient = httpClient;
|
|
4023
|
-
/** The client's locale, handed to every builder here to ask when it sends. */
|
|
4024
|
-
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
4025
|
-
this.clientLocale = readClientLocale(locale);
|
|
4026
|
-
}
|
|
4027
|
-
/**
|
|
4028
|
-
* Start a search query
|
|
4029
|
-
* @param query - Search query string
|
|
4030
|
-
*/
|
|
4031
|
-
search(query) {
|
|
4032
|
-
return new SearchBuilder(this.httpClient, query, this.clientLocale);
|
|
4033
|
-
}
|
|
4034
|
-
/**
|
|
4035
|
-
* Start an autocomplete query
|
|
4036
|
-
* @param query - Partial query to autocomplete
|
|
4037
|
-
*/
|
|
4038
|
-
autocomplete(query) {
|
|
4039
|
-
return new AutocompleteBuilder(this.httpClient, query, this.clientLocale);
|
|
4040
|
-
}
|
|
4041
|
-
/**
|
|
4042
|
-
* Find content similar to a given entry
|
|
4043
|
-
* @param sourceId - Entry ID to find similar content for
|
|
4044
|
-
*/
|
|
4045
|
-
similar(sourceId) {
|
|
4046
|
-
return new SimilarBuilder(this.httpClient, sourceId, this.clientLocale);
|
|
4047
|
-
}
|
|
4048
|
-
};
|
|
4049
|
-
chunkMWMSFIWN_cjs.__name(_SearchClient, "SearchClient");
|
|
4050
|
-
var SearchClient = _SearchClient;
|
|
4051
|
-
|
|
4052
|
-
// src/batch/batch-client.ts
|
|
4053
|
-
var _BatchBuilder = class _BatchBuilder {
|
|
4054
|
-
/**
|
|
4055
|
-
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), each
|
|
4056
|
-
* operation's when it names none: the function `TypedRelyIOClient` hands over, or a locale fixed
|
|
4057
|
-
* for this batch
|
|
4058
|
-
*/
|
|
4059
|
-
constructor(httpClient, locale) {
|
|
4060
|
-
this.httpClient = httpClient;
|
|
4061
|
-
chunkMWMSFIWN_cjs.__publicField(this, "operations", []);
|
|
4062
|
-
chunkMWMSFIWN_cjs.__publicField(this, "defaultOptions", {
|
|
4063
|
-
atomic: false,
|
|
4064
|
-
dryRun: false,
|
|
4065
|
-
returnData: true,
|
|
4066
|
-
continueOnError: true
|
|
4067
|
-
});
|
|
4068
|
-
chunkMWMSFIWN_cjs.__publicField(this, "requestHeaders");
|
|
4069
|
-
/** The client's locale, asked as each operation is added rather than copied when this was built. */
|
|
4070
|
-
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
4071
|
-
this.clientLocale = readClientLocale(locale);
|
|
4072
|
-
}
|
|
4073
|
-
/**
|
|
4074
|
-
* An operation's body with its locale: the one it names, else the client's as it is when the
|
|
4075
|
-
* operation is added.
|
|
4076
|
-
*/
|
|
4077
|
-
localized(data) {
|
|
4078
|
-
const locale = callLocale(data.locale, this.clientLocale());
|
|
4079
|
-
return locale === void 0 ? data : { ...data, locale };
|
|
4080
|
-
}
|
|
4081
|
-
// ==========================================================================
|
|
4082
|
-
// ENTRY OPERATIONS
|
|
4083
|
-
// ==========================================================================
|
|
4084
|
-
/**
|
|
4085
|
-
* Add a create operation
|
|
4086
|
-
* @param contentType - Content type to create
|
|
4087
|
-
* @param data - Entry data with content field
|
|
4088
|
-
* @param id - Optional operation ID for tracking
|
|
4089
|
-
*/
|
|
4090
|
-
create(contentType, data, id) {
|
|
4091
|
-
this.operations.push({
|
|
4092
|
-
id,
|
|
4093
|
-
method: "POST",
|
|
4094
|
-
path: `/${contentType}`,
|
|
4095
|
-
body: this.localized(data)
|
|
4096
|
-
});
|
|
4097
|
-
return this;
|
|
4098
|
-
}
|
|
4099
|
-
/**
|
|
4100
|
-
* Add an update operation (partial update).
|
|
4101
|
-
*
|
|
4102
|
-
* The submitted fields are merged into the entry and the rest are left as they are. The merge is
|
|
4103
|
-
* field-level rather than deep: sending an object-typed field replaces that field's whole value.
|
|
4104
|
-
*
|
|
4105
|
-
* @param contentType - Content type
|
|
4106
|
-
* @param entryId - Entry ID to update
|
|
4107
|
-
* @param data - Fields to update
|
|
4108
|
-
* @param id - Optional operation ID for tracking
|
|
4109
|
-
*/
|
|
4110
|
-
update(contentType, entryId, data, id) {
|
|
4111
|
-
this.operations.push({
|
|
4112
|
-
id,
|
|
4113
|
-
method: "PATCH",
|
|
4114
|
-
path: `/${contentType}/${entryId}`,
|
|
4115
|
-
body: this.localized(data)
|
|
4116
|
-
});
|
|
4117
|
-
return this;
|
|
4118
|
-
}
|
|
4119
|
-
/**
|
|
4120
|
-
* Add a replace operation (full replacement).
|
|
4121
|
-
*
|
|
4122
|
-
* The payload becomes the entry's content for the addressed locale: fields you do not send are
|
|
4123
|
-
* cleared. Send the whole entry, or use {@link BatchClient.update} to change part of one.
|
|
4124
|
-
*
|
|
4125
|
-
* @param contentType - Content type
|
|
4126
|
-
* @param entryId - Entry ID to replace
|
|
4127
|
-
* @param data - Complete entry data
|
|
4128
|
-
* @param id - Optional operation ID for tracking
|
|
4129
|
-
*/
|
|
4130
|
-
replace(contentType, entryId, data, id) {
|
|
4131
|
-
this.operations.push({
|
|
4132
|
-
id,
|
|
4133
|
-
method: "PUT",
|
|
4134
|
-
path: `/${contentType}/${entryId}`,
|
|
4135
|
-
body: this.localized(data)
|
|
4136
|
-
});
|
|
4137
|
-
return this;
|
|
4138
|
-
}
|
|
4139
|
-
/**
|
|
4140
|
-
* Add a delete operation
|
|
4141
|
-
* @param contentType - Content type
|
|
4142
|
-
* @param entryId - Entry ID to delete
|
|
4143
|
-
* @param id - Optional operation ID for tracking
|
|
4144
|
-
*/
|
|
4145
|
-
delete(contentType, entryId, id) {
|
|
4146
|
-
this.operations.push({
|
|
4147
|
-
id,
|
|
4148
|
-
method: "DELETE",
|
|
4149
|
-
path: `/${contentType}/${entryId}`
|
|
4150
|
-
});
|
|
4151
|
-
return this;
|
|
4152
|
-
}
|
|
4153
|
-
// ==========================================================================
|
|
4154
|
-
// SINGLETON OPERATIONS
|
|
4155
|
-
// ==========================================================================
|
|
4156
|
-
/**
|
|
4157
|
-
* Add a singleton upsert operation
|
|
4158
|
-
* @param singletonKey - Singleton key
|
|
4159
|
-
* @param data - Singleton content
|
|
4160
|
-
* @param id - Optional operation ID for tracking
|
|
4161
|
-
*/
|
|
4162
|
-
upsertSingleton(singletonKey, data, id) {
|
|
4163
|
-
this.operations.push({
|
|
4164
|
-
id,
|
|
4165
|
-
method: "PATCH",
|
|
4166
|
-
path: `/_singletons/${singletonKey}`,
|
|
4167
|
-
body: this.localized(data)
|
|
4168
|
-
});
|
|
4169
|
-
return this;
|
|
4170
|
-
}
|
|
4171
|
-
/**
|
|
4172
|
-
* Add a singleton create operation (alias for upsert with POST)
|
|
4173
|
-
* @param singletonKey - Singleton key
|
|
4174
|
-
* @param data - Singleton content
|
|
4175
|
-
* @param id - Optional operation ID for tracking
|
|
4176
|
-
*/
|
|
4177
|
-
createSingleton(singletonKey, data, id) {
|
|
4178
|
-
this.operations.push({
|
|
4179
|
-
id,
|
|
4180
|
-
method: "POST",
|
|
4181
|
-
path: `/_singletons/${singletonKey}`,
|
|
4182
|
-
body: this.localized(data)
|
|
4183
|
-
});
|
|
4184
|
-
return this;
|
|
4185
|
-
}
|
|
4186
|
-
// ==========================================================================
|
|
4187
|
-
// RAW OPERATIONS
|
|
4188
|
-
// ==========================================================================
|
|
4189
|
-
/**
|
|
4190
|
-
* Add a raw operation (for advanced use cases). It is sent exactly as written: the client's
|
|
4191
|
-
* locale is not added to it.
|
|
4192
|
-
* @param operation - The operation to add
|
|
4193
|
-
*/
|
|
4194
|
-
raw(operation) {
|
|
4195
|
-
this.operations.push(operation);
|
|
4196
|
-
return this;
|
|
4197
|
-
}
|
|
4198
|
-
/**
|
|
4199
|
-
* Add multiple raw operations
|
|
4200
|
-
* @param operations - Operations to add
|
|
4201
|
-
*/
|
|
4202
|
-
rawMany(operations) {
|
|
4203
|
-
this.operations.push(...operations);
|
|
4204
|
-
return this;
|
|
4205
|
-
}
|
|
4206
|
-
// ==========================================================================
|
|
4207
|
-
// BULK HELPERS
|
|
4208
|
-
// ==========================================================================
|
|
4209
|
-
/**
|
|
4210
|
-
* Bulk create multiple entries of the same content type
|
|
4211
|
-
* @param contentType - Content type
|
|
4212
|
-
* @param items - Array of entry data
|
|
4213
|
-
*/
|
|
4214
|
-
bulkCreate(contentType, items) {
|
|
4215
|
-
for (const item of items) {
|
|
4216
|
-
const { id, ...data } = item;
|
|
4217
|
-
this.create(contentType, data, id);
|
|
4218
|
-
}
|
|
4219
|
-
return this;
|
|
4220
|
-
}
|
|
4221
|
-
/**
|
|
4222
|
-
* Bulk update multiple entries
|
|
4223
|
-
* @param contentType - Content type
|
|
4224
|
-
* @param updates - Array of { entryId, data } pairs
|
|
4225
|
-
*/
|
|
4226
|
-
bulkUpdate(contentType, updates) {
|
|
4227
|
-
for (const update of updates) {
|
|
4228
|
-
this.update(contentType, update.entryId, update.data, update.id);
|
|
4229
|
-
}
|
|
4230
|
-
return this;
|
|
4231
|
-
}
|
|
4232
|
-
/**
|
|
4233
|
-
* Bulk delete multiple entries
|
|
4234
|
-
* @param contentType - Content type
|
|
4235
|
-
* @param entryIds - Entry IDs to delete
|
|
4236
|
-
*/
|
|
4237
|
-
bulkDelete(contentType, entryIds) {
|
|
4238
|
-
for (const entryId of entryIds) {
|
|
4239
|
-
this.delete(contentType, entryId);
|
|
4240
|
-
}
|
|
4241
|
-
return this;
|
|
4242
|
-
}
|
|
4243
|
-
// ==========================================================================
|
|
4244
|
-
// CONFIGURATION
|
|
4245
|
-
// ==========================================================================
|
|
4246
|
-
/**
|
|
4247
|
-
* Configure default options for execution
|
|
4248
|
-
* @param options - Batch options
|
|
4249
|
-
*/
|
|
4250
|
-
configure(options) {
|
|
4251
|
-
this.defaultOptions = { ...this.defaultOptions, ...options };
|
|
4252
|
-
return this;
|
|
4253
|
-
}
|
|
4254
|
-
/**
|
|
4255
|
-
* Enable atomic mode (all-or-nothing)
|
|
4256
|
-
*/
|
|
4257
|
-
atomic() {
|
|
4258
|
-
this.defaultOptions.atomic = true;
|
|
4259
|
-
return this;
|
|
4260
|
-
}
|
|
4261
|
-
/**
|
|
4262
|
-
* Enable dry-run mode (validate without executing)
|
|
4263
|
-
*/
|
|
4264
|
-
dryRun() {
|
|
4265
|
-
this.defaultOptions.dryRun = true;
|
|
4266
|
-
return this;
|
|
4267
|
-
}
|
|
4268
|
-
/**
|
|
4269
|
-
* Disable returning full data in response
|
|
4270
|
-
*/
|
|
4271
|
-
noData() {
|
|
4272
|
-
this.defaultOptions.returnData = false;
|
|
4273
|
-
return this;
|
|
4274
|
-
}
|
|
4275
|
-
/**
|
|
4276
|
-
* Stop on first error (non-atomic mode)
|
|
4277
|
-
*/
|
|
4278
|
-
stopOnError() {
|
|
4279
|
-
this.defaultOptions.continueOnError = false;
|
|
4280
|
-
return this;
|
|
4281
|
-
}
|
|
4282
|
-
/**
|
|
4283
|
-
* Headers the batch request adds — e.g. `{ 'X-RelyIO-Dataset': 'staging' }` to write a dataset
|
|
4284
|
-
* other than the client's. They replace the client's own header of the same name for this
|
|
4285
|
-
* request alone, and apply to every operation in it: a batch is one request.
|
|
4286
|
-
*/
|
|
4287
|
-
headers(headers) {
|
|
4288
|
-
this.requestHeaders = { ...this.requestHeaders, ...headers };
|
|
4289
|
-
return this;
|
|
4290
|
-
}
|
|
4291
|
-
// ==========================================================================
|
|
4292
|
-
// EXECUTION
|
|
4293
|
-
// ==========================================================================
|
|
4294
|
-
/**
|
|
4295
|
-
* Get the current list of operations
|
|
4296
|
-
*/
|
|
4297
|
-
getOperations() {
|
|
4298
|
-
return [...this.operations];
|
|
4299
|
-
}
|
|
4300
|
-
/**
|
|
4301
|
-
* Get the number of operations
|
|
4302
|
-
*/
|
|
4303
|
-
size() {
|
|
4304
|
-
return this.operations.length;
|
|
4305
|
-
}
|
|
4306
|
-
/**
|
|
4307
|
-
* Clear all operations
|
|
4308
|
-
*/
|
|
4309
|
-
clear() {
|
|
4310
|
-
this.operations = [];
|
|
4311
|
-
return this;
|
|
4312
|
-
}
|
|
4313
|
-
/**
|
|
4314
|
-
* Clone the builder
|
|
4315
|
-
*/
|
|
4316
|
-
clone() {
|
|
4317
|
-
const cloned = new _BatchBuilder(this.httpClient, this.clientLocale);
|
|
4318
|
-
cloned.operations = [...this.operations];
|
|
4319
|
-
cloned.defaultOptions = { ...this.defaultOptions };
|
|
4320
|
-
cloned.requestHeaders = this.requestHeaders === void 0 ? void 0 : { ...this.requestHeaders };
|
|
4321
|
-
return cloned;
|
|
4322
|
-
}
|
|
4323
|
-
/**
|
|
4324
|
-
* Execute the batch operations
|
|
4325
|
-
* @param options - Override default options
|
|
4326
|
-
*/
|
|
4327
|
-
async execute(options) {
|
|
4328
|
-
if (this.operations.length === 0) {
|
|
4329
|
-
throw new Error(
|
|
4330
|
-
"No operations to execute. Add operations using .create(), .update(), .delete(), etc."
|
|
4331
|
-
);
|
|
4332
|
-
}
|
|
4333
|
-
if (this.operations.length > 100) {
|
|
4334
|
-
throw new Error("Maximum 100 operations per batch. Split into multiple batches.");
|
|
4335
|
-
}
|
|
4336
|
-
const finalOptions = { ...this.defaultOptions, ...options };
|
|
4337
|
-
return this.httpClient.fetchPayload("/v1/batch", "post", {
|
|
4338
|
-
body: { operations: this.operations, options: finalOptions },
|
|
4339
|
-
headers: this.requestHeaders
|
|
4340
|
-
});
|
|
4341
|
-
}
|
|
4342
|
-
/**
|
|
4343
|
-
* Validate operations without executing (convenience for dry-run)
|
|
4344
|
-
*/
|
|
4345
|
-
async validate() {
|
|
4346
|
-
return this.execute({ dryRun: true });
|
|
4347
|
-
}
|
|
4348
|
-
/**
|
|
4349
|
-
* Execute and throw if any operation failed
|
|
4350
|
-
*/
|
|
4351
|
-
async executeOrThrow(options) {
|
|
4352
|
-
const response = await this.execute(options);
|
|
4353
|
-
if (response.summary.failed > 0) {
|
|
4354
|
-
const failedOps = response.results.filter(
|
|
4355
|
-
(result) => "error" in result
|
|
4356
|
-
);
|
|
4357
|
-
const errorMessages = failedOps.map(
|
|
4358
|
-
(op) => `Operation ${op.index}${op.id != null && op.id !== "" ? ` (${op.id})` : ""}: ${op.error.code} \u2014 ${op.error.messages.join(" ")}`
|
|
4359
|
-
).join("; ");
|
|
4360
|
-
throw new Error(
|
|
4361
|
-
`Batch execution failed: ${response.summary.failed} of ${response.summary.total} operations failed. ${errorMessages}`
|
|
4362
|
-
);
|
|
4363
|
-
}
|
|
4364
|
-
return response;
|
|
4365
|
-
}
|
|
4366
|
-
};
|
|
4367
|
-
chunkMWMSFIWN_cjs.__name(_BatchBuilder, "BatchBuilder");
|
|
4368
|
-
var BatchBuilder = _BatchBuilder;
|
|
4369
|
-
var _BatchClient = class _BatchClient {
|
|
4370
|
-
/**
|
|
4371
|
-
* @param locale - The client's locale: the function `TypedRelyIOClient` hands over, or a locale
|
|
4372
|
-
* fixed for this client
|
|
4373
|
-
*/
|
|
4374
|
-
constructor(httpClient, locale) {
|
|
4375
|
-
this.httpClient = httpClient;
|
|
4376
|
-
/** The client's locale, handed to every batch this builds to ask as operations are added. */
|
|
4377
|
-
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
4378
|
-
this.clientLocale = readClientLocale(locale);
|
|
4379
|
-
}
|
|
4380
|
-
/**
|
|
4381
|
-
* Create a new batch builder, whose operations default to this client's locale
|
|
4382
|
-
*/
|
|
4383
|
-
create() {
|
|
4384
|
-
return new BatchBuilder(this.httpClient, this.clientLocale);
|
|
4385
|
-
}
|
|
4386
|
-
/**
|
|
4387
|
-
* Quick bulk create entries
|
|
4388
|
-
* @param contentType - Content type
|
|
4389
|
-
* @param items - Array of entry data
|
|
4390
|
-
* @param options - Batch options
|
|
4391
|
-
*/
|
|
4392
|
-
async bulkCreate(contentType, items, options) {
|
|
4393
|
-
return this.create().bulkCreate(contentType, items).execute(options);
|
|
4394
|
-
}
|
|
4395
|
-
/**
|
|
4396
|
-
* Quick bulk update entries
|
|
4397
|
-
* @param contentType - Content type
|
|
4398
|
-
* @param updates - Array of updates
|
|
4399
|
-
* @param options - Batch options
|
|
4400
|
-
*/
|
|
4401
|
-
async bulkUpdate(contentType, updates, options) {
|
|
4402
|
-
return this.create().bulkUpdate(contentType, updates).execute(options);
|
|
4403
|
-
}
|
|
4404
|
-
/**
|
|
4405
|
-
* Quick bulk delete entries
|
|
4406
|
-
* @param contentType - Content type
|
|
4407
|
-
* @param entryIds - Entry IDs to delete
|
|
4408
|
-
* @param options - Batch options
|
|
4409
|
-
*/
|
|
4410
|
-
async bulkDelete(contentType, entryIds, options) {
|
|
4411
|
-
return this.create().bulkDelete(contentType, entryIds).execute(options);
|
|
4412
|
-
}
|
|
4413
|
-
/**
|
|
4414
|
-
* Execute raw batch operations
|
|
4415
|
-
* @param operations - Array of operations
|
|
4416
|
-
* @param options - Batch options
|
|
4417
|
-
*/
|
|
4418
|
-
async execute(operations, options) {
|
|
4419
|
-
return this.create().rawMany(operations).execute(options);
|
|
4420
|
-
}
|
|
4421
|
-
};
|
|
4422
|
-
chunkMWMSFIWN_cjs.__name(_BatchClient, "BatchClient");
|
|
4423
|
-
var BatchClient = _BatchClient;
|
|
4424
|
-
|
|
4425
|
-
// src/queries/adhoc-query-client.ts
|
|
4426
|
-
function withClientLocale(parameters, clientLocale) {
|
|
4427
|
-
if (clientLocale === void 0 || clientLocale === "" || parameters?.locale != null) {
|
|
4428
|
-
return parameters;
|
|
4429
|
-
}
|
|
4430
|
-
return { ...parameters, locale: clientLocale };
|
|
4431
|
-
}
|
|
4432
|
-
chunkMWMSFIWN_cjs.__name(withClientLocale, "withClientLocale");
|
|
4433
|
-
var _AdhocQueryBuilder = class _AdhocQueryBuilder {
|
|
4434
|
-
/**
|
|
4435
|
-
* @param locale - The client's locale (`withLocale()`, `updateConfig({ locale })`), sent as the
|
|
4436
|
-
* `locale` parameter when `.param('locale', …)` binds none: the function `TypedRelyIOClient`
|
|
4437
|
-
* hands over, or a locale fixed for this builder
|
|
4438
|
-
*/
|
|
4439
|
-
constructor(httpClient, locale) {
|
|
4440
|
-
this.httpClient = httpClient;
|
|
4441
|
-
chunkMWMSFIWN_cjs.__publicField(this, "queryDef", {});
|
|
4442
|
-
chunkMWMSFIWN_cjs.__publicField(this, "parameters", {});
|
|
4443
|
-
chunkMWMSFIWN_cjs.__publicField(this, "options", {});
|
|
4444
|
-
/** The client's locale, asked when the query is sent rather than copied when it was built. */
|
|
4445
|
-
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
4446
|
-
this.clientLocale = readClientLocale(locale);
|
|
4447
|
-
}
|
|
4448
|
-
// ==========================================================================
|
|
4449
|
-
// QUERY BLOCKS
|
|
4450
|
-
// ==========================================================================
|
|
4451
|
-
/**
|
|
4452
|
-
* Add a fetch block to retrieve content
|
|
4453
|
-
* @param config - Fetch configuration
|
|
4454
|
-
*/
|
|
4455
|
-
fetch(config) {
|
|
4456
|
-
this.queryDef.fetch = config;
|
|
4457
|
-
return this;
|
|
4458
|
-
}
|
|
4459
|
-
/**
|
|
4460
|
-
* Fetch from a content type
|
|
4461
|
-
* @param contentType - Content type to fetch
|
|
4462
|
-
*/
|
|
4463
|
-
from(contentType) {
|
|
4464
|
-
this.queryDef.fetch = { ...this.queryDef.fetch, contentType };
|
|
4465
|
-
return this;
|
|
4466
|
-
}
|
|
4467
|
-
/**
|
|
4468
|
-
* Fetch a singleton
|
|
4469
|
-
* @param singletonKey - Singleton key
|
|
4470
|
-
*/
|
|
4471
|
-
singleton(singletonKey) {
|
|
4472
|
-
this.queryDef.fetch = { ...this.queryDef.fetch, singleton: singletonKey };
|
|
4473
|
-
return this;
|
|
4474
|
-
}
|
|
4475
|
-
/**
|
|
4476
|
-
* Add aggregate block
|
|
4477
|
-
* @param config - Aggregate configuration
|
|
4478
|
-
*/
|
|
4479
|
-
aggregate(config) {
|
|
4480
|
-
this.queryDef.aggregate = config;
|
|
4481
|
-
return this;
|
|
4482
|
-
}
|
|
4483
|
-
/**
|
|
4484
|
-
* Add search block
|
|
4485
|
-
* @param config - Search configuration
|
|
4486
|
-
*/
|
|
4487
|
-
search(config) {
|
|
4488
|
-
this.queryDef.search = config;
|
|
4489
|
-
return this;
|
|
4490
|
-
}
|
|
4491
|
-
// ==========================================================================
|
|
4492
|
-
// FETCH MODIFIERS
|
|
4493
|
-
// ==========================================================================
|
|
4494
|
-
/**
|
|
4495
|
-
* Add where conditions to fetch
|
|
4496
|
-
* @param conditions - Filter conditions
|
|
4497
|
-
*/
|
|
4498
|
-
where(conditions) {
|
|
4499
|
-
this.queryDef.fetch = {
|
|
4500
|
-
...this.queryDef.fetch,
|
|
4501
|
-
where: { ...this.queryDef.fetch?.where, ...conditions }
|
|
4502
|
-
};
|
|
4503
|
-
return this;
|
|
4504
|
-
}
|
|
4505
|
-
/**
|
|
4506
|
-
* Add include for reference population
|
|
4507
|
-
* @param fields - Reference fields to include
|
|
4508
|
-
*/
|
|
4509
|
-
include(fields) {
|
|
4510
|
-
this.queryDef.fetch = {
|
|
4511
|
-
...this.queryDef.fetch,
|
|
4512
|
-
include: fields
|
|
4513
|
-
};
|
|
4514
|
-
return this;
|
|
4515
|
-
}
|
|
4516
|
-
/**
|
|
4517
|
-
* Add sort specification
|
|
4518
|
-
* @param sort - Sort configuration
|
|
4519
|
-
*/
|
|
4520
|
-
sort(sort) {
|
|
4521
|
-
this.queryDef.fetch = {
|
|
4522
|
-
...this.queryDef.fetch,
|
|
4523
|
-
sort: { ...this.queryDef.fetch?.sort, ...sort }
|
|
4524
|
-
};
|
|
4525
|
-
return this;
|
|
4526
|
-
}
|
|
4527
|
-
/**
|
|
4528
|
-
* Sort by field ascending
|
|
4529
|
-
* @param field - Field to sort by
|
|
4530
|
-
*/
|
|
4531
|
-
sortAsc(field) {
|
|
4532
|
-
return this.sort({ [field]: "asc" });
|
|
4533
|
-
}
|
|
4534
|
-
/**
|
|
4535
|
-
* Sort by field descending
|
|
4536
|
-
* @param field - Field to sort by
|
|
4537
|
-
*/
|
|
4538
|
-
sortDesc(field) {
|
|
4539
|
-
return this.sort({ [field]: "desc" });
|
|
4540
|
-
}
|
|
4541
|
-
/**
|
|
4542
|
-
* Limit results
|
|
4543
|
-
* @param count - Maximum results
|
|
4544
|
-
*/
|
|
4545
|
-
limit(count) {
|
|
4546
|
-
this.queryDef.fetch = {
|
|
4547
|
-
...this.queryDef.fetch,
|
|
4548
|
-
limit: count
|
|
4549
|
-
};
|
|
4550
|
-
return this;
|
|
4551
|
-
}
|
|
4552
|
-
/**
|
|
4553
|
-
* Skip results
|
|
4554
|
-
* @param count - Number to skip
|
|
4555
|
-
*/
|
|
4556
|
-
offset(count) {
|
|
4557
|
-
this.queryDef.fetch = {
|
|
4558
|
-
...this.queryDef.fetch,
|
|
4559
|
-
offset: count
|
|
4560
|
-
};
|
|
4561
|
-
return this;
|
|
4562
|
-
}
|
|
4563
|
-
// ==========================================================================
|
|
4564
|
-
// PROJECTIONS & FILTERS
|
|
4565
|
-
// ==========================================================================
|
|
4566
|
-
/**
|
|
4567
|
-
* Select and transform fields in output
|
|
4568
|
-
* @param projection - Field mapping (outputField: sourceField)
|
|
4569
|
-
*/
|
|
4570
|
-
select(projection) {
|
|
4571
|
-
this.queryDef.select = { ...this.queryDef.select, ...projection };
|
|
4572
|
-
return this;
|
|
4573
|
-
}
|
|
4574
|
-
/**
|
|
4575
|
-
* Add a post-fetch filter (supports ${param} syntax)
|
|
4576
|
-
* @param field - Field path to filter
|
|
4577
|
-
* @param condition - Filter condition
|
|
4578
|
-
*/
|
|
4579
|
-
filter(field, condition) {
|
|
4580
|
-
this.queryDef.filters = { ...this.queryDef.filters, [field]: condition };
|
|
4581
|
-
return this;
|
|
4582
|
-
}
|
|
4583
|
-
/**
|
|
4584
|
-
* Add full-text search
|
|
4585
|
-
* @param config - Full-text configuration
|
|
4586
|
-
*/
|
|
4587
|
-
fullText(config) {
|
|
4588
|
-
this.queryDef.fullText = config;
|
|
4589
|
-
return this;
|
|
4590
|
-
}
|
|
4591
|
-
// ==========================================================================
|
|
4592
|
-
// PARAMETERS
|
|
4593
|
-
// ==========================================================================
|
|
4594
|
-
/**
|
|
4595
|
-
* Set query parameters
|
|
4596
|
-
* @param params - Parameter values
|
|
4597
|
-
*/
|
|
4598
|
-
params(params) {
|
|
4599
|
-
this.parameters = { ...this.parameters, ...params };
|
|
4600
|
-
return this;
|
|
4601
|
-
}
|
|
4602
|
-
/**
|
|
4603
|
-
* Set a single parameter
|
|
4604
|
-
* @param name - Parameter name
|
|
4605
|
-
* @param value - Parameter value
|
|
4606
|
-
*/
|
|
4607
|
-
param(name, value) {
|
|
4608
|
-
this.parameters[name] = value;
|
|
4609
|
-
return this;
|
|
4610
|
-
}
|
|
4611
|
-
// ==========================================================================
|
|
4612
|
-
// OPTIONS
|
|
4613
|
-
// ==========================================================================
|
|
4614
|
-
/**
|
|
4615
|
-
* Enable debug mode
|
|
4616
|
-
*/
|
|
4617
|
-
debug() {
|
|
4618
|
-
this.options.debug = true;
|
|
4619
|
-
return this;
|
|
4620
|
-
}
|
|
4621
|
-
/**
|
|
4622
|
-
* Skip cache for this request
|
|
4623
|
-
*/
|
|
4624
|
-
skipCache() {
|
|
4625
|
-
this.options.skipCache = true;
|
|
4626
|
-
return this;
|
|
4627
|
-
}
|
|
4628
|
-
/**
|
|
4629
|
-
* Set custom timeout
|
|
4630
|
-
* @param ms - Timeout in milliseconds (1000-60000)
|
|
4631
|
-
*/
|
|
4632
|
-
timeout(ms) {
|
|
4633
|
-
if (ms < 1e3 || ms > 6e4) {
|
|
4634
|
-
throw new Error("Timeout must be between 1000 and 60000 milliseconds");
|
|
4635
|
-
}
|
|
4636
|
-
this.options.timeout = ms;
|
|
4637
|
-
return this;
|
|
4638
|
-
}
|
|
4639
|
-
/**
|
|
4640
|
-
* Set cache policy
|
|
4641
|
-
* @param ttl - Cache TTL in seconds
|
|
4642
|
-
* @param strategy - Cache strategy
|
|
4643
|
-
*/
|
|
4644
|
-
cache(ttl, strategy) {
|
|
4645
|
-
this.queryDef.cache = { ttl, strategy };
|
|
4646
|
-
return this;
|
|
4647
|
-
}
|
|
4648
|
-
// ==========================================================================
|
|
4649
|
-
// EXECUTION
|
|
4650
|
-
// ==========================================================================
|
|
4651
|
-
/**
|
|
4652
|
-
* Get the query definition (for debugging)
|
|
4653
|
-
*/
|
|
4654
|
-
getDefinition() {
|
|
4655
|
-
return { ...this.queryDef };
|
|
4656
|
-
}
|
|
4657
|
-
/**
|
|
4658
|
-
* Get the parameters (for debugging)
|
|
4659
|
-
*/
|
|
4660
|
-
getParameters() {
|
|
4661
|
-
return { ...this.parameters };
|
|
4662
|
-
}
|
|
2764
|
+
// src/content/singleton-client.ts
|
|
2765
|
+
var _SingletonClient = class _SingletonClient extends DocumentHandle {
|
|
4663
2766
|
/**
|
|
4664
|
-
*
|
|
2767
|
+
* The singleton, or `null` when nobody has written it yet (REL-2419, REL-2409 Q18).
|
|
2768
|
+
*
|
|
2769
|
+
* `null` only for a singleton with no content: one the schema does not declare, or a dataset with
|
|
2770
|
+
* no schema deployed, throws `ResourceNotFoundError` naming which (`context.resourceType`
|
|
2771
|
+
* `'singleton'` or `'schema'`), as a content type's `get` does.
|
|
2772
|
+
*
|
|
2773
|
+
* It takes a content read's options where the route declares them — `include`, `locale` (one
|
|
2774
|
+
* code), `dataset` and `fresh` (`DocumentReadOptions`).
|
|
2775
|
+
*
|
|
2776
|
+
* @example
|
|
2777
|
+
* ```typescript
|
|
2778
|
+
* const home = await relyio.singleton('homepage').get({ include: ['hero'], locale: 'fr-FR' })
|
|
2779
|
+
* if (home) await relyio.singleton('homepage').update(home, { headline: 'Bonjour' })
|
|
2780
|
+
* ```
|
|
4665
2781
|
*/
|
|
4666
|
-
async
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
if (parameters !== void 0 && Object.keys(parameters).length > 0) {
|
|
4677
|
-
body.parameters = parameters;
|
|
4678
|
-
}
|
|
4679
|
-
if (Object.keys(this.options).length > 0) {
|
|
4680
|
-
body.options = this.options;
|
|
2782
|
+
async get(options = {}) {
|
|
2783
|
+
try {
|
|
2784
|
+
return await this.httpClient.fetchPayload("/v1/singletons/{key}", "get", {
|
|
2785
|
+
path: { key: this.name },
|
|
2786
|
+
query: documentQuery(options, this.clientLocale()),
|
|
2787
|
+
headers: readHeaders(options)
|
|
2788
|
+
});
|
|
2789
|
+
} catch (error) {
|
|
2790
|
+
if (isMissingEntry(error)) return null;
|
|
2791
|
+
throw error;
|
|
4681
2792
|
}
|
|
2793
|
+
}
|
|
2794
|
+
/** The API publishes on PATCH: there is no separate publish route. */
|
|
2795
|
+
patch(write, options) {
|
|
4682
2796
|
return this.httpClient.fetchPayload(
|
|
4683
|
-
"/v1/
|
|
4684
|
-
"
|
|
4685
|
-
{
|
|
2797
|
+
"/v1/singletons/{key}",
|
|
2798
|
+
"patch",
|
|
2799
|
+
{
|
|
2800
|
+
path: { key: this.name },
|
|
2801
|
+
body: DocumentHandle.bodyOf(write),
|
|
2802
|
+
headers: DocumentHandle.headersOf(write, options)
|
|
2803
|
+
}
|
|
4686
2804
|
);
|
|
4687
2805
|
}
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
*/
|
|
4691
|
-
async items() {
|
|
4692
|
-
const { result } = await this.execute();
|
|
4693
|
-
if (result === void 0) return [];
|
|
4694
|
-
return Array.isArray(result) ? result : [result];
|
|
4695
|
-
}
|
|
4696
|
-
/**
|
|
4697
|
-
* Execute and return the single record (for singleton queries).
|
|
4698
|
-
*/
|
|
4699
|
-
async data() {
|
|
4700
|
-
const { result } = await this.execute();
|
|
4701
|
-
if (Array.isArray(result)) return result[0];
|
|
4702
|
-
return result;
|
|
2806
|
+
async readVersions(query) {
|
|
2807
|
+
return this.httpClient.fetchPayload("/v1/singletons/{key}/versions", "get", { path: { key: this.name }, query });
|
|
4703
2808
|
}
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
2809
|
+
readVersion(versionNumber, query) {
|
|
2810
|
+
return this.httpClient.fetchPayload(
|
|
2811
|
+
"/v1/singletons/{key}/versions/{versionNumber}",
|
|
2812
|
+
"get",
|
|
2813
|
+
{
|
|
2814
|
+
path: { key: this.name, versionNumber },
|
|
2815
|
+
query
|
|
2816
|
+
}
|
|
2817
|
+
);
|
|
4713
2818
|
}
|
|
4714
2819
|
};
|
|
4715
|
-
chunkMWMSFIWN_cjs.__name(
|
|
4716
|
-
var
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
* `locale` parameter of every query that binds none: the function `TypedRelyIOClient` hands
|
|
4721
|
-
* over, or a locale fixed for this client
|
|
4722
|
-
*/
|
|
4723
|
-
constructor(httpClient, locale) {
|
|
4724
|
-
this.httpClient = httpClient;
|
|
4725
|
-
/** The client's locale, asked on every query rather than copied when this client was taken. */
|
|
4726
|
-
chunkMWMSFIWN_cjs.__publicField(this, "clientLocale");
|
|
4727
|
-
this.clientLocale = readClientLocale(locale);
|
|
4728
|
-
}
|
|
2820
|
+
chunkMWMSFIWN_cjs.__name(_SingletonClient, "SingletonClient");
|
|
2821
|
+
var SingletonClient = _SingletonClient;
|
|
2822
|
+
|
|
2823
|
+
// src/content/settings-client.ts
|
|
2824
|
+
var _SettingsClient = class _SettingsClient extends DocumentHandle {
|
|
4729
2825
|
/**
|
|
4730
|
-
*
|
|
2826
|
+
* The settings group (REL-2419, REL-2409 Q18).
|
|
2827
|
+
*
|
|
2828
|
+
* Never `null`: the API answers a declared group that nobody has written yet with its declared
|
|
2829
|
+
* defaults (it initializes the group on that first read), so there is no missing group to report.
|
|
2830
|
+
* A group the schema does not declare, or a dataset with no schema deployed, throws
|
|
2831
|
+
* `ResourceNotFoundError` naming which (`context.resourceType` `'settingsGroup'` or `'schema'`) —
|
|
2832
|
+
* the not-found rule every handle's `get` follows.
|
|
2833
|
+
*
|
|
2834
|
+
* It takes a content read's options where the route declares them — `include`, `locale` (one
|
|
2835
|
+
* code), `dataset` and `fresh` (`DocumentReadOptions`).
|
|
2836
|
+
*
|
|
2837
|
+
* @example
|
|
2838
|
+
* ```typescript
|
|
2839
|
+
* const site = await relyio.settings('site').get({ include: ['logo'] })
|
|
2840
|
+
* await relyio.settings('site').update(site, { title: 'New title' })
|
|
2841
|
+
* ```
|
|
4731
2842
|
*/
|
|
4732
|
-
|
|
4733
|
-
return
|
|
2843
|
+
async get(options = {}) {
|
|
2844
|
+
return this.httpClient.fetchPayload(
|
|
2845
|
+
"/v1/settings/{groupId}",
|
|
2846
|
+
"get",
|
|
2847
|
+
{
|
|
2848
|
+
path: { groupId: this.name },
|
|
2849
|
+
query: documentQuery(options, this.clientLocale()),
|
|
2850
|
+
headers: readHeaders(options)
|
|
2851
|
+
}
|
|
2852
|
+
);
|
|
4734
2853
|
}
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
* @param parameters - Parameter values
|
|
4739
|
-
* @param options - Execution options
|
|
4740
|
-
* @param request - `headers` this one request adds to the client's own, e.g. `X-RelyIO-Dataset`
|
|
4741
|
-
* to query another dataset the key can see. A name the client already sends is replaced for
|
|
4742
|
-
* this request only.
|
|
4743
|
-
*/
|
|
4744
|
-
async execute(definition, parameters, options, request) {
|
|
4745
|
-
const body = {
|
|
4746
|
-
query: definition
|
|
4747
|
-
};
|
|
4748
|
-
const sent = withClientLocale(parameters, this.clientLocale());
|
|
4749
|
-
if (sent !== void 0 && Object.keys(sent).length > 0) {
|
|
4750
|
-
body.parameters = sent;
|
|
4751
|
-
}
|
|
4752
|
-
if (options && Object.keys(options).length > 0) {
|
|
4753
|
-
body.options = options;
|
|
4754
|
-
}
|
|
2854
|
+
async reset(...args) {
|
|
2855
|
+
const [first, second] = args;
|
|
2856
|
+
const write = first !== void 0 && isRead(first) ? { ...versionCheckOf(first), options: second } : { locale: this.localeOf(first?.locale), ifMatch: void 0, options: first };
|
|
4755
2857
|
return this.httpClient.fetchPayload(
|
|
4756
|
-
"/v1/
|
|
2858
|
+
"/v1/settings/{groupId}/reset",
|
|
4757
2859
|
"post",
|
|
4758
|
-
{
|
|
2860
|
+
{
|
|
2861
|
+
path: { groupId: this.name },
|
|
2862
|
+
query: write.locale === void 0 ? void 0 : { locale: write.locale },
|
|
2863
|
+
headers: DocumentHandle.headersOf(write, write.options)
|
|
2864
|
+
}
|
|
4759
2865
|
);
|
|
4760
2866
|
}
|
|
4761
|
-
/**
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
if (result === void 0) return [];
|
|
4769
|
-
return Array.isArray(result) ? result : [result];
|
|
2867
|
+
/** The group's default values, as the schema declares them. */
|
|
2868
|
+
async getDefaults() {
|
|
2869
|
+
return this.httpClient.fetchPayload(
|
|
2870
|
+
"/v1/settings/{groupId}/defaults",
|
|
2871
|
+
"get",
|
|
2872
|
+
{ path: { groupId: this.name } }
|
|
2873
|
+
);
|
|
4770
2874
|
}
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
2875
|
+
patch(write, options) {
|
|
2876
|
+
return this.httpClient.fetchPayload(
|
|
2877
|
+
"/v1/settings/{groupId}",
|
|
2878
|
+
"patch",
|
|
2879
|
+
{
|
|
2880
|
+
path: { groupId: this.name },
|
|
2881
|
+
body: DocumentHandle.bodyOf(write),
|
|
2882
|
+
headers: DocumentHandle.headersOf(write, options)
|
|
2883
|
+
}
|
|
2884
|
+
);
|
|
4779
2885
|
}
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
if (result === void 0) return [];
|
|
4789
|
-
return Array.isArray(result) ? result : [result];
|
|
2886
|
+
async readVersions(query) {
|
|
2887
|
+
return this.httpClient.fetchPayload("/v1/settings/{groupId}/versions", "get", { path: { groupId: this.name }, query });
|
|
2888
|
+
}
|
|
2889
|
+
readVersion(versionNumber, query) {
|
|
2890
|
+
return this.httpClient.fetchPayload("/v1/settings/{groupId}/versions/{versionNumber}", "get", {
|
|
2891
|
+
path: { groupId: this.name, versionNumber },
|
|
2892
|
+
query
|
|
2893
|
+
});
|
|
4790
2894
|
}
|
|
4791
2895
|
};
|
|
4792
|
-
chunkMWMSFIWN_cjs.__name(
|
|
4793
|
-
var
|
|
2896
|
+
chunkMWMSFIWN_cjs.__name(_SettingsClient, "SettingsClient");
|
|
2897
|
+
var SettingsClient = _SettingsClient;
|
|
4794
2898
|
|
|
4795
2899
|
// src/changes/changes.ts
|
|
4796
2900
|
var CHANGES_POLL_TIMEOUT_MS = 25e3 + 5e3;
|
|
@@ -5427,6 +3531,264 @@ function hasOwn(object, key) {
|
|
|
5427
3531
|
}
|
|
5428
3532
|
chunkMWMSFIWN_cjs.__name(hasOwn, "hasOwn");
|
|
5429
3533
|
|
|
3534
|
+
// src/search/search-options.ts
|
|
3535
|
+
function scopeOf(contentType) {
|
|
3536
|
+
if (contentType === void 0) return { contentTypes: "*" };
|
|
3537
|
+
if (typeof contentType === "string") return { contentType };
|
|
3538
|
+
return { contentTypes: [...contentType] };
|
|
3539
|
+
}
|
|
3540
|
+
chunkMWMSFIWN_cjs.__name(scopeOf, "scopeOf");
|
|
3541
|
+
function selectedFields(select) {
|
|
3542
|
+
if (select === void 0 || select.length === 0) return {};
|
|
3543
|
+
return { fields: Object.fromEntries(select.map((field) => [field, field])) };
|
|
3544
|
+
}
|
|
3545
|
+
chunkMWMSFIWN_cjs.__name(selectedFields, "selectedFields");
|
|
3546
|
+
function localeOf(own, client) {
|
|
3547
|
+
const locale = own ?? client;
|
|
3548
|
+
return locale === void 0 || locale === "" ? {} : { locale };
|
|
3549
|
+
}
|
|
3550
|
+
chunkMWMSFIWN_cjs.__name(localeOf, "localeOf");
|
|
3551
|
+
function whereOf(where) {
|
|
3552
|
+
if (where === void 0) return {};
|
|
3553
|
+
refuseMetadataConditions(where);
|
|
3554
|
+
return Object.keys(where).length === 0 ? {} : { where };
|
|
3555
|
+
}
|
|
3556
|
+
chunkMWMSFIWN_cjs.__name(whereOf, "whereOf");
|
|
3557
|
+
function given(options) {
|
|
3558
|
+
return Object.fromEntries(Object.entries(options).filter(([, value]) => value !== void 0));
|
|
3559
|
+
}
|
|
3560
|
+
chunkMWMSFIWN_cjs.__name(given, "given");
|
|
3561
|
+
function transportOf(options) {
|
|
3562
|
+
const headers = readHeaders(options);
|
|
3563
|
+
return {
|
|
3564
|
+
...headers === void 0 ? {} : { headers },
|
|
3565
|
+
...typeof options.fresh === "string" ? { query: { [FRESH_PARAMETER]: options.fresh } } : {}
|
|
3566
|
+
};
|
|
3567
|
+
}
|
|
3568
|
+
chunkMWMSFIWN_cjs.__name(transportOf, "transportOf");
|
|
3569
|
+
async function runSearch(http, q, options, clientLocale) {
|
|
3570
|
+
const sort = options.sort === void 0 ? [] : Object.entries(options.sort).flatMap(
|
|
3571
|
+
([field, direction]) => direction === void 0 ? [] : [{ field, direction }]
|
|
3572
|
+
);
|
|
3573
|
+
const body = {
|
|
3574
|
+
q,
|
|
3575
|
+
...scopeOf(options.contentType),
|
|
3576
|
+
...whereOf(options.where),
|
|
3577
|
+
...given({
|
|
3578
|
+
searchFields: options.searchFields === void 0 ? void 0 : [...options.searchFields]
|
|
3579
|
+
}),
|
|
3580
|
+
...selectedFields(options.select),
|
|
3581
|
+
...sort.length === 0 ? {} : { sort },
|
|
3582
|
+
...given({
|
|
3583
|
+
page: options.page,
|
|
3584
|
+
limit: options.limit,
|
|
3585
|
+
includeScore: options.includeScore,
|
|
3586
|
+
explain: options.explain,
|
|
3587
|
+
highlight: options.highlight,
|
|
3588
|
+
facets: options.facets
|
|
3589
|
+
}),
|
|
3590
|
+
...localeOf(options.locale, clientLocale)
|
|
3591
|
+
};
|
|
3592
|
+
const response = await http.send(
|
|
3593
|
+
"/v1/search",
|
|
3594
|
+
"post",
|
|
3595
|
+
{
|
|
3596
|
+
body,
|
|
3597
|
+
...transportOf(options)
|
|
3598
|
+
}
|
|
3599
|
+
);
|
|
3600
|
+
return response.body;
|
|
3601
|
+
}
|
|
3602
|
+
chunkMWMSFIWN_cjs.__name(runSearch, "runSearch");
|
|
3603
|
+
async function runAutocomplete(http, q, options, clientLocale) {
|
|
3604
|
+
const body = {
|
|
3605
|
+
q,
|
|
3606
|
+
contentType: options.contentType,
|
|
3607
|
+
field: options.field,
|
|
3608
|
+
...given({ fuzzy: options.fuzzy }),
|
|
3609
|
+
...whereOf(options.where),
|
|
3610
|
+
...given({ limit: options.limit }),
|
|
3611
|
+
...localeOf(options.locale, clientLocale)
|
|
3612
|
+
};
|
|
3613
|
+
const response = await http.send(
|
|
3614
|
+
"/v1/search/autocomplete",
|
|
3615
|
+
"post",
|
|
3616
|
+
{ body, ...transportOf(options) }
|
|
3617
|
+
);
|
|
3618
|
+
return response.body;
|
|
3619
|
+
}
|
|
3620
|
+
chunkMWMSFIWN_cjs.__name(runAutocomplete, "runAutocomplete");
|
|
3621
|
+
async function runSimilar(http, source, options, clientLocale) {
|
|
3622
|
+
const body = {
|
|
3623
|
+
source,
|
|
3624
|
+
...scopeOf(options.contentType),
|
|
3625
|
+
...given({ limit: options.limit }),
|
|
3626
|
+
...localeOf(options.locale, clientLocale),
|
|
3627
|
+
...selectedFields(options.select)
|
|
3628
|
+
};
|
|
3629
|
+
const response = await http.send(
|
|
3630
|
+
"/v1/search/similar",
|
|
3631
|
+
"post",
|
|
3632
|
+
{ body, ...transportOf(options) }
|
|
3633
|
+
);
|
|
3634
|
+
return response.body;
|
|
3635
|
+
}
|
|
3636
|
+
chunkMWMSFIWN_cjs.__name(runSimilar, "runSimilar");
|
|
3637
|
+
|
|
3638
|
+
// src/batch/batch-operations.ts
|
|
3639
|
+
var VERBS = ["create", "update", "replace", "delete", "singleton"];
|
|
3640
|
+
async function runBatch(http, operations, options, clientLocale) {
|
|
3641
|
+
const { atomic, dryRun, stopOnError, returnData, dataset } = options;
|
|
3642
|
+
const runOptions = {
|
|
3643
|
+
...atomic === void 0 ? {} : { atomic },
|
|
3644
|
+
...dryRun === void 0 ? {} : { dryRun },
|
|
3645
|
+
...stopOnError === void 0 ? {} : { continueOnError: !stopOnError },
|
|
3646
|
+
...returnData === void 0 ? {} : { returnData }
|
|
3647
|
+
};
|
|
3648
|
+
const headers = readHeaders({ ...dataset === void 0 ? {} : { dataset } });
|
|
3649
|
+
const response = await http.send("/v1/batch", "post", {
|
|
3650
|
+
body: {
|
|
3651
|
+
operations: operations.map((operation, index) => operationOf(operation, index, clientLocale)),
|
|
3652
|
+
...Object.keys(runOptions).length === 0 ? {} : { options: runOptions }
|
|
3653
|
+
},
|
|
3654
|
+
...headers === void 0 ? {} : { headers }
|
|
3655
|
+
});
|
|
3656
|
+
return response.body;
|
|
3657
|
+
}
|
|
3658
|
+
chunkMWMSFIWN_cjs.__name(runBatch, "runBatch");
|
|
3659
|
+
function operationOf(operation, index, clientLocale) {
|
|
3660
|
+
const named = VERBS.filter((verb2) => operation[verb2] !== void 0);
|
|
3661
|
+
const verb = named[0];
|
|
3662
|
+
if (verb === void 0 || named.length > 1) {
|
|
3663
|
+
throw new ValidationError(
|
|
3664
|
+
`Batch operation ${index} must name exactly one of ${VERBS.join(", ")}; it names ${named.length === 0 ? "none" : named.join(" and ")}.`,
|
|
3665
|
+
[{ field: `operations[${index}]`, code: "ONE_VERB", message: "name one verb" }]
|
|
3666
|
+
);
|
|
3667
|
+
}
|
|
3668
|
+
const { slug, parentId, sortOrder } = operation;
|
|
3669
|
+
const placement = {
|
|
3670
|
+
...slug === void 0 ? {} : { slug },
|
|
3671
|
+
...parentId === void 0 ? {} : { parentId },
|
|
3672
|
+
...sortOrder === void 0 ? {} : { sortOrder }
|
|
3673
|
+
};
|
|
3674
|
+
const located = /* @__PURE__ */ chunkMWMSFIWN_cjs.__name((locale) => locale === void 0 ? {} : { locale }, "located");
|
|
3675
|
+
switch (verb) {
|
|
3676
|
+
case "create": {
|
|
3677
|
+
return {
|
|
3678
|
+
method: "POST",
|
|
3679
|
+
path: `/${operation.create}`,
|
|
3680
|
+
body: {
|
|
3681
|
+
content: operation.data,
|
|
3682
|
+
...placement,
|
|
3683
|
+
...located(callLocale(operation.locale, clientLocale))
|
|
3684
|
+
}
|
|
3685
|
+
};
|
|
3686
|
+
}
|
|
3687
|
+
case "update":
|
|
3688
|
+
case "replace": {
|
|
3689
|
+
const target = targetOf(operation, clientLocale);
|
|
3690
|
+
return {
|
|
3691
|
+
method: verb === "update" ? "PATCH" : "PUT",
|
|
3692
|
+
path: `/${operation[verb]}/${target.id}`,
|
|
3693
|
+
...target.ifMatch === void 0 ? {} : { ifMatch: target.ifMatch },
|
|
3694
|
+
body: { content: operation.data, ...placement, ...located(target.locale) }
|
|
3695
|
+
};
|
|
3696
|
+
}
|
|
3697
|
+
case "delete": {
|
|
3698
|
+
const target = targetOf(operation, void 0);
|
|
3699
|
+
return {
|
|
3700
|
+
method: "DELETE",
|
|
3701
|
+
path: `/${operation.delete}/${target.id}`,
|
|
3702
|
+
...target.ifMatch === void 0 ? {} : { ifMatch: target.ifMatch }
|
|
3703
|
+
};
|
|
3704
|
+
}
|
|
3705
|
+
case "singleton": {
|
|
3706
|
+
return {
|
|
3707
|
+
method: "PATCH",
|
|
3708
|
+
path: `/_singletons/${operation.singleton}`,
|
|
3709
|
+
body: { content: operation.data, ...located(callLocale(operation.locale, clientLocale)) }
|
|
3710
|
+
};
|
|
3711
|
+
}
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
chunkMWMSFIWN_cjs.__name(operationOf, "operationOf");
|
|
3715
|
+
function targetOf(operation, clientLocale) {
|
|
3716
|
+
if (operation.entry !== void 0) return versionCheckOf(operation.entry);
|
|
3717
|
+
if (operation.id === void 0) {
|
|
3718
|
+
throw new ValidationError("A batch update, replace or delete names an `entry` or an `id`.", [
|
|
3719
|
+
{ field: "id", code: "MISSING_TARGET", message: "name an entry or an id" }
|
|
3720
|
+
]);
|
|
3721
|
+
}
|
|
3722
|
+
const locale = callLocale(operation.locale, clientLocale);
|
|
3723
|
+
return { id: operation.id, ...locale === void 0 ? {} : { locale } };
|
|
3724
|
+
}
|
|
3725
|
+
chunkMWMSFIWN_cjs.__name(targetOf, "targetOf");
|
|
3726
|
+
|
|
3727
|
+
// src/queries/query-call.ts
|
|
3728
|
+
async function runAdhocQuery(http, query, clientLocale) {
|
|
3729
|
+
const { where, include, select, sort, limit, page, aggregate, fullText } = query;
|
|
3730
|
+
if (where !== void 0) refuseMetadataConditions(where);
|
|
3731
|
+
const order = sort === void 0 ? [] : Object.entries(sort).flatMap(
|
|
3732
|
+
([field, direction]) => direction === void 0 ? [] : [{ [field]: direction }]
|
|
3733
|
+
);
|
|
3734
|
+
const fetch2 = {
|
|
3735
|
+
contentType: query.from,
|
|
3736
|
+
...where === void 0 || Object.keys(where).length === 0 ? {} : { where },
|
|
3737
|
+
...include === void 0 || include.length === 0 ? {} : { include: [...include] },
|
|
3738
|
+
...order.length === 0 ? {} : { sort: order },
|
|
3739
|
+
...limit === void 0 ? {} : { limit },
|
|
3740
|
+
...page === void 0 ? {} : { offset: offsetOf(page, limit) }
|
|
3741
|
+
};
|
|
3742
|
+
const locale = query.locale ?? clientLocale;
|
|
3743
|
+
const parameters = {
|
|
3744
|
+
...query.params,
|
|
3745
|
+
...locale === void 0 || locale === "" ? {} : { locale }
|
|
3746
|
+
};
|
|
3747
|
+
const body = {
|
|
3748
|
+
query: {
|
|
3749
|
+
fetch: fetch2,
|
|
3750
|
+
...aggregate === void 0 ? {} : { aggregate },
|
|
3751
|
+
...select === void 0 || select.length === 0 ? {} : { select: Object.fromEntries(select.map((field) => [field, field])) },
|
|
3752
|
+
...fullText === void 0 ? {} : { fullText }
|
|
3753
|
+
},
|
|
3754
|
+
...Object.keys(parameters).length === 0 ? {} : { parameters }
|
|
3755
|
+
};
|
|
3756
|
+
const headers = readHeaders(query);
|
|
3757
|
+
const response = await http.send("/v1/query", "post", {
|
|
3758
|
+
body,
|
|
3759
|
+
...headers === void 0 ? {} : { headers },
|
|
3760
|
+
...typeof query.fresh === "string" ? { query: { [FRESH_PARAMETER]: query.fresh } } : {}
|
|
3761
|
+
});
|
|
3762
|
+
return response.body;
|
|
3763
|
+
}
|
|
3764
|
+
chunkMWMSFIWN_cjs.__name(runAdhocQuery, "runAdhocQuery");
|
|
3765
|
+
function offsetOf(page, limit) {
|
|
3766
|
+
if (limit === void 0 || !Number.isInteger(page) || page < 1) {
|
|
3767
|
+
throw new ValidationError(
|
|
3768
|
+
"`page` is a whole number from 1, beside the `limit` that sizes it.",
|
|
3769
|
+
[{ field: "page", code: "INVALID_PAGE", message: `page ${page}, limit ${String(limit)}` }]
|
|
3770
|
+
);
|
|
3771
|
+
}
|
|
3772
|
+
return (page - 1) * limit;
|
|
3773
|
+
}
|
|
3774
|
+
chunkMWMSFIWN_cjs.__name(offsetOf, "offsetOf");
|
|
3775
|
+
async function runNamedQuery(http, name, options, clientLocale) {
|
|
3776
|
+
const locale = options.locale ?? clientLocale;
|
|
3777
|
+
const headers = readHeaders(options);
|
|
3778
|
+
const response = await http.send(
|
|
3779
|
+
"/v1/queries/{name}",
|
|
3780
|
+
"post",
|
|
3781
|
+
{
|
|
3782
|
+
path: { name },
|
|
3783
|
+
body: options.params === void 0 ? {} : { params: options.params },
|
|
3784
|
+
...locale === void 0 || locale === "" ? {} : { query: { locale } },
|
|
3785
|
+
...headers === void 0 ? {} : { headers }
|
|
3786
|
+
}
|
|
3787
|
+
);
|
|
3788
|
+
return response.body;
|
|
3789
|
+
}
|
|
3790
|
+
chunkMWMSFIWN_cjs.__name(runNamedQuery, "runNamedQuery");
|
|
3791
|
+
|
|
5430
3792
|
// src/config/dev-detection.ts
|
|
5431
3793
|
function sandboxStateOf(resolution) {
|
|
5432
3794
|
return resolution.state === "active" ? resolution.sandbox : resolution;
|
|
@@ -5631,9 +3993,9 @@ function withHandshake(configured) {
|
|
|
5631
3993
|
return { config: merged, sandbox: sandboxStateOf(dev), configured };
|
|
5632
3994
|
}
|
|
5633
3995
|
chunkMWMSFIWN_cjs.__name(withHandshake, "withHandshake");
|
|
5634
|
-
function withDefaults(base,
|
|
3996
|
+
function withDefaults(base, given2, defaults) {
|
|
5635
3997
|
const merged = new Map(Object.entries(base));
|
|
5636
|
-
const givenValues = new Map(Object.entries(
|
|
3998
|
+
const givenValues = new Map(Object.entries(given2 ?? {}));
|
|
5637
3999
|
const defaultValues = new Map(Object.entries(defaults));
|
|
5638
4000
|
for (const key of /* @__PURE__ */ new Set([...merged.keys(), ...givenValues.keys()])) {
|
|
5639
4001
|
const fallback = merged.get(key);
|
|
@@ -5660,7 +4022,6 @@ function isOptionBag(value) {
|
|
|
5660
4022
|
chunkMWMSFIWN_cjs.__name(isOptionBag, "isOptionBag");
|
|
5661
4023
|
|
|
5662
4024
|
// src/client/create-client.ts
|
|
5663
|
-
var API_VERSION_SEGMENT = "v1";
|
|
5664
4025
|
var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
5665
4026
|
constructor(config) {
|
|
5666
4027
|
/**
|
|
@@ -5671,7 +4032,7 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
5671
4032
|
chunkMWMSFIWN_cjs.__publicField(this, "config");
|
|
5672
4033
|
/**
|
|
5673
4034
|
* The configuration as `createClient()`, `setApiKey()` and `updateConfig()` gave it, before the
|
|
5674
|
-
* `relyio dev` handshake: what the next update is laid over, and what `
|
|
4035
|
+
* `relyio dev` handshake: what the next update is laid over, and what `with()` starts from.
|
|
5675
4036
|
*/
|
|
5676
4037
|
chunkMWMSFIWN_cjs.__publicField(this, "configured");
|
|
5677
4038
|
chunkMWMSFIWN_cjs.__publicField(this, "_sandbox");
|
|
@@ -5681,7 +4042,15 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
5681
4042
|
* rather than a copy of the locale, so one taken before `updateConfig({ locale })` sends the new
|
|
5682
4043
|
* locale, or none after `locale: null` (REL-1453).
|
|
5683
4044
|
*/
|
|
5684
|
-
chunkMWMSFIWN_cjs.__publicField(this, "currentLocale", /* @__PURE__ */ chunkMWMSFIWN_cjs.__name(() => this.config.locale, "currentLocale"));
|
|
4045
|
+
chunkMWMSFIWN_cjs.__publicField(this, "currentLocale", /* @__PURE__ */ chunkMWMSFIWN_cjs.__name(() => this.defaults.locale ?? (this.parent === void 0 ? this.config.locale : this.parent.currentLocale()), "currentLocale"));
|
|
4046
|
+
/**
|
|
4047
|
+
* The client `with()` was called on, for a client it made: whose key, base URL and configuration
|
|
4048
|
+
* this one reads with as they are when each request is sent. `undefined` for a client
|
|
4049
|
+
* `createClient()` made, which reads its own.
|
|
4050
|
+
*/
|
|
4051
|
+
chunkMWMSFIWN_cjs.__publicField(this, "parent");
|
|
4052
|
+
/** What `with()` gave this client over its parent's: the locale and dataset it names, and no other. */
|
|
4053
|
+
chunkMWMSFIWN_cjs.__publicField(this, "defaults", {});
|
|
5685
4054
|
/** The live edge's poll client id: chosen once, when first needed, and kept for this client's life. */
|
|
5686
4055
|
chunkMWMSFIWN_cjs.__publicField(this, "_liveClientId");
|
|
5687
4056
|
const { schema, ...clientConfig } = config;
|
|
@@ -5695,12 +4064,6 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
5695
4064
|
// ============================================================================
|
|
5696
4065
|
// CORE CLIENTS
|
|
5697
4066
|
// ============================================================================
|
|
5698
|
-
/**
|
|
5699
|
-
* Get the schema definition
|
|
5700
|
-
*/
|
|
5701
|
-
get schema() {
|
|
5702
|
-
return this._schema;
|
|
5703
|
-
}
|
|
5704
4067
|
/**
|
|
5705
4068
|
* The `relyio dev` sandbox this client resolved at construction, as the preview toolbar displays
|
|
5706
4069
|
* it (`sdk-surfaces-spec.md` decision 22).
|
|
@@ -5716,13 +4079,23 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
5716
4079
|
* ```
|
|
5717
4080
|
*/
|
|
5718
4081
|
get sandbox() {
|
|
5719
|
-
return this._sandbox;
|
|
4082
|
+
return this.parent === void 0 ? this._sandbox : this.parent.sandbox;
|
|
5720
4083
|
}
|
|
5721
4084
|
/**
|
|
5722
|
-
*
|
|
4085
|
+
* Run a query in one call (REL-2421, REL-2409 Q22):
|
|
4086
|
+
*
|
|
4087
|
+
* - `query({ from, … })` runs one inline, with `list`'s option names — `where` (the query
|
|
4088
|
+
* route's dialect), `include`, `select`, `sort`, `limit`, `page`, `locale`, `dataset`, `fresh` —
|
|
4089
|
+
* plus `aggregate`, `params` and `fullText`;
|
|
4090
|
+
* - `query(name, { params, … })` runs the saved query the schema declares under `name`, its
|
|
4091
|
+
* `params` typed from that declaration.
|
|
4092
|
+
*
|
|
4093
|
+
* Both answer the API's body, `{ data: { result, metadata } }`. See {@link QueryCall}. Every query
|
|
4094
|
+
* is sent in the client's locale as it is then, unless it names its own.
|
|
5723
4095
|
*/
|
|
5724
4096
|
get query() {
|
|
5725
|
-
|
|
4097
|
+
const call = /* @__PURE__ */ chunkMWMSFIWN_cjs.__name((target, options = {}) => typeof target === "string" ? runNamedQuery(this.httpClient, target, options, this.currentLocale()) : runAdhocQuery(this.httpClient, target, this.currentLocale()), "call");
|
|
4098
|
+
return call;
|
|
5726
4099
|
}
|
|
5727
4100
|
// ============================================================================
|
|
5728
4101
|
// CONTENT OPERATIONS
|
|
@@ -5733,12 +4106,11 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
5733
4106
|
*
|
|
5734
4107
|
* @example
|
|
5735
4108
|
* ```typescript
|
|
5736
|
-
* const products = await relyio.content('product')
|
|
5737
|
-
*
|
|
5738
|
-
*
|
|
5739
|
-
*
|
|
5740
|
-
*
|
|
5741
|
-
* .execute()
|
|
4109
|
+
* const { data: products } = await relyio.content('product').list({
|
|
4110
|
+
* where: { status: 'active' }, // ← Field names autocomplete with schema!
|
|
4111
|
+
* locale: 'en-US',
|
|
4112
|
+
* limit: 20,
|
|
4113
|
+
* })
|
|
5742
4114
|
* ```
|
|
5743
4115
|
*/
|
|
5744
4116
|
content(contentType) {
|
|
@@ -5747,9 +4119,9 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
5747
4119
|
/**
|
|
5748
4120
|
* Get an asset client for a specific asset type.
|
|
5749
4121
|
*
|
|
5750
|
-
*
|
|
5751
|
-
* dynamic `/{assetTypeId}` routes, and adds
|
|
5752
|
-
* builder
|
|
4122
|
+
* Reads and writes as `content()` does — `list`, `get`, `listAll`, `update`, `delete` — over
|
|
4123
|
+
* `entryType: 'asset'` entries on the same dynamic `/{assetTypeId}` routes, and adds `create`,
|
|
4124
|
+
* the `file(entryUid)` sub-resource builder and a high-level `upload()` helper. Type-safe when a schema is
|
|
5753
4125
|
* provided: autocompletes asset type names AND metadata field names.
|
|
5754
4126
|
*
|
|
5755
4127
|
* @example
|
|
@@ -5771,10 +4143,10 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
5771
4143
|
*
|
|
5772
4144
|
* @example
|
|
5773
4145
|
* ```typescript
|
|
5774
|
-
* const homepage = await relyio.singleton('homepage')
|
|
5775
|
-
*
|
|
5776
|
-
*
|
|
5777
|
-
*
|
|
4146
|
+
* const homepage = await relyio.singleton('homepage').get({
|
|
4147
|
+
* include: ['featuredProducts'],
|
|
4148
|
+
* locale: 'en',
|
|
4149
|
+
* })
|
|
5778
4150
|
* ```
|
|
5779
4151
|
*/
|
|
5780
4152
|
singleton(key) {
|
|
@@ -5786,101 +4158,54 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
5786
4158
|
*
|
|
5787
4159
|
* @example
|
|
5788
4160
|
* ```typescript
|
|
5789
|
-
* const emailConfig = await relyio.settings('email-config')
|
|
5790
|
-
*
|
|
5791
|
-
*
|
|
4161
|
+
* const emailConfig = await relyio.settings('email-config').get({
|
|
4162
|
+
* include: ['defaultTemplate'],
|
|
4163
|
+
* })
|
|
5792
4164
|
* ```
|
|
5793
4165
|
*/
|
|
5794
4166
|
settings(groupId) {
|
|
5795
4167
|
return new SettingsClient(this.httpClient, groupId, this.currentLocale);
|
|
5796
4168
|
}
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
// ============================================================================
|
|
5800
|
-
/**
|
|
5801
|
-
* Start a search query with full-text, semantic, or hybrid search.
|
|
5802
|
-
*
|
|
5803
|
-
* Where a schema types the client, the results are its entries — every content type's until
|
|
5804
|
-
* `in()` or `across()` narrows them (`INV-SS-TYPES-INFERRED`).
|
|
5805
|
-
*
|
|
5806
|
-
* @example
|
|
5807
|
-
* ```typescript
|
|
5808
|
-
* const results = await relyio.search('wireless headphones')
|
|
5809
|
-
* .in('product')
|
|
5810
|
-
* .where({ status: 'active' })
|
|
5811
|
-
* .limit(20)
|
|
5812
|
-
* .includeScore()
|
|
5813
|
-
* .execute()
|
|
5814
|
-
* ```
|
|
5815
|
-
*/
|
|
5816
|
-
search(query) {
|
|
5817
|
-
return this.searchClient().search(query);
|
|
4169
|
+
search(query, options) {
|
|
4170
|
+
return runSearch(this.httpClient, query, options, this.currentLocale());
|
|
5818
4171
|
}
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
*
|
|
5822
|
-
* @example
|
|
5823
|
-
* ```typescript
|
|
5824
|
-
* const suggestions = await relyio.autocomplete('wire')
|
|
5825
|
-
* .in('product')
|
|
5826
|
-
* .field('title')
|
|
5827
|
-
* .fuzzy()
|
|
5828
|
-
* .limit(10)
|
|
5829
|
-
* .execute()
|
|
5830
|
-
* ```
|
|
5831
|
-
*/
|
|
5832
|
-
autocomplete(query) {
|
|
5833
|
-
return this.searchClient().autocomplete(query);
|
|
4172
|
+
autocomplete(query, options) {
|
|
4173
|
+
return runAutocomplete(this.httpClient, query, options, this.currentLocale());
|
|
5834
4174
|
}
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
*
|
|
5838
|
-
* @example
|
|
5839
|
-
* ```typescript
|
|
5840
|
-
* const similar = await relyio.similar('entry_abc123')
|
|
5841
|
-
* .in('product')
|
|
5842
|
-
* .locale('fr-FR')
|
|
5843
|
-
* .limit(5)
|
|
5844
|
-
* .execute()
|
|
5845
|
-
* ```
|
|
5846
|
-
*/
|
|
5847
|
-
similar(sourceId) {
|
|
5848
|
-
return this.searchClient().similar(sourceId);
|
|
4175
|
+
similar(sourceId, options) {
|
|
4176
|
+
return runSimilar(this.httpClient, sourceId, options, this.currentLocale());
|
|
5849
4177
|
}
|
|
5850
4178
|
// ============================================================================
|
|
5851
4179
|
// BATCH OPERATIONS
|
|
5852
4180
|
// ============================================================================
|
|
5853
4181
|
/**
|
|
5854
|
-
*
|
|
4182
|
+
* Write a list of operations in one request (REL-2421, REL-2409 Q22): each a create, update,
|
|
4183
|
+
* replace or delete of an entry, or a singleton write.
|
|
4184
|
+
*
|
|
4185
|
+
* An update, replace or delete takes the **entry you read** — checked against the version it
|
|
4186
|
+
* carries, in the locale it was read in, as `update(entry, data)` is — or an **id**, which writes
|
|
4187
|
+
* unchecked, on purpose. A stale entry fails its operation with `RESOURCE_CONFLICT` naming the
|
|
4188
|
+
* versions that disagreed: re-read it with `fresh: true` and retry. With `atomic: true` nothing
|
|
4189
|
+
* in the batch is written then — and the API takes an atomic batch only when every operation is
|
|
4190
|
+
* the same kind of write.
|
|
5855
4191
|
*
|
|
5856
|
-
*
|
|
5857
|
-
*
|
|
5858
|
-
* writes a singleton that does not exist yet.
|
|
4192
|
+
* Answers the API's body, `{ data: { results, summary } }`: one result per operation, in order,
|
|
4193
|
+
* each an `outcome` or an `error`. An operation that failed is not thrown.
|
|
5859
4194
|
*
|
|
5860
4195
|
* @example
|
|
5861
4196
|
* ```typescript
|
|
5862
|
-
* const
|
|
5863
|
-
*
|
|
5864
|
-
*
|
|
5865
|
-
*
|
|
5866
|
-
*
|
|
5867
|
-
*
|
|
5868
|
-
*
|
|
5869
|
-
* console.log(
|
|
5870
|
-
*
|
|
5871
|
-
* // All or nothing: one kind of write
|
|
5872
|
-
* await relyio.batch()
|
|
5873
|
-
* .update('product', 'entry_abc', { content: { price: 899 } })
|
|
5874
|
-
* .update('product', 'entry_def', { content: { price: 799 } })
|
|
5875
|
-
* .execute({ atomic: true })
|
|
4197
|
+
* const post = await relyio.content('post').get('hello-world')
|
|
4198
|
+
* const { data } = await relyio.batch([
|
|
4199
|
+
* { create: 'post', data: { title: 'New' } },
|
|
4200
|
+
* ...(post ? [{ update: 'post' as const, entry: post, data: { title: 'Changed' } }] : []),
|
|
4201
|
+
* { delete: 'post', id: 'entry_xyz' },
|
|
4202
|
+
* { singleton: 'homepage', data: { hero: 'Welcome!' } },
|
|
4203
|
+
* ])
|
|
4204
|
+
* console.log(data.summary.succeeded)
|
|
5876
4205
|
* ```
|
|
5877
4206
|
*/
|
|
5878
|
-
batch() {
|
|
5879
|
-
return
|
|
5880
|
-
}
|
|
5881
|
-
/** The search client, whose builders send the client's locale as it is when each one is sent. */
|
|
5882
|
-
searchClient() {
|
|
5883
|
-
return new SearchClient(this.httpClient, this.currentLocale);
|
|
4207
|
+
async batch(operations, options = {}) {
|
|
4208
|
+
return runBatch(this.httpClient, operations, options, this.currentLocale());
|
|
5884
4209
|
}
|
|
5885
4210
|
// ============================================================================
|
|
5886
4211
|
// CHANGES FEED
|
|
@@ -5900,7 +4225,7 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
5900
4225
|
* const controller = new AbortController()
|
|
5901
4226
|
* for await (const change of relyio.changes({ since: cursor, types: ['post'], signal: controller.signal })) {
|
|
5902
4227
|
* // { entryId, contentType, locale, kind, cursor, fresh }
|
|
5903
|
-
* await relyio.content(change.contentType).
|
|
4228
|
+
* await relyio.content(change.contentType).get(change.entryId, { fresh: change.fresh })
|
|
5904
4229
|
* }
|
|
5905
4230
|
* ```
|
|
5906
4231
|
*
|
|
@@ -5942,7 +4267,7 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
5942
4267
|
* signal: controller.signal,
|
|
5943
4268
|
* // `fresh` names a position no cache holds a body for from before the change.
|
|
5944
4269
|
* onChange: change =>
|
|
5945
|
-
* relyio.content(change.contentType).
|
|
4270
|
+
* relyio.content(change.contentType).get(change.entryId, { fresh: change.fresh }),
|
|
5946
4271
|
* onResync: resync => refetchEverything(resync.cause === 'expired' ? resync.expired.fresh : undefined),
|
|
5947
4272
|
* })
|
|
5948
4273
|
* ```
|
|
@@ -5951,7 +4276,7 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
5951
4276
|
* edge's URL. On a server, follow `changes()` with it instead.
|
|
5952
4277
|
*/
|
|
5953
4278
|
liveChanges(options = {}) {
|
|
5954
|
-
const { apiKey, dataset, baseUrl, liveUrl, fetch: fetch2, webSocket, timeout } = this.
|
|
4279
|
+
const { apiKey, dataset, baseUrl, liveUrl, fetch: fetch2, webSocket, timeout } = this.getConfig();
|
|
5955
4280
|
this._liveClientId ?? (this._liveClientId = randomClientId());
|
|
5956
4281
|
return subscribeLiveEdge(
|
|
5957
4282
|
{
|
|
@@ -5979,60 +4304,13 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
5979
4304
|
* @example
|
|
5980
4305
|
* ```typescript
|
|
5981
4306
|
* const since = await relyio.changesHead()
|
|
5982
|
-
* const post = await relyio.content('post').
|
|
4307
|
+
* const post = await relyio.content('post').get(id)
|
|
5983
4308
|
* for await (const change of relyio.changes({ since, ids: [id] })) { … }
|
|
5984
4309
|
* ```
|
|
5985
4310
|
*/
|
|
5986
4311
|
changesHead(options = {}) {
|
|
5987
4312
|
return readChangesHead(this.httpClient, options);
|
|
5988
4313
|
}
|
|
5989
|
-
// ============================================================================
|
|
5990
|
-
// QUERY OPERATIONS
|
|
5991
|
-
// ============================================================================
|
|
5992
|
-
/**
|
|
5993
|
-
* Build and execute an ad-hoc query dynamically
|
|
5994
|
-
*
|
|
5995
|
-
* @example
|
|
5996
|
-
* ```typescript
|
|
5997
|
-
* const result = await relyio.adhoc()
|
|
5998
|
-
* .from('product')
|
|
5999
|
-
* .where({ status: 'active' })
|
|
6000
|
-
* .include(['brand', 'categories'])
|
|
6001
|
-
* .select({
|
|
6002
|
-
* id: 'id',
|
|
6003
|
-
* title: 'title',
|
|
6004
|
-
* price: 'pricing.basePrice'
|
|
6005
|
-
* })
|
|
6006
|
-
* .limit(20)
|
|
6007
|
-
* .execute()
|
|
6008
|
-
* ```
|
|
6009
|
-
*/
|
|
6010
|
-
adhoc() {
|
|
6011
|
-
return this.query.build();
|
|
6012
|
-
}
|
|
6013
|
-
/**
|
|
6014
|
-
* Execute a predefined query by name (from schema)
|
|
6015
|
-
* Type-safe when schema is provided: autocompletes query names
|
|
6016
|
-
*
|
|
6017
|
-
* @example
|
|
6018
|
-
* ```typescript
|
|
6019
|
-
* const featured = await relyio.executeQuery('featured-products', {
|
|
6020
|
-
* limit: 10,
|
|
6021
|
-
* category: 'electronics'
|
|
6022
|
-
* })
|
|
6023
|
-
* ```
|
|
6024
|
-
*/
|
|
6025
|
-
async executeQuery(queryName, params) {
|
|
6026
|
-
const clientLocale = this.config.locale;
|
|
6027
|
-
const namesLocale = params?.locale != null || params?.locales != null;
|
|
6028
|
-
const response = await this.httpClient.request({
|
|
6029
|
-
method: "GET",
|
|
6030
|
-
url: `/${API_VERSION_SEGMENT}/${String(queryName)}`,
|
|
6031
|
-
params: namesLocale || clientLocale === void 0 || clientLocale === "" ? params ?? {} : { ...params, locale: clientLocale }
|
|
6032
|
-
});
|
|
6033
|
-
const payload = readPayload(response.body);
|
|
6034
|
-
return Array.isArray(payload) ? payload : [payload];
|
|
6035
|
-
}
|
|
6036
4314
|
/**
|
|
6037
4315
|
* Describe the project this key resolves to — `GET /v1/project`.
|
|
6038
4316
|
*
|
|
@@ -6051,46 +4329,61 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
6051
4329
|
return this.httpClient.fetchPayload("/v1/project", "get", {});
|
|
6052
4330
|
}
|
|
6053
4331
|
/**
|
|
6054
|
-
*
|
|
4332
|
+
* The schema definition the key's branch has deployed, as stored — `GET /v1/meta/schema` — or,
|
|
4333
|
+
* given a content type or singleton id, that one type's definition — `GET /v1/meta/schema/{id}`.
|
|
4334
|
+
*
|
|
4335
|
+
* It answers what the deployed schema declares; `project()` answers where the key points
|
|
4336
|
+
* (organization, project, dataset, branch, Studio link). The two share no field.
|
|
4337
|
+
*
|
|
4338
|
+
* @example
|
|
4339
|
+
* ```typescript
|
|
4340
|
+
* const definition = await relyio.schema('post')
|
|
4341
|
+
* ```
|
|
6055
4342
|
*/
|
|
6056
|
-
async
|
|
4343
|
+
async schema(contentType) {
|
|
6057
4344
|
return contentType == null ? this.httpClient.fetchPayload("/v1/meta/schema", "get", {}) : this.httpClient.fetchPayload("/v1/meta/schema/{contentType}", "get", {
|
|
6058
4345
|
path: { contentType }
|
|
6059
4346
|
});
|
|
6060
4347
|
}
|
|
6061
4348
|
/**
|
|
6062
|
-
*
|
|
4349
|
+
* The content types and singletons the key's branch has deployed — `GET /v1/meta/content-types`.
|
|
4350
|
+
*
|
|
4351
|
+
* Each is named by its `id` (what `content()` and `singleton()` take), its `name` (the schema's
|
|
4352
|
+
* `displayName`) and its `type`, content types first, each group in the order the schema declares it.
|
|
4353
|
+
*
|
|
4354
|
+
* @example
|
|
4355
|
+
* ```typescript
|
|
4356
|
+
* const types = await relyio.contentTypes()
|
|
4357
|
+
* const singletons = types.filter(type => type.type === 'singleton').map(type => type.id)
|
|
4358
|
+
* ```
|
|
6063
4359
|
*/
|
|
6064
|
-
async
|
|
6065
|
-
return this.httpClient.fetchPayload(
|
|
4360
|
+
async contentTypes() {
|
|
4361
|
+
return this.httpClient.fetchPayload(
|
|
4362
|
+
"/v1/meta/content-types",
|
|
4363
|
+
"get",
|
|
4364
|
+
{}
|
|
4365
|
+
);
|
|
6066
4366
|
}
|
|
6067
4367
|
/**
|
|
6068
|
-
*
|
|
4368
|
+
* Whether the API can serve requests now — `GET /health/ready`.
|
|
4369
|
+
*
|
|
4370
|
+
* Resolves `{ status: 'ok', timestamp }` when the API answers and reaches every store it reads.
|
|
4371
|
+
* Rejects otherwise, with the error the request met: a `503` naming the store that did not answer,
|
|
4372
|
+
* or a network error when the API could not be reached at all. So there is no `status` to check:
|
|
4373
|
+
* a call that resolves is the healthy answer.
|
|
4374
|
+
*
|
|
4375
|
+
* @example
|
|
4376
|
+
* ```typescript
|
|
4377
|
+
* try {
|
|
4378
|
+
* await relyio.health()
|
|
4379
|
+
* } catch (error) {
|
|
4380
|
+
* console.error('RelyIO cannot serve now', error)
|
|
4381
|
+
* }
|
|
4382
|
+
* ```
|
|
6069
4383
|
*/
|
|
6070
4384
|
async health() {
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
/**
|
|
6074
|
-
* Check if the API is ready
|
|
6075
|
-
*/
|
|
6076
|
-
async ready() {
|
|
6077
|
-
try {
|
|
6078
|
-
const payload = await this.httpClient.fetchPayload("/health/ready", "get", {});
|
|
6079
|
-
return payload.status === "ok";
|
|
6080
|
-
} catch {
|
|
6081
|
-
return false;
|
|
6082
|
-
}
|
|
6083
|
-
}
|
|
6084
|
-
/**
|
|
6085
|
-
* Test the connection to the API
|
|
6086
|
-
*/
|
|
6087
|
-
async testConnection() {
|
|
6088
|
-
try {
|
|
6089
|
-
await this.health();
|
|
6090
|
-
return true;
|
|
6091
|
-
} catch {
|
|
6092
|
-
return false;
|
|
6093
|
-
}
|
|
4385
|
+
const { status, timestamp } = await this.httpClient.fetchPayload("/health/ready", "get", {});
|
|
4386
|
+
return { status, timestamp };
|
|
6094
4387
|
}
|
|
6095
4388
|
/**
|
|
6096
4389
|
* Change some of the client's options and keep the rest.
|
|
@@ -6118,11 +4411,10 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
6118
4411
|
*
|
|
6119
4412
|
* The client's one HTTP client is changed in place, so every request from now on is sent as the
|
|
6120
4413
|
* update says — including one from a `content()`, `asset()`, `singleton()` or `settings()`
|
|
6121
|
-
* sub-client
|
|
6122
|
-
*
|
|
6123
|
-
*
|
|
6124
|
-
*
|
|
6125
|
-
* by `withLocale()` is a client of its own: an update of this one does not reach it.
|
|
4414
|
+
* sub-client taken before the call. The locale reaches them too: each reads the client's locale
|
|
4415
|
+
* when it sends, so a new `locale` is the default of its next request and `locale: null` leaves
|
|
4416
|
+
* that request with none. A locale the call names still wins over it, and so does the locale of a
|
|
4417
|
+
* client `with({ locale })` made from this one.
|
|
6126
4418
|
*
|
|
6127
4419
|
* @example
|
|
6128
4420
|
* ```typescript
|
|
@@ -6135,6 +4427,7 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
6135
4427
|
* ```
|
|
6136
4428
|
*/
|
|
6137
4429
|
updateConfig(update) {
|
|
4430
|
+
if (this.parent !== void 0) return this.parent.updateConfig(update);
|
|
6138
4431
|
const resolved = resolveConfigUpdate(this.configured, update);
|
|
6139
4432
|
this.config = resolved.config;
|
|
6140
4433
|
this.configured = resolved.configured;
|
|
@@ -6145,7 +4438,8 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
6145
4438
|
* Get the current configuration
|
|
6146
4439
|
*/
|
|
6147
4440
|
getConfig() {
|
|
6148
|
-
return { ...this.config };
|
|
4441
|
+
if (this.parent === void 0) return { ...this.config };
|
|
4442
|
+
return { ...this.parent.getConfig(), ...this.defaults };
|
|
6149
4443
|
}
|
|
6150
4444
|
/**
|
|
6151
4445
|
* Replace the API key every later request sends as `X-API-Key`.
|
|
@@ -6153,8 +4447,8 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
6153
4447
|
* It reaches every request this client makes from now on, including those of a `content()`,
|
|
6154
4448
|
* `asset()` or other sub-client taken before the call, and `getConfig().apiKey` reports it. A key
|
|
6155
4449
|
* given in `headers`, under any spelling, is replaced with it and does not come back on a later
|
|
6156
|
-
* `updateConfig()`. A client
|
|
6157
|
-
*
|
|
4450
|
+
* `updateConfig()`. A client `with()` made from this one sends the new key too: the two share one
|
|
4451
|
+
* connection.
|
|
6158
4452
|
*
|
|
6159
4453
|
* An empty or blank key is no key, as it is when passed to `createClient`: the next request
|
|
6160
4454
|
* rejects with `MissingApiKeyError` and nothing is sent.
|
|
@@ -6170,6 +4464,7 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
6170
4464
|
* ```
|
|
6171
4465
|
*/
|
|
6172
4466
|
setApiKey(apiKey) {
|
|
4467
|
+
if (this.parent !== void 0) return this.parent.setApiKey(apiKey);
|
|
6173
4468
|
this.configured = withConfiguredKey(this.configured, apiKey);
|
|
6174
4469
|
if (this._sandbox.state === "active") return;
|
|
6175
4470
|
this.httpClient.setApiKey(apiKey);
|
|
@@ -6184,73 +4479,76 @@ var _TypedRelyIOClient = class _TypedRelyIOClient {
|
|
|
6184
4479
|
// LOCALE OPERATIONS
|
|
6185
4480
|
// ============================================================================
|
|
6186
4481
|
/**
|
|
6187
|
-
*
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
*
|
|
6194
|
-
*
|
|
4482
|
+
* Get the current default locale
|
|
4483
|
+
*/
|
|
4484
|
+
getLocale() {
|
|
4485
|
+
return this.currentLocale();
|
|
4486
|
+
}
|
|
4487
|
+
/**
|
|
4488
|
+
* A client whose reads and writes are in `locale` and `dataset` unless a call names its own, and
|
|
4489
|
+
* which otherwise **follows this one** (REL-2417, Q9): it sends this client's key, to this
|
|
4490
|
+
* client's base URL, under this client's configuration as it is when each request is sent — so a
|
|
4491
|
+
* later `setApiKey()` or `updateConfig()` here reaches it. A default it does not name is this
|
|
4492
|
+
* client's, as this client changes it.
|
|
6195
4493
|
*
|
|
6196
|
-
*
|
|
4494
|
+
* The two share one connection, so a `setApiKey()` or `updateConfig()` called on the client made
|
|
4495
|
+
* here changes this one too. A call's own `locale` or `dataset` wins over the defaults.
|
|
6197
4496
|
*
|
|
6198
4497
|
* @example
|
|
6199
4498
|
* ```typescript
|
|
6200
|
-
* const
|
|
6201
|
-
*
|
|
6202
|
-
* // Reads and writes use Spanish
|
|
6203
|
-
* const products = await spanish.content('product').query().execute()
|
|
6204
|
-
* const homepage = await spanish.singleton('homepage').fetch()
|
|
6205
|
-
* const results = await spanish.search('zapatos').execute()
|
|
6206
|
-
* await spanish.content('product').update(id, { title: 'Zapatos' })
|
|
4499
|
+
* const staging = relyio.with({ dataset: 'staging' })
|
|
4500
|
+
* const { data } = await staging.content('post').list({ limit: 10 })
|
|
6207
4501
|
*
|
|
6208
|
-
* //
|
|
6209
|
-
* const englishProducts = await relyio.content('product').query().execute()
|
|
4502
|
+
* const french = relyio.with({ locale: 'fr-FR' }) // ← autocompletes the schema's locales
|
|
6210
4503
|
* ```
|
|
6211
4504
|
*/
|
|
6212
|
-
|
|
6213
|
-
const
|
|
6214
|
-
...this.
|
|
6215
|
-
|
|
4505
|
+
with(defaults) {
|
|
4506
|
+
const child = new _TypedRelyIOClient({
|
|
4507
|
+
...this.configuredNow(),
|
|
4508
|
+
dev: false,
|
|
6216
4509
|
schema: this._schema
|
|
4510
|
+
});
|
|
4511
|
+
child.follow(this, defaults);
|
|
4512
|
+
return child;
|
|
4513
|
+
}
|
|
4514
|
+
/** Make this client one `with()` made from `parent`: see {@link with}. */
|
|
4515
|
+
follow(parent, defaults) {
|
|
4516
|
+
const { locale, dataset } = defaults;
|
|
4517
|
+
this.parent = parent;
|
|
4518
|
+
this.defaults = {
|
|
4519
|
+
...locale === void 0 ? {} : { locale },
|
|
4520
|
+
...dataset === void 0 ? {} : { dataset }
|
|
6217
4521
|
};
|
|
6218
|
-
|
|
4522
|
+
this.httpClient = parent.httpClient.withHeaders(
|
|
4523
|
+
dataset === void 0 ? {} : { [DATASET_HEADER]: dataset }
|
|
4524
|
+
);
|
|
6219
4525
|
}
|
|
6220
4526
|
/**
|
|
6221
|
-
*
|
|
4527
|
+
* The configuration as given, before the `relyio dev` handshake — this client's own, or for a
|
|
4528
|
+
* client `with()` made, its parent's with its defaults laid over it.
|
|
6222
4529
|
*/
|
|
6223
|
-
|
|
6224
|
-
return this.
|
|
4530
|
+
configuredNow() {
|
|
4531
|
+
return this.parent === void 0 ? this.configured : { ...this.parent.configuredNow(), ...this.defaults };
|
|
6225
4532
|
}
|
|
6226
4533
|
/**
|
|
6227
|
-
*
|
|
4534
|
+
* Every locale the key's branch has deployed, the default marked — `GET /v1/meta/locales`.
|
|
4535
|
+
*
|
|
4536
|
+
* In the order the schema declares them. Exactly one has `default: true`, the locale a read or
|
|
4537
|
+
* write that names none is in; every other has `default: false`. `fallback`, `direction` and
|
|
4538
|
+
* `active` are as the schema declares them, absent where it does not.
|
|
6228
4539
|
*
|
|
6229
4540
|
* @example
|
|
6230
4541
|
* ```typescript
|
|
6231
|
-
* const
|
|
4542
|
+
* const locales = await relyio.locales()
|
|
4543
|
+
* const defaultLocale = locales.find(locale => locale.default)?.code
|
|
6232
4544
|
*
|
|
6233
|
-
* // Build language switcher
|
|
6234
|
-
* const options = locales.map(
|
|
6235
|
-
* code: l.code,
|
|
6236
|
-
* label: l.displayName,
|
|
6237
|
-
* isDefault: l.default,
|
|
6238
|
-
* }))
|
|
4545
|
+
* // Build a language switcher
|
|
4546
|
+
* const options = locales.map(locale => ({ code: locale.code, label: locale.displayName }))
|
|
6239
4547
|
* ```
|
|
6240
4548
|
*/
|
|
6241
|
-
async
|
|
6242
|
-
const
|
|
6243
|
-
|
|
6244
|
-
params.search = search;
|
|
6245
|
-
}
|
|
6246
|
-
return this.httpClient.fetchPayload("/v1/meta/locales", "get", { query: params });
|
|
6247
|
-
}
|
|
6248
|
-
/**
|
|
6249
|
-
* Get the default locale from the API
|
|
6250
|
-
*/
|
|
6251
|
-
async getDefaultLocale() {
|
|
6252
|
-
const { defaultLocale } = await this.getLocales();
|
|
6253
|
-
return defaultLocale;
|
|
4549
|
+
async locales() {
|
|
4550
|
+
const { locales, defaultLocale } = await this.httpClient.fetchPayload("/v1/meta/locales", "get", {});
|
|
4551
|
+
return locales.map((locale) => ({ ...locale, default: locale.code === defaultLocale }));
|
|
6254
4552
|
}
|
|
6255
4553
|
};
|
|
6256
4554
|
chunkMWMSFIWN_cjs.__name(_TypedRelyIOClient, "TypedRelyIOClient");
|
|
@@ -6273,21 +4571,14 @@ function randomClientId() {
|
|
|
6273
4571
|
}
|
|
6274
4572
|
chunkMWMSFIWN_cjs.__name(randomClientId, "randomClientId");
|
|
6275
4573
|
|
|
6276
|
-
exports.AdhocQueryBuilder = AdhocQueryBuilder;
|
|
6277
|
-
exports.AdhocQueryClient = AdhocQueryClient;
|
|
6278
4574
|
exports.AssetClient = AssetClient;
|
|
6279
4575
|
exports.AssetFileBuilder = AssetFileBuilder;
|
|
6280
4576
|
exports.AssetUploadBuilder = AssetUploadBuilder;
|
|
6281
4577
|
exports.AuthorizationError = AuthorizationError;
|
|
6282
|
-
exports.AutocompleteBuilder = AutocompleteBuilder;
|
|
6283
4578
|
exports.BaseValidationError = BaseValidationError;
|
|
6284
|
-
exports.BatchBuilder = BatchBuilder;
|
|
6285
|
-
exports.BatchClient = BatchClient;
|
|
6286
4579
|
exports.ChangesExpiredError = ChangesExpiredError;
|
|
6287
4580
|
exports.ConnectionError = ConnectionError;
|
|
6288
|
-
exports.ContentByIdBuilder = ContentByIdBuilder;
|
|
6289
4581
|
exports.ContentClient = ContentClient;
|
|
6290
|
-
exports.ContentQueryBuilder = ContentQueryBuilder;
|
|
6291
4582
|
exports.ErrorMapper = ErrorMapper;
|
|
6292
4583
|
exports.FileUploadError = FileUploadError;
|
|
6293
4584
|
exports.FileValidationError = FileValidationError;
|
|
@@ -6309,12 +4600,9 @@ exports.ResourceConflictError = ResourceConflictError;
|
|
|
6309
4600
|
exports.ResourceExpiredError = ResourceExpiredError;
|
|
6310
4601
|
exports.ResourceNotFoundError = ResourceNotFoundError;
|
|
6311
4602
|
exports.SDKError = SDKError;
|
|
6312
|
-
exports.SearchBuilder = SearchBuilder;
|
|
6313
|
-
exports.SearchClient = SearchClient;
|
|
6314
4603
|
exports.ServerError = ServerError;
|
|
6315
4604
|
exports.ServiceIndeterminateError = ServiceIndeterminateError;
|
|
6316
4605
|
exports.SettingsClient = SettingsClient;
|
|
6317
|
-
exports.SimilarBuilder = SimilarBuilder;
|
|
6318
4606
|
exports.SingletonClient = SingletonClient;
|
|
6319
4607
|
exports.TimeoutError = TimeoutError;
|
|
6320
4608
|
exports.TransactionRolledBackError = TransactionRolledBackError;
|
|
@@ -6324,14 +4612,15 @@ exports.UsageQuotaExceededError = UsageQuotaExceededError;
|
|
|
6324
4612
|
exports.VISITOR_ADMISSION_RETRY_AFTER_SECONDS = VISITOR_ADMISSION_RETRY_AFTER_SECONDS;
|
|
6325
4613
|
exports.ValidationError = ValidationError;
|
|
6326
4614
|
exports.createClient = createClient;
|
|
6327
|
-
exports.entityTagOf = entityTagOf;
|
|
6328
4615
|
exports.isAborted = isAborted;
|
|
6329
4616
|
exports.isAssetEntry = isAssetEntry;
|
|
4617
|
+
exports.isMissingEntry = isMissingEntry;
|
|
6330
4618
|
exports.isPublishableKey = isPublishableKey;
|
|
6331
4619
|
exports.isResourceNotFound = isResourceNotFound;
|
|
6332
4620
|
exports.matchRoute = matchRoute;
|
|
6333
4621
|
exports.serviceInstructedDelayMs = serviceInstructedDelayMs;
|
|
6334
4622
|
exports.sleep = sleep;
|
|
6335
4623
|
exports.validateFile = validateFile;
|
|
6336
|
-
|
|
6337
|
-
//# sourceMappingURL=chunk-
|
|
4624
|
+
exports.versionCheckOf = versionCheckOf;
|
|
4625
|
+
//# sourceMappingURL=chunk-GUPV2M3X.cjs.map
|
|
4626
|
+
//# sourceMappingURL=chunk-GUPV2M3X.cjs.map
|