@sanity/client 6.6.0 → 6.7.1-canary.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.
@@ -0,0 +1,127 @@
1
+ import type {ContentSourceMap, ContentSourceMapDocuments, ContentSourceMapMapping} from '../types'
2
+ import {jsonPath, parseJsonPath} from './jsonpath'
3
+ import type {PathSegment} from './types'
4
+
5
+ function isRecord(value: unknown): value is Record<string, unknown> {
6
+ return typeof value === 'object' && value !== null
7
+ }
8
+
9
+ function isArray(value: unknown): value is Array<unknown> {
10
+ return value !== null && Array.isArray(value)
11
+ }
12
+
13
+ /** @alpha */
14
+ export type Encoder<E> = (
15
+ value: string,
16
+ sourceDocument: ContentSourceMapDocuments[number],
17
+ path: PathSegment[],
18
+ ) => E
19
+
20
+ /** @alpha */
21
+ export function encode<R, E>(
22
+ result: R,
23
+ csm: ContentSourceMap,
24
+ encoder: Encoder<E>,
25
+ options?: {keyArraySelectors: boolean},
26
+ ): R {
27
+ return encodeIntoResult(result, csm, encoder, options) as R
28
+ }
29
+
30
+ /** @alpha */
31
+ export function encodeIntoResult<R>(
32
+ result: R,
33
+ csm: ContentSourceMap,
34
+ encoder: Encoder<unknown>,
35
+ options?: {keyArraySelectors: boolean},
36
+ ): ReturnType<Encoder<unknown>> {
37
+ return walkMap(result, (value, path) => {
38
+ // Only map strings, we could extend this in the future to support other types like integers...
39
+ if (typeof value !== 'string') {
40
+ return value
41
+ }
42
+
43
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
44
+ const resolveMappingResult = resolveMapping(path, csm)
45
+ if (!resolveMappingResult) {
46
+ return value
47
+ }
48
+
49
+ const [mapping, matchedPath, pathSuffix] = resolveMappingResult
50
+ if (mapping.type !== 'value') {
51
+ return value
52
+ }
53
+
54
+ if (mapping.source.type !== 'documentValue') {
55
+ return value
56
+ }
57
+
58
+ const sourceDocument =
59
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
60
+ csm.documents[mapping.source.document!]
61
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
62
+ const sourcePath = csm.paths[mapping.source.path]
63
+
64
+ if (options?.keyArraySelectors) {
65
+ const matchPathSegments = parseJsonPath(matchedPath)
66
+ const sourcePathSegments = parseJsonPath(sourcePath)
67
+ const fullSourceSegments = sourcePathSegments.concat(path.slice(matchPathSegments.length))
68
+
69
+ return encoder(value, sourceDocument, fullSourceSegments)
70
+ }
71
+
72
+ return encoder(value, sourceDocument, parseJsonPath(sourcePath + pathSuffix))
73
+ })
74
+ }
75
+
76
+ /** @alpha */
77
+ export type WalkMapFn = (value: unknown, path: PathSegment[]) => unknown
78
+
79
+ /** generic way to walk a nested object or array and apply a mapping function to each value
80
+ * @alpha
81
+ */
82
+ export function walkMap(value: unknown, mappingFn: WalkMapFn, path: PathSegment[] = []): unknown {
83
+ if (isArray(value)) {
84
+ return value.map((v, idx) => {
85
+ if (isRecord(v)) {
86
+ const key = v['_key']
87
+ if (typeof key === 'string') {
88
+ return walkMap(v, mappingFn, path.concat({key, index: idx}))
89
+ }
90
+ }
91
+
92
+ return walkMap(v, mappingFn, path.concat(idx))
93
+ })
94
+ }
95
+
96
+ if (isRecord(value)) {
97
+ return Object.fromEntries(
98
+ Object.entries(value).map(([k, v]) => [k, walkMap(v, mappingFn, path.concat(k))]),
99
+ )
100
+ }
101
+
102
+ return mappingFn(value, path)
103
+ }
104
+
105
+ /** @alpha */
106
+ export function resolveMapping(
107
+ resultPath: PathSegment[],
108
+ csm: ContentSourceMap,
109
+ ): [ContentSourceMapMapping, string, string] | undefined {
110
+ const resultJsonPath = jsonPath(resultPath)
111
+
112
+ if (csm.mappings[resultJsonPath] !== undefined) {
113
+ return [csm.mappings[resultJsonPath], resultJsonPath, '']
114
+ }
115
+
116
+ const mappings = Object.entries(csm.mappings)
117
+ .filter(([key]) => resultJsonPath.startsWith(key))
118
+ .sort(([key1], [key2]) => key2.length - key1.length)
119
+
120
+ if (mappings.length == 0) {
121
+ return undefined
122
+ }
123
+
124
+ const [matchedPath, mapping] = mappings[0]
125
+ const pathSuffix = resultJsonPath.substring(matchedPath.length)
126
+ return [mapping, matchedPath, pathSuffix]
127
+ }
@@ -0,0 +1,8 @@
1
+ /** @public */
2
+ export type PathSegment = string | number | KeyedSegment
3
+
4
+ /** @public */
5
+ export type KeyedSegment = {key: string; index: number}
6
+
7
+ /** @public */
8
+ export type StudioUrl = `/${string}` | `${string}.sanity.studio` | `https://${string}` | string
@@ -323,8 +323,9 @@ export function _requestObservable<R>(
323
323
  ['GET', 'HEAD', 'POST'].indexOf(options.method || 'GET') >= 0 &&
324
324
  uri.indexOf('/data/query/') === 0
325
325
  ) {
326
- if (options.resultSourceMap ?? config.resultSourceMap) {
327
- options.query = {resultSourceMap: true, ...options.query}
326
+ const resultSourceMap = options.resultSourceMap ?? config.resultSourceMap
327
+ if (resultSourceMap !== undefined && resultSourceMap !== false) {
328
+ options.query = {resultSourceMap, ...options.query}
328
329
  }
329
330
  const perspective = options.perspective || config.perspective
330
331
  if (typeof perspective === 'string' && perspective !== 'raw') {
package/src/types.ts CHANGED
@@ -84,7 +84,7 @@ export interface ClientConfig {
84
84
  /**
85
85
  * Adds a `resultSourceMap` key to the API response, with the type `ContentSourceMap`
86
86
  */
87
- resultSourceMap?: boolean
87
+ resultSourceMap?: boolean | 'withKeyArraySelector'
88
88
  /**
89
89
  *@deprecated set `cache` and `next` options on `client.fetch` instead
90
90
  */
@@ -219,17 +219,6 @@
219
219
  initMiddleware.forEach(request.use);
220
220
  return request;
221
221
  }
222
- var __defProp$1 = Object.defineProperty;
223
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, {
224
- enumerable: true,
225
- configurable: true,
226
- writable: true,
227
- value
228
- }) : obj[key] = value;
229
- var __publicField$1 = (obj, key, value) => {
230
- __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
231
- return value;
232
- };
233
222
  var __accessCheck$7 = (obj, member, msg) => {
234
223
  if (!member.has(obj)) throw TypeError("Cannot " + msg);
235
224
  };
@@ -249,23 +238,11 @@
249
238
  var _method, _url, _resHeaders, _headers, _controller, _init, _useAbortSignal;
250
239
  class FetchXhr {
251
240
  constructor() {
252
- /**
253
- * Public interface, interop with real XMLHttpRequest
254
- */
255
- __publicField$1(this, "onabort");
256
- __publicField$1(this, "onerror");
257
- __publicField$1(this, "onreadystatechange");
258
- __publicField$1(this, "ontimeout");
259
241
  /**
260
242
  * https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState
261
243
  */
262
- __publicField$1(this, "readyState", 0);
263
- __publicField$1(this, "response");
264
- __publicField$1(this, "responseText");
265
- __publicField$1(this, "responseType", "");
266
- __publicField$1(this, "status");
267
- __publicField$1(this, "statusText");
268
- __publicField$1(this, "withCredentials");
244
+ this.readyState = 0;
245
+ this.responseType = "";
269
246
  /**
270
247
  * Private implementation details
271
248
  */
@@ -1365,21 +1342,9 @@
1365
1342
  }
1366
1343
  };
1367
1344
  }
1368
- var __defProp = Object.defineProperty;
1369
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
1370
- enumerable: true,
1371
- configurable: true,
1372
- writable: true,
1373
- value
1374
- }) : obj[key] = value;
1375
- var __publicField = (obj, key, value) => {
1376
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1377
- return value;
1378
- };
1379
1345
  class Cancel {
1380
1346
  constructor(message) {
1381
- __publicField(this, "__CANCEL__", true);
1382
- __publicField(this, "message");
1347
+ this.__CANCEL__ = true;
1383
1348
  this.message = message;
1384
1349
  }
1385
1350
  toString() {
@@ -1388,8 +1353,6 @@
1388
1353
  }
1389
1354
  const _CancelToken = class _CancelToken {
1390
1355
  constructor(executor) {
1391
- __publicField(this, "promise");
1392
- __publicField(this, "reason");
1393
1356
  if (typeof executor !== "function") {
1394
1357
  throw new TypeError("executor must be a function.");
1395
1358
  }
@@ -1406,7 +1369,7 @@
1406
1369
  });
1407
1370
  }
1408
1371
  };
1409
- __publicField(_CancelToken, "source", () => {
1372
+ _CancelToken.source = () => {
1410
1373
  let cancel;
1411
1374
  const token = new _CancelToken(can => {
1412
1375
  cancel = can;
@@ -1415,7 +1378,7 @@
1415
1378
  token,
1416
1379
  cancel
1417
1380
  };
1418
- });
1381
+ };
1419
1382
  var defaultShouldRetry = (err, attempt, options) => {
1420
1383
  if (options.method !== "GET" && options.method !== "HEAD") {
1421
1384
  return false;
@@ -3112,9 +3075,10 @@
3112
3075
  };
3113
3076
  }
3114
3077
  if (["GET", "HEAD", "POST"].indexOf(options.method || "GET") >= 0 && uri.indexOf("/data/query/") === 0) {
3115
- if ((_a = options.resultSourceMap) != null ? _a : config.resultSourceMap) {
3078
+ const resultSourceMap = (_a = options.resultSourceMap) != null ? _a : config.resultSourceMap;
3079
+ if (resultSourceMap !== void 0 && resultSourceMap !== false) {
3116
3080
  options.query = {
3117
- resultSourceMap: true,
3081
+ resultSourceMap,
3118
3082
  ...options.query
3119
3083
  };
3120
3084
  }