@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.
- package/README.md +126 -1
- package/dist/_chunks-cjs/isRecord.cjs +6 -0
- package/dist/_chunks-cjs/isRecord.cjs.map +1 -0
- package/dist/_chunks-cjs/resolveEditInfo.cjs +3 -5
- package/dist/_chunks-cjs/resolveEditInfo.cjs.map +1 -1
- package/dist/_chunks-cjs/stegaClean.cjs +4 -0
- package/dist/_chunks-cjs/stegaClean.cjs.map +1 -1
- package/dist/_chunks-cjs/stegaEncodeSourceMap.cjs +2 -5
- package/dist/_chunks-cjs/stegaEncodeSourceMap.cjs.map +1 -1
- package/dist/_chunks-es/isRecord.js +7 -0
- package/dist/_chunks-es/isRecord.js.map +1 -0
- package/dist/_chunks-es/resolveEditInfo.js +1 -3
- package/dist/_chunks-es/resolveEditInfo.js.map +1 -1
- package/dist/_chunks-es/stegaClean.js +4 -0
- package/dist/_chunks-es/stegaClean.js.map +1 -1
- package/dist/_chunks-es/stegaEncodeSourceMap.js +1 -4
- package/dist/_chunks-es/stegaEncodeSourceMap.js.map +1 -1
- package/dist/index.browser.cjs +158 -33
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.d.cts +485 -68
- package/dist/index.browser.d.ts +485 -68
- package/dist/index.browser.js +159 -34
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cjs +160 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +485 -68
- package/dist/index.d.ts +485 -68
- package/dist/index.js +160 -34
- package/dist/index.js.map +1 -1
- package/dist/stega.browser.d.cts +485 -68
- package/dist/stega.browser.d.ts +485 -68
- package/dist/stega.d.cts +485 -68
- package/dist/stega.d.ts +485 -68
- package/package.json +1 -1
- package/src/agent/actions/AgentActionsClient.ts +29 -2
- package/src/agent/actions/commonTypes.ts +57 -17
- package/src/agent/actions/generate.ts +36 -2
- package/src/agent/actions/patch.ts +136 -0
- package/src/agent/actions/prompt.ts +145 -0
- package/src/agent/actions/transform.ts +27 -4
- package/src/agent/actions/translate.ts +5 -2
- package/src/csm/walkMap.ts +1 -1
- package/src/data/eventsource.ts +16 -7
- package/src/data/listen.ts +10 -4
- package/src/data/live.ts +13 -5
- package/src/defineCreateClient.ts +7 -1
- package/src/http/errors.ts +92 -27
- package/src/http/request.ts +3 -3
- package/src/http/requestOptions.ts +4 -0
- package/src/types.ts +39 -10
- package/src/util/codeFrame.ts +174 -0
- package/src/{csm → util}/isRecord.ts +1 -1
- package/umd/sanityClient.js +161 -36
- package/umd/sanityClient.min.js +2 -2
package/dist/index.browser.js
CHANGED
|
@@ -2,17 +2,86 @@ import { getIt } from "get-it";
|
|
|
2
2
|
import { adapter, environment } from "get-it";
|
|
3
3
|
import { retry, jsonRequest, jsonResponse, progress, observable } 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 { stegaClean } from "./_chunks-es/stegaClean.js";
|
|
5
|
+
import { isRecord, stegaClean } from "./_chunks-es/stegaClean.js";
|
|
6
6
|
import { combineLatestWith, map, filter, finalize as finalize$1 } from "rxjs/operators";
|
|
7
7
|
import { getVersionFromId, isDraftId, getVersionId, getDraftId, isVersionId, getPublishedId } from "@sanity/client/csm";
|
|
8
8
|
import { customAlphabet } from "nanoid";
|
|
9
|
+
const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
|
|
10
|
+
function codeFrame(query, location2, message) {
|
|
11
|
+
const lines = query.split(NEWLINE), loc = {
|
|
12
|
+
start: columnToLine(location2.start, lines),
|
|
13
|
+
end: location2.end ? columnToLine(location2.end, lines) : void 0
|
|
14
|
+
}, { start, end, markerLines } = getMarkerLines(loc, lines), numberMaxWidth = `${end}`.length;
|
|
15
|
+
return query.split(NEWLINE, end).slice(start, end).map((line, index) => {
|
|
16
|
+
const number = start + 1 + index, gutter = ` ${` ${number}`.slice(-numberMaxWidth)} |`, hasMarker = markerLines[number], lastMarkerLine = !markerLines[number + 1];
|
|
17
|
+
if (!hasMarker)
|
|
18
|
+
return ` ${gutter}${line.length > 0 ? ` ${line}` : ""}`;
|
|
19
|
+
let markerLine = "";
|
|
20
|
+
if (Array.isArray(hasMarker)) {
|
|
21
|
+
const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " "), numberOfMarkers = hasMarker[1] || 1;
|
|
22
|
+
markerLine = [
|
|
23
|
+
`
|
|
24
|
+
`,
|
|
25
|
+
gutter.replace(/\d/g, " "),
|
|
26
|
+
" ",
|
|
27
|
+
markerSpacing,
|
|
28
|
+
"^".repeat(numberOfMarkers)
|
|
29
|
+
].join(""), lastMarkerLine && message && (markerLine += " " + message);
|
|
30
|
+
}
|
|
31
|
+
return [">", gutter, line.length > 0 ? ` ${line}` : "", markerLine].join("");
|
|
32
|
+
}).join(`
|
|
33
|
+
`);
|
|
34
|
+
}
|
|
35
|
+
function getMarkerLines(loc, source) {
|
|
36
|
+
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;
|
|
37
|
+
let start = Math.max(startLine - (linesAbove + 1), 0), end = Math.min(source.length, endLine + linesBelow);
|
|
38
|
+
startLine === -1 && (start = 0), endLine === -1 && (end = source.length);
|
|
39
|
+
const lineDiff = endLine - startLine, markerLines = {};
|
|
40
|
+
if (lineDiff)
|
|
41
|
+
for (let i = 0; i <= lineDiff; i++) {
|
|
42
|
+
const lineNumber = i + startLine;
|
|
43
|
+
if (!startColumn)
|
|
44
|
+
markerLines[lineNumber] = !0;
|
|
45
|
+
else if (i === 0) {
|
|
46
|
+
const sourceLength = source[lineNumber - 1].length;
|
|
47
|
+
markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1];
|
|
48
|
+
} else if (i === lineDiff)
|
|
49
|
+
markerLines[lineNumber] = [0, endColumn];
|
|
50
|
+
else {
|
|
51
|
+
const sourceLength = source[lineNumber - i].length;
|
|
52
|
+
markerLines[lineNumber] = [0, sourceLength];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else
|
|
56
|
+
startColumn === endColumn ? startColumn ? markerLines[startLine] = [startColumn, 0] : markerLines[startLine] = !0 : markerLines[startLine] = [startColumn, endColumn - startColumn];
|
|
57
|
+
return { start, end, markerLines };
|
|
58
|
+
}
|
|
59
|
+
function columnToLine(column, lines) {
|
|
60
|
+
let offset = 0;
|
|
61
|
+
for (let i = 0; i < lines.length; i++) {
|
|
62
|
+
const lineLength = lines[i].length + 1;
|
|
63
|
+
if (offset + lineLength > column)
|
|
64
|
+
return {
|
|
65
|
+
line: i + 1,
|
|
66
|
+
// 1-based line
|
|
67
|
+
column: column - offset
|
|
68
|
+
// 0-based column
|
|
69
|
+
};
|
|
70
|
+
offset += lineLength;
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
line: lines.length,
|
|
74
|
+
column: lines[lines.length - 1]?.length ?? 0
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const MAX_ITEMS_IN_ERROR_MESSAGE = 5;
|
|
9
78
|
class ClientError extends Error {
|
|
10
79
|
response;
|
|
11
80
|
statusCode = 400;
|
|
12
81
|
responseBody;
|
|
13
82
|
details;
|
|
14
|
-
constructor(res) {
|
|
15
|
-
const props = extractErrorProps(res);
|
|
83
|
+
constructor(res, context) {
|
|
84
|
+
const props = extractErrorProps(res, context);
|
|
16
85
|
super(props.message), Object.assign(this, props);
|
|
17
86
|
}
|
|
18
87
|
}
|
|
@@ -26,7 +95,7 @@ class ServerError extends Error {
|
|
|
26
95
|
super(props.message), Object.assign(this, props);
|
|
27
96
|
}
|
|
28
97
|
}
|
|
29
|
-
function extractErrorProps(res) {
|
|
98
|
+
function extractErrorProps(res, context) {
|
|
30
99
|
const body = res.body, props = {
|
|
31
100
|
response: res,
|
|
32
101
|
statusCode: res.statusCode,
|
|
@@ -34,34 +103,56 @@ function extractErrorProps(res) {
|
|
|
34
103
|
message: "",
|
|
35
104
|
details: void 0
|
|
36
105
|
};
|
|
37
|
-
if (body
|
|
38
|
-
return props.message =
|
|
39
|
-
|
|
40
|
-
|
|
106
|
+
if (!isRecord(body))
|
|
107
|
+
return props.message = httpErrorMessage(res, body), props;
|
|
108
|
+
const error = body.error;
|
|
109
|
+
if (typeof error == "string" && typeof body.message == "string")
|
|
110
|
+
return props.message = `${error} - ${body.message}`, props;
|
|
111
|
+
if (typeof error != "object" || error === null)
|
|
112
|
+
return typeof error == "string" ? props.message = error : typeof body.message == "string" ? props.message = body.message : props.message = httpErrorMessage(res, body), props;
|
|
113
|
+
if (isMutationError(error) || isActionError(error)) {
|
|
114
|
+
const allItems = error.items || [], items = allItems.slice(0, MAX_ITEMS_IN_ERROR_MESSAGE).map((item) => item.error?.description).filter(Boolean);
|
|
41
115
|
let itemsStr = items.length ? `:
|
|
42
116
|
- ${items.join(`
|
|
43
117
|
- `)}` : "";
|
|
44
|
-
return allItems.length >
|
|
45
|
-
...and ${allItems.length -
|
|
118
|
+
return allItems.length > MAX_ITEMS_IN_ERROR_MESSAGE && (itemsStr += `
|
|
119
|
+
...and ${allItems.length - MAX_ITEMS_IN_ERROR_MESSAGE} more`), props.message = `${error.description}${itemsStr}`, props.details = body.error, props;
|
|
120
|
+
}
|
|
121
|
+
if (isQueryParseError(error)) {
|
|
122
|
+
const tag = context?.options?.query?.tag;
|
|
123
|
+
return props.message = formatQueryParseError(error, tag), props.details = body.error, props;
|
|
46
124
|
}
|
|
47
|
-
return
|
|
125
|
+
return "description" in error && typeof error.description == "string" ? (props.message = error.description, props.details = error, props) : (props.message = httpErrorMessage(res, body), props);
|
|
48
126
|
}
|
|
49
|
-
function isMutationError(
|
|
50
|
-
return
|
|
127
|
+
function isMutationError(error) {
|
|
128
|
+
return "type" in error && error.type === "mutationError" && "description" in error && typeof error.description == "string";
|
|
51
129
|
}
|
|
52
|
-
function isActionError(
|
|
53
|
-
return
|
|
130
|
+
function isActionError(error) {
|
|
131
|
+
return "type" in error && error.type === "actionError" && "description" in error && typeof error.description == "string";
|
|
54
132
|
}
|
|
55
|
-
function
|
|
56
|
-
return typeof
|
|
133
|
+
function isQueryParseError(error) {
|
|
134
|
+
return isRecord(error) && error.type === "queryParseError" && typeof error.query == "string" && typeof error.start == "number" && typeof error.end == "number";
|
|
57
135
|
}
|
|
58
|
-
function
|
|
59
|
-
const
|
|
60
|
-
|
|
136
|
+
function formatQueryParseError(error, tag) {
|
|
137
|
+
const { query, start, end, description } = error;
|
|
138
|
+
if (!query || typeof start > "u")
|
|
139
|
+
return `GROQ query parse error: ${description}`;
|
|
140
|
+
const withTag = tag ? `
|
|
141
|
+
|
|
142
|
+
Tag: ${tag}` : "";
|
|
143
|
+
return `GROQ query parse error:
|
|
144
|
+
${codeFrame(query, { start, end }, description)}${withTag}`;
|
|
145
|
+
}
|
|
146
|
+
function httpErrorMessage(res, body) {
|
|
147
|
+
const details = typeof body == "string" ? ` (${sliceWithEllipsis(body, 100)})` : "", statusMessage = res.statusMessage ? ` ${res.statusMessage}` : "";
|
|
148
|
+
return `${res.method}-request to ${res.url} resulted in HTTP ${res.statusCode}${statusMessage}${details}`;
|
|
61
149
|
}
|
|
62
150
|
function stringifyBody(body, res) {
|
|
63
151
|
return (res.headers["content-type"] || "").toLowerCase().indexOf("application/json") !== -1 ? JSON.stringify(body, null, 2) : body;
|
|
64
152
|
}
|
|
153
|
+
function sliceWithEllipsis(str, max) {
|
|
154
|
+
return str.length > max ? `${str.slice(0, max)}\u2026` : str;
|
|
155
|
+
}
|
|
65
156
|
class CorsOriginError extends Error {
|
|
66
157
|
projectId;
|
|
67
158
|
addOriginUrl;
|
|
@@ -76,11 +167,11 @@ class CorsOriginError extends Error {
|
|
|
76
167
|
}
|
|
77
168
|
}
|
|
78
169
|
const httpError = {
|
|
79
|
-
onResponse: (res) => {
|
|
170
|
+
onResponse: (res, context) => {
|
|
80
171
|
if (res.statusCode >= 500)
|
|
81
172
|
throw new ServerError(res);
|
|
82
173
|
if (res.statusCode >= 400)
|
|
83
|
-
throw new ClientError(res);
|
|
174
|
+
throw new ClientError(res, context);
|
|
84
175
|
return res;
|
|
85
176
|
}
|
|
86
177
|
};
|
|
@@ -341,7 +432,8 @@ function connectWithESInstance(es, events) {
|
|
|
341
432
|
return;
|
|
342
433
|
}
|
|
343
434
|
if (message.type === "channelError") {
|
|
344
|
-
|
|
435
|
+
const tag = new URL(es.url).searchParams.get("tag");
|
|
436
|
+
observer.error(new ChannelError(extractErrorMessage(event?.data, tag), event.data));
|
|
345
437
|
return;
|
|
346
438
|
}
|
|
347
439
|
if (message.type === "disconnect") {
|
|
@@ -380,8 +472,9 @@ function parseEvent(message) {
|
|
|
380
472
|
return [err, null];
|
|
381
473
|
}
|
|
382
474
|
}
|
|
383
|
-
function extractErrorMessage(err) {
|
|
384
|
-
|
|
475
|
+
function extractErrorMessage(err, tag) {
|
|
476
|
+
const error = err.error;
|
|
477
|
+
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";
|
|
385
478
|
}
|
|
386
479
|
function isEmptyObject(data) {
|
|
387
480
|
for (const _ in data)
|
|
@@ -724,7 +817,9 @@ class ObservableTransaction extends BaseTransaction {
|
|
|
724
817
|
}
|
|
725
818
|
const projectHeader = "X-Sanity-Project-ID";
|
|
726
819
|
function requestOptions(config, overrides = {}) {
|
|
727
|
-
const headers = {}
|
|
820
|
+
const headers = {};
|
|
821
|
+
config.headers && Object.assign(headers, config.headers);
|
|
822
|
+
const token = overrides.token || config.token;
|
|
728
823
|
token && (headers.Authorization = `Bearer ${token}`), !overrides.useGlobalApi && !config.useProjectHostname && config.projectId && (headers[projectHeader] = config.projectId);
|
|
729
824
|
const withCredentials = !!(typeof overrides.withCredentials > "u" ? config.withCredentials : overrides.withCredentials), timeout = typeof overrides.timeout > "u" ? config.timeout : overrides.timeout;
|
|
730
825
|
return Object.assign({}, overrides, {
|
|
@@ -1042,6 +1137,22 @@ function _generate(client, httpRequest, request) {
|
|
|
1042
1137
|
body: request
|
|
1043
1138
|
});
|
|
1044
1139
|
}
|
|
1140
|
+
function _patch(client, httpRequest, request) {
|
|
1141
|
+
const dataset2 = hasDataset(client.config());
|
|
1142
|
+
return _request(client, httpRequest, {
|
|
1143
|
+
method: "POST",
|
|
1144
|
+
uri: `/agent/action/patch/${dataset2}`,
|
|
1145
|
+
body: request
|
|
1146
|
+
});
|
|
1147
|
+
}
|
|
1148
|
+
function _prompt(client, httpRequest, request) {
|
|
1149
|
+
const dataset2 = hasDataset(client.config());
|
|
1150
|
+
return _request(client, httpRequest, {
|
|
1151
|
+
method: "POST",
|
|
1152
|
+
uri: `/agent/action/prompt/${dataset2}`,
|
|
1153
|
+
body: request
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1045
1156
|
function _transform(client, httpRequest, request) {
|
|
1046
1157
|
const dataset2 = hasDataset(client.config());
|
|
1047
1158
|
return _request(client, httpRequest, {
|
|
@@ -1113,6 +1224,21 @@ class AgentActionsClient {
|
|
|
1113
1224
|
translate(request) {
|
|
1114
1225
|
return lastValueFrom(_translate(this.#client, this.#httpRequest, request));
|
|
1115
1226
|
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Run a raw instruction and return the result either as text or json
|
|
1229
|
+
* @param request - prompt request
|
|
1230
|
+
*/
|
|
1231
|
+
prompt(request) {
|
|
1232
|
+
return lastValueFrom(_prompt(this.#client, this.#httpRequest, request));
|
|
1233
|
+
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Patch a document using a schema aware API.
|
|
1236
|
+
* Does not use an LLM, but uses the schema to ensure paths and values matches the schema.
|
|
1237
|
+
* @param request - instruction request
|
|
1238
|
+
*/
|
|
1239
|
+
patch(request) {
|
|
1240
|
+
return lastValueFrom(_patch(this.#client, this.#httpRequest, request));
|
|
1241
|
+
}
|
|
1116
1242
|
}
|
|
1117
1243
|
class ObservableAssetsClient {
|
|
1118
1244
|
#client;
|
|
@@ -1219,13 +1345,11 @@ const MAX_URL_LENGTH = 14800, possibleOptions = [
|
|
|
1219
1345
|
includeResult: !0
|
|
1220
1346
|
};
|
|
1221
1347
|
function _listen(query, params, opts = {}) {
|
|
1222
|
-
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)}`;
|
|
1348
|
+
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)}`;
|
|
1223
1349
|
if (uri.length > MAX_URL_LENGTH)
|
|
1224
1350
|
return throwError(() => new Error("Query too large for listener"));
|
|
1225
1351
|
const listenFor = options.events ? options.events : ["mutation"], esOptions = {};
|
|
1226
|
-
return withCredentials && (esOptions.withCredentials = !0), token && (esOptions.headers = {
|
|
1227
|
-
Authorization: `Bearer ${token}`
|
|
1228
|
-
}), connectEventSource(() => (
|
|
1352
|
+
return withCredentials && (esOptions.withCredentials = !0), (token || configHeaders) && (esOptions.headers = {}, token && (esOptions.headers.Authorization = `Bearer ${token}`), configHeaders && Object.assign(esOptions.headers, configHeaders)), connectEventSource(() => (
|
|
1229
1353
|
// use polyfill if there is no global EventSource or if we need to set headers
|
|
1230
1354
|
(typeof EventSource > "u" || esOptions.headers ? eventSourcePolyfill : of(EventSource)).pipe(map((EventSource2) => new EventSource2(uri, esOptions)))
|
|
1231
1355
|
), listenFor).pipe(
|
|
@@ -1283,7 +1407,8 @@ class LiveClient {
|
|
|
1283
1407
|
apiVersion: _apiVersion,
|
|
1284
1408
|
token,
|
|
1285
1409
|
withCredentials,
|
|
1286
|
-
requestTagPrefix
|
|
1410
|
+
requestTagPrefix,
|
|
1411
|
+
headers: configHeaders
|
|
1287
1412
|
} = this.#client.config(), apiVersion = _apiVersion.replace(/^v/, "");
|
|
1288
1413
|
if (apiVersion !== "X" && apiVersion < requiredApiVersion)
|
|
1289
1414
|
throw new Error(
|
|
@@ -1296,9 +1421,7 @@ class LiveClient {
|
|
|
1296
1421
|
const path = _getDataUrl(this.#client, "live/events"), url = new URL(this.#client.getUrl(path, !1)), tag = _tag && requestTagPrefix ? [requestTagPrefix, _tag].join(".") : _tag;
|
|
1297
1422
|
tag && url.searchParams.set("tag", tag), includeDrafts && url.searchParams.set("includeDrafts", "true");
|
|
1298
1423
|
const esOptions = {};
|
|
1299
|
-
includeDrafts && token && (esOptions.headers = {
|
|
1300
|
-
Authorization: `Bearer ${token}`
|
|
1301
|
-
}), includeDrafts && withCredentials && (esOptions.withCredentials = !0);
|
|
1424
|
+
includeDrafts && withCredentials && (esOptions.withCredentials = !0), (includeDrafts && token || configHeaders) && (esOptions.headers = {}, includeDrafts && token && (esOptions.headers.Authorization = `Bearer ${token}`), configHeaders && Object.assign(esOptions.headers, configHeaders));
|
|
1302
1425
|
const key = `${url.href}::${JSON.stringify(esOptions)}`, existing = eventsCache.get(key);
|
|
1303
1426
|
if (existing)
|
|
1304
1427
|
return existing;
|
|
@@ -2577,6 +2700,8 @@ export {
|
|
|
2577
2700
|
connectEventSource,
|
|
2578
2701
|
createClient,
|
|
2579
2702
|
deprecatedCreateClient as default,
|
|
2703
|
+
formatQueryParseError,
|
|
2704
|
+
isQueryParseError,
|
|
2580
2705
|
requester,
|
|
2581
2706
|
adapter as unstable__adapter,
|
|
2582
2707
|
environment as unstable__environment,
|