@sanity/client 7.3.0 → 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 (53) hide show
  1. package/README.md +122 -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 +155 -32
  19. package/dist/index.browser.cjs.map +1 -1
  20. package/dist/index.browser.d.cts +473 -68
  21. package/dist/index.browser.d.ts +473 -68
  22. package/dist/index.browser.js +156 -33
  23. package/dist/index.browser.js.map +1 -1
  24. package/dist/index.cjs +157 -34
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +473 -68
  27. package/dist/index.d.ts +473 -68
  28. package/dist/index.js +157 -33
  29. package/dist/index.js.map +1 -1
  30. package/dist/stega.browser.d.cts +473 -68
  31. package/dist/stega.browser.d.ts +473 -68
  32. package/dist/stega.d.cts +473 -68
  33. package/dist/stega.d.ts +473 -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/types.ts +25 -10
  50. package/src/util/codeFrame.ts +174 -0
  51. package/src/{csm → util}/isRecord.ts +1 -1
  52. package/umd/sanityClient.js +158 -35
  53. 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)
@@ -875,6 +969,22 @@ function _generate(client, httpRequest, request) {
875
969
  body: request
876
970
  });
877
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
+ }
878
988
  function _transform(client, httpRequest, request) {
879
989
  const dataset2 = hasDataset(client.config());
880
990
  return _request(client, httpRequest, {
@@ -946,6 +1056,21 @@ class AgentActionsClient {
946
1056
  translate(request) {
947
1057
  return lastValueFrom(_translate(this.#client, this.#httpRequest, request));
948
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
+ }
949
1074
  }
950
1075
  class ObservableAssetsClient {
951
1076
  #client;
@@ -1052,13 +1177,11 @@ const MAX_URL_LENGTH = 14800, possibleOptions = [
1052
1177
  includeResult: !0
1053
1178
  };
1054
1179
  function _listen(query, params, opts = {}) {
1055
- 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)}`;
1056
1181
  if (uri.length > MAX_URL_LENGTH)
1057
1182
  return throwError(() => new Error("Query too large for listener"));
1058
1183
  const listenFor = options.events ? options.events : ["mutation"], esOptions = {};
1059
- return withCredentials && (esOptions.withCredentials = !0), token && (esOptions.headers = {
1060
- Authorization: `Bearer ${token}`
1061
- }), connectEventSource(() => (
1184
+ return withCredentials && (esOptions.withCredentials = !0), (token || configHeaders) && (esOptions.headers = {}, token && (esOptions.headers.Authorization = `Bearer ${token}`), configHeaders && Object.assign(esOptions.headers, configHeaders)), connectEventSource(() => (
1062
1185
  // use polyfill if there is no global EventSource or if we need to set headers
1063
1186
  (typeof EventSource > "u" || esOptions.headers ? eventSourcePolyfill : of(EventSource)).pipe(map((EventSource2) => new EventSource2(uri, esOptions)))
1064
1187
  ), listenFor).pipe(
@@ -1116,7 +1239,8 @@ class LiveClient {
1116
1239
  apiVersion: _apiVersion,
1117
1240
  token,
1118
1241
  withCredentials,
1119
- requestTagPrefix
1242
+ requestTagPrefix,
1243
+ headers: configHeaders
1120
1244
  } = this.#client.config(), apiVersion = _apiVersion.replace(/^v/, "");
1121
1245
  if (apiVersion !== "X" && apiVersion < requiredApiVersion)
1122
1246
  throw new Error(
@@ -1129,9 +1253,7 @@ class LiveClient {
1129
1253
  const path = _getDataUrl(this.#client, "live/events"), url = new URL(this.#client.getUrl(path, !1)), tag = _tag && requestTagPrefix ? [requestTagPrefix, _tag].join(".") : _tag;
1130
1254
  tag && url.searchParams.set("tag", tag), includeDrafts && url.searchParams.set("includeDrafts", "true");
1131
1255
  const esOptions = {};
1132
- includeDrafts && token && (esOptions.headers = {
1133
- Authorization: `Bearer ${token}`
1134
- }), 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));
1135
1257
  const key = `${url.href}::${JSON.stringify(esOptions)}`, existing = eventsCache.get(key);
1136
1258
  if (existing)
1137
1259
  return existing;
@@ -2388,7 +2510,7 @@ function defineDeprecatedCreateClient(createClient2) {
2388
2510
  return printNoDefaultExport(), createClient2(config);
2389
2511
  };
2390
2512
  }
2391
- var name = "@sanity/client", version = "7.3.0";
2513
+ var name = "@sanity/client", version = "7.4.0";
2392
2514
  const middleware = [
2393
2515
  debug({ verbose: !0, namespace: "sanity:client" }),
2394
2516
  headers({ "User-Agent": `${name} ${version}` }),
@@ -2426,6 +2548,8 @@ export {
2426
2548
  connectEventSource,
2427
2549
  createClient,
2428
2550
  deprecatedCreateClient as default,
2551
+ formatQueryParseError,
2552
+ isQueryParseError,
2429
2553
  requester,
2430
2554
  adapter as unstable__adapter,
2431
2555
  environment as unstable__environment,