@sanity/client 8.0.0 → 8.1.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.
Files changed (54) hide show
  1. package/README.md +94 -0
  2. package/dist/{browserUpload-CQgx9YYo.js → browserUpload-2tz6Sdqp.js} +4 -3
  3. package/dist/browserUpload-2tz6Sdqp.js.map +1 -0
  4. package/dist/{browserUpload-icWlVP15.js → browserUpload-CwpNx7Vl.js} +4 -3
  5. package/dist/browserUpload-CwpNx7Vl.js.map +1 -0
  6. package/dist/{config-a8VajuEY.js → config-3wiPP-sZ.js} +2 -2
  7. package/dist/config-3wiPP-sZ.js.map +1 -0
  8. package/dist/csm.js +2 -2
  9. package/dist/csm.js.map +1 -1
  10. package/dist/index.d.ts +17 -11
  11. package/dist/index.js +247 -120
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.node.d.ts +270 -26
  14. package/dist/index.node.js +183 -50
  15. package/dist/index.node.js.map +1 -1
  16. package/dist/media-library.d.ts +1 -1
  17. package/dist/{request-CJxcN16k.js → request-BhMuKj0D.js} +10 -9
  18. package/dist/request-BhMuKj0D.js.map +1 -0
  19. package/dist/{request-k7VS_NnC.js → request-SnMg7nUX.js} +10 -9
  20. package/dist/request-SnMg7nUX.js.map +1 -0
  21. package/dist/{resolveEditInfo-sq7yF78q.js → resolveEditInfo-Cz-smq3a.js} +17 -3
  22. package/dist/resolveEditInfo-Cz-smq3a.js.map +1 -0
  23. package/dist/stega.js +1 -1
  24. package/dist/{stegaEncodeSourceMap-DkoIlutY.js → stegaEncodeSourceMap-DbM2fTN4.js} +8 -2
  25. package/dist/stegaEncodeSourceMap-DbM2fTN4.js.map +1 -0
  26. package/dist/{stegaEncodeSourceMap-B2fGArSf.js → stegaEncodeSourceMap-YR3NQ3iz.js} +2 -2
  27. package/dist/{stegaEncodeSourceMap-B2fGArSf.js.map → stegaEncodeSourceMap-YR3NQ3iz.js.map} +1 -1
  28. package/dist/{types-CUxZSgB2.d.ts → types-BODIEY7F.d.ts} +262 -24
  29. package/package.json +26 -11
  30. package/src/SanityClient.ts +19 -20
  31. package/src/assets/AssetsClient.ts +54 -5
  32. package/src/csm/applySourceDocuments.ts +2 -4
  33. package/src/csm/draftUtils.ts +23 -4
  34. package/src/data/dataMethods.ts +2 -19
  35. package/src/data/eventsource.ts +71 -41
  36. package/src/data/live.ts +17 -9
  37. package/src/data/resolveEventSourceFetch.ts +9 -1
  38. package/src/defineCreateClient.ts +5 -1
  39. package/src/functions/FunctionsClient.ts +66 -0
  40. package/src/functions/invoke.ts +176 -0
  41. package/src/http/browserUpload.ts +1 -0
  42. package/src/http/errors.ts +2 -1
  43. package/src/http/request.ts +8 -14
  44. package/src/mediaLibrary/MediaLibraryVideoClient.ts +1 -1
  45. package/src/types.ts +186 -4
  46. package/src/validators.ts +1 -1
  47. package/src/warnings.ts +7 -1
  48. package/dist/browserUpload-CQgx9YYo.js.map +0 -1
  49. package/dist/browserUpload-icWlVP15.js.map +0 -1
  50. package/dist/config-a8VajuEY.js.map +0 -1
  51. package/dist/request-CJxcN16k.js.map +0 -1
  52. package/dist/request-k7VS_NnC.js.map +0 -1
  53. package/dist/resolveEditInfo-sq7yF78q.js.map +0 -1
  54. package/dist/stegaEncodeSourceMap-DkoIlutY.js.map +0 -1
@@ -1,5 +1,7 @@
1
1
  import { t as require_dist } from "./dist-C9ExSk2R.js";
2
- import { a as ServerError, c as isHttpError, i as CorsOriginError, l as isQueryParseError, o as formatQueryParseError, r as ClientError, t as defineRequester } from "./request-k7VS_NnC.js";
2
+ import { a as ServerError, c as isHttpError, i as CorsOriginError, l as isQueryParseError, o as formatQueryParseError, r as ClientError, t as defineRequester } from "./request-SnMg7nUX.js";
3
+ import { t as isRecord } from "./isRecord-Kfmt-nk-.js";
4
+ import { isTimeoutError } from "get-it";
3
5
  import { debug } from "get-it/middleware";
4
6
  import { Observable, catchError, concat, defer, finalize, isObservable, lastValueFrom, map, merge, mergeMap, of, share, tap, throwError, timer } from "rxjs";
5
7
  import { getDraftId, getPublishedId, getVersionFromId, getVersionId, isDraftId, isVersionId } from "@sanity/client/csm";
@@ -80,7 +82,7 @@ const createWarningPrinter = (message) => once((...args) => console.warn(message
80
82
  "Since you haven't set a value for `useCdn`, we will deliver content using our",
81
83
  "global, edge-cached API-CDN. If you wish to have content delivered faster, set",
82
84
  "`useCdn: false` to use the Live API. Note: You may incur higher costs using the live API."
83
- ]), printCdnPreviewDraftsWarning = createWarningPrinter(["The Sanity client is configured with the `perspective` set to `drafts` or `previewDrafts`, which doesn't support the API-CDN.", "The Live API will be used instead. Set `useCdn: false` in your configuration to hide this warning."]), printPreviewDraftsDeprecationWarning = createWarningPrinter(["The `previewDrafts` perspective has been renamed to `drafts` and will be removed in a future API version"]), printBrowserTokenWarning = createWarningPrinter(["You have configured Sanity client to use a token in the browser. This may cause unintentional security issues.", `See ${generateHelpUrl("js-client-browser-token")} for more information and how to hide this warning.`]), printCredentialedTokenWarning = createWarningPrinter(["You have configured Sanity client to use a token, but also provided `withCredentials: true`.", "This is no longer supported - only token will be used - remove `withCredentials: true`."]), printNoApiVersionSpecifiedWarning = createWarningPrinter(["Using the Sanity client without specifying an API version is deprecated.", `See ${generateHelpUrl("js-client-api-version")}`]), printNoDefaultExport = createWarningPrinter(["The default export of @sanity/client has been deprecated. Use the named export `createClient` instead."]), printCreateVersionWithBaseIdWarning = createWarningPrinter(["You have called `createVersion()` with a defined `document`. The recommended approach is to provide a `baseId` and `releaseId` instead."]), printDeprecatedUriOptionWarning = createWarningPrinter(["The `uri` request option has been renamed to `url`.", "Please update your code to use `url` instead. Support for `uri` will be removed in a future version."]), printDeprecatedResourceConfigWarning = createWarningPrinter(["The `~experimental_resource` configuration property has been renamed to `resource`.", "Please update your client configuration to use `resource` instead. Support for `~experimental_resource` will be removed in a future version."]), defaultConfig = {
85
+ ]), printCdnPreviewDraftsWarning = createWarningPrinter(["The Sanity client is configured with the `perspective` set to `drafts` or `previewDrafts`, which doesn't support the API-CDN.", "The Live API will be used instead. Set `useCdn: false` in your configuration to hide this warning."]), printPreviewDraftsDeprecationWarning = createWarningPrinter(["The `previewDrafts` perspective has been renamed to `drafts` and will be removed in a future API version"]), printBrowserTokenWarning = createWarningPrinter(["You have configured Sanity client to use a token in the browser. This may cause unintentional security issues.", `See ${generateHelpUrl("js-client-browser-token")} for more information and how to hide this warning.`]), printCredentialedTokenWarning = createWarningPrinter(["You have configured Sanity client to use a token, but also provided `withCredentials: true`.", "This is no longer supported - only token will be used - remove `withCredentials: true`."]), printNoApiVersionSpecifiedWarning = createWarningPrinter(["Using the Sanity client without specifying an API version is deprecated.", `See ${generateHelpUrl("js-client-api-version")}`]), printNoDefaultExport = createWarningPrinter(["The default export of @sanity/client has been deprecated. Use the named export `createClient` instead."]), printCreateVersionWithBaseIdWarning = createWarningPrinter(["You have called `createVersion()` with a defined `document`.", "If you are creating a version of a document that already exists, prefer providing `baseId` and `releaseId` instead."]), printDeprecatedUriOptionWarning = createWarningPrinter(["The `uri` request option has been renamed to `url`.", "Please update your code to use `url` instead. Support for `uri` will be removed in a future version."]), printDeprecatedResourceConfigWarning = createWarningPrinter(["The `~experimental_resource` configuration property has been renamed to `resource`.", "Please update your client configuration to use `resource` instead. Support for `~experimental_resource` will be removed in a future version."]), defaultConfig = {
84
86
  apiHost: "https://api.sanity.io",
85
87
  apiVersion: "1",
86
88
  useProjectHostname: !0,
@@ -133,11 +135,12 @@ const initConfig = (config, prevConfig) => {
133
135
  return projectBased ? (newConfig.url = `${protocol}://${newConfig.projectId}.${host}/v${newConfig.apiVersion}`, newConfig.cdnUrl = `${protocol}://${newConfig.projectId}.${cdnHost}/v${newConfig.apiVersion}`) : (newConfig.url = `${newConfig.apiHost}/v${newConfig.apiVersion}`, newConfig.cdnUrl = newConfig.url), newConfig;
134
136
  };
135
137
  /**
136
- * @public
137
138
  * Thrown when the EventSource connection could not be established, or was rejected by the server.
138
139
  * Transient failures (network drops, 5xx, 408, 429) are reconnected internally and emitted as
139
140
  * `reconnect` events; a permanent rejection (any other 4xx, eg an expired token) errors the
140
141
  * stream with this class so consumers can react — check `status` for the rejection code.
142
+ *
143
+ * @public
141
144
  */
142
145
  var ConnectionFailedError = class extends Error {
143
146
  name = "ConnectionFailedError";
@@ -208,26 +211,30 @@ function connectEventSource(initEventSource, events) {
208
211
  */
209
212
  function connectWithESInstance(es, events) {
210
213
  return new Observable((observer) => {
211
- let emitOpen = events.includes("open"), emitReconnect = events.includes("reconnect");
214
+ let requestedEvents = new Set(events), isRequestedEvent = (type) => requestedEvents.has(type), emitOpen = isRequestedEvent("open");
212
215
  function onError(evt) {
213
216
  if ("data" in evt) {
214
217
  let [parseError, event] = parseEvent(evt);
215
- observer.error(parseError ? new MessageParseError("Unable to parse EventSource error message", { cause: parseError }) : new MessageError(event.data.message, event));
218
+ observer.error(parseError || !event ? new MessageParseError("Unable to parse EventSource error message", { cause: parseError }) : new MessageError(isRecord(event.data) && typeof event.data.message == "string" ? event.data.message : "", event));
216
219
  return;
217
220
  }
218
- let rawStatus = evt.code, status = typeof rawStatus == "number" ? rawStatus : void 0;
219
- if (status !== void 0) {
220
- observer.error(new ConnectionFailedError("EventSource connection failed", { status }));
221
+ if (evt.code !== void 0) {
222
+ observer.error(new ConnectionFailedError("EventSource connection failed", { status: evt.code }));
221
223
  return;
222
224
  }
223
- es.readyState === es.CLOSED ? observer.error(new ConnectionFailedError("EventSource connection failed")) : emitReconnect && observer.next({ type: "reconnect" });
225
+ if (es.readyState === es.CLOSED) observer.error(new ConnectionFailedError("EventSource connection failed"));
226
+ else {
227
+ let type = "reconnect";
228
+ isRequestedEvent(type) && observer.next({ type });
229
+ }
224
230
  }
225
231
  function onOpen() {
226
- observer.next({ type: "open" });
232
+ let type = "open";
233
+ isRequestedEvent(type) && observer.next({ type });
227
234
  }
228
235
  function onMessage(message) {
229
236
  let [parseError, event] = parseEvent(message);
230
- if (parseError) {
237
+ if (parseError || !event) {
231
238
  observer.error(new MessageParseError("Unable to parse EventSource message", { cause: parseError }));
232
239
  return;
233
240
  }
@@ -237,10 +244,10 @@ function connectWithESInstance(es, events) {
237
244
  return;
238
245
  }
239
246
  if (message.type === "disconnect") {
240
- observer.error(new DisconnectError(`Server disconnected client: ${event.data?.reason || "unknown error"}`));
247
+ observer.error(new DisconnectError(`Server disconnected client: ${isRecord(event.data) && typeof event.data.reason == "string" && event.data.reason || "unknown error"}`));
241
248
  return;
242
249
  }
243
- observer.next({
250
+ isRequestedEvent(message.type) && observer.next({
244
251
  type: message.type,
245
252
  id: message.lastEventId,
246
253
  ...event.data ? { data: event.data } : {}
@@ -266,8 +273,16 @@ function parseEvent(message) {
266
273
  }
267
274
  }
268
275
  function extractErrorMessage(err, tag) {
269
- let error = err.error;
270
- return error ? isQueryParseError(error) ? formatQueryParseError(error, tag) : error.description ? error.description : typeof error == "string" ? error : JSON.stringify(error, null, 2) : err.message || "Unknown listener error";
276
+ let error = isRecord(err) ? err.error : void 0;
277
+ if (!error) {
278
+ let message = isRecord(err) ? err.message : void 0;
279
+ return typeof message == "string" && message || "Unknown listener error";
280
+ }
281
+ if (isRecord(error)) {
282
+ if (isQueryParseError(error)) return formatQueryParseError(error, tag);
283
+ if (typeof error.description == "string") return error.description;
284
+ }
285
+ return typeof error == "string" ? error : JSON.stringify(error, null, 2);
271
286
  }
272
287
  function isEmptyObject(data) {
273
288
  for (let _ in data) return !1;
@@ -726,7 +741,7 @@ function _fetch(client, httpRequest, _stega, query, _params = {}, options = {})
726
741
  query,
727
742
  params
728
743
  }, reqOpts);
729
- return stega.enabled ? Promise.all([request, import("./stegaEncodeSourceMap-DkoIlutY.js")]).then(([res, { stegaEncodeSourceMap }]) => {
744
+ return stega.enabled ? Promise.all([request, import("./stegaEncodeSourceMap-DbM2fTN4.js")]).then(([res, { stegaEncodeSourceMap }]) => {
730
745
  let result = stegaEncodeSourceMap(res.result, res.resultSourceMap, stega);
731
746
  return mapResponse({
732
747
  ...res,
@@ -969,8 +984,6 @@ function _mapDataResponse(res, isMutation, returnFirst, returnDocuments) {
969
984
  };
970
985
  }
971
986
  /**
972
- * Promise-based sibling of {@link _dataRequestObservable}.
973
- *
974
987
  * @internal
975
988
  */
976
989
  function _dataRequest(client, httpRequest, endpoint, body, options = {}) {
@@ -1195,7 +1208,7 @@ function _observe(userSignal, run) {
1195
1208
  * @internal
1196
1209
  */
1197
1210
  function _request(client, httpRequest, options) {
1198
- return httpRequest(_prepareRequest(client, options)).then((body) => body);
1211
+ return httpRequest(_prepareRequest(client, options), client.config().requestHandler).then((body) => body);
1199
1212
  }
1200
1213
  /**
1201
1214
  * Execute an HTTP request through the regular pipeline and resolve to the
@@ -1436,9 +1449,22 @@ var ObservableAgentsActionClient = class {
1436
1449
  }
1437
1450
  upload(assetType, body, options) {
1438
1451
  let observable = _upload(this.#client, this.#httpRequest, assetType, body, options);
1439
- return lastValueFrom(observable.pipe(filter((event) => event.type === "response"), map$1((event) => event.body.document)));
1452
+ return lastValueFrom(observable.pipe(filter((event) => event.type === "response"), map$1((event) => pluckUploadedAsset(event.body))));
1440
1453
  }
1441
1454
  };
1455
+ /**
1456
+ * Content Lake's upload endpoint responds with `{document: ...}`; the Media
1457
+ * Library upload endpoint responds with `{asset: ...}` instead (a
1458
+ * `sanity.asset` document, not a Content Lake asset document). Narrowing on
1459
+ * the response body itself - rather than on the client's `resource` config -
1460
+ * keeps this correct regardless of how the two are ever wired together.
1461
+ */
1462
+ function isMediaLibraryUploadBody(body) {
1463
+ return "asset" in body;
1464
+ }
1465
+ function pluckUploadedAsset(body) {
1466
+ return isMediaLibraryUploadBody(body) ? body.asset : body.document;
1467
+ }
1442
1468
  function _upload(client, _httpRequest, assetType, body, opts = {}) {
1443
1469
  validateAssetType(assetType);
1444
1470
  let meta = opts.extract || void 0;
@@ -1465,7 +1491,7 @@ function _upload(client, _httpRequest, assetType, body, opts = {}) {
1465
1491
  body
1466
1492
  };
1467
1493
  return typeof XMLHttpRequest < "u" ? defer(async () => {
1468
- let { uploadWithProgress } = await import("./browserUpload-icWlVP15.js"), req = _prepareRequest(client, { ...baseRequest });
1494
+ let { uploadWithProgress } = await import("./browserUpload-2tz6Sdqp.js"), req = _prepareRequest(client, { ...baseRequest });
1469
1495
  return uploadWithProgress({
1470
1496
  url: appendQuery(req.url, req.query),
1471
1497
  method: req.method ?? "POST",
@@ -1552,6 +1578,14 @@ function resolveEventSourceFetch(config, options = {}) {
1552
1578
  return credentials !== void 0 && (mergedInit.credentials = credentials), baseFetch(typeof url == "string" ? url : url.href, mergedInit);
1553
1579
  };
1554
1580
  }
1581
+ /**
1582
+ * The fetch the client's own transport resolves for this config: the
1583
+ * configured `resolveFetch` (honouring an explicit `proxy`) if present,
1584
+ * otherwise the global fetch. Shared by the EventSource connection and the
1585
+ * `/check/cors` probe so both resolve identically.
1586
+ *
1587
+ * @internal
1588
+ */
1555
1589
  function pickBaseFetch(config) {
1556
1590
  return config.resolveFetch ? config.resolveFetch(typeof config.proxy == "string" ? config.proxy : void 0) : globalThis.fetch.bind(globalThis);
1557
1591
  }
@@ -1651,7 +1685,7 @@ var LiveClient = class {
1651
1685
  "welcome",
1652
1686
  "reconnect",
1653
1687
  "goaway"
1654
- ]), checkCors = checkCorsObservable(new URL(this.#client.getUrl("/check/cors", !1)), projectId, eventSourceWithCredentials), observable = events.pipe(reconnectOnConnectionFailure(), mergeMap((event) => event.type === "reconnect" ? checkCors.pipe(mergeMap(() => of(event))) : of(event)), catchError((err) => err instanceof CorsOriginError ? throwError(() => err) : checkCors.pipe(mergeMap(() => {
1688
+ ]), checkCors = checkCorsObservable(new URL(this.#client.getUrl("/check/cors", !1)), projectId, eventSourceWithCredentials, pickBaseFetch(config)), observable = events.pipe(reconnectOnConnectionFailure(), mergeMap((event) => event.type === "reconnect" ? checkCors.pipe(mergeMap(() => of(event))) : of(event)), catchError((err) => err instanceof CorsOriginError ? throwError(() => err) : checkCors.pipe(mergeMap(() => {
1655
1689
  throw err;
1656
1690
  }))), map$1((event) => {
1657
1691
  if (event.type === "message") {
@@ -1704,34 +1738,33 @@ var LiveClient = class {
1704
1738
  * In all of those cases the caller's original underlying error from the
1705
1739
  * EventSource is allowed to propagate unchanged.
1706
1740
  */
1707
- function checkCorsObservable(url, projectId, requireCredentials) {
1741
+ function checkCorsObservable(url, projectId, requireCredentials, fetcher) {
1708
1742
  return new Observable((observer) => {
1709
1743
  let controller = new AbortController(), { signal } = controller;
1710
- return fetch(url, {
1744
+ return fetcher(url.href, {
1711
1745
  method: "GET",
1712
- mode: "cors",
1713
1746
  credentials: "omit",
1714
1747
  signal
1715
1748
  }).then((response) => {
1716
- if (!(signal.aborted || !response.ok)) return response.json();
1717
- }).then((body) => {
1718
- if (!signal.aborted) {
1719
- if (requireCredentials && body?.result?.withCredentials === !1) {
1720
- observer.error(new CorsOriginError({
1721
- projectId,
1722
- credentials: !0
1723
- }));
1724
- return;
1725
- }
1726
- if (body?.result?.allowed === !1) {
1727
- observer.error(new CorsOriginError({
1728
- projectId,
1729
- credentials: requireCredentials
1730
- }));
1731
- return;
1732
- }
1733
- observer.next(), observer.complete();
1749
+ if (!(signal.aborted || !response.ok)) return response.text();
1750
+ }).then((text) => {
1751
+ if (signal.aborted) return;
1752
+ let parsed = text === void 0 ? void 0 : JSON.parse(text), result = isRecord(parsed) ? parsed.result : void 0;
1753
+ if (requireCredentials && isRecord(result) && result.withCredentials === !1) {
1754
+ observer.error(new CorsOriginError({
1755
+ projectId,
1756
+ credentials: !0
1757
+ }));
1758
+ return;
1759
+ }
1760
+ if (isRecord(result) && result.allowed === !1) {
1761
+ observer.error(new CorsOriginError({
1762
+ projectId,
1763
+ credentials: requireCredentials
1764
+ }));
1765
+ return;
1734
1766
  }
1767
+ observer.next(), observer.complete();
1735
1768
  }).catch(() => {
1736
1769
  signal.aborted || observer.closed || (observer.next(), observer.complete());
1737
1770
  }), () => controller.abort();
@@ -1901,8 +1934,106 @@ function _modify(client, httpRequest, method, name, options) {
1901
1934
  tag: null
1902
1935
  });
1903
1936
  }
1937
+ /** Function resource types in a blueprint are namespaced under this prefix. */
1938
+ const scopeHeaders = (config, request) => {
1939
+ let organizationId = request?.organizationId || config.organizationId;
1940
+ if (organizationId) return {
1941
+ "X-Sanity-Scope-Type": "organization",
1942
+ "X-Sanity-Scope-Id": organizationId
1943
+ };
1944
+ let { projectId } = config;
1945
+ if (!projectId) throw Error("`functions.invoke()` requires a `projectId` to be set in the client config, or an `organizationId` for a stack deployed at organization scope");
1946
+ return {
1947
+ "X-Sanity-Scope-Type": "project",
1948
+ "X-Sanity-Scope-Id": projectId
1949
+ };
1950
+ }, resolveStackId = (config, request) => {
1951
+ let stackId = request?.stackId || config.stackId;
1952
+ if (!stackId) throw Error("`functions.invoke()` requires a `stackId`, either in the client config or on the request. Function names are only unique within a stack.");
1953
+ return stackId;
1954
+ };
1955
+ /**
1956
+ * The invoke route is keyed by function id, but callers know functions by the
1957
+ * name declared in the blueprint. Names are unique within a stack, so the stack
1958
+ * both makes the name resolvable and confines the call to its own functions.
1959
+ *
1960
+ * @internal
1961
+ */
1962
+ function _resolveFunctionId(client, httpRequest, functionName, stackId, headers, request) {
1963
+ return _requestObservable(client, httpRequest, {
1964
+ method: "GET",
1965
+ url: `/blueprints/stacks/${stackId}`,
1966
+ headers,
1967
+ signal: request?.signal
1968
+ }).pipe(map((stack) => {
1969
+ let match = (stack?.resources || []).find((resource) => resource.type?.startsWith("sanity.function.") && resource.name === functionName);
1970
+ if (!match) throw Error(`Function "${functionName}" not found in stack "${stackId}"`);
1971
+ if (!match.externalId) throw Error(`Function "${functionName}" is declared in stack "${stackId}" but is not deployed`);
1972
+ if (match.type !== "sanity.function.pubsub") throw Error(`Function invocation is not supported for ${match.type}`);
1973
+ return match.externalId;
1974
+ }));
1975
+ }
1904
1976
  /** @internal */
1905
- var ObservableMediaLibraryVideoClient = class {
1977
+ function _invoke(client, httpRequest, functionName, request) {
1978
+ return defer(() => {
1979
+ let config = client.config(), headers = scopeHeaders(config, request);
1980
+ return _resolveFunctionId(client, httpRequest, functionName, resolveStackId(config, request), headers, request).pipe(mergeMap((functionId) => _requestObservable(client, httpRequest, {
1981
+ method: "POST",
1982
+ url: `/functions/${functionId}/invoke`,
1983
+ headers,
1984
+ body: { event: { data: request?.event?.data ?? {} } },
1985
+ timeout: request?.timeout,
1986
+ signal: request?.signal
1987
+ })));
1988
+ });
1989
+ }
1990
+ /** @public */
1991
+ var ObservableFunctionsClient = class {
1992
+ #client;
1993
+ #httpRequest;
1994
+ constructor(client, httpRequest) {
1995
+ this.#client = client, this.#httpRequest = httpRequest;
1996
+ }
1997
+ /**
1998
+ * Invoke a deployed function by its blueprint name.
1999
+ *
2000
+ * The name is resolved within the stack given by `stackId` on the request or
2001
+ * the client config. Passes the function's return value once it finishes.
2002
+ *
2003
+ * @param functionName - name of the function, as declared in the blueprint
2004
+ * @param request - payload and request options
2005
+ */
2006
+ invoke(functionName, request) {
2007
+ return _invoke(this.#client, this.#httpRequest, functionName, request);
2008
+ }
2009
+ }, FunctionsClient = class {
2010
+ #client;
2011
+ #httpRequest;
2012
+ constructor(client, httpRequest) {
2013
+ this.#client = client, this.#httpRequest = httpRequest;
2014
+ }
2015
+ /**
2016
+ * Invoke a deployed function by its blueprint name.
2017
+ *
2018
+ * The name is resolved within the stack given by `stackId` on the request or
2019
+ * the client config, which costs one extra request per call. Rejects if the
2020
+ * stack has no function by that name, or if the name resolves to anything
2021
+ * other than a `sanity.function.pubsub` function.
2022
+ *
2023
+ * The lookup is scoped to `projectId`, or to `organizationId` when one is set
2024
+ * for a stack deployed at organization scope.
2025
+ *
2026
+ * The request stays open until the function finishes, and resolves with its
2027
+ * return value, or `undefined` if it returns nothing. Long-running functions
2028
+ * may need an explicit `timeout`.
2029
+ *
2030
+ * @param functionName - name of the function, as declared in the blueprint
2031
+ * @param request - payload and request options
2032
+ */
2033
+ invoke(functionName, request) {
2034
+ return lastValueFrom(_invoke(this.#client, this.#httpRequest, functionName, request));
2035
+ }
2036
+ }, ObservableMediaLibraryVideoClient = class {
1906
2037
  #client;
1907
2038
  #httpRequest;
1908
2039
  constructor(client, httpRequest) {
@@ -2558,6 +2689,7 @@ var ObservableReleasesClient = class {
2558
2689
  projects;
2559
2690
  users;
2560
2691
  agent;
2692
+ functions;
2561
2693
  releases;
2562
2694
  /**
2563
2695
  * Private properties
@@ -2569,7 +2701,7 @@ var ObservableReleasesClient = class {
2569
2701
  */
2570
2702
  listen = _listen;
2571
2703
  constructor(httpRequest, config = defaultConfig) {
2572
- this.config(config), this.#httpRequest = httpRequest, this.assets = new ObservableAssetsClient(this, this.#httpRequest), this.datasets = new ObservableDatasetsClient(this, this.#httpRequest), this.live = new LiveClient(this), this.mediaLibrary = { video: new ObservableMediaLibraryVideoClient(this, this.#httpRequest) }, this.projects = new ObservableProjectsClient(this, this.#httpRequest), this.users = new ObservableUsersClient(this, this.#httpRequest), this.agent = { action: new ObservableAgentsActionClient(this, this.#httpRequest) }, this.releases = new ObservableReleasesClient(this, this.#httpRequest);
2704
+ this.config(config), this.#httpRequest = httpRequest, this.assets = new ObservableAssetsClient(this, this.#httpRequest), this.datasets = new ObservableDatasetsClient(this, this.#httpRequest), this.live = new LiveClient(this), this.mediaLibrary = { video: new ObservableMediaLibraryVideoClient(this, this.#httpRequest) }, this.projects = new ObservableProjectsClient(this, this.#httpRequest), this.users = new ObservableUsersClient(this, this.#httpRequest), this.agent = { action: new ObservableAgentsActionClient(this, this.#httpRequest) }, this.functions = new ObservableFunctionsClient(this, this.#httpRequest), this.releases = new ObservableReleasesClient(this, this.#httpRequest);
2573
2705
  }
2574
2706
  /**
2575
2707
  * Clone the client - returns a new instance
@@ -2792,6 +2924,7 @@ var ObservableReleasesClient = class {
2792
2924
  projects;
2793
2925
  users;
2794
2926
  agent;
2927
+ functions;
2795
2928
  releases;
2796
2929
  /**
2797
2930
  * Observable version of the Sanity client, with the same configuration as the promise-based one
@@ -2807,7 +2940,7 @@ var ObservableReleasesClient = class {
2807
2940
  */
2808
2941
  listen = _listen;
2809
2942
  constructor(httpRequest, config = defaultConfig) {
2810
- this.config(config), this.#httpRequest = httpRequest, this.assets = new AssetsClient(this, this.#httpRequest), this.datasets = new DatasetsClient(this, this.#httpRequest), this.live = new LiveClient(this), this.mediaLibrary = { video: new MediaLibraryVideoClient(this, this.#httpRequest) }, this.projects = new ProjectsClient(this, this.#httpRequest), this.users = new UsersClient(this, this.#httpRequest), this.agent = { action: new AgentActionsClient(this, this.#httpRequest) }, this.releases = new ReleasesClient(this, this.#httpRequest), this.observable = new ObservableSanityClient(httpRequest, config);
2943
+ this.config(config), this.#httpRequest = httpRequest, this.assets = new AssetsClient(this, this.#httpRequest), this.datasets = new DatasetsClient(this, this.#httpRequest), this.live = new LiveClient(this), this.mediaLibrary = { video: new MediaLibraryVideoClient(this, this.#httpRequest) }, this.projects = new ProjectsClient(this, this.#httpRequest), this.users = new UsersClient(this, this.#httpRequest), this.agent = { action: new AgentActionsClient(this, this.#httpRequest) }, this.functions = new FunctionsClient(this, this.#httpRequest), this.releases = new ReleasesClient(this, this.#httpRequest), this.observable = new ObservableSanityClient(httpRequest, config);
2811
2944
  }
2812
2945
  /**
2813
2946
  * Clone the client - returns a new instance
@@ -3049,10 +3182,10 @@ function defineCreateClientExports(envOptions, ClassConstructor) {
3049
3182
  ignoreWarnings: config.ignoreWarnings,
3050
3183
  maxRetries: config.maxRetries,
3051
3184
  retryDelay: config.retryDelay
3052
- }), httpRequest = async (options) => (await clientRequesterPromise({
3185
+ }), performRequest = async (options) => (await clientRequesterPromise({
3053
3186
  redirect: "manual",
3054
3187
  ...options
3055
- })).body;
3188
+ })).body, httpRequest = (options, requestHandler) => requestHandler ? requestHandler(options, performRequest) : performRequest(options);
3056
3189
  return new ClassConstructor(httpRequest, {
3057
3190
  ...config,
3058
3191
  requester: clientRequester,
@@ -3069,7 +3202,7 @@ function defineDeprecatedCreateClient(createClient) {
3069
3202
  return printNoDefaultExport(), createClient(config);
3070
3203
  };
3071
3204
  }
3072
- var name = "@sanity/client", version = "8.0.0";
3205
+ var name = "@sanity/client", version = "8.1.0";
3073
3206
  const log = createDebug("sanity:client");
3074
3207
  function isNodeReadableStream(value) {
3075
3208
  return typeof value != "object" || !value || !("pipe" in value) ? !1 : typeof value.pipe == "function";
@@ -3126,6 +3259,6 @@ const middleware = [
3126
3259
  middleware,
3127
3260
  resolveFetch
3128
3261
  }, SanityClient), requester = exp.requester, createClient = exp.createClient, deprecatedCreateClient = defineDeprecatedCreateClient(createClient);
3129
- export { BasePatch, BaseTransaction, ChannelError, ClientError, ConnectionFailedError, CorsOriginError, DisconnectError, EXPERIMENTAL_API_WARNING, MessageError, MessageParseError, ObservablePatch, ObservableSanityClient, ObservableTransaction, Patch, SanityClient, ServerError, Transaction, connectEventSource, createClient, deprecatedCreateClient as default, formatQueryParseError, isHttpError, isQueryParseError, requester, validateApiPerspective };
3262
+ export { BasePatch, BaseTransaction, ChannelError, ClientError, ConnectionFailedError, CorsOriginError, DisconnectError, EXPERIMENTAL_API_WARNING, MessageError, MessageParseError, ObservablePatch, ObservableSanityClient, ObservableTransaction, Patch, SanityClient, ServerError, Transaction, connectEventSource, createClient, deprecatedCreateClient as default, formatQueryParseError, isHttpError, isQueryParseError, isTimeoutError, requester, validateApiPerspective };
3130
3263
 
3131
3264
  //# sourceMappingURL=index.node.js.map