@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.
package/dist/index.d.cts CHANGED
@@ -1039,9 +1039,9 @@ export declare interface ContentSourceMapValueMapping {
1039
1039
 
1040
1040
  /** @public */
1041
1041
  export declare class CorsOriginError extends Error {
1042
- projectId: string
1042
+ projectId?: string
1043
1043
  addOriginUrl?: URL
1044
- constructor({projectId}: {projectId: string})
1044
+ constructor({projectId, credentials}?: {projectId?: string; credentials?: boolean})
1045
1045
  }
1046
1046
 
1047
1047
  /**
@@ -3191,6 +3191,20 @@ export declare class ObservableSanityClient {
3191
3191
  tag?: string
3192
3192
  },
3193
3193
  ): Observable<(SanityDocument<R> | null)[]>
3194
+ /**
3195
+ * Convenient and bandwidth efficient method of checking wether a set of document IDs exists.
3196
+ * Returns a set of the IDs that exist.
3197
+ *
3198
+ * @param ids - Document IDs to check
3199
+ * @param options - Request options
3200
+ */
3201
+ documentsExists(
3202
+ ids: string[],
3203
+ options?: {
3204
+ signal?: AbortSignal
3205
+ tag?: string
3206
+ },
3207
+ ): Observable<Set<string>>
3194
3208
  /**
3195
3209
  * Create a document. Requires a `_type` property. If no `_id` is provided, it will be generated by the database.
3196
3210
  * Returns an observable that resolves to the created document.
@@ -5102,6 +5116,20 @@ export declare class SanityClient {
5102
5116
  tag?: string
5103
5117
  },
5104
5118
  ): Promise<(SanityDocument<R> | null)[]>
5119
+ /**
5120
+ * Convenient and bandwidth efficient method of checking wether a set of document IDs exists.
5121
+ * Returns a set of the IDs that exist.
5122
+ *
5123
+ * @param ids - Document IDs to check
5124
+ * @param options - Request options
5125
+ */
5126
+ documentsExists(
5127
+ ids: string[],
5128
+ options?: {
5129
+ signal?: AbortSignal
5130
+ tag?: string
5131
+ },
5132
+ ): Promise<Set<string>>
5105
5133
  /**
5106
5134
  * Create a document. Requires a `_type` property. If no `_id` is provided, it will be generated by the database.
5107
5135
  * Returns a promise that resolves to the created document.
package/dist/index.d.ts CHANGED
@@ -1039,9 +1039,9 @@ export declare interface ContentSourceMapValueMapping {
1039
1039
 
1040
1040
  /** @public */
1041
1041
  export declare class CorsOriginError extends Error {
1042
- projectId: string
1042
+ projectId?: string
1043
1043
  addOriginUrl?: URL
1044
- constructor({projectId}: {projectId: string})
1044
+ constructor({projectId, credentials}?: {projectId?: string; credentials?: boolean})
1045
1045
  }
1046
1046
 
1047
1047
  /**
@@ -3191,6 +3191,20 @@ export declare class ObservableSanityClient {
3191
3191
  tag?: string
3192
3192
  },
3193
3193
  ): Observable<(SanityDocument<R> | null)[]>
3194
+ /**
3195
+ * Convenient and bandwidth efficient method of checking wether a set of document IDs exists.
3196
+ * Returns a set of the IDs that exist.
3197
+ *
3198
+ * @param ids - Document IDs to check
3199
+ * @param options - Request options
3200
+ */
3201
+ documentsExists(
3202
+ ids: string[],
3203
+ options?: {
3204
+ signal?: AbortSignal
3205
+ tag?: string
3206
+ },
3207
+ ): Observable<Set<string>>
3194
3208
  /**
3195
3209
  * Create a document. Requires a `_type` property. If no `_id` is provided, it will be generated by the database.
3196
3210
  * Returns an observable that resolves to the created document.
@@ -5102,6 +5116,20 @@ export declare class SanityClient {
5102
5116
  tag?: string
5103
5117
  },
5104
5118
  ): Promise<(SanityDocument<R> | null)[]>
5119
+ /**
5120
+ * Convenient and bandwidth efficient method of checking wether a set of document IDs exists.
5121
+ * Returns a set of the IDs that exist.
5122
+ *
5123
+ * @param ids - Document IDs to check
5124
+ * @param options - Request options
5125
+ */
5126
+ documentsExists(
5127
+ ids: string[],
5128
+ options?: {
5129
+ signal?: AbortSignal
5130
+ tag?: string
5131
+ },
5132
+ ): Promise<Set<string>>
5105
5133
  /**
5106
5134
  * Create a document. Requires a `_type` property. If no `_id` is provided, it will be generated by the database.
5107
5135
  * Returns a promise that resolves to the created document.
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { retry, jsonRequest, jsonResponse, progress, observable, debug, headers,
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 } from "./_chunks-es/isRecord.js";
6
6
  import { stegaClean } from "./_chunks-es/stegaClean.js";
7
- import { combineLatestWith, map, filter, finalize as finalize$1 } from "rxjs/operators";
7
+ import { combineLatestWith, map, filter, concatMap, reduce, finalize as finalize$1 } from "rxjs/operators";
8
8
  import { getVersionFromId, isDraftId, getVersionId, getDraftId, isVersionId, getPublishedId } from "@sanity/client/csm";
9
9
  import { customAlphabet } from "nanoid";
10
10
  import { validateObject, validateInsert, requireDocumentId, validateDocumentId, requireDocumentType, printCreateVersionWithBaseIdWarning, resourceConfig, hasDataset, requestTag, printPreviewDraftsDeprecationWarning, validateApiPerspective, printCdnPreviewDraftsWarning, validateAssetType, resourceGuard, dataset, validateVersionIdMatch, defaultConfig, initConfig, printNoDefaultExport } from "./_chunks-es/config.js";
@@ -176,14 +176,11 @@ function sliceWithEllipsis(str, max) {
176
176
  class CorsOriginError extends Error {
177
177
  projectId;
178
178
  addOriginUrl;
179
- constructor({ projectId }) {
180
- super("CorsOriginError"), this.name = "CorsOriginError", this.projectId = projectId;
181
- const url = new URL(`https://sanity.io/manage/project/${projectId}/api`);
182
- if (typeof location < "u") {
183
- const { origin } = location;
184
- 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}`;
185
- } else
186
- this.message = `The current origin is not allowed to connect to the Live Content API. Change your configuration here: ${url}`;
179
+ constructor({ projectId, credentials } = {}) {
180
+ if (super("CorsOriginError"), this.name = "CorsOriginError", this.projectId = projectId, projectId && typeof location < "u") {
181
+ const url = new URL(`https://sanity.io/manage/project/${projectId}/api`), { origin } = location;
182
+ 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}`;
183
+ } else projectId ? this.message = `The current origin is not allowed to connect to the Live Content API. Change your configuration here: https://sanity.io/manage/project/${projectId}/api` : this.message = "The current origin is not allowed to connect to the Live Content API.";
187
184
  }
188
185
  }
189
186
  const httpError = {
@@ -786,6 +783,35 @@ function _getDocuments(client, httpRequest, ids, opts = {}) {
786
783
  })
787
784
  );
788
785
  }
786
+ const DOCUMENTS_EXISTS_BATCH_SIZE = 100;
787
+ function _documentsExists(client, httpRequest, ids, opts = {}) {
788
+ if (ids.length === 0)
789
+ return of(/* @__PURE__ */ new Set());
790
+ const batches = [];
791
+ for (let i = 0; i < ids.length; i += DOCUMENTS_EXISTS_BATCH_SIZE)
792
+ batches.push(ids.slice(i, i + DOCUMENTS_EXISTS_BATCH_SIZE));
793
+ const fetchBatch = (batchIds) => _requestObservable(client, httpRequest, {
794
+ uri: _getDataUrl(client, "doc", batchIds.map(encodeURIComponent).join(",")),
795
+ tag: opts.tag,
796
+ signal: opts.signal,
797
+ query: { excludeContent: !0 }
798
+ }).pipe(
799
+ filter(isResponse),
800
+ map((event) => {
801
+ const missing = /* @__PURE__ */ new Set();
802
+ for (const omitted of event.body.omitted || [])
803
+ omitted.reason === "existence" && missing.add(omitted.id);
804
+ return new Set(batchIds.filter((id) => !missing.has(id)));
805
+ })
806
+ );
807
+ return from(batches).pipe(
808
+ concatMap(fetchBatch),
809
+ reduce((acc, set) => {
810
+ for (const id of set) acc.add(id);
811
+ return acc;
812
+ }, /* @__PURE__ */ new Set())
813
+ );
814
+ }
789
815
  function _getReleaseDocuments(client, httpRequest, releaseId, opts = {}) {
790
816
  return _dataRequest(
791
817
  client,
@@ -922,7 +948,7 @@ const hasDataConfig = (client) => {
922
948
  return config.dataset !== void 0 && config.projectId !== void 0 || config.resource !== void 0;
923
949
  }, 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);
924
950
  function _requestObservable(client, httpRequest, options) {
925
- 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;
951
+ 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;
926
952
  let useCdn = (options.useCdn ?? config.useCdn) && canUseCdn;
927
953
  const tag = options.tag && config.requestTagPrefix ? [config.requestTagPrefix, options.tag].join(".") : options.tag || config.requestTagPrefix;
928
954
  if (tag && options.tag !== null && (options.query = { tag: requestTag(tag), ...options.query }), ["GET", "HEAD", "POST"].indexOf(options.method || "GET") >= 0 && isQuery(client, uri)) {
@@ -938,7 +964,8 @@ function _requestObservable(client, httpRequest, options) {
938
964
  const reqOptions = requestOptions(
939
965
  config,
940
966
  Object.assign({}, options, {
941
- url: _getUrl(client, uri, useCdn)
967
+ url: _getUrl(client, uri, useCdn),
968
+ callSiteStack
942
969
  })
943
970
  ), request = new Observable(
944
971
  (subscriber) => httpRequest(reqOptions, config.requester).subscribe(subscriber)
@@ -1316,19 +1343,14 @@ class LiveClient {
1316
1343
  "welcome",
1317
1344
  "reconnect",
1318
1345
  "goaway"
1319
- ]), checkCors = fetchObservable(url, {
1320
- method: "OPTIONS",
1321
- mode: "cors",
1322
- credentials: esOptions.withCredentials ? "include" : "omit",
1323
- headers: esOptions.headers
1324
- }).pipe(
1325
- catchError(() => {
1326
- throw new CorsOriginError({ projectId });
1327
- })
1346
+ ]), checkCors = checkCorsObservable(
1347
+ new URL(this.#client.getUrl("/check/cors", !1)),
1348
+ projectId,
1349
+ esOptions.withCredentials === !0
1328
1350
  ), observable2 = events.pipe(
1329
1351
  reconnectOnConnectionFailure(),
1330
1352
  mergeMap((event) => event.type === "reconnect" ? checkCors.pipe(mergeMap(() => of(event))) : of(event)),
1331
- catchError((err) => checkCors.pipe(
1353
+ catchError((err) => err instanceof CorsOriginError ? throwError(() => err) : checkCors.pipe(
1332
1354
  mergeMap(() => {
1333
1355
  throw err;
1334
1356
  })
@@ -1349,17 +1371,27 @@ class LiveClient {
1349
1371
  return eventsCache.set(key, observable2), observable2;
1350
1372
  }
1351
1373
  }
1352
- function fetchObservable(url, init) {
1374
+ function checkCorsObservable(url, projectId, requireCredentials) {
1353
1375
  return new Observable((observer) => {
1354
- const controller = new AbortController(), signal = controller.signal;
1355
- return fetch(url, { ...init, signal: controller.signal }).then(
1356
- (response) => {
1357
- observer.next(response), observer.complete();
1358
- },
1359
- (err) => {
1360
- signal.aborted || observer.error(err);
1376
+ const controller = new AbortController(), { signal } = controller;
1377
+ return fetch(url, { method: "GET", mode: "cors", credentials: "omit", signal }).then((response) => {
1378
+ if (!(signal.aborted || !response.ok))
1379
+ return response.json();
1380
+ }).then((body) => {
1381
+ if (!signal.aborted) {
1382
+ if (requireCredentials && body?.result?.withCredentials === !1) {
1383
+ observer.error(new CorsOriginError({ projectId, credentials: !0 }));
1384
+ return;
1385
+ }
1386
+ if (body?.result?.allowed === !1) {
1387
+ observer.error(new CorsOriginError({ projectId, credentials: requireCredentials }));
1388
+ return;
1389
+ }
1390
+ observer.next(), observer.complete();
1361
1391
  }
1362
- ), () => controller.abort();
1392
+ }).catch(() => {
1393
+ signal.aborted || observer.closed || (observer.next(), observer.complete());
1394
+ }), () => controller.abort();
1363
1395
  });
1364
1396
  }
1365
1397
  const eventsCache = /* @__PURE__ */ new Map();
@@ -2287,6 +2319,16 @@ class ObservableSanityClient {
2287
2319
  getDocuments(ids, options) {
2288
2320
  return _getDocuments(this, this.#httpRequest, ids, options);
2289
2321
  }
2322
+ /**
2323
+ * Convenient and bandwidth efficient method of checking wether a set of document IDs exists.
2324
+ * Returns a set of the IDs that exist.
2325
+ *
2326
+ * @param ids - Document IDs to check
2327
+ * @param options - Request options
2328
+ */
2329
+ documentsExists(ids, options) {
2330
+ return _documentsExists(this, this.#httpRequest, ids, options);
2331
+ }
2290
2332
  create(document, options) {
2291
2333
  return _create(this, this.#httpRequest, document, "create", options);
2292
2334
  }
@@ -2564,6 +2606,16 @@ class SanityClient {
2564
2606
  getDocuments(ids, options) {
2565
2607
  return lastValueFrom(_getDocuments(this, this.#httpRequest, ids, options));
2566
2608
  }
2609
+ /**
2610
+ * Convenient and bandwidth efficient method of checking wether a set of document IDs exists.
2611
+ * Returns a set of the IDs that exist.
2612
+ *
2613
+ * @param ids - Document IDs to check
2614
+ * @param options - Request options
2615
+ */
2616
+ documentsExists(ids, options) {
2617
+ return lastValueFrom(_documentsExists(this, this.#httpRequest, ids, options));
2618
+ }
2567
2619
  create(document, options) {
2568
2620
  return lastValueFrom(
2569
2621
  _create(this, this.#httpRequest, document, "create", options)
@@ -2786,7 +2838,7 @@ function defineDeprecatedCreateClient(createClient2) {
2786
2838
  return printNoDefaultExport(), createClient2(config);
2787
2839
  };
2788
2840
  }
2789
- var name = "@sanity/client", version = "7.22.0";
2841
+ var name = "@sanity/client", version = "7.23.0";
2790
2842
  const middleware = [
2791
2843
  debug({ verbose: !0, namespace: "sanity:client" }),
2792
2844
  headers({ "User-Agent": `${name} ${version}` }),