@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.cjs CHANGED
@@ -19,14 +19,83 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
19
19
  mod
20
20
  ));
21
21
  Object.defineProperty(exports, "__esModule", { value: !0 });
22
- var getIt = require("get-it"), middleware$1 = require("get-it/middleware"), rxjs = require("rxjs"), stegaClean = require("./_chunks-cjs/stegaClean.cjs"), operators = require("rxjs/operators"), csm = require("@sanity/client/csm"), nanoid = require("nanoid"), config = require("./_chunks-cjs/config.cjs");
22
+ var getIt = require("get-it"), middleware$1 = require("get-it/middleware"), rxjs = require("rxjs"), isRecord = require("./_chunks-cjs/isRecord.cjs"), stegaClean = require("./_chunks-cjs/stegaClean.cjs"), operators = require("rxjs/operators"), csm = require("@sanity/client/csm"), nanoid = require("nanoid"), config = require("./_chunks-cjs/config.cjs");
23
+ const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
24
+ function codeFrame(query, location2, message) {
25
+ const lines = query.split(NEWLINE), loc = {
26
+ start: columnToLine(location2.start, lines),
27
+ end: location2.end ? columnToLine(location2.end, lines) : void 0
28
+ }, { start, end, markerLines } = getMarkerLines(loc, lines), numberMaxWidth = `${end}`.length;
29
+ return query.split(NEWLINE, end).slice(start, end).map((line, index) => {
30
+ const number = start + 1 + index, gutter = ` ${` ${number}`.slice(-numberMaxWidth)} |`, hasMarker = markerLines[number], lastMarkerLine = !markerLines[number + 1];
31
+ if (!hasMarker)
32
+ return ` ${gutter}${line.length > 0 ? ` ${line}` : ""}`;
33
+ let markerLine = "";
34
+ if (Array.isArray(hasMarker)) {
35
+ const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " "), numberOfMarkers = hasMarker[1] || 1;
36
+ markerLine = [
37
+ `
38
+ `,
39
+ gutter.replace(/\d/g, " "),
40
+ " ",
41
+ markerSpacing,
42
+ "^".repeat(numberOfMarkers)
43
+ ].join(""), lastMarkerLine && message && (markerLine += " " + message);
44
+ }
45
+ return [">", gutter, line.length > 0 ? ` ${line}` : "", markerLine].join("");
46
+ }).join(`
47
+ `);
48
+ }
49
+ function getMarkerLines(loc, source) {
50
+ 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;
51
+ let start = Math.max(startLine - (linesAbove + 1), 0), end = Math.min(source.length, endLine + linesBelow);
52
+ startLine === -1 && (start = 0), endLine === -1 && (end = source.length);
53
+ const lineDiff = endLine - startLine, markerLines = {};
54
+ if (lineDiff)
55
+ for (let i = 0; i <= lineDiff; i++) {
56
+ const lineNumber = i + startLine;
57
+ if (!startColumn)
58
+ markerLines[lineNumber] = !0;
59
+ else if (i === 0) {
60
+ const sourceLength = source[lineNumber - 1].length;
61
+ markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1];
62
+ } else if (i === lineDiff)
63
+ markerLines[lineNumber] = [0, endColumn];
64
+ else {
65
+ const sourceLength = source[lineNumber - i].length;
66
+ markerLines[lineNumber] = [0, sourceLength];
67
+ }
68
+ }
69
+ else
70
+ startColumn === endColumn ? startColumn ? markerLines[startLine] = [startColumn, 0] : markerLines[startLine] = !0 : markerLines[startLine] = [startColumn, endColumn - startColumn];
71
+ return { start, end, markerLines };
72
+ }
73
+ function columnToLine(column, lines) {
74
+ let offset = 0;
75
+ for (let i = 0; i < lines.length; i++) {
76
+ const lineLength = lines[i].length + 1;
77
+ if (offset + lineLength > column)
78
+ return {
79
+ line: i + 1,
80
+ // 1-based line
81
+ column: column - offset
82
+ // 0-based column
83
+ };
84
+ offset += lineLength;
85
+ }
86
+ return {
87
+ line: lines.length,
88
+ column: lines[lines.length - 1]?.length ?? 0
89
+ };
90
+ }
91
+ const MAX_ITEMS_IN_ERROR_MESSAGE = 5;
23
92
  class ClientError extends Error {
24
93
  response;
25
94
  statusCode = 400;
26
95
  responseBody;
27
96
  details;
28
- constructor(res) {
29
- const props = extractErrorProps(res);
97
+ constructor(res, context) {
98
+ const props = extractErrorProps(res, context);
30
99
  super(props.message), Object.assign(this, props);
31
100
  }
32
101
  }
@@ -40,7 +109,7 @@ class ServerError extends Error {
40
109
  super(props.message), Object.assign(this, props);
41
110
  }
42
111
  }
43
- function extractErrorProps(res) {
112
+ function extractErrorProps(res, context) {
44
113
  const body = res.body, props = {
45
114
  response: res,
46
115
  statusCode: res.statusCode,
@@ -48,34 +117,56 @@ function extractErrorProps(res) {
48
117
  message: "",
49
118
  details: void 0
50
119
  };
51
- if (body.error && body.message)
52
- return props.message = `${body.error} - ${body.message}`, props;
53
- if (isMutationError(body) || isActionError(body)) {
54
- const allItems = body.error.items || [], items = allItems.slice(0, 5).map((item) => item.error?.description).filter(Boolean);
120
+ if (!isRecord.isRecord(body))
121
+ return props.message = httpErrorMessage(res, body), props;
122
+ const error = body.error;
123
+ if (typeof error == "string" && typeof body.message == "string")
124
+ return props.message = `${error} - ${body.message}`, props;
125
+ if (typeof error != "object" || error === null)
126
+ return typeof error == "string" ? props.message = error : typeof body.message == "string" ? props.message = body.message : props.message = httpErrorMessage(res, body), props;
127
+ if (isMutationError(error) || isActionError(error)) {
128
+ const allItems = error.items || [], items = allItems.slice(0, MAX_ITEMS_IN_ERROR_MESSAGE).map((item) => item.error?.description).filter(Boolean);
55
129
  let itemsStr = items.length ? `:
56
130
  - ${items.join(`
57
131
  - `)}` : "";
58
- return allItems.length > 5 && (itemsStr += `
59
- ...and ${allItems.length - 5} more`), props.message = `${body.error.description}${itemsStr}`, props.details = body.error, props;
132
+ return allItems.length > MAX_ITEMS_IN_ERROR_MESSAGE && (itemsStr += `
133
+ ...and ${allItems.length - MAX_ITEMS_IN_ERROR_MESSAGE} more`), props.message = `${error.description}${itemsStr}`, props.details = body.error, props;
134
+ }
135
+ if (isQueryParseError(error)) {
136
+ const tag = context?.options?.query?.tag;
137
+ return props.message = formatQueryParseError(error, tag), props.details = body.error, props;
60
138
  }
61
- 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);
139
+ return "description" in error && typeof error.description == "string" ? (props.message = error.description, props.details = error, props) : (props.message = httpErrorMessage(res, body), props);
62
140
  }
63
- function isMutationError(body) {
64
- return isPlainObject(body) && isPlainObject(body.error) && body.error.type === "mutationError" && typeof body.error.description == "string";
141
+ function isMutationError(error) {
142
+ return "type" in error && error.type === "mutationError" && "description" in error && typeof error.description == "string";
65
143
  }
66
- function isActionError(body) {
67
- return isPlainObject(body) && isPlainObject(body.error) && body.error.type === "actionError" && typeof body.error.description == "string";
144
+ function isActionError(error) {
145
+ return "type" in error && error.type === "actionError" && "description" in error && typeof error.description == "string";
68
146
  }
69
- function isPlainObject(obj) {
70
- return typeof obj == "object" && obj !== null && !Array.isArray(obj);
147
+ function isQueryParseError(error) {
148
+ return isRecord.isRecord(error) && error.type === "queryParseError" && typeof error.query == "string" && typeof error.start == "number" && typeof error.end == "number";
71
149
  }
72
- function httpErrorMessage(res) {
73
- const statusMessage = res.statusMessage ? ` ${res.statusMessage}` : "";
74
- return `${res.method}-request to ${res.url} resulted in HTTP ${res.statusCode}${statusMessage}`;
150
+ function formatQueryParseError(error, tag) {
151
+ const { query, start, end, description } = error;
152
+ if (!query || typeof start > "u")
153
+ return `GROQ query parse error: ${description}`;
154
+ const withTag = tag ? `
155
+
156
+ Tag: ${tag}` : "";
157
+ return `GROQ query parse error:
158
+ ${codeFrame(query, { start, end }, description)}${withTag}`;
159
+ }
160
+ function httpErrorMessage(res, body) {
161
+ const details = typeof body == "string" ? ` (${sliceWithEllipsis(body, 100)})` : "", statusMessage = res.statusMessage ? ` ${res.statusMessage}` : "";
162
+ return `${res.method}-request to ${res.url} resulted in HTTP ${res.statusCode}${statusMessage}${details}`;
75
163
  }
76
164
  function stringifyBody(body, res) {
77
165
  return (res.headers["content-type"] || "").toLowerCase().indexOf("application/json") !== -1 ? JSON.stringify(body, null, 2) : body;
78
166
  }
167
+ function sliceWithEllipsis(str, max) {
168
+ return str.length > max ? `${str.slice(0, max)}\u2026` : str;
169
+ }
79
170
  class CorsOriginError extends Error {
80
171
  projectId;
81
172
  addOriginUrl;
@@ -90,11 +181,11 @@ class CorsOriginError extends Error {
90
181
  }
91
182
  }
92
183
  const httpError = {
93
- onResponse: (res) => {
184
+ onResponse: (res, context) => {
94
185
  if (res.statusCode >= 500)
95
186
  throw new ServerError(res);
96
187
  if (res.statusCode >= 400)
97
- throw new ClientError(res);
188
+ throw new ClientError(res, context);
98
189
  return res;
99
190
  }
100
191
  };
@@ -185,7 +276,8 @@ function connectWithESInstance(es, events) {
185
276
  return;
186
277
  }
187
278
  if (message.type === "channelError") {
188
- observer.error(new ChannelError(extractErrorMessage(event?.data), event.data));
279
+ const tag = new URL(es.url).searchParams.get("tag");
280
+ observer.error(new ChannelError(extractErrorMessage(event?.data, tag), event.data));
189
281
  return;
190
282
  }
191
283
  if (message.type === "disconnect") {
@@ -224,8 +316,9 @@ function parseEvent(message) {
224
316
  return [err, null];
225
317
  }
226
318
  }
227
- function extractErrorMessage(err) {
228
- 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";
319
+ function extractErrorMessage(err, tag) {
320
+ const error = err.error;
321
+ 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";
229
322
  }
230
323
  function isEmptyObject(data) {
231
324
  for (const _ in data)
@@ -890,6 +983,22 @@ function _generate(client, httpRequest, request) {
890
983
  body: request
891
984
  });
892
985
  }
986
+ function _patch(client, httpRequest, request) {
987
+ const dataset = config.hasDataset(client.config());
988
+ return _request(client, httpRequest, {
989
+ method: "POST",
990
+ uri: `/agent/action/patch/${dataset}`,
991
+ body: request
992
+ });
993
+ }
994
+ function _prompt(client, httpRequest, request) {
995
+ const dataset = config.hasDataset(client.config());
996
+ return _request(client, httpRequest, {
997
+ method: "POST",
998
+ uri: `/agent/action/prompt/${dataset}`,
999
+ body: request
1000
+ });
1001
+ }
893
1002
  function _transform(client, httpRequest, request) {
894
1003
  const dataset = config.hasDataset(client.config());
895
1004
  return _request(client, httpRequest, {
@@ -961,6 +1070,21 @@ class AgentActionsClient {
961
1070
  translate(request) {
962
1071
  return rxjs.lastValueFrom(_translate(this.#client, this.#httpRequest, request));
963
1072
  }
1073
+ /**
1074
+ * Run a raw instruction and return the result either as text or json
1075
+ * @param request - prompt request
1076
+ */
1077
+ prompt(request) {
1078
+ return rxjs.lastValueFrom(_prompt(this.#client, this.#httpRequest, request));
1079
+ }
1080
+ /**
1081
+ * Patch a document using a schema aware API.
1082
+ * Does not use an LLM, but uses the schema to ensure paths and values matches the schema.
1083
+ * @param request - instruction request
1084
+ */
1085
+ patch(request) {
1086
+ return rxjs.lastValueFrom(_patch(this.#client, this.#httpRequest, request));
1087
+ }
964
1088
  }
965
1089
  class ObservableAssetsClient {
966
1090
  #client;
@@ -1067,13 +1191,11 @@ const MAX_URL_LENGTH = 14800, possibleOptions = [
1067
1191
  includeResult: !0
1068
1192
  };
1069
1193
  function _listen(query, params, opts = {}) {
1070
- 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)}`;
1194
+ 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)}`;
1071
1195
  if (uri.length > MAX_URL_LENGTH)
1072
1196
  return rxjs.throwError(() => new Error("Query too large for listener"));
1073
1197
  const listenFor = options.events ? options.events : ["mutation"], esOptions = {};
1074
- return withCredentials && (esOptions.withCredentials = !0), token && (esOptions.headers = {
1075
- Authorization: `Bearer ${token}`
1076
- }), connectEventSource(() => (
1198
+ return withCredentials && (esOptions.withCredentials = !0), (token || configHeaders) && (esOptions.headers = {}, token && (esOptions.headers.Authorization = `Bearer ${token}`), configHeaders && Object.assign(esOptions.headers, configHeaders)), connectEventSource(() => (
1077
1199
  // use polyfill if there is no global EventSource or if we need to set headers
1078
1200
  (typeof EventSource > "u" || esOptions.headers ? eventSourcePolyfill : rxjs.of(EventSource)).pipe(operators.map((EventSource2) => new EventSource2(uri, esOptions)))
1079
1201
  ), listenFor).pipe(
@@ -1131,7 +1253,8 @@ class LiveClient {
1131
1253
  apiVersion: _apiVersion,
1132
1254
  token,
1133
1255
  withCredentials,
1134
- requestTagPrefix
1256
+ requestTagPrefix,
1257
+ headers: configHeaders
1135
1258
  } = this.#client.config(), apiVersion = _apiVersion.replace(/^v/, "");
1136
1259
  if (apiVersion !== "X" && apiVersion < requiredApiVersion)
1137
1260
  throw new Error(
@@ -1144,9 +1267,7 @@ class LiveClient {
1144
1267
  const path = _getDataUrl(this.#client, "live/events"), url = new URL(this.#client.getUrl(path, !1)), tag = _tag && requestTagPrefix ? [requestTagPrefix, _tag].join(".") : _tag;
1145
1268
  tag && url.searchParams.set("tag", tag), includeDrafts && url.searchParams.set("includeDrafts", "true");
1146
1269
  const esOptions = {};
1147
- includeDrafts && token && (esOptions.headers = {
1148
- Authorization: `Bearer ${token}`
1149
- }), includeDrafts && withCredentials && (esOptions.withCredentials = !0);
1270
+ includeDrafts && withCredentials && (esOptions.withCredentials = !0), (includeDrafts && token || configHeaders) && (esOptions.headers = {}, includeDrafts && token && (esOptions.headers.Authorization = `Bearer ${token}`), configHeaders && Object.assign(esOptions.headers, configHeaders));
1150
1271
  const key = `${url.href}::${JSON.stringify(esOptions)}`, existing = eventsCache.get(key);
1151
1272
  if (existing)
1152
1273
  return existing;
@@ -2403,7 +2524,7 @@ function defineDeprecatedCreateClient(createClient2) {
2403
2524
  return config.printNoDefaultExport(), createClient2(config$1);
2404
2525
  };
2405
2526
  }
2406
- var name = "@sanity/client", version = "7.3.0";
2527
+ var name = "@sanity/client", version = "7.4.0";
2407
2528
  const middleware = [
2408
2529
  middleware$1.debug({ verbose: !0, namespace: "sanity:client" }),
2409
2530
  middleware$1.headers({ "User-Agent": `${name} ${version}` }),
@@ -2453,5 +2574,7 @@ exports.Transaction = Transaction;
2453
2574
  exports.connectEventSource = connectEventSource;
2454
2575
  exports.createClient = createClient;
2455
2576
  exports.default = deprecatedCreateClient;
2577
+ exports.formatQueryParseError = formatQueryParseError;
2578
+ exports.isQueryParseError = isQueryParseError;
2456
2579
  exports.requester = requester;
2457
2580
  //# sourceMappingURL=index.cjs.map