@sanity/client 8.2.0 → 8.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +2 -2
  2. package/dist/{browserUpload-2tz6Sdqp.js → browserUpload-C7PwCs-C.js} +6 -9
  3. package/dist/browserUpload-C7PwCs-C.js.map +1 -0
  4. package/dist/{browserUpload-CwpNx7Vl.js → browserUpload-D-2Rmfjo.js} +6 -9
  5. package/dist/browserUpload-D-2Rmfjo.js.map +1 -0
  6. package/dist/{config-3wiPP-sZ.js → config-CgJ16jET.js} +4 -2
  7. package/dist/config-CgJ16jET.js.map +1 -0
  8. package/dist/csm.js +1 -1
  9. package/dist/{dist-C9ExSk2R.js → dist-C5K_YcEU.js} +3 -2
  10. package/dist/{dist-C9ExSk2R.js.map → dist-C5K_YcEU.js.map} +1 -1
  11. package/dist/index.d.ts +2 -2
  12. package/dist/index.js +942 -115
  13. package/dist/index.js.map +1 -1
  14. package/dist/index.node.d.ts +3345 -16
  15. package/dist/index.node.js +865 -59
  16. package/dist/index.node.js.map +1 -1
  17. package/dist/media-library.d.ts +1 -1
  18. package/dist/rolldown-runtime-4YWMqDIC.js +9 -0
  19. package/dist/{stegaEncodeSourceMap-DbM2fTN4.js → stegaEncodeSourceMap-CO1HKnm2.js} +2 -2
  20. package/dist/{stegaEncodeSourceMap-DbM2fTN4.js.map → stegaEncodeSourceMap-CO1HKnm2.js.map} +1 -1
  21. package/dist/{types-nJhm5Nyq.d.ts → types-DiPF0ENT.d.ts} +3346 -17
  22. package/package.json +3 -3
  23. package/src/SanityClient.ts +7 -0
  24. package/src/assets/AssetsClient.ts +5 -0
  25. package/src/collaboration/types.ts +59 -8
  26. package/src/config.ts +1 -0
  27. package/src/context/ContextClient.ts +1006 -0
  28. package/src/context/openapi.json +5345 -0
  29. package/src/context/reads.ts +206 -0
  30. package/src/context/store.ts +100 -0
  31. package/src/context/types.gen.ts +2428 -0
  32. package/src/context/types.ts +228 -0
  33. package/src/data/dataMethods.ts +4 -1
  34. package/src/defineCreateClient.ts +1 -0
  35. package/src/functions/FunctionsClient.ts +52 -9
  36. package/src/functions/invoke.ts +47 -6
  37. package/src/http/browserUpload.ts +0 -12
  38. package/src/types.ts +29 -3
  39. package/src/util/createVersionId.ts +15 -5
  40. package/src/validators.ts +1 -0
  41. package/dist/browserUpload-2tz6Sdqp.js.map +0 -1
  42. package/dist/browserUpload-CwpNx7Vl.js.map +0 -1
  43. package/dist/config-3wiPP-sZ.js.map +0 -1
@@ -1,13 +1,13 @@
1
- import { t as require_dist } from "./dist-C9ExSk2R.js";
1
+ import { n as __exportAll } from "./rolldown-runtime-4YWMqDIC.js";
2
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
3
  import { t as isRecord } from "./isRecord-Kfmt-nk-.js";
4
+ import { t as require_dist } from "./dist-C5K_YcEU.js";
4
5
  import { isTimeoutError } from "get-it";
5
6
  import { debug } from "get-it/middleware";
6
7
  import { Observable, catchError, concat, defer, finalize, isObservable, lastValueFrom, map, merge, mergeMap, of, share, tap, throwError, timer } from "rxjs";
7
8
  import { getDraftId, getPublishedId, getVersionFromId, getVersionId, isDraftId, isVersionId } from "@sanity/client/csm";
8
9
  import { filter, finalize as finalize$1, map as map$1, mergeAll } from "rxjs/operators";
9
10
  import { EventSource } from "eventsource";
10
- import { customAlphabet } from "nanoid";
11
11
  import { Readable } from "node:stream";
12
12
  import { createNodeFetch } from "get-it/node";
13
13
  import { createDebug } from "obug";
@@ -67,6 +67,7 @@ const VALID_ASSET_TYPES = ["image", "file"], VALID_INSERT_LOCATIONS = [
67
67
  if (id.split(".").length !== 2) throw Error("Dataset resource ID must be in the format \"project.dataset\"");
68
68
  return;
69
69
  case "dashboard":
70
+ case "knowledge-base":
70
71
  case "media-library":
71
72
  case "canvas": return;
72
73
  default: throw Error(`Unsupported resource type: ${type.toString()}`);
@@ -115,7 +116,8 @@ const initConfig = (config, prevConfig) => {
115
116
  specifiedConfig.apiVersion || printNoApiVersionSpecifiedWarning();
116
117
  let newConfig = {
117
118
  ...defaultConfig,
118
- ...specifiedConfig
119
+ ...specifiedConfig,
120
+ apiHost: specifiedConfig.apiHost ?? defaultConfig.apiHost
119
121
  };
120
122
  newConfig["~experimental_resource"] && !newConfig.resource && (printDeprecatedResourceConfigWarning(), newConfig.resource = newConfig["~experimental_resource"]);
121
123
  let resourceConfig$1 = newConfig.resource, projectBased = newConfig.useProjectHostname && !resourceConfig$1;
@@ -612,7 +614,15 @@ var BaseTransaction = class {
612
614
  ...patchOps
613
615
  } });
614
616
  }
615
- };
617
+ }, types_exports = /* @__PURE__ */ __exportAll({ possibleStoreRequestOptions: () => possibleStoreRequestOptions });
618
+ /** @internal */
619
+ const possibleStoreRequestOptions = [
620
+ "headers",
621
+ "signal",
622
+ "tag",
623
+ "timeout",
624
+ "token"
625
+ ];
616
626
  /**
617
627
  * Project the public request options (`timeout: 0` to disable,
618
628
  * `withCredentials`, `maxRedirects`, the function/object-form `fetch`, ...)
@@ -726,7 +736,7 @@ function _fetchRequest(_stega, _params, options) {
726
736
  }
727
737
  /** @internal */
728
738
  function _fetchObservable(client, httpRequest, _stega, query, _params = {}, options = {}) {
729
- return _observe(options.signal, (signal) => _fetch$1(client, httpRequest, _stega, query, _params, {
739
+ return _observe(options.signal, (signal) => _fetch$2(client, httpRequest, _stega, query, _params, {
730
740
  ...options,
731
741
  signal
732
742
  }));
@@ -736,12 +746,12 @@ function _fetchObservable(client, httpRequest, _stega, query, _params = {}, opti
736
746
  *
737
747
  * @internal
738
748
  */
739
- function _fetch$1(client, httpRequest, _stega, query, _params = {}, options = {}) {
749
+ function _fetch$2(client, httpRequest, _stega, query, _params = {}, options = {}) {
740
750
  let { stega, params, mapResponse, reqOpts } = _fetchRequest(_stega, _params, options), request = _dataRequest(client, httpRequest, "query", {
741
751
  query,
742
752
  params
743
753
  }, reqOpts);
744
- return stega.enabled ? Promise.all([request, import("./stegaEncodeSourceMap-DbM2fTN4.js")]).then(([res, { stegaEncodeSourceMap }]) => {
754
+ return stega.enabled ? Promise.all([request, import("./stegaEncodeSourceMap-CO1HKnm2.js")]).then(([res, { stegaEncodeSourceMap }]) => {
745
755
  let result = stegaEncodeSourceMap(res.result, res.resultSourceMap, stega);
746
756
  return mapResponse({
747
757
  ...res,
@@ -1298,6 +1308,7 @@ const resourceDataBase = (config) => {
1298
1308
  return `/projects/${segments[0]}/datasets/${segments[1]}`;
1299
1309
  }
1300
1310
  case "canvas": return `/canvases/${id}`;
1311
+ case "knowledge-base": return `/knowledge-bases/${id}`;
1301
1312
  case "media-library": return `/media-libraries/${id}`;
1302
1313
  case "dashboard": return `/dashboards/${id}`;
1303
1314
  default: throw Error(`Unsupported resource type: ${type.toString()}`);
@@ -1491,7 +1502,7 @@ function _upload(client, _httpRequest, assetType, body, opts = {}) {
1491
1502
  body
1492
1503
  };
1493
1504
  return typeof XMLHttpRequest < "u" ? defer(async () => {
1494
- let { uploadWithProgress } = await import("./browserUpload-2tz6Sdqp.js"), req = _prepareRequest(client, { ...baseRequest });
1505
+ let { uploadWithProgress } = await import("./browserUpload-C7PwCs-C.js"), req = _prepareRequest(client, { ...baseRequest });
1495
1506
  return uploadWithProgress({
1496
1507
  url: appendQuery(req.url, req.query),
1497
1508
  method: req.method ?? "POST",
@@ -1515,6 +1526,7 @@ function buildAssetUploadUrl(config, assetType) {
1515
1526
  switch (type) {
1516
1527
  case "dataset": throw Error("Assets are not supported for dataset resources, yet. Configure the client with `{projectId: <projectId>, dataset: <datasetId>}` instead.");
1517
1528
  case "canvas": return `/canvases/${id}/assets/${assetTypeEndpoint}`;
1529
+ case "knowledge-base": throw Error("Assets are not supported for knowledge-base resources. Use `client.context.imports` to add content instead.");
1518
1530
  case "media-library": return `/media-libraries/${id}/upload`;
1519
1531
  case "dashboard": return `/dashboards/${id}/assets/${assetTypeEndpoint}`;
1520
1532
  default: throw Error(`Unsupported resource type: ${type.toString()}`);
@@ -1601,7 +1613,7 @@ const possibleOptions = [
1601
1613
  "tag"
1602
1614
  ], defaultOptions = { includeResult: !0 };
1603
1615
  /** @public */
1604
- function _listen$1(query, params, opts = {}) {
1616
+ function _listen$2(query, params, opts = {}) {
1605
1617
  let { url, requestTagPrefix } = this.config(), tag = opts.tag && requestTagPrefix ? [requestTagPrefix, opts.tag].join(".") : opts.tag, options = {
1606
1618
  ...defaults_default(opts, defaultOptions),
1607
1619
  tag
@@ -1720,7 +1732,7 @@ function _removeReaction(client, httpRequest, id, shortName, options) {
1720
1732
  return writeDocument(id, client, httpRequest, "DELETE", `${commentUrl(id)}/reactions/${encodeURIComponent(shortName)}`, void 0, options);
1721
1733
  }
1722
1734
  /** @internal */
1723
- function _fetch(client, httpRequest, query, params, options) {
1735
+ function _fetch$1(client, httpRequest, query, params, options) {
1724
1736
  let search = resourceQuery(client);
1725
1737
  return _requestObservable(client, httpRequest, {
1726
1738
  ...encodeQueryString({
@@ -1746,7 +1758,7 @@ function _fetch(client, httpRequest, query, params, options) {
1746
1758
  }).pipe(map$1((response) => response.result));
1747
1759
  }
1748
1760
  /** @internal */
1749
- function _listen(client, query, params, options) {
1761
+ function _listen$1(client, query, params, options) {
1750
1762
  let opts = options ?? {}, { requestTagPrefix } = client.config(), tag = opts.tag && requestTagPrefix ? [requestTagPrefix, opts.tag].join(".") : opts.tag, listenOpts = pick({
1751
1763
  ...defaults_default(opts, defaultOptions),
1752
1764
  tag
@@ -1869,10 +1881,10 @@ var ObservableCollaborationCommentsClient = class {
1869
1881
  * @param options - Optional request options
1870
1882
  */
1871
1883
  fetch(query, params, options) {
1872
- return _fetch(this.#client, this.#httpRequest, query, params, options);
1884
+ return _fetch$1(this.#client, this.#httpRequest, query, params, options);
1873
1885
  }
1874
1886
  listen(query, params, options) {
1875
- return _listen(this.#client, query, params, options);
1887
+ return _listen$1(this.#client, query, params, options);
1876
1888
  }
1877
1889
  }, CollaborationCommentsClient = class {
1878
1890
  #client;
@@ -1975,12 +1987,811 @@ var ObservableCollaborationCommentsClient = class {
1975
1987
  * @param params - Optional query parameters
1976
1988
  * @param options - Optional request options
1977
1989
  */
1990
+ fetch(query, params, options) {
1991
+ return lastValueFrom(_fetch$1(this.#client, this.#httpRequest, query, params, options));
1992
+ }
1993
+ listen(query, params, options) {
1994
+ return _listen$1(this.#client, query, params, options);
1995
+ }
1996
+ };
1997
+ /** @internal */
1998
+ function _organizationId(client) {
1999
+ let organizationId = client.config().context?.organizationId;
2000
+ if (!organizationId) throw Error("`context.organizationId` must be configured to query Context documents");
2001
+ return organizationId;
2002
+ }
2003
+ function storeUrl(client, suffix) {
2004
+ return `/context/organizations/${encodeURIComponent(_organizationId(client))}/${suffix}`;
2005
+ }
2006
+ /** @internal */
2007
+ function _fetch(client, httpRequest, query, params, options) {
2008
+ let url = storeUrl(client, "query");
2009
+ return _requestObservable(client, httpRequest, {
2010
+ ...encodeQueryString({
2011
+ query,
2012
+ params
2013
+ }).length < 11264 ? {
2014
+ method: "GET",
2015
+ url: `${url}${encodeQueryString({
2016
+ query,
2017
+ params
2018
+ })}`
2019
+ } : {
2020
+ method: "POST",
2021
+ url,
2022
+ body: {
2023
+ query,
2024
+ params: params ?? {}
2025
+ }
2026
+ },
2027
+ ...pick(options || {}, possibleStoreRequestOptions)
2028
+ }).pipe(map$1((response) => response.result));
2029
+ }
2030
+ /** @internal */
2031
+ function _listen(client, query, params, options) {
2032
+ let opts = options ?? {}, { requestTagPrefix } = client.config(), tag = opts.tag && requestTagPrefix ? [requestTagPrefix, opts.tag].join(".") : opts.tag, listenOpts = pick({
2033
+ ...defaults_default(opts, defaultOptions),
2034
+ tag
2035
+ }, possibleOptions), qs = encodeQueryString({
2036
+ query,
2037
+ params,
2038
+ options: listenOpts
2039
+ }), uri = `${client.getUrl(storeUrl(client, "listen"))}${qs}`;
2040
+ return uri.length > 14800 ? throwError(() => /* @__PURE__ */ Error("Query too large for listener")) : _connectListenEventSource(client, uri, opts.events ? opts.events : ["mutation"]);
2041
+ }
2042
+ const ENTRY_TYPE = "sanity.context.entry", ISSUE_TYPE = "sanity.context.issue", MCP_TYPE = "sanity.context.mcp";
2043
+ function _one(client, httpRequest, query, params, options) {
2044
+ return lastValueFrom(_fetch(client, httpRequest, query, params, options));
2045
+ }
2046
+ /**
2047
+ * Drain every page of a `(_createdAt, _id)`-keyset read. Termination keys on
2048
+ * the raw page length before anything looks at the rows: a short page means
2049
+ * the store had nothing more to give, and filtering must never shorten a
2050
+ * full page into a false stop.
2051
+ */
2052
+ async function _drainByCreatedAt(client, httpRequest, filter, params, options) {
2053
+ let all = [], cursor;
2054
+ for (;;) {
2055
+ let query = `*[${cursor ? `${filter} && (_createdAt > \$c || (_createdAt == \$c && _id > \$i))` : filter}] | order(_createdAt asc, _id asc) [0...200]`, page = await lastValueFrom(_fetch(client, httpRequest, query, cursor ? {
2056
+ ...params,
2057
+ ...cursor
2058
+ } : params, options));
2059
+ if (all.push(...page), page.length < 200) return all;
2060
+ let last = page[page.length - 1];
2061
+ cursor = {
2062
+ c: last._createdAt,
2063
+ i: last._id
2064
+ };
2065
+ }
2066
+ }
2067
+ /** @internal */
2068
+ function _readEntry(client, httpRequest, knowledgeBaseId, path, options) {
2069
+ return _one(client, httpRequest, `*[_type == "${ENTRY_TYPE}" && knowledgeBaseId == $kb && path == $path][0]`, {
2070
+ kb: knowledgeBaseId,
2071
+ path
2072
+ }, options);
2073
+ }
2074
+ /** @internal */
2075
+ async function _listEntries(client, httpRequest, knowledgeBaseId, options) {
2076
+ let all = [], after = "";
2077
+ for (;;) {
2078
+ let page = await lastValueFrom(_fetch(client, httpRequest, `*[_type == "${ENTRY_TYPE}" && knowledgeBaseId == $kb && path > $after] | order(path asc) [0...200] {_id, path, title, tldr, status}`, {
2079
+ kb: knowledgeBaseId,
2080
+ after
2081
+ }, options));
2082
+ if (all.push(...page), page.length < 200) return all;
2083
+ after = page[page.length - 1].path;
2084
+ }
2085
+ }
2086
+ /** @internal */
2087
+ function _listIssues(client, httpRequest, knowledgeBaseId, status, options) {
2088
+ return _drainByCreatedAt(client, httpRequest, `_type == "${ISSUE_TYPE}" && knowledgeBaseId == $kb${status === void 0 ? "" : " && status == $status"}`, status === void 0 ? { kb: knowledgeBaseId } : {
2089
+ kb: knowledgeBaseId,
2090
+ status
2091
+ }, options);
2092
+ }
2093
+ /** @internal */
2094
+ function _readIssue(client, httpRequest, knowledgeBaseId, issueId, options) {
2095
+ return _one(client, httpRequest, `*[_type == "${ISSUE_TYPE}" && knowledgeBaseId == $kb && _id == $id][0]`, {
2096
+ kb: knowledgeBaseId,
2097
+ id: issueId
2098
+ }, options);
2099
+ }
2100
+ /** @internal */
2101
+ function _listInstructions(client, httpRequest, knowledgeBaseId, options) {
2102
+ return _drainByCreatedAt(client, httpRequest, "_type == \"sanity.context.instruction\" && knowledgeBaseId == $kb && schemaVersion == 1", { kb: knowledgeBaseId }, options);
2103
+ }
2104
+ /** @internal */
2105
+ function _listMcpEndpoints(client, httpRequest, options) {
2106
+ return lastValueFrom(_fetch(client, httpRequest, `*[_type == "${MCP_TYPE}" && organizationId == $org] | order(_createdAt asc, _id asc) [0...500]`, { org: _organizationId(client) }, options));
2107
+ }
2108
+ /** @internal */
2109
+ function _readMcpEndpoint(client, httpRequest, name, options) {
2110
+ return _one(client, httpRequest, `*[_type == "${MCP_TYPE}" && organizationId == $org && name == $name][0]`, {
2111
+ org: _organizationId(client),
2112
+ name
2113
+ }, options);
2114
+ }
2115
+ /** @internal */
2116
+ function _readConversation(client, httpRequest, threadId, options) {
2117
+ return _one(client, httpRequest, "*[_type == \"sanity.context.conversation\" && organizationId == $org && threadId == $threadId][0]", {
2118
+ org: _organizationId(client),
2119
+ threadId
2120
+ }, options);
2121
+ }
2122
+ const COLLECTION_URL = "/context/knowledge-bases";
2123
+ /**
2124
+ * The knowledge base every scoped method operates on comes from the client's
2125
+ * `resource` configuration, matching how media libraries and canvases are
2126
+ * addressed. Resolved per call so `withConfig` clones behave.
2127
+ */
2128
+ function _resolveKnowledgeBaseId(client) {
2129
+ let resource = client.config().resource;
2130
+ if (resource?.type !== "knowledge-base") throw Error("`resource` of type `knowledge-base` must be configured to use knowledge-base methods");
2131
+ return resource.id;
2132
+ }
2133
+ function _knowledgeBaseUrl(knowledgeBaseId, suffix = "") {
2134
+ return `${COLLECTION_URL}/${encodeURIComponent(knowledgeBaseId)}${suffix}`;
2135
+ }
2136
+ /** Serialize defined values into query params, dropping the undefined ones. */
2137
+ function _conversationUrl(client, threadId) {
2138
+ let organizationId = client.config().context?.organizationId;
2139
+ if (!organizationId) throw Error("`context.organizationId` must be configured to record conversations");
2140
+ if (!threadId) throw Error("`threadId` must be provided");
2141
+ return `/context/organizations/${encodeURIComponent(organizationId)}/conversations/${encodeURIComponent(threadId)}`;
2142
+ }
2143
+ function _query(entries) {
2144
+ return Object.fromEntries(Object.entries(entries).flatMap(([key, value]) => value === void 0 ? [] : [[key, `${value}`]]));
2145
+ }
2146
+ function _fetchBody(file) {
2147
+ return ArrayBuffer.isView(file) ? file.buffer instanceof ArrayBuffer ? new Uint8Array(file.buffer, file.byteOffset, file.byteLength) : Uint8Array.from(file) : file;
2148
+ }
2149
+ /**
2150
+ * `client.context` — knowledge bases and everything scoped to them.
2151
+ *
2152
+ * Collection-level management (create, list, get, edit, delete) addresses
2153
+ * knowledge bases per call, like `client.projects`. Everything scoped to one
2154
+ * knowledge base (imports, builds, issues, entries, ...) operates on the
2155
+ * client's configured `resource`, like media libraries:
2156
+ *
2157
+ * @example Full lifecycle
2158
+ * ```ts
2159
+ * const created = await client.context.knowledgeBases.create({
2160
+ * organizationId: 'org123',
2161
+ * title: 'Support docs',
2162
+ * description: 'Product docs and troubleshooting guides',
2163
+ * })
2164
+ *
2165
+ * const kb = createClient({
2166
+ * apiVersion: '2026-08-25',
2167
+ * token,
2168
+ * resource: {type: 'knowledge-base', id: created.publicId},
2169
+ * })
2170
+ *
2171
+ * await kb.context.imports.create({type: 'text', title: 'Refund policy', content: refundMd})
2172
+ * const {jobId} = await kb.context.build()
2173
+ * ```
2174
+ *
2175
+ * @beta
2176
+ */
2177
+ var ContextClient = class {
2178
+ #client;
2179
+ #httpRequest;
2180
+ constructor(client, httpRequest) {
2181
+ this.#client = client, this.#httpRequest = httpRequest;
2182
+ }
2183
+ /** Request against the configured knowledge base. */
2184
+ #request(suffix, reqOptions = {}) {
2185
+ return _request(this.#client, this.#httpRequest, {
2186
+ url: _knowledgeBaseUrl(_resolveKnowledgeBaseId(this.#client), suffix),
2187
+ ...reqOptions
2188
+ });
2189
+ }
2190
+ /** Shared shape of every paginated list endpoint scoped to the knowledge base. */
2191
+ #list(suffix, params, extraQuery) {
2192
+ return this.#request(suffix, {
2193
+ query: _query({
2194
+ cursor: params?.cursor,
2195
+ limit: params?.limit,
2196
+ ...extraQuery
2197
+ }),
2198
+ signal: params?.signal,
2199
+ tag: params?.tag
2200
+ });
2201
+ }
2202
+ async #uploadFile(params, options) {
2203
+ let staged = await this.#request("/imports/uploads", {
2204
+ method: "POST",
2205
+ body: {
2206
+ filename: params.filename,
2207
+ ...params.contentType && { contentType: params.contentType }
2208
+ },
2209
+ ...options
2210
+ }), config = this.#client.config(), putResponse = await (config.resolveFetch?.(config.proxy) ?? globalThis.fetch)(staged.uploadUrl, {
2211
+ method: "PUT",
2212
+ body: _fetchBody(params.file),
2213
+ ...params.contentType && { headers: { "content-type": params.contentType } },
2214
+ signal: options?.signal
2215
+ });
2216
+ if (!putResponse.ok) throw Error(`File upload failed: ${putResponse.status} ${putResponse.statusText}`);
2217
+ return this.#request(`/imports/uploads/${encodeURIComponent(staged.importId)}/complete`, {
2218
+ method: "POST",
2219
+ body: {},
2220
+ ...options
2221
+ });
2222
+ }
2223
+ /** The knowledge base collection: management addressed per call. */
2224
+ knowledgeBases = {
2225
+ /** Create a knowledge base. Requires the org-level knowledge-base create grant. */
2226
+ create: (params, options) => _request(this.#client, this.#httpRequest, {
2227
+ url: COLLECTION_URL,
2228
+ method: "POST",
2229
+ body: params,
2230
+ ...options
2231
+ }),
2232
+ /** List the organization's knowledge bases. */
2233
+ list: (params) => _request(this.#client, this.#httpRequest, {
2234
+ url: COLLECTION_URL,
2235
+ query: _query({
2236
+ organizationId: params.organizationId,
2237
+ cursor: params.cursor,
2238
+ limit: params.limit
2239
+ }),
2240
+ signal: params.signal,
2241
+ tag: params.tag
2242
+ }),
2243
+ /** Fetch a knowledge base by its id. */
2244
+ get: (knowledgeBaseId, options) => _request(this.#client, this.#httpRequest, {
2245
+ url: _knowledgeBaseUrl(knowledgeBaseId),
2246
+ ...options
2247
+ }),
2248
+ /** Edit a knowledge base's configuration. */
2249
+ edit: (knowledgeBaseId, params, options) => _request(this.#client, this.#httpRequest, {
2250
+ url: _knowledgeBaseUrl(knowledgeBaseId),
2251
+ method: "PATCH",
2252
+ body: params,
2253
+ ...options
2254
+ }),
2255
+ /** Delete a knowledge base and its generated content. */
2256
+ delete: async (knowledgeBaseId, options) => {
2257
+ await _request(this.#client, this.#httpRequest, {
2258
+ url: _knowledgeBaseUrl(knowledgeBaseId),
2259
+ method: "DELETE",
2260
+ ...options
2261
+ });
2262
+ }
2263
+ };
2264
+ /**
2265
+ * GROQ over the organization's Context documents (conversation telemetry
2266
+ * today; the store holds every Context family and the caller's access
2267
+ * decides what a query returns, so filter on `_type`).
2268
+ *
2269
+ * Requires `context.organizationId` in the client configuration.
2270
+ */
1978
2271
  fetch(query, params, options) {
1979
2272
  return lastValueFrom(_fetch(this.#client, this.#httpRequest, query, params, options));
1980
2273
  }
2274
+ /**
2275
+ * Listen for changes to the organization's Context documents. Mirrors
2276
+ * `client.listen(query, params, options)` and emits mutation events by
2277
+ * default.
2278
+ */
1981
2279
  listen(query, params, options) {
1982
2280
  return _listen(this.#client, query, params, options);
1983
2281
  }
2282
+ /**
2283
+ * Conversation telemetry. `threadId` identifies the conversation within
2284
+ * the organization — reuse means the same conversation. Beyond the canned
2285
+ * `get`, reads go through {@link fetch} and {@link listen} with GROQ
2286
+ * (`_type == "sanity.context.conversation"`).
2287
+ *
2288
+ * Requires `context.organizationId` in the client configuration.
2289
+ */
2290
+ conversations = {
2291
+ /**
2292
+ * Record a conversation. Messages replace the stored transcript
2293
+ * wholesale; `metadata` and model fields only overwrite when present.
2294
+ * Last write per thread wins — retries are safe.
2295
+ */
2296
+ save: (params, options) => {
2297
+ let { threadId, ...body } = params;
2298
+ return _request(this.#client, this.#httpRequest, {
2299
+ url: _conversationUrl(this.#client, threadId),
2300
+ method: "PUT",
2301
+ body,
2302
+ ...options
2303
+ });
2304
+ },
2305
+ /**
2306
+ * Record the classification your own model produced for one thread:
2307
+ * exactly one of `coreMetrics` (a verdict) or `classificationError`
2308
+ * (why classification failed).
2309
+ */
2310
+ classify: (params, options) => {
2311
+ let { threadId, ...body } = params;
2312
+ return _request(this.#client, this.#httpRequest, {
2313
+ url: _conversationUrl(this.#client, threadId),
2314
+ method: "PATCH",
2315
+ body,
2316
+ ...options
2317
+ });
2318
+ },
2319
+ /**
2320
+ * One recorded conversation by its thread id, or `null` when the thread
2321
+ * was never recorded. Runs:
2322
+ *
2323
+ * `*[_type == "sanity.context.conversation" && organizationId == $org && threadId == $threadId][0]`
2324
+ *
2325
+ * For anything more, use {@link fetch}.
2326
+ */
2327
+ get: (params, options) => _readConversation(this.#client, this.#httpRequest, params.threadId, options)
2328
+ };
2329
+ /**
2330
+ * Build the configured knowledge base. The server waits for pending import
2331
+ * processing before assembling, so importing and building back to back is
2332
+ * safe. Track the returned job with {@link jobs}.
2333
+ */
2334
+ build(options) {
2335
+ return this.#request("/build", {
2336
+ method: "POST",
2337
+ ...options
2338
+ });
2339
+ }
2340
+ /** Cancel the running build, if any. */
2341
+ cancelBuild(options) {
2342
+ return this.#request("/build/cancel", {
2343
+ method: "POST",
2344
+ ...options
2345
+ });
2346
+ }
2347
+ /** Run an incremental refresh: re-check sources and apply what changed. */
2348
+ refresh(options) {
2349
+ return this.#request("/refresh", {
2350
+ method: "POST",
2351
+ ...options
2352
+ });
2353
+ }
2354
+ /** Imports: feed content into the configured knowledge base. */
2355
+ imports = {
2356
+ /**
2357
+ * Import content. One entry point, discriminated on `type`: inline
2358
+ * `text`, a website `crawl`, a Sanity `dataset` bind, or a `file`
2359
+ * upload. Processing queues automatically. The file variant stages the
2360
+ * upload, PUTs the bytes to a signed storage URL, and confirms; the
2361
+ * bytes never pass through the Context API.
2362
+ */
2363
+ create: (params, options) => params.type === "file" ? this.#uploadFile(params, options) : this.#request("/imports", {
2364
+ method: "POST",
2365
+ body: params,
2366
+ ...options
2367
+ }),
2368
+ list: (params) => this.#list("/imports", params),
2369
+ get: (params, options) => this.#request(`/imports/${encodeURIComponent(params.importId)}`, options),
2370
+ /** A short-lived signed URL for the original uploaded bytes. */
2371
+ download: (params, options) => this.#request(`/imports/${encodeURIComponent(params.importId)}/download`, options),
2372
+ delete: async (params, options) => {
2373
+ await this.#request(`/imports/${encodeURIComponent(params.importId)}`, {
2374
+ method: "DELETE",
2375
+ ...options
2376
+ });
2377
+ }
2378
+ };
2379
+ /** Jobs: poll async work (builds, imports) to a terminal state. */
2380
+ jobs = { get: (params, options) => this.#request(`/jobs/${encodeURIComponent(params.jobId)}`, options) };
2381
+ /**
2382
+ * Issues: findings from builds awaiting triage. Reads are canned GROQ
2383
+ * queries against the organization's document store; for anything more,
2384
+ * use {@link fetch}. Reads require `context.organizationId` alongside the
2385
+ * knowledge-base `resource` in the client configuration.
2386
+ */
2387
+ issues = {
2388
+ /**
2389
+ * Every issue on the knowledge base, oldest first, optionally narrowed
2390
+ * to one status. Drains keyset pages internally and resolves with the
2391
+ * complete set. Runs:
2392
+ *
2393
+ * `*[_type == "sanity.context.issue" && knowledgeBaseId == $kb && status == $status] | order(_createdAt asc, _id asc)`
2394
+ *
2395
+ * (the status clause only when given). For anything more, use {@link fetch}.
2396
+ */
2397
+ list: (params, options) => _listIssues(this.#client, this.#httpRequest, _resolveKnowledgeBaseId(this.#client), params?.status, options),
2398
+ /**
2399
+ * One issue by its document id, or `null` when it does not exist. Runs:
2400
+ *
2401
+ * `*[_type == "sanity.context.issue" && knowledgeBaseId == $kb && _id == $id][0]`
2402
+ *
2403
+ * For anything more, use {@link fetch}.
2404
+ */
2405
+ get: (params, options) => _readIssue(this.#client, this.#httpRequest, _resolveKnowledgeBaseId(this.#client), params.issueId, options),
2406
+ /** Resolve a conflict issue. Mints the standing instruction, same as the dashboard. */
2407
+ resolve: (params, options) => {
2408
+ let { issueId, ...body } = params;
2409
+ return this.#request(`/issues/${encodeURIComponent(issueId)}/resolve`, {
2410
+ method: "POST",
2411
+ body,
2412
+ ...options
2413
+ });
2414
+ },
2415
+ dismiss: (params, options) => this.#request(`/issues/${encodeURIComponent(params.issueId)}/dismiss`, {
2416
+ method: "POST",
2417
+ ...options
2418
+ }),
2419
+ reopen: (params, options) => this.#request(`/issues/${encodeURIComponent(params.issueId)}/reopen`, {
2420
+ method: "POST",
2421
+ ...options
2422
+ }),
2423
+ /** Apply already-accepted issues to the knowledge base in one batch. */
2424
+ apply: (params, options) => this.#request("/issues/apply", {
2425
+ method: "POST",
2426
+ body: params,
2427
+ ...options
2428
+ })
2429
+ };
2430
+ /** Instructions: standing decisions that steer every build. */
2431
+ instructions = {
2432
+ create: (params, options) => this.#request("/instructions", {
2433
+ method: "POST",
2434
+ body: params,
2435
+ ...options
2436
+ }),
2437
+ /**
2438
+ * Every current-schema instruction on the knowledge base, oldest first.
2439
+ * Drains keyset pages internally and resolves with the complete set.
2440
+ * Runs:
2441
+ *
2442
+ * `*[_type == "sanity.context.instruction" && knowledgeBaseId == $kb && schemaVersion == 1] | order(_createdAt asc, _id asc)`
2443
+ *
2444
+ * For anything more, use {@link fetch}. Requires `context.organizationId`
2445
+ * alongside the knowledge-base `resource` in the client configuration.
2446
+ */
2447
+ list: (options) => _listInstructions(this.#client, this.#httpRequest, _resolveKnowledgeBaseId(this.#client), options),
2448
+ edit: (params, options) => {
2449
+ let { instructionId, ...body } = params;
2450
+ return this.#request(`/instructions/${encodeURIComponent(instructionId)}`, {
2451
+ method: "PATCH",
2452
+ body,
2453
+ ...options
2454
+ });
2455
+ },
2456
+ delete: async (params, options) => {
2457
+ await this.#request(`/instructions/${encodeURIComponent(params.instructionId)}`, {
2458
+ method: "DELETE",
2459
+ ...options
2460
+ });
2461
+ }
2462
+ };
2463
+ /**
2464
+ * Entries: the built outline, one entry per node. Reads are canned GROQ
2465
+ * queries against the organization's document store; for anything more,
2466
+ * use {@link fetch}. Requires `context.organizationId` alongside the
2467
+ * knowledge-base `resource` in the client configuration.
2468
+ */
2469
+ entries = {
2470
+ /**
2471
+ * Every entry, path-ordered, as a metadata view (`_id`, `path`,
2472
+ * `title`, `tldr`, `status`) with bodies excluded. Drains keyset pages
2473
+ * internally and resolves with the complete set. Runs:
2474
+ *
2475
+ * `*[_type == "sanity.context.entry" && knowledgeBaseId == $kb && path > $after] | order(path asc) [0...200] {_id, path, title, tldr, status}`
2476
+ *
2477
+ * For bodies, use `entries.get` or {@link fetch}.
2478
+ */
2479
+ list: (options) => _listEntries(this.#client, this.#httpRequest, _resolveKnowledgeBaseId(this.#client), options),
2480
+ /**
2481
+ * One entry with its full body and citations, by outline path (e.g.
2482
+ * `billing/refunds`), or `null` when no entry sits at that path. Runs:
2483
+ *
2484
+ * `*[_type == "sanity.context.entry" && knowledgeBaseId == $kb && path == $path][0]`
2485
+ *
2486
+ * For anything more, use {@link fetch}.
2487
+ */
2488
+ get: (params, options) => _readEntry(this.#client, this.#httpRequest, _resolveKnowledgeBaseId(this.#client), params.path, options),
2489
+ /**
2490
+ * Rebuild one entry from its already-placed sources, by outline path.
2491
+ * Poll the returned job with {@link jobs}; `affectedEntries` lists every
2492
+ * entry the rebuild touches.
2493
+ */
2494
+ rebuild: (params, options) => this.#request(`/entries/${encodeURIComponent(params.path)}/rebuild`, {
2495
+ method: "POST",
2496
+ ...options
2497
+ })
2498
+ };
2499
+ /**
2500
+ * MCP endpoint configurations, org-owned documents read with canned GROQ
2501
+ * queries. Requires `context.organizationId` in the client configuration.
2502
+ */
2503
+ mcpEndpoints = {
2504
+ /**
2505
+ * The organization's MCP endpoint configurations, oldest first. Runs:
2506
+ *
2507
+ * `*[_type == "sanity.context.mcp" && organizationId == $org] | order(_createdAt asc, _id asc) [0...500]`
2508
+ *
2509
+ * For anything more, use {@link fetch}.
2510
+ */
2511
+ list: (options) => _listMcpEndpoints(this.#client, this.#httpRequest, options),
2512
+ /**
2513
+ * One MCP endpoint configuration by its URL name, or `null` when none
2514
+ * carries that name. Runs:
2515
+ *
2516
+ * `*[_type == "sanity.context.mcp" && organizationId == $org && name == $name][0]`
2517
+ *
2518
+ * For anything more, use {@link fetch}.
2519
+ */
2520
+ get: (params, options) => _readMcpEndpoint(this.#client, this.#httpRequest, params.name, options)
2521
+ };
2522
+ /** Sources: the distilled units builds cite. */
2523
+ sources = {
2524
+ /**
2525
+ * List sources, optionally filtered by `status` or the `importId` they
2526
+ * came from. `ids` is a lookup mode: it resolves those exact sources
2527
+ * (e.g. from an entry's citations) and overrides `status` and `cursor`.
2528
+ */
2529
+ list: (params) => this.#list("/sources", params, {
2530
+ status: params?.status,
2531
+ importId: params?.importId,
2532
+ ids: params?.ids?.join(",")
2533
+ }),
2534
+ get: (params, options) => this.#request(`/sources/${encodeURIComponent(params.sourceId)}`, options),
2535
+ /**
2536
+ * Distilled source content, optionally a line range: the evidence behind
2537
+ * a citation or an issue.
2538
+ */
2539
+ content: (params, options) => this.#request(`/sources/${encodeURIComponent(params.sourceId)}/content`, {
2540
+ query: _query({
2541
+ startLine: params.startLine,
2542
+ endLine: params.endLine
2543
+ }),
2544
+ ...options
2545
+ }),
2546
+ delete: async (params, options) => {
2547
+ await this.#request(`/sources/${encodeURIComponent(params.sourceId)}`, {
2548
+ method: "DELETE",
2549
+ ...options
2550
+ });
2551
+ }
2552
+ };
2553
+ }, ObservableContextClient = class {
2554
+ #client;
2555
+ #httpRequest;
2556
+ constructor(client, httpRequest) {
2557
+ this.#client = client, this.#httpRequest = httpRequest;
2558
+ }
2559
+ /** The knowledge base collection: management addressed per call. */
2560
+ knowledgeBases = {
2561
+ /** Create a knowledge base. Requires the org-level knowledge-base create grant. */
2562
+ create: (params, options) => _observe(options?.signal, (signal) => _request(this.#client, this.#httpRequest, {
2563
+ url: COLLECTION_URL,
2564
+ method: "POST",
2565
+ body: params,
2566
+ tag: options?.tag,
2567
+ signal
2568
+ })),
2569
+ /** List the organization's knowledge bases. */
2570
+ list: (params) => _observe(params.signal, (signal) => _request(this.#client, this.#httpRequest, {
2571
+ url: COLLECTION_URL,
2572
+ query: _query({
2573
+ organizationId: params.organizationId,
2574
+ cursor: params.cursor,
2575
+ limit: params.limit
2576
+ }),
2577
+ tag: params.tag,
2578
+ signal
2579
+ })),
2580
+ /** Fetch a knowledge base by its id. */
2581
+ get: (knowledgeBaseId, options) => _observe(options?.signal, (signal) => _request(this.#client, this.#httpRequest, {
2582
+ url: _knowledgeBaseUrl(knowledgeBaseId),
2583
+ tag: options?.tag,
2584
+ signal
2585
+ })),
2586
+ /** Edit a knowledge base's configuration. */
2587
+ edit: (knowledgeBaseId, params, options) => _observe(options?.signal, (signal) => _request(this.#client, this.#httpRequest, {
2588
+ url: _knowledgeBaseUrl(knowledgeBaseId),
2589
+ method: "PATCH",
2590
+ body: params,
2591
+ tag: options?.tag,
2592
+ signal
2593
+ })),
2594
+ /** Delete a knowledge base and its generated content. */
2595
+ delete: (knowledgeBaseId, options) => _observe(options?.signal, (signal) => _request(this.#client, this.#httpRequest, {
2596
+ url: _knowledgeBaseUrl(knowledgeBaseId),
2597
+ method: "DELETE",
2598
+ tag: options?.tag,
2599
+ signal
2600
+ }))
2601
+ };
2602
+ /**
2603
+ * GROQ over the organization's Context documents (conversation telemetry
2604
+ * today; the store holds every Context family and the caller's access
2605
+ * decides what a query returns, so filter on `_type`).
2606
+ *
2607
+ * Requires `context.organizationId` in the client configuration.
2608
+ */
2609
+ fetch(query, params, options) {
2610
+ return _fetch(this.#client, this.#httpRequest, query, params, options);
2611
+ }
2612
+ /**
2613
+ * Listen for changes to the organization's Context documents. Mirrors
2614
+ * `client.listen(query, params, options)` and emits mutation events by
2615
+ * default.
2616
+ */
2617
+ listen(query, params, options) {
2618
+ return _listen(this.#client, query, params, options);
2619
+ }
2620
+ /**
2621
+ * Conversation telemetry. `threadId` identifies the conversation within
2622
+ * the organization — reuse means the same conversation. Beyond the canned
2623
+ * `get`, reads go through {@link fetch} and {@link listen} with GROQ
2624
+ * (`_type == "sanity.context.conversation"`).
2625
+ *
2626
+ * Requires `context.organizationId` in the client configuration.
2627
+ */
2628
+ conversations = {
2629
+ /**
2630
+ * Record a conversation. Messages replace the stored transcript
2631
+ * wholesale; `metadata` and model fields only overwrite when present.
2632
+ * Last write per thread wins — retries are safe.
2633
+ */
2634
+ save: (params, options) => {
2635
+ let { threadId, ...body } = params;
2636
+ return _observe(options?.signal, (signal) => _request(this.#client, this.#httpRequest, {
2637
+ url: _conversationUrl(this.#client, threadId),
2638
+ method: "PUT",
2639
+ body,
2640
+ tag: options?.tag,
2641
+ signal
2642
+ }));
2643
+ },
2644
+ /**
2645
+ * Record the classification your own model produced for one thread:
2646
+ * exactly one of `coreMetrics` (a verdict) or `classificationError`
2647
+ * (why classification failed).
2648
+ */
2649
+ classify: (params, options) => {
2650
+ let { threadId, ...body } = params;
2651
+ return _observe(options?.signal, (signal) => _request(this.#client, this.#httpRequest, {
2652
+ url: _conversationUrl(this.#client, threadId),
2653
+ method: "PATCH",
2654
+ body,
2655
+ tag: options?.tag,
2656
+ signal
2657
+ }));
2658
+ },
2659
+ /**
2660
+ * One recorded conversation by its thread id, or `null` when the thread
2661
+ * was never recorded. Runs:
2662
+ *
2663
+ * `*[_type == "sanity.context.conversation" && organizationId == $org && threadId == $threadId][0]`
2664
+ *
2665
+ * For anything more, use {@link fetch}.
2666
+ */
2667
+ get: (params, options) => _observe(options?.signal, (signal) => _readConversation(this.#client, this.#httpRequest, params.threadId, {
2668
+ ...options,
2669
+ signal
2670
+ }))
2671
+ };
2672
+ /**
2673
+ * Entries: the built outline, one entry per node. Reads are canned GROQ
2674
+ * queries against the organization's document store; for anything more,
2675
+ * use {@link fetch}. Requires `context.organizationId` alongside the
2676
+ * knowledge-base `resource` in the client configuration.
2677
+ */
2678
+ entries = {
2679
+ /**
2680
+ * Every entry, path-ordered, as a metadata view (`_id`, `path`,
2681
+ * `title`, `tldr`, `status`) with bodies excluded. Drains keyset pages
2682
+ * internally and emits the complete set. Runs:
2683
+ *
2684
+ * `*[_type == "sanity.context.entry" && knowledgeBaseId == $kb && path > $after] | order(path asc) [0...200] {_id, path, title, tldr, status}`
2685
+ *
2686
+ * For bodies, use `entries.get` or {@link fetch}.
2687
+ */
2688
+ list: (options) => _observe(options?.signal, (signal) => _listEntries(this.#client, this.#httpRequest, _resolveKnowledgeBaseId(this.#client), {
2689
+ ...options,
2690
+ signal
2691
+ })),
2692
+ /**
2693
+ * One entry with its full body and citations, by outline path (e.g.
2694
+ * `billing/refunds`), or `null` when no entry sits at that path. Runs:
2695
+ *
2696
+ * `*[_type == "sanity.context.entry" && knowledgeBaseId == $kb && path == $path][0]`
2697
+ *
2698
+ * For anything more, use {@link fetch}.
2699
+ */
2700
+ get: (params, options) => _observe(options?.signal, (signal) => _readEntry(this.#client, this.#httpRequest, _resolveKnowledgeBaseId(this.#client), params.path, {
2701
+ ...options,
2702
+ signal
2703
+ })),
2704
+ /**
2705
+ * Rebuild one entry from its already-placed sources, by outline path.
2706
+ * Poll the returned job with the promise client's `jobs`;
2707
+ * `affectedEntries` lists every entry the rebuild touches.
2708
+ */
2709
+ rebuild: (params, options) => _observe(options?.signal, (signal) => _request(this.#client, this.#httpRequest, {
2710
+ url: _knowledgeBaseUrl(_resolveKnowledgeBaseId(this.#client), `/entries/${encodeURIComponent(params.path)}/rebuild`),
2711
+ method: "POST",
2712
+ tag: options?.tag,
2713
+ signal
2714
+ }))
2715
+ };
2716
+ /**
2717
+ * Issues: findings from builds awaiting triage. Reads are canned GROQ
2718
+ * queries against the organization's document store; for anything more,
2719
+ * use {@link fetch}. Requires `context.organizationId` alongside the
2720
+ * knowledge-base `resource` in the client configuration.
2721
+ */
2722
+ issues = {
2723
+ /**
2724
+ * Every issue on the knowledge base, oldest first, optionally narrowed
2725
+ * to one status. Drains keyset pages internally and emits the complete
2726
+ * set. Runs:
2727
+ *
2728
+ * `*[_type == "sanity.context.issue" && knowledgeBaseId == $kb && status == $status] | order(_createdAt asc, _id asc)`
2729
+ *
2730
+ * (the status clause only when given). For anything more, use {@link fetch}.
2731
+ */
2732
+ list: (params, options) => _observe(options?.signal, (signal) => _listIssues(this.#client, this.#httpRequest, _resolveKnowledgeBaseId(this.#client), params?.status, {
2733
+ ...options,
2734
+ signal
2735
+ })),
2736
+ /**
2737
+ * One issue by its document id, or `null` when it does not exist. Runs:
2738
+ *
2739
+ * `*[_type == "sanity.context.issue" && knowledgeBaseId == $kb && _id == $id][0]`
2740
+ *
2741
+ * For anything more, use {@link fetch}.
2742
+ */
2743
+ get: (params, options) => _observe(options?.signal, (signal) => _readIssue(this.#client, this.#httpRequest, _resolveKnowledgeBaseId(this.#client), params.issueId, {
2744
+ ...options,
2745
+ signal
2746
+ }))
2747
+ };
2748
+ /**
2749
+ * Instructions: standing decisions that steer every build. The canned
2750
+ * GROQ read; writes are promise-based on `client.context`.
2751
+ */
2752
+ instructions = {
2753
+ /**
2754
+ * Every current-schema instruction on the knowledge base, oldest first.
2755
+ * Drains keyset pages internally and emits the complete set. Runs:
2756
+ *
2757
+ * `*[_type == "sanity.context.instruction" && knowledgeBaseId == $kb && schemaVersion == 1] | order(_createdAt asc, _id asc)`
2758
+ *
2759
+ * For anything more, use {@link fetch}. Requires `context.organizationId`
2760
+ * alongside the knowledge-base `resource` in the client configuration.
2761
+ */
2762
+ list: (options) => _observe(options?.signal, (signal) => _listInstructions(this.#client, this.#httpRequest, _resolveKnowledgeBaseId(this.#client), {
2763
+ ...options,
2764
+ signal
2765
+ })) };
2766
+ /**
2767
+ * MCP endpoint configurations, org-owned documents read with canned GROQ
2768
+ * queries. Requires `context.organizationId` in the client configuration.
2769
+ */
2770
+ mcpEndpoints = {
2771
+ /**
2772
+ * The organization's MCP endpoint configurations, oldest first. Runs:
2773
+ *
2774
+ * `*[_type == "sanity.context.mcp" && organizationId == $org] | order(_createdAt asc, _id asc) [0...500]`
2775
+ *
2776
+ * For anything more, use {@link fetch}.
2777
+ */
2778
+ list: (options) => _observe(options?.signal, (signal) => _listMcpEndpoints(this.#client, this.#httpRequest, {
2779
+ ...options,
2780
+ signal
2781
+ })),
2782
+ /**
2783
+ * One MCP endpoint configuration by its URL name, or `null` when none
2784
+ * carries that name. Runs:
2785
+ *
2786
+ * `*[_type == "sanity.context.mcp" && organizationId == $org && name == $name][0]`
2787
+ *
2788
+ * For anything more, use {@link fetch}.
2789
+ */
2790
+ get: (params, options) => _observe(options?.signal, (signal) => _readMcpEndpoint(this.#client, this.#httpRequest, params.name, {
2791
+ ...options,
2792
+ signal
2793
+ }))
2794
+ };
1984
2795
  };
1985
2796
  /**
1986
2797
  * A variant of share that takes a predicate function to determine which value to replay to new subscribers
@@ -2293,7 +3104,11 @@ function _modify(client, httpRequest, method, name, options) {
2293
3104
  });
2294
3105
  }
2295
3106
  /** Function resource types in a blueprint are namespaced under this prefix. */
2296
- const scopeHeaders = (config, request) => {
3107
+ const SYNC_INVOCABLE_FUNCTION_TYPES = ["sanity.function.pubsub"], ASYNC_INVOCABLE_FUNCTION_TYPES = [
3108
+ "sanity.function.durable",
3109
+ "sanity.function.pubsub",
3110
+ "sanity.function.queue"
3111
+ ], INVOCABLE_FUNCTION_TYPES = [.../* @__PURE__ */ new Set([...SYNC_INVOCABLE_FUNCTION_TYPES, ...ASYNC_INVOCABLE_FUNCTION_TYPES])], scopeHeaders = (config, request) => {
2297
3112
  let organizationId = request?.organizationId || config.organizationId;
2298
3113
  if (organizationId) return {
2299
3114
  "X-Sanity-Scope-Type": "organization",
@@ -2317,7 +3132,7 @@ const scopeHeaders = (config, request) => {
2317
3132
  *
2318
3133
  * @internal
2319
3134
  */
2320
- function _resolveFunctionId(client, httpRequest, functionName, stackId, headers, request) {
3135
+ function _resolveFunctionId(client, httpRequest, functionName, stackId, headers, request, sync) {
2321
3136
  return _requestObservable(client, httpRequest, {
2322
3137
  method: "GET",
2323
3138
  url: `/blueprints/stacks/${stackId}`,
@@ -2327,17 +3142,19 @@ function _resolveFunctionId(client, httpRequest, functionName, stackId, headers,
2327
3142
  let match = (stack?.resources || []).find((resource) => resource.type?.startsWith("sanity.function.") && resource.name === functionName);
2328
3143
  if (!match) throw Error(`Function "${functionName}" not found in stack "${stackId}"`);
2329
3144
  if (!match.externalId) throw Error(`Function "${functionName}" is declared in stack "${stackId}" but is not deployed`);
2330
- if (match.type !== "sanity.function.pubsub") throw Error(`Function invocation is not supported for ${match.type}`);
3145
+ if (!INVOCABLE_FUNCTION_TYPES.includes(match.type)) throw Error(`Function invocation is not supported for ${match.type}`);
3146
+ if (sync && !SYNC_INVOCABLE_FUNCTION_TYPES.includes(match.type)) throw Error(`Synchronous function invocation is not supported for ${match.type}`);
3147
+ if (!sync && !ASYNC_INVOCABLE_FUNCTION_TYPES.includes(match.type)) throw Error(`Asynchronous function invocation is not supported for ${match.type}`);
2331
3148
  return match.externalId;
2332
3149
  }));
2333
3150
  }
2334
3151
  /** @internal */
2335
- function _invoke(client, httpRequest, functionName, request) {
3152
+ function _invoke(client, httpRequest, functionName, request, options) {
2336
3153
  return defer(() => {
2337
- let config = client.config(), headers = scopeHeaders(config, request);
2338
- return _resolveFunctionId(client, httpRequest, functionName, resolveStackId(config, request), headers, request).pipe(mergeMap((functionId) => _requestObservable(client, httpRequest, {
3154
+ let config = client.config(), headers = scopeHeaders(config, request), stackId = resolveStackId(config, request), sync = options?.sync ?? !1;
3155
+ return _resolveFunctionId(client, httpRequest, functionName, stackId, headers, request, sync).pipe(mergeMap((functionId) => _requestObservable(client, httpRequest, {
2339
3156
  method: "POST",
2340
- url: `/functions/${functionId}/invoke`,
3157
+ url: `/functions/${functionId}/invoke${sync ? "?sync=true" : ""}`,
2341
3158
  headers,
2342
3159
  body: { event: { data: request?.event?.data ?? {} } },
2343
3160
  timeout: request?.timeout,
@@ -2352,17 +3169,8 @@ var ObservableFunctionsClient = class {
2352
3169
  constructor(client, httpRequest) {
2353
3170
  this.#client = client, this.#httpRequest = httpRequest;
2354
3171
  }
2355
- /**
2356
- * Invoke a deployed function by its blueprint name.
2357
- *
2358
- * The name is resolved within the stack given by `stackId` on the request or
2359
- * the client config. Passes the function's return value once it finishes.
2360
- *
2361
- * @param functionName - name of the function, as declared in the blueprint
2362
- * @param request - payload and request options
2363
- */
2364
- invoke(functionName, request) {
2365
- return _invoke(this.#client, this.#httpRequest, functionName, request);
3172
+ invoke(functionName, request, options) {
3173
+ return _invoke(this.#client, this.#httpRequest, functionName, request, options);
2366
3174
  }
2367
3175
  }, FunctionsClient = class {
2368
3176
  #client;
@@ -2370,26 +3178,8 @@ var ObservableFunctionsClient = class {
2370
3178
  constructor(client, httpRequest) {
2371
3179
  this.#client = client, this.#httpRequest = httpRequest;
2372
3180
  }
2373
- /**
2374
- * Invoke a deployed function by its blueprint name.
2375
- *
2376
- * The name is resolved within the stack given by `stackId` on the request or
2377
- * the client config, which costs one extra request per call. Rejects if the
2378
- * stack has no function by that name, or if the name resolves to anything
2379
- * other than a `sanity.function.pubsub` function.
2380
- *
2381
- * The lookup is scoped to `projectId`, or to `organizationId` when one is set
2382
- * for a stack deployed at organization scope.
2383
- *
2384
- * The request stays open until the function finishes, and resolves with its
2385
- * return value, or `undefined` if it returns nothing. Long-running functions
2386
- * may need an explicit `timeout`.
2387
- *
2388
- * @param functionName - name of the function, as declared in the blueprint
2389
- * @param request - payload and request options
2390
- */
2391
- invoke(functionName, request) {
2392
- return lastValueFrom(_invoke(this.#client, this.#httpRequest, functionName, request));
3181
+ invoke(functionName, request, options) {
3182
+ return lastValueFrom(_invoke(this.#client, this.#httpRequest, functionName, request, options));
2393
3183
  }
2394
3184
  }, ObservableMediaLibraryVideoClient = class {
2395
3185
  #client;
@@ -2537,7 +3327,19 @@ var ObservableProjectsClient = class {
2537
3327
  *
2538
3328
  * ~24 years (or 7.54e+8 seconds) needed, in order to have a 1% probability of at least one collision if 10 ID's are generated every hour.
2539
3329
  */
2540
- const generateReleaseId = customAlphabet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 8), getDocumentVersionId = (publishedId, releaseId) => releaseId ? getVersionId(publishedId, releaseId) : getDraftId(publishedId);
3330
+ function generateReleaseId() {
3331
+ let id = "";
3332
+ for (; id.length < 8;) {
3333
+ let bytes = crypto.getRandomValues(new Uint8Array(8 - id.length));
3334
+ for (let byte of bytes) {
3335
+ let index = byte & 63;
3336
+ index < 62 && (id += "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[index]);
3337
+ }
3338
+ }
3339
+ return id;
3340
+ }
3341
+ /** @internal */
3342
+ const getDocumentVersionId = (publishedId, releaseId) => releaseId ? getVersionId(publishedId, releaseId) : getDraftId(publishedId);
2541
3343
  /** @internal */
2542
3344
  function deriveDocumentVersionId(op, { releaseId, publishedId, document }) {
2543
3345
  if (publishedId && document._id) {
@@ -3050,6 +3852,8 @@ var ObservableReleasesClient = class {
3050
3852
  collaboration;
3051
3853
  functions;
3052
3854
  releases;
3855
+ /** @beta */
3856
+ context;
3053
3857
  /**
3054
3858
  * Private properties
3055
3859
  */
@@ -3058,9 +3862,9 @@ var ObservableReleasesClient = class {
3058
3862
  /**
3059
3863
  * Instance properties
3060
3864
  */
3061
- listen = _listen$1;
3865
+ listen = _listen$2;
3062
3866
  constructor(httpRequest, config = defaultConfig) {
3063
- 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.collaboration = { comments: new ObservableCollaborationCommentsClient(this, this.#httpRequest) }, this.functions = new ObservableFunctionsClient(this, this.#httpRequest), this.releases = new ObservableReleasesClient(this, this.#httpRequest);
3867
+ 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.collaboration = { comments: new ObservableCollaborationCommentsClient(this, this.#httpRequest) }, this.functions = new ObservableFunctionsClient(this, this.#httpRequest), this.releases = new ObservableReleasesClient(this, this.#httpRequest), this.context = new ObservableContextClient(this, this.#httpRequest);
3064
3868
  }
3065
3869
  /**
3066
3870
  * Clone the client - returns a new instance
@@ -3286,6 +4090,8 @@ var ObservableReleasesClient = class {
3286
4090
  collaboration;
3287
4091
  functions;
3288
4092
  releases;
4093
+ /** @beta */
4094
+ context;
3289
4095
  /**
3290
4096
  * Observable version of the Sanity client, with the same configuration as the promise-based one
3291
4097
  */
@@ -3298,9 +4104,9 @@ var ObservableReleasesClient = class {
3298
4104
  /**
3299
4105
  * Instance properties
3300
4106
  */
3301
- listen = _listen$1;
4107
+ listen = _listen$2;
3302
4108
  constructor(httpRequest, config = defaultConfig) {
3303
- 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.collaboration = { comments: new CollaborationCommentsClient(this, this.#httpRequest) }, this.functions = new FunctionsClient(this, this.#httpRequest), this.releases = new ReleasesClient(this, this.#httpRequest), this.observable = new ObservableSanityClient(httpRequest, config);
4109
+ 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.collaboration = { comments: new CollaborationCommentsClient(this, this.#httpRequest) }, this.functions = new FunctionsClient(this, this.#httpRequest), this.releases = new ReleasesClient(this, this.#httpRequest), this.context = new ContextClient(this, this.#httpRequest), this.observable = new ObservableSanityClient(httpRequest, config);
3304
4110
  }
3305
4111
  /**
3306
4112
  * Clone the client - returns a new instance
@@ -3330,7 +4136,7 @@ var ObservableReleasesClient = class {
3330
4136
  });
3331
4137
  }
3332
4138
  fetch(query, params, options) {
3333
- return _fetch$1(this, this.#httpRequest, this.#clientConfig.stega, query, params, options);
4139
+ return _fetch$2(this, this.#httpRequest, this.#clientConfig.stega, query, params, options);
3334
4140
  }
3335
4141
  getDocument(id, options) {
3336
4142
  if (options?.includeAllVersions === !0) return _getDocument(this, this.#httpRequest, id, {
@@ -3562,7 +4368,7 @@ function defineDeprecatedCreateClient(createClient) {
3562
4368
  return printNoDefaultExport(), createClient(config);
3563
4369
  };
3564
4370
  }
3565
- var name = "@sanity/client", version = "8.2.0";
4371
+ var name = "@sanity/client", version = "8.4.0";
3566
4372
  const log = createDebug("sanity:client");
3567
4373
  function isNodeReadableStream(value) {
3568
4374
  return typeof value != "object" || !value || !("pipe" in value) ? !1 : typeof value.pipe == "function";
@@ -3619,6 +4425,6 @@ const middleware = [
3619
4425
  middleware,
3620
4426
  resolveFetch
3621
4427
  }, SanityClient), requester = exp.requester, createClient = exp.createClient, deprecatedCreateClient = defineDeprecatedCreateClient(createClient);
3622
- 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 };
4428
+ export { BasePatch, BaseTransaction, ChannelError, ClientError, ConnectionFailedError, types_exports as Context, 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 };
3623
4429
 
3624
4430
  //# sourceMappingURL=index.node.js.map