@sanity/client 7.22.0 → 7.23.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.
@@ -1046,9 +1046,9 @@ export declare interface ContentSourceMapValueMapping {
1046
1046
 
1047
1047
  /** @public */
1048
1048
  export declare class CorsOriginError extends Error {
1049
- projectId: string
1049
+ projectId?: string
1050
1050
  addOriginUrl?: URL
1051
- constructor({projectId}: {projectId: string})
1051
+ constructor({projectId, credentials}?: {projectId?: string; credentials?: boolean})
1052
1052
  }
1053
1053
 
1054
1054
  /**
@@ -3199,6 +3199,20 @@ export declare class ObservableSanityClient {
3199
3199
  tag?: string
3200
3200
  },
3201
3201
  ): Observable<(SanityDocument<R> | null)[]>
3202
+ /**
3203
+ * Convenient and bandwidth efficient method of checking wether a set of document IDs exists.
3204
+ * Returns a set of the IDs that exist.
3205
+ *
3206
+ * @param ids - Document IDs to check
3207
+ * @param options - Request options
3208
+ */
3209
+ documentsExists(
3210
+ ids: string[],
3211
+ options?: {
3212
+ signal?: AbortSignal
3213
+ tag?: string
3214
+ },
3215
+ ): Observable<Set<string>>
3202
3216
  /**
3203
3217
  * Create a document. Requires a `_type` property. If no `_id` is provided, it will be generated by the database.
3204
3218
  * Returns an observable that resolves to the created document.
@@ -5110,6 +5124,20 @@ export declare class SanityClient {
5110
5124
  tag?: string
5111
5125
  },
5112
5126
  ): Promise<(SanityDocument<R> | null)[]>
5127
+ /**
5128
+ * Convenient and bandwidth efficient method of checking wether a set of document IDs exists.
5129
+ * Returns a set of the IDs that exist.
5130
+ *
5131
+ * @param ids - Document IDs to check
5132
+ * @param options - Request options
5133
+ */
5134
+ documentsExists(
5135
+ ids: string[],
5136
+ options?: {
5137
+ signal?: AbortSignal
5138
+ tag?: string
5139
+ },
5140
+ ): Promise<Set<string>>
5113
5141
  /**
5114
5142
  * Create a document. Requires a `_type` property. If no `_id` is provided, it will be generated by the database.
5115
5143
  * Returns a promise that resolves to the created document.
@@ -1046,9 +1046,9 @@ export declare interface ContentSourceMapValueMapping {
1046
1046
 
1047
1047
  /** @public */
1048
1048
  export declare class CorsOriginError extends Error {
1049
- projectId: string
1049
+ projectId?: string
1050
1050
  addOriginUrl?: URL
1051
- constructor({projectId}: {projectId: string})
1051
+ constructor({projectId, credentials}?: {projectId?: string; credentials?: boolean})
1052
1052
  }
1053
1053
 
1054
1054
  /**
@@ -3199,6 +3199,20 @@ export declare class ObservableSanityClient {
3199
3199
  tag?: string
3200
3200
  },
3201
3201
  ): Observable<(SanityDocument<R> | null)[]>
3202
+ /**
3203
+ * Convenient and bandwidth efficient method of checking wether a set of document IDs exists.
3204
+ * Returns a set of the IDs that exist.
3205
+ *
3206
+ * @param ids - Document IDs to check
3207
+ * @param options - Request options
3208
+ */
3209
+ documentsExists(
3210
+ ids: string[],
3211
+ options?: {
3212
+ signal?: AbortSignal
3213
+ tag?: string
3214
+ },
3215
+ ): Observable<Set<string>>
3202
3216
  /**
3203
3217
  * Create a document. Requires a `_type` property. If no `_id` is provided, it will be generated by the database.
3204
3218
  * Returns an observable that resolves to the created document.
@@ -5110,6 +5124,20 @@ export declare class SanityClient {
5110
5124
  tag?: string
5111
5125
  },
5112
5126
  ): Promise<(SanityDocument<R> | null)[]>
5127
+ /**
5128
+ * Convenient and bandwidth efficient method of checking wether a set of document IDs exists.
5129
+ * Returns a set of the IDs that exist.
5130
+ *
5131
+ * @param ids - Document IDs to check
5132
+ * @param options - Request options
5133
+ */
5134
+ documentsExists(
5135
+ ids: string[],
5136
+ options?: {
5137
+ signal?: AbortSignal
5138
+ tag?: string
5139
+ },
5140
+ ): Promise<Set<string>>
5113
5141
  /**
5114
5142
  * Create a document. Requires a `_type` property. If no `_id` is provided, it will be generated by the database.
5115
5143
  * Returns a promise that resolves to the created document.
@@ -3,7 +3,7 @@ import { adapter, environment } from "get-it";
3
3
  import { retry, jsonRequest, jsonResponse, progress, observable } from "get-it/middleware";
4
4
  import { Observable, defer, isObservable, of, mergeMap, from, lastValueFrom, shareReplay, catchError, concat, timer, throwError, tap, finalize, share, merge, map as map$1, firstValueFrom } from "rxjs";
5
5
  import { isRecord, stegaClean } from "./_chunks-es/stegaClean.js";
6
- import { combineLatestWith, map, filter, finalize as finalize$1 } from "rxjs/operators";
6
+ import { combineLatestWith, map, filter, concatMap, reduce, finalize as finalize$1 } from "rxjs/operators";
7
7
  import { getVersionFromId, isDraftId, getVersionId, getDraftId, isVersionId, getPublishedId } from "@sanity/client/csm";
8
8
  import { customAlphabet } from "nanoid";
9
9
  const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
@@ -174,14 +174,11 @@ function sliceWithEllipsis(str, max) {
174
174
  class CorsOriginError extends Error {
175
175
  projectId;
176
176
  addOriginUrl;
177
- constructor({ projectId: projectId2 }) {
178
- super("CorsOriginError"), this.name = "CorsOriginError", this.projectId = projectId2;
179
- const url = new URL(`https://sanity.io/manage/project/${projectId2}/api`);
180
- if (typeof location < "u") {
181
- const { origin } = location;
182
- url.searchParams.set("cors", "add"), url.searchParams.set("origin", origin), this.addOriginUrl = url, this.message = `The current origin is not allowed to connect to the Live Content API. Add it here: ${url}`;
183
- } else
184
- this.message = `The current origin is not allowed to connect to the Live Content API. Change your configuration here: ${url}`;
177
+ constructor({ projectId: projectId2, credentials } = {}) {
178
+ if (super("CorsOriginError"), this.name = "CorsOriginError", this.projectId = projectId2, projectId2 && typeof location < "u") {
179
+ const url = new URL(`https://sanity.io/manage/project/${projectId2}/api`), { origin } = location;
180
+ url.searchParams.set("cors", "add"), url.searchParams.set("origin", origin), credentials && url.searchParams.set("credentials", ""), this.addOriginUrl = url, this.message = `The current origin is not allowed to connect to the Live Content API. Add it here: ${url}`;
181
+ } else projectId2 ? this.message = `The current origin is not allowed to connect to the Live Content API. Change your configuration here: https://sanity.io/manage/project/${projectId2}/api` : this.message = "The current origin is not allowed to connect to the Live Content API.";
185
182
  }
186
183
  }
187
184
  const httpError = {
@@ -968,6 +965,35 @@ function _getDocuments(client, httpRequest, ids, opts = {}) {
968
965
  })
969
966
  );
970
967
  }
968
+ const DOCUMENTS_EXISTS_BATCH_SIZE = 100;
969
+ function _documentsExists(client, httpRequest, ids, opts = {}) {
970
+ if (ids.length === 0)
971
+ return of(/* @__PURE__ */ new Set());
972
+ const batches = [];
973
+ for (let i = 0; i < ids.length; i += DOCUMENTS_EXISTS_BATCH_SIZE)
974
+ batches.push(ids.slice(i, i + DOCUMENTS_EXISTS_BATCH_SIZE));
975
+ const fetchBatch = (batchIds) => _requestObservable(client, httpRequest, {
976
+ uri: _getDataUrl(client, "doc", batchIds.map(encodeURIComponent).join(",")),
977
+ tag: opts.tag,
978
+ signal: opts.signal,
979
+ query: { excludeContent: !0 }
980
+ }).pipe(
981
+ filter(isResponse),
982
+ map((event) => {
983
+ const missing = /* @__PURE__ */ new Set();
984
+ for (const omitted of event.body.omitted || [])
985
+ omitted.reason === "existence" && missing.add(omitted.id);
986
+ return new Set(batchIds.filter((id) => !missing.has(id)));
987
+ })
988
+ );
989
+ return from(batches).pipe(
990
+ concatMap(fetchBatch),
991
+ reduce((acc, set) => {
992
+ for (const id of set) acc.add(id);
993
+ return acc;
994
+ }, /* @__PURE__ */ new Set())
995
+ );
996
+ }
971
997
  function _getReleaseDocuments(client, httpRequest, releaseId, opts = {}) {
972
998
  return _dataRequest(
973
999
  client,
@@ -1104,7 +1130,7 @@ const hasDataConfig = (client) => {
1104
1130
  return config.dataset !== void 0 && config.projectId !== void 0 || config.resource !== void 0;
1105
1131
  }, isQuery = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "query")), isMutate = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "mutate")), isDoc = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "doc", "")), isListener = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "listen")), isHistory = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "history", "")), isData = (client, uri) => uri.startsWith("/data/") || isQuery(client, uri) || isMutate(client, uri) || isDoc(client, uri) || isListener(client, uri) || isHistory(client, uri);
1106
1132
  function _requestObservable(client, httpRequest, options) {
1107
- const uri = options.url || options.uri, config = client.config(), canUseCdn = typeof options.canUseCdn > "u" ? ["GET", "HEAD"].indexOf(options.method || "GET") >= 0 && isData(client, uri) : options.canUseCdn;
1133
+ const callSiteStack = new Error(), uri = options.url || options.uri, config = client.config(), canUseCdn = typeof options.canUseCdn > "u" ? ["GET", "HEAD"].indexOf(options.method || "GET") >= 0 && isData(client, uri) : options.canUseCdn;
1108
1134
  let useCdn = (options.useCdn ?? config.useCdn) && canUseCdn;
1109
1135
  const tag = options.tag && config.requestTagPrefix ? [config.requestTagPrefix, options.tag].join(".") : options.tag || config.requestTagPrefix;
1110
1136
  if (tag && options.tag !== null && (options.query = { tag: requestTag(tag), ...options.query }), ["GET", "HEAD", "POST"].indexOf(options.method || "GET") >= 0 && isQuery(client, uri)) {
@@ -1120,7 +1146,8 @@ function _requestObservable(client, httpRequest, options) {
1120
1146
  const reqOptions = requestOptions(
1121
1147
  config,
1122
1148
  Object.assign({}, options, {
1123
- url: _getUrl(client, uri, useCdn)
1149
+ url: _getUrl(client, uri, useCdn),
1150
+ callSiteStack
1124
1151
  })
1125
1152
  ), request = new Observable(
1126
1153
  (subscriber) => httpRequest(reqOptions, config.requester).subscribe(subscriber)
@@ -1498,19 +1525,14 @@ class LiveClient {
1498
1525
  "welcome",
1499
1526
  "reconnect",
1500
1527
  "goaway"
1501
- ]), checkCors = fetchObservable(url, {
1502
- method: "OPTIONS",
1503
- mode: "cors",
1504
- credentials: esOptions.withCredentials ? "include" : "omit",
1505
- headers: esOptions.headers
1506
- }).pipe(
1507
- catchError(() => {
1508
- throw new CorsOriginError({ projectId: projectId2 });
1509
- })
1528
+ ]), checkCors = checkCorsObservable(
1529
+ new URL(this.#client.getUrl("/check/cors", !1)),
1530
+ projectId2,
1531
+ esOptions.withCredentials === !0
1510
1532
  ), observable2 = events.pipe(
1511
1533
  reconnectOnConnectionFailure(),
1512
1534
  mergeMap((event) => event.type === "reconnect" ? checkCors.pipe(mergeMap(() => of(event))) : of(event)),
1513
- catchError((err) => checkCors.pipe(
1535
+ catchError((err) => err instanceof CorsOriginError ? throwError(() => err) : checkCors.pipe(
1514
1536
  mergeMap(() => {
1515
1537
  throw err;
1516
1538
  })
@@ -1531,17 +1553,27 @@ class LiveClient {
1531
1553
  return eventsCache.set(key, observable2), observable2;
1532
1554
  }
1533
1555
  }
1534
- function fetchObservable(url, init) {
1556
+ function checkCorsObservable(url, projectId2, requireCredentials) {
1535
1557
  return new Observable((observer) => {
1536
- const controller = new AbortController(), signal = controller.signal;
1537
- return fetch(url, { ...init, signal: controller.signal }).then(
1538
- (response) => {
1539
- observer.next(response), observer.complete();
1540
- },
1541
- (err) => {
1542
- signal.aborted || observer.error(err);
1558
+ const controller = new AbortController(), { signal } = controller;
1559
+ return fetch(url, { method: "GET", mode: "cors", credentials: "omit", signal }).then((response) => {
1560
+ if (!(signal.aborted || !response.ok))
1561
+ return response.json();
1562
+ }).then((body) => {
1563
+ if (!signal.aborted) {
1564
+ if (requireCredentials && body?.result?.withCredentials === !1) {
1565
+ observer.error(new CorsOriginError({ projectId: projectId2, credentials: !0 }));
1566
+ return;
1567
+ }
1568
+ if (body?.result?.allowed === !1) {
1569
+ observer.error(new CorsOriginError({ projectId: projectId2, credentials: requireCredentials }));
1570
+ return;
1571
+ }
1572
+ observer.next(), observer.complete();
1543
1573
  }
1544
- ), () => controller.abort();
1574
+ }).catch(() => {
1575
+ signal.aborted || observer.closed || (observer.next(), observer.complete());
1576
+ }), () => controller.abort();
1545
1577
  });
1546
1578
  }
1547
1579
  const eventsCache = /* @__PURE__ */ new Map();
@@ -2469,6 +2501,16 @@ class ObservableSanityClient {
2469
2501
  getDocuments(ids, options) {
2470
2502
  return _getDocuments(this, this.#httpRequest, ids, options);
2471
2503
  }
2504
+ /**
2505
+ * Convenient and bandwidth efficient method of checking wether a set of document IDs exists.
2506
+ * Returns a set of the IDs that exist.
2507
+ *
2508
+ * @param ids - Document IDs to check
2509
+ * @param options - Request options
2510
+ */
2511
+ documentsExists(ids, options) {
2512
+ return _documentsExists(this, this.#httpRequest, ids, options);
2513
+ }
2472
2514
  create(document, options) {
2473
2515
  return _create(this, this.#httpRequest, document, "create", options);
2474
2516
  }
@@ -2746,6 +2788,16 @@ class SanityClient {
2746
2788
  getDocuments(ids, options) {
2747
2789
  return lastValueFrom(_getDocuments(this, this.#httpRequest, ids, options));
2748
2790
  }
2791
+ /**
2792
+ * Convenient and bandwidth efficient method of checking wether a set of document IDs exists.
2793
+ * Returns a set of the IDs that exist.
2794
+ *
2795
+ * @param ids - Document IDs to check
2796
+ * @param options - Request options
2797
+ */
2798
+ documentsExists(ids, options) {
2799
+ return lastValueFrom(_documentsExists(this, this.#httpRequest, ids, options));
2800
+ }
2749
2801
  create(document, options) {
2750
2802
  return lastValueFrom(
2751
2803
  _create(this, this.#httpRequest, document, "create", options)