@sanity/client 7.2.2 → 7.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 (54) hide show
  1. package/README.md +126 -1
  2. package/dist/_chunks-cjs/isRecord.cjs +6 -0
  3. package/dist/_chunks-cjs/isRecord.cjs.map +1 -0
  4. package/dist/_chunks-cjs/resolveEditInfo.cjs +3 -5
  5. package/dist/_chunks-cjs/resolveEditInfo.cjs.map +1 -1
  6. package/dist/_chunks-cjs/stegaClean.cjs +4 -0
  7. package/dist/_chunks-cjs/stegaClean.cjs.map +1 -1
  8. package/dist/_chunks-cjs/stegaEncodeSourceMap.cjs +2 -5
  9. package/dist/_chunks-cjs/stegaEncodeSourceMap.cjs.map +1 -1
  10. package/dist/_chunks-es/isRecord.js +7 -0
  11. package/dist/_chunks-es/isRecord.js.map +1 -0
  12. package/dist/_chunks-es/resolveEditInfo.js +1 -3
  13. package/dist/_chunks-es/resolveEditInfo.js.map +1 -1
  14. package/dist/_chunks-es/stegaClean.js +4 -0
  15. package/dist/_chunks-es/stegaClean.js.map +1 -1
  16. package/dist/_chunks-es/stegaEncodeSourceMap.js +1 -4
  17. package/dist/_chunks-es/stegaEncodeSourceMap.js.map +1 -1
  18. package/dist/index.browser.cjs +158 -33
  19. package/dist/index.browser.cjs.map +1 -1
  20. package/dist/index.browser.d.cts +485 -68
  21. package/dist/index.browser.d.ts +485 -68
  22. package/dist/index.browser.js +159 -34
  23. package/dist/index.browser.js.map +1 -1
  24. package/dist/index.cjs +160 -35
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +485 -68
  27. package/dist/index.d.ts +485 -68
  28. package/dist/index.js +160 -34
  29. package/dist/index.js.map +1 -1
  30. package/dist/stega.browser.d.cts +485 -68
  31. package/dist/stega.browser.d.ts +485 -68
  32. package/dist/stega.d.cts +485 -68
  33. package/dist/stega.d.ts +485 -68
  34. package/package.json +1 -1
  35. package/src/agent/actions/AgentActionsClient.ts +29 -2
  36. package/src/agent/actions/commonTypes.ts +57 -17
  37. package/src/agent/actions/generate.ts +36 -2
  38. package/src/agent/actions/patch.ts +136 -0
  39. package/src/agent/actions/prompt.ts +145 -0
  40. package/src/agent/actions/transform.ts +27 -4
  41. package/src/agent/actions/translate.ts +5 -2
  42. package/src/csm/walkMap.ts +1 -1
  43. package/src/data/eventsource.ts +16 -7
  44. package/src/data/listen.ts +10 -4
  45. package/src/data/live.ts +13 -5
  46. package/src/defineCreateClient.ts +7 -1
  47. package/src/http/errors.ts +92 -27
  48. package/src/http/request.ts +3 -3
  49. package/src/http/requestOptions.ts +4 -0
  50. package/src/types.ts +39 -10
  51. package/src/util/codeFrame.ts +174 -0
  52. package/src/{csm → util}/isRecord.ts +1 -1
  53. package/umd/sanityClient.js +161 -36
  54. package/umd/sanityClient.min.js +2 -2
package/dist/index.js CHANGED
@@ -2,18 +2,88 @@ import { getIt } from "get-it";
2
2
  import { adapter, environment } from "get-it";
3
3
  import { retry, jsonRequest, jsonResponse, progress, observable, debug, headers, agent } from "get-it/middleware";
4
4
  import { Observable, defer, of, isObservable, mergeMap, from, lastValueFrom, shareReplay, catchError, concat, throwError, timer, tap, finalize, share, merge, EMPTY, map as map$1, firstValueFrom } from "rxjs";
5
+ import { isRecord } from "./_chunks-es/isRecord.js";
5
6
  import { stegaClean } from "./_chunks-es/stegaClean.js";
6
7
  import { combineLatestWith, map, filter, finalize as finalize$1 } from "rxjs/operators";
7
8
  import { getVersionFromId, isDraftId, getVersionId, getDraftId, isVersionId, getPublishedId } from "@sanity/client/csm";
8
9
  import { customAlphabet } from "nanoid";
9
10
  import { validateObject, validateInsert, requireDocumentId, validateDocumentId, requireDocumentType, resourceConfig, hasDataset, requestTag, printPreviewDraftsDeprecationWarning, validateApiPerspective, printCdnPreviewDraftsWarning, validateAssetType, resourceGuard, dataset, validateVersionIdMatch, defaultConfig, initConfig, printNoDefaultExport } from "./_chunks-es/config.js";
11
+ const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
12
+ function codeFrame(query, location2, message) {
13
+ const lines = query.split(NEWLINE), loc = {
14
+ start: columnToLine(location2.start, lines),
15
+ end: location2.end ? columnToLine(location2.end, lines) : void 0
16
+ }, { start, end, markerLines } = getMarkerLines(loc, lines), numberMaxWidth = `${end}`.length;
17
+ return query.split(NEWLINE, end).slice(start, end).map((line, index) => {
18
+ const number = start + 1 + index, gutter = ` ${` ${number}`.slice(-numberMaxWidth)} |`, hasMarker = markerLines[number], lastMarkerLine = !markerLines[number + 1];
19
+ if (!hasMarker)
20
+ return ` ${gutter}${line.length > 0 ? ` ${line}` : ""}`;
21
+ let markerLine = "";
22
+ if (Array.isArray(hasMarker)) {
23
+ const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " "), numberOfMarkers = hasMarker[1] || 1;
24
+ markerLine = [
25
+ `
26
+ `,
27
+ gutter.replace(/\d/g, " "),
28
+ " ",
29
+ markerSpacing,
30
+ "^".repeat(numberOfMarkers)
31
+ ].join(""), lastMarkerLine && message && (markerLine += " " + message);
32
+ }
33
+ return [">", gutter, line.length > 0 ? ` ${line}` : "", markerLine].join("");
34
+ }).join(`
35
+ `);
36
+ }
37
+ function getMarkerLines(loc, source) {
38
+ const startLoc = { ...loc.start }, endLoc = { ...startLoc, ...loc.end }, linesAbove = 2, linesBelow = 3, startLine = startLoc.line ?? -1, startColumn = startLoc.column ?? 0, endLine = endLoc.line, endColumn = endLoc.column;
39
+ let start = Math.max(startLine - (linesAbove + 1), 0), end = Math.min(source.length, endLine + linesBelow);
40
+ startLine === -1 && (start = 0), endLine === -1 && (end = source.length);
41
+ const lineDiff = endLine - startLine, markerLines = {};
42
+ if (lineDiff)
43
+ for (let i = 0; i <= lineDiff; i++) {
44
+ const lineNumber = i + startLine;
45
+ if (!startColumn)
46
+ markerLines[lineNumber] = !0;
47
+ else if (i === 0) {
48
+ const sourceLength = source[lineNumber - 1].length;
49
+ markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1];
50
+ } else if (i === lineDiff)
51
+ markerLines[lineNumber] = [0, endColumn];
52
+ else {
53
+ const sourceLength = source[lineNumber - i].length;
54
+ markerLines[lineNumber] = [0, sourceLength];
55
+ }
56
+ }
57
+ else
58
+ startColumn === endColumn ? startColumn ? markerLines[startLine] = [startColumn, 0] : markerLines[startLine] = !0 : markerLines[startLine] = [startColumn, endColumn - startColumn];
59
+ return { start, end, markerLines };
60
+ }
61
+ function columnToLine(column, lines) {
62
+ let offset = 0;
63
+ for (let i = 0; i < lines.length; i++) {
64
+ const lineLength = lines[i].length + 1;
65
+ if (offset + lineLength > column)
66
+ return {
67
+ line: i + 1,
68
+ // 1-based line
69
+ column: column - offset
70
+ // 0-based column
71
+ };
72
+ offset += lineLength;
73
+ }
74
+ return {
75
+ line: lines.length,
76
+ column: lines[lines.length - 1]?.length ?? 0
77
+ };
78
+ }
79
+ const MAX_ITEMS_IN_ERROR_MESSAGE = 5;
10
80
  class ClientError extends Error {
11
81
  response;
12
82
  statusCode = 400;
13
83
  responseBody;
14
84
  details;
15
- constructor(res) {
16
- const props = extractErrorProps(res);
85
+ constructor(res, context) {
86
+ const props = extractErrorProps(res, context);
17
87
  super(props.message), Object.assign(this, props);
18
88
  }
19
89
  }
@@ -27,7 +97,7 @@ class ServerError extends Error {
27
97
  super(props.message), Object.assign(this, props);
28
98
  }
29
99
  }
30
- function extractErrorProps(res) {
100
+ function extractErrorProps(res, context) {
31
101
  const body = res.body, props = {
32
102
  response: res,
33
103
  statusCode: res.statusCode,
@@ -35,34 +105,56 @@ function extractErrorProps(res) {
35
105
  message: "",
36
106
  details: void 0
37
107
  };
38
- if (body.error && body.message)
39
- return props.message = `${body.error} - ${body.message}`, props;
40
- if (isMutationError(body) || isActionError(body)) {
41
- const allItems = body.error.items || [], items = allItems.slice(0, 5).map((item) => item.error?.description).filter(Boolean);
108
+ if (!isRecord(body))
109
+ return props.message = httpErrorMessage(res, body), props;
110
+ const error = body.error;
111
+ if (typeof error == "string" && typeof body.message == "string")
112
+ return props.message = `${error} - ${body.message}`, props;
113
+ if (typeof error != "object" || error === null)
114
+ return typeof error == "string" ? props.message = error : typeof body.message == "string" ? props.message = body.message : props.message = httpErrorMessage(res, body), props;
115
+ if (isMutationError(error) || isActionError(error)) {
116
+ const allItems = error.items || [], items = allItems.slice(0, MAX_ITEMS_IN_ERROR_MESSAGE).map((item) => item.error?.description).filter(Boolean);
42
117
  let itemsStr = items.length ? `:
43
118
  - ${items.join(`
44
119
  - `)}` : "";
45
- return allItems.length > 5 && (itemsStr += `
46
- ...and ${allItems.length - 5} more`), props.message = `${body.error.description}${itemsStr}`, props.details = body.error, props;
120
+ return allItems.length > MAX_ITEMS_IN_ERROR_MESSAGE && (itemsStr += `
121
+ ...and ${allItems.length - MAX_ITEMS_IN_ERROR_MESSAGE} more`), props.message = `${error.description}${itemsStr}`, props.details = body.error, props;
122
+ }
123
+ if (isQueryParseError(error)) {
124
+ const tag = context?.options?.query?.tag;
125
+ return props.message = formatQueryParseError(error, tag), props.details = body.error, props;
47
126
  }
48
- return body.error && body.error.description ? (props.message = body.error.description, props.details = body.error, props) : (props.message = body.error || body.message || httpErrorMessage(res), props);
127
+ return "description" in error && typeof error.description == "string" ? (props.message = error.description, props.details = error, props) : (props.message = httpErrorMessage(res, body), props);
49
128
  }
50
- function isMutationError(body) {
51
- return isPlainObject(body) && isPlainObject(body.error) && body.error.type === "mutationError" && typeof body.error.description == "string";
129
+ function isMutationError(error) {
130
+ return "type" in error && error.type === "mutationError" && "description" in error && typeof error.description == "string";
52
131
  }
53
- function isActionError(body) {
54
- return isPlainObject(body) && isPlainObject(body.error) && body.error.type === "actionError" && typeof body.error.description == "string";
132
+ function isActionError(error) {
133
+ return "type" in error && error.type === "actionError" && "description" in error && typeof error.description == "string";
55
134
  }
56
- function isPlainObject(obj) {
57
- return typeof obj == "object" && obj !== null && !Array.isArray(obj);
135
+ function isQueryParseError(error) {
136
+ return isRecord(error) && error.type === "queryParseError" && typeof error.query == "string" && typeof error.start == "number" && typeof error.end == "number";
58
137
  }
59
- function httpErrorMessage(res) {
60
- const statusMessage = res.statusMessage ? ` ${res.statusMessage}` : "";
61
- return `${res.method}-request to ${res.url} resulted in HTTP ${res.statusCode}${statusMessage}`;
138
+ function formatQueryParseError(error, tag) {
139
+ const { query, start, end, description } = error;
140
+ if (!query || typeof start > "u")
141
+ return `GROQ query parse error: ${description}`;
142
+ const withTag = tag ? `
143
+
144
+ Tag: ${tag}` : "";
145
+ return `GROQ query parse error:
146
+ ${codeFrame(query, { start, end }, description)}${withTag}`;
147
+ }
148
+ function httpErrorMessage(res, body) {
149
+ const details = typeof body == "string" ? ` (${sliceWithEllipsis(body, 100)})` : "", statusMessage = res.statusMessage ? ` ${res.statusMessage}` : "";
150
+ return `${res.method}-request to ${res.url} resulted in HTTP ${res.statusCode}${statusMessage}${details}`;
62
151
  }
63
152
  function stringifyBody(body, res) {
64
153
  return (res.headers["content-type"] || "").toLowerCase().indexOf("application/json") !== -1 ? JSON.stringify(body, null, 2) : body;
65
154
  }
155
+ function sliceWithEllipsis(str, max) {
156
+ return str.length > max ? `${str.slice(0, max)}\u2026` : str;
157
+ }
66
158
  class CorsOriginError extends Error {
67
159
  projectId;
68
160
  addOriginUrl;
@@ -77,11 +169,11 @@ class CorsOriginError extends Error {
77
169
  }
78
170
  }
79
171
  const httpError = {
80
- onResponse: (res) => {
172
+ onResponse: (res, context) => {
81
173
  if (res.statusCode >= 500)
82
174
  throw new ServerError(res);
83
175
  if (res.statusCode >= 400)
84
- throw new ClientError(res);
176
+ throw new ClientError(res, context);
85
177
  return res;
86
178
  }
87
179
  };
@@ -172,7 +264,8 @@ function connectWithESInstance(es, events) {
172
264
  return;
173
265
  }
174
266
  if (message.type === "channelError") {
175
- observer.error(new ChannelError(extractErrorMessage(event?.data), event.data));
267
+ const tag = new URL(es.url).searchParams.get("tag");
268
+ observer.error(new ChannelError(extractErrorMessage(event?.data, tag), event.data));
176
269
  return;
177
270
  }
178
271
  if (message.type === "disconnect") {
@@ -211,8 +304,9 @@ function parseEvent(message) {
211
304
  return [err, null];
212
305
  }
213
306
  }
214
- function extractErrorMessage(err) {
215
- return err.error ? err.error.description ? err.error.description : typeof err.error == "string" ? err.error : JSON.stringify(err.error, null, 2) : err.message || "Unknown listener error";
307
+ function extractErrorMessage(err, tag) {
308
+ const error = err.error;
309
+ 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";
216
310
  }
217
311
  function isEmptyObject(data) {
218
312
  for (const _ in data)
@@ -555,7 +649,9 @@ class ObservableTransaction extends BaseTransaction {
555
649
  }
556
650
  const projectHeader = "X-Sanity-Project-ID";
557
651
  function requestOptions(config, overrides = {}) {
558
- const headers2 = {}, token = overrides.token || config.token;
652
+ const headers2 = {};
653
+ config.headers && Object.assign(headers2, config.headers);
654
+ const token = overrides.token || config.token;
559
655
  token && (headers2.Authorization = `Bearer ${token}`), !overrides.useGlobalApi && !config.useProjectHostname && config.projectId && (headers2[projectHeader] = config.projectId);
560
656
  const withCredentials = !!(typeof overrides.withCredentials > "u" ? config.withCredentials : overrides.withCredentials), timeout = typeof overrides.timeout > "u" ? config.timeout : overrides.timeout;
561
657
  return Object.assign({}, overrides, {
@@ -873,6 +969,22 @@ function _generate(client, httpRequest, request) {
873
969
  body: request
874
970
  });
875
971
  }
972
+ function _patch(client, httpRequest, request) {
973
+ const dataset2 = hasDataset(client.config());
974
+ return _request(client, httpRequest, {
975
+ method: "POST",
976
+ uri: `/agent/action/patch/${dataset2}`,
977
+ body: request
978
+ });
979
+ }
980
+ function _prompt(client, httpRequest, request) {
981
+ const dataset2 = hasDataset(client.config());
982
+ return _request(client, httpRequest, {
983
+ method: "POST",
984
+ uri: `/agent/action/prompt/${dataset2}`,
985
+ body: request
986
+ });
987
+ }
876
988
  function _transform(client, httpRequest, request) {
877
989
  const dataset2 = hasDataset(client.config());
878
990
  return _request(client, httpRequest, {
@@ -944,6 +1056,21 @@ class AgentActionsClient {
944
1056
  translate(request) {
945
1057
  return lastValueFrom(_translate(this.#client, this.#httpRequest, request));
946
1058
  }
1059
+ /**
1060
+ * Run a raw instruction and return the result either as text or json
1061
+ * @param request - prompt request
1062
+ */
1063
+ prompt(request) {
1064
+ return lastValueFrom(_prompt(this.#client, this.#httpRequest, request));
1065
+ }
1066
+ /**
1067
+ * Patch a document using a schema aware API.
1068
+ * Does not use an LLM, but uses the schema to ensure paths and values matches the schema.
1069
+ * @param request - instruction request
1070
+ */
1071
+ patch(request) {
1072
+ return lastValueFrom(_patch(this.#client, this.#httpRequest, request));
1073
+ }
947
1074
  }
948
1075
  class ObservableAssetsClient {
949
1076
  #client;
@@ -1050,13 +1177,11 @@ const MAX_URL_LENGTH = 14800, possibleOptions = [
1050
1177
  includeResult: !0
1051
1178
  };
1052
1179
  function _listen(query, params, opts = {}) {
1053
- const { url, token, withCredentials, requestTagPrefix } = this.config(), tag = opts.tag && requestTagPrefix ? [requestTagPrefix, opts.tag].join(".") : opts.tag, options = { ...defaults(opts, defaultOptions), tag }, listenOpts = pick(options, possibleOptions), qs = encodeQueryString({ query, params, options: { tag, ...listenOpts } }), uri = `${url}${_getDataUrl(this, "listen", qs)}`;
1180
+ const { url, token, withCredentials, requestTagPrefix, headers: configHeaders } = this.config(), tag = opts.tag && requestTagPrefix ? [requestTagPrefix, opts.tag].join(".") : opts.tag, options = { ...defaults(opts, defaultOptions), tag }, listenOpts = pick(options, possibleOptions), qs = encodeQueryString({ query, params, options: { tag, ...listenOpts } }), uri = `${url}${_getDataUrl(this, "listen", qs)}`;
1054
1181
  if (uri.length > MAX_URL_LENGTH)
1055
1182
  return throwError(() => new Error("Query too large for listener"));
1056
1183
  const listenFor = options.events ? options.events : ["mutation"], esOptions = {};
1057
- return withCredentials && (esOptions.withCredentials = !0), token && (esOptions.headers = {
1058
- Authorization: `Bearer ${token}`
1059
- }), connectEventSource(() => (
1184
+ return withCredentials && (esOptions.withCredentials = !0), (token || configHeaders) && (esOptions.headers = {}, token && (esOptions.headers.Authorization = `Bearer ${token}`), configHeaders && Object.assign(esOptions.headers, configHeaders)), connectEventSource(() => (
1060
1185
  // use polyfill if there is no global EventSource or if we need to set headers
1061
1186
  (typeof EventSource > "u" || esOptions.headers ? eventSourcePolyfill : of(EventSource)).pipe(map((EventSource2) => new EventSource2(uri, esOptions)))
1062
1187
  ), listenFor).pipe(
@@ -1114,7 +1239,8 @@ class LiveClient {
1114
1239
  apiVersion: _apiVersion,
1115
1240
  token,
1116
1241
  withCredentials,
1117
- requestTagPrefix
1242
+ requestTagPrefix,
1243
+ headers: configHeaders
1118
1244
  } = this.#client.config(), apiVersion = _apiVersion.replace(/^v/, "");
1119
1245
  if (apiVersion !== "X" && apiVersion < requiredApiVersion)
1120
1246
  throw new Error(
@@ -1127,9 +1253,7 @@ class LiveClient {
1127
1253
  const path = _getDataUrl(this.#client, "live/events"), url = new URL(this.#client.getUrl(path, !1)), tag = _tag && requestTagPrefix ? [requestTagPrefix, _tag].join(".") : _tag;
1128
1254
  tag && url.searchParams.set("tag", tag), includeDrafts && url.searchParams.set("includeDrafts", "true");
1129
1255
  const esOptions = {};
1130
- includeDrafts && token && (esOptions.headers = {
1131
- Authorization: `Bearer ${token}`
1132
- }), includeDrafts && withCredentials && (esOptions.withCredentials = !0);
1256
+ includeDrafts && withCredentials && (esOptions.withCredentials = !0), (includeDrafts && token || configHeaders) && (esOptions.headers = {}, includeDrafts && token && (esOptions.headers.Authorization = `Bearer ${token}`), configHeaders && Object.assign(esOptions.headers, configHeaders));
1133
1257
  const key = `${url.href}::${JSON.stringify(esOptions)}`, existing = eventsCache.get(key);
1134
1258
  if (existing)
1135
1259
  return existing;
@@ -2386,7 +2510,7 @@ function defineDeprecatedCreateClient(createClient2) {
2386
2510
  return printNoDefaultExport(), createClient2(config);
2387
2511
  };
2388
2512
  }
2389
- var name = "@sanity/client", version = "7.2.2";
2513
+ var name = "@sanity/client", version = "7.4.0";
2390
2514
  const middleware = [
2391
2515
  debug({ verbose: !0, namespace: "sanity:client" }),
2392
2516
  headers({ "User-Agent": `${name} ${version}` }),
@@ -2424,6 +2548,8 @@ export {
2424
2548
  connectEventSource,
2425
2549
  createClient,
2426
2550
  deprecatedCreateClient as default,
2551
+ formatQueryParseError,
2552
+ isQueryParseError,
2427
2553
  requester,
2428
2554
  adapter as unstable__adapter,
2429
2555
  environment as unstable__environment,