@sanity/client 5.4.2 → 5.4.3-dev.1

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 CHANGED
@@ -26,8 +26,8 @@ import {createClient} from '@sanity/client'
26
26
  export const client = createClient({
27
27
  projectId: 'your-project-id',
28
28
  dataset: 'your-dataset-name',
29
- useCdn: false, // set to `true` to fetch from edge cache
30
- apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
29
+ useCdn: true, // set to `false` to bypass the edge cache
30
+ apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version
31
31
  // token: process.env.SANITY_SECRET_TOKEN // Only if you want to update content with the client
32
32
  })
33
33
 
@@ -65,6 +65,7 @@ export async function updateDocumentTitle(_id, title) {
65
65
  - [UMD](#umd)
66
66
  - [Specifying API version](#specifying-api-version)
67
67
  - [Performing queries](#performing-queries)
68
+ - [Get started with Content Source Maps](#get-started-with-content-source-maps)
68
69
  - [Listening to queries](#listening-to-queries)
69
70
  - [Fetch a single document](#fetch-a-single-document)
70
71
  - [Fetch multiple documents in one go](#fetch-multiple-documents-in-one-go)
@@ -93,7 +94,9 @@ export async function updateDocumentTitle(_id, title) {
93
94
  - [Set client configuration](#set-client-configuration)
94
95
  - [Release new version](#release-new-version)
95
96
  - [License](#license)
96
- - [From `v4`](#from-v4)
97
+ - [Migrate](#migrate)
98
+ - [From `v5`](#from-v5)
99
+ - [From `v4`](#from-v4)
97
100
 
98
101
  ## Requirements
99
102
 
@@ -119,7 +122,7 @@ pnpm install @sanity/client
119
122
 
120
123
  `const client = createClient(options)`
121
124
 
122
- Initializes a new Sanity Client. Required options are `projectId`, `dataset`, and `apiVersion`. Setting a value for `useCdn` is encouraged. Typically you want to have it as `false` in development to always fetch the freshest content and `true` in production environments so that content is fetched from the distributed cache. [You can learn more about the API CDN here][api-cdn].
125
+ Initializes a new Sanity Client. Required options are `projectId`, `dataset`, and `apiVersion`. [We encourage setting `useCdn` to either `true` or `false`.](https://www.sanity.io/help/js-client-cdn-configuration) The default is `true`. If you're not sure which option to choose we recommend starting with `true` and revise later if you find that you require uncached content. [Our awesome Slack community can help guide you on how to avoid stale data tailored to your tech stack and architecture.](https://slack.sanity.io/)
123
126
 
124
127
  #### [ESM](https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/)
125
128
 
@@ -129,8 +132,8 @@ import {createClient} from '@sanity/client'
129
132
  const client = createClient({
130
133
  projectId: 'your-project-id',
131
134
  dataset: 'your-dataset-name',
132
- useCdn: false, // set to `true` to fetch from edge cache
133
- apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
135
+ useCdn: true, // set to `false` to bypass the edge cache
136
+ apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version
134
137
  })
135
138
 
136
139
  const data = await client.fetch(`count(*)`)
@@ -145,8 +148,8 @@ const {createClient} = require('@sanity/client')
145
148
  const client = createClient({
146
149
  projectId: 'your-project-id',
147
150
  dataset: 'your-dataset-name',
148
- useCdn: false, // set to `true` to fetch from edge cache
149
- apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
151
+ useCdn: true, // set to `false` to bypass the edge cache
152
+ apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version
150
153
  })
151
154
 
152
155
  client
@@ -163,8 +166,8 @@ import {createClient, type ClientConfig} from '@sanity/client'
163
166
  const config: ClientConfig = {
164
167
  projectId: 'your-project-id',
165
168
  dataset: 'your-dataset-name',
166
- useCdn: false, // set to `true` to fetch from edge cache
167
- apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
169
+ useCdn: true, // set to `false` to bypass the edge cache
170
+ apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version
168
171
  }
169
172
  const client = createClient(config)
170
173
 
@@ -183,8 +186,8 @@ import {z} from 'zod'
183
186
  const client = createClient({
184
187
  projectId: 'your-project-id',
185
188
  dataset: 'your-dataset-name',
186
- useCdn: false, // set to `true` to fetch from edge cache
187
- apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
189
+ useCdn: true, // set to `false` to bypass the edge cache
190
+ apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version
188
191
  })
189
192
 
190
193
  const schema = z.number()
@@ -210,8 +213,8 @@ import {createClient} from '@sanity/client'
210
213
  const client = createClient({
211
214
  projectId: 'your-project-id',
212
215
  dataset: 'your-dataset-name',
213
- useCdn: false, // set to `true` to fetch from edge cache
214
- apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
216
+ useCdn: true, // set to `false` to bypass the edge cache
217
+ apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version
215
218
  })
216
219
 
217
220
  const data = await client.fetch<number>(`count(*)`)
@@ -238,8 +241,8 @@ import {createClient} from 'https://esm.sh/@sanity/client'
238
241
  const client = createClient({
239
242
  projectId: 'your-project-id',
240
243
  dataset: 'your-dataset-name',
241
- useCdn: false, // set to `true` to fetch from edge cache
242
- apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
244
+ useCdn: true, // set to `false` to bypass the edge cache
245
+ apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version
243
246
  })
244
247
 
245
248
  const data = await client.fetch<number>(`count(*)`)
@@ -271,8 +274,8 @@ export default async function handler(req: NextRequest) {
271
274
  const client = createClient({
272
275
  projectId: 'your-project-id',
273
276
  dataset: 'your-dataset-name',
274
- useCdn: false, // set to `true` to fetch from edge cache
275
- apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
277
+ useCdn: true, // set to `false` to bypass the edge cache
278
+ apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version
276
279
  })
277
280
 
278
281
  const count = await client.fetch<number>(`count(*)`)
@@ -302,8 +305,8 @@ Using [esm.sh] you can either load the client using a `<script type="module">` t
302
305
  const client = createClient({
303
306
  projectId: 'your-project-id',
304
307
  dataset: 'your-dataset-name',
305
- useCdn: false, // set to `true` to fetch from edge cache
306
- apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
308
+ useCdn: true, // set to `false` to bypass the edge cache
309
+ apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version
307
310
  })
308
311
 
309
312
  const data = await client.fetch(`count(*)`)
@@ -321,8 +324,8 @@ const {createClient} = await import('https://esm.sh/@sanity/client')
321
324
  const client = createClient({
322
325
  projectId: 'your-project-id',
323
326
  dataset: 'your-dataset-name',
324
- useCdn: false, // set to `true` to fetch from edge cache
325
- apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
327
+ useCdn: true, // set to `false` to bypass the edge cache
328
+ apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version
326
329
  })
327
330
 
328
331
  const data = await client.fetch(`count(*)`)
@@ -343,8 +346,8 @@ Loading the UMD script creates a `SanityClient` global that have the same export
343
346
  const client = createClient({
344
347
  projectId: 'your-project-id',
345
348
  dataset: 'your-dataset-name',
346
- useCdn: false, // set to `true` to fetch from edge cache
347
- apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
349
+ useCdn: true, // set to `false` to bypass the edge cache
350
+ apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version
348
351
  })
349
352
 
350
353
  client.fetch(`count(*)`).then((data) => console.log(`Number of documents: ${data}`))
@@ -364,8 +367,8 @@ The `require-unpkg` library lets you consume `npm` packages from `unpkg.com` sim
364
367
  const client = createClient({
365
368
  projectId: 'your-project-id',
366
369
  dataset: 'your-dataset-name',
367
- useCdn: false, // set to `true` to fetch from edge cache
368
- apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
370
+ useCdn: true, // set to `false` to bypass the edge cache
371
+ apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version
369
372
  })
370
373
 
371
374
  const data = await client.fetch(`count(*)`)
@@ -402,6 +405,58 @@ client.fetch(query, params).then((bikes) => {
402
405
 
403
406
  Perform a query using the given parameters (if any).
404
407
 
408
+ ### Get started with Content Source Maps
409
+
410
+ > **Note**
411
+ >
412
+ > [Content Source Maps][content-source-maps-intro] are available [as an API][content-source-maps] for select [Sanity enterprise customers][enterprise-cta]. [Contact our sales team for more information.][sales-cta]
413
+
414
+ [Visual editing][visual-editing] is available in [`@sanity/preview-kit/client`][preview-kit-client]. It offers both a turn-key solution and a flexible API for custom experiences.
415
+
416
+ This guide is for developers who want to build custom use cases beyond, or in addition to, [visual editing][visual-editing]. Read the [Content Source Maps introduction][content-source-maps-intro] before diving in, and keep the [Content Source Maps reference][content-source-maps] handy.
417
+
418
+ Enabling Content Source Maps is a two-step process:
419
+
420
+ 1. Update your client configuration with `resultSourceMap`.
421
+
422
+ ```js
423
+ import {createClient} from '@sanity/client'
424
+
425
+ const client = createClient({
426
+ projectId: 'your-project-id',
427
+ dataset: 'your-dataset-name',
428
+ useCdn: true, // set to `false` to bypass the edge cache
429
+ apiVersion: '2023-05-03', // use current date (YYYY-MM-DD) to target the latest API version
430
+ resultSourceMap: true, // tells the API to start sending source maps, if available
431
+ })
432
+ ```
433
+
434
+ 2. On `client.fetch` calls add `{filterResponse: false}` to return the full response on queries.
435
+
436
+ ```js
437
+ // Before
438
+ // const result = await client.fetch(query, params)
439
+
440
+ // After adding `filterResponse: false`
441
+ const {result, resultSourceMap} = await client.fetch(query, params, {filterResponse: false})
442
+ // Build something cool with the source map
443
+ console.log(resultSourceMap)
444
+ ```
445
+
446
+ Once enabled, the `resultSourceMap` property will always exist on the response, given your `apiVersion` is recent enough. If there is no source map, it will be an empty object. There's also a TypeScript definition for it:
447
+
448
+ ```ts
449
+ import type {ContentSourceMapping} from '@sanity/client'
450
+
451
+ const {result, resultSourceMap} = await client.fetch(query, params, {filterResponse: false})
452
+
453
+ function useContentSourceMap(resultSourceMap: ContentSourceMapping): unknown {
454
+ // Sky's the limit
455
+ }
456
+
457
+ useContentSourceMap(resultSourceMap)
458
+ ```
459
+
405
460
  ### Listening to queries
406
461
 
407
462
  ```js
@@ -924,6 +979,23 @@ MIT © [Sanity.io](https://www.sanity.io/)
924
979
 
925
980
  # Migrate
926
981
 
982
+ ## From `v5`
983
+
984
+ ### The default `useCdn` is changed to `true`
985
+
986
+ It was previously `false`. If you were relying on the default being `false` you can continue using the live API by setting it in the constructor:
987
+
988
+ ```diff
989
+ import {createClient} from '@sanity/client'
990
+
991
+ export const client = createClient({
992
+ projectId: 'your-project-id',
993
+ dataset: 'your-dataset-name',
994
+ apiVersion: '2023-03-12',
995
+ + useCdn: false, // set to `true` to use the edge cache
996
+ })
997
+ ```
998
+
927
999
  ## From `v4`
928
1000
 
929
1001
  ### No longer shipping `ES5`
@@ -1223,3 +1295,9 @@ await client.request<void>({uri: '/auth/logout', method: 'POST'})
1223
1295
  [groqd]: https://github.com/FormidableLabs/groqd#readme
1224
1296
  [AbortSignal]: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
1225
1297
  [AbortController]: https://developer.mozilla.org/en-US/docs/Web/API/AbortController
1298
+ [visual-editing]: https://www.sanity.io/docs/vercel-visual-editing?utm_source=github.com&utm_medium=referral&utm_campaign=may-vercel-launch
1299
+ [content-source-maps]: https://www.sanity.io/docs/content-source-maps?utm_source=github.com&utm_medium=referral&utm_campaign=may-vercel-launch
1300
+ [content-source-maps-intro]: https://www.sanity.io/blog/content-source-maps-announce?utm_source=github.com&utm_medium=referral&utm_campaign=may-vercel-launch
1301
+ [preview-kit-client]: https://github.com/sanity-io/preview-kit#sanitypreview-kitclient
1302
+ [sales-cta]: https://www.sanity.io/contact/sales?utm_source=github.com&utm_medium=referral&utm_campaign=may-vercel-launch
1303
+ [enterprise-cta]: https://www.sanity.io/enterprise?utm_source=github.com&utm_medium=referral&utm_campaign=may-vercel-launch
@@ -93,8 +93,18 @@ const printWarnings = {
93
93
  return res;
94
94
  }
95
95
  };
96
- function defineHttpRequest(envMiddleware) {
97
- const request = getIt.getIt([...envMiddleware, printWarnings, middleware.jsonRequest(), middleware.jsonResponse(), middleware.progress(), httpError, middleware.observable({
96
+ function defineHttpRequest(envMiddleware, _ref) {
97
+ let {
98
+ maxRetries = 5,
99
+ retryDelay
100
+ } = _ref;
101
+ const request = getIt.getIt([maxRetries > 0 ? middleware.retry({
102
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
103
+ retryDelay,
104
+ // This option is typed incorrectly in get-it.
105
+ maxRetries,
106
+ shouldRetry
107
+ }) : {}, ...envMiddleware, printWarnings, middleware.jsonRequest(), middleware.jsonResponse(), middleware.progress(), httpError, middleware.observable({
98
108
  implementation: rxjs.Observable
99
109
  })]);
100
110
  function httpRequest(options) {
@@ -107,6 +117,13 @@ function defineHttpRequest(envMiddleware) {
107
117
  httpRequest.defaultRequester = request;
108
118
  return httpRequest;
109
119
  }
120
+ function shouldRetry(err, attempt, options) {
121
+ const isSafe = options.method === "GET" || options.method === "HEAD";
122
+ const isQuery = options.uri.startsWith("/data/query");
123
+ const isRetriableResponse = err.response && (err.response.statusCode === 429 || err.response.statusCode === 502 || err.response.statusCode === 503);
124
+ if ((isSafe || isQuery) && isRetriableResponse) return true;
125
+ return middleware.retry.shouldRetry(err, attempt, options);
126
+ }
110
127
  const projectHeader = "X-Sanity-Project-ID";
111
128
  function requestOptions(config) {
112
129
  let overrides = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -203,12 +220,12 @@ const requestTag = tag => {
203
220
  }
204
221
  return tag;
205
222
  };
206
- const encodeQueryString = _ref => {
223
+ const encodeQueryString = _ref2 => {
207
224
  let {
208
225
  query,
209
226
  params = {},
210
227
  options = {}
211
- } = _ref;
228
+ } = _ref2;
212
229
  const searchParams = new URLSearchParams();
213
230
  const {
214
231
  tag,
@@ -817,6 +834,12 @@ function _requestObservable(client, httpRequest, options) {
817
834
  ...options.query
818
835
  };
819
836
  }
837
+ if (config.resultSourceMap) {
838
+ options.query = {
839
+ resultSourceMap: true,
840
+ ...options.query
841
+ };
842
+ }
820
843
  const reqOptions = requestOptions(config, Object.assign({}, options, {
821
844
  url: _getUrl(client, uri, useCdn)
822
845
  }));
@@ -993,10 +1016,10 @@ once(function () {
993
1016
  }
994
1017
  return console.warn(message.join(" "), ...args);
995
1018
  });
996
- const printCdnWarning = createWarningPrinter(["You are not using the Sanity CDN. That means your data is always fresh, but the CDN is faster and", "cheaper. Think about it! For more info, see ".concat(generateHelpUrl("js-client-cdn-configuration"), " "), "To hide this warning, please set the `useCdn` option to either `true` or `false` when creating", "the client."]);
1019
+ const printCdnWarning = createWarningPrinter(["Since you haven't set a value for `useCdn`, we will deliver content using our", "global, edge-cached API-CDN. If you wish to have content delivered faster, set", "`useCdn: false` to use the Live API. Note: You may incur higher costs using the live API."]);
997
1020
  const printBrowserTokenWarning = createWarningPrinter(["You have configured Sanity client to use a token in the browser. This may cause unintentional security issues.", "See ".concat(generateHelpUrl("js-client-browser-token"), " for more information and how to hide this warning.")]);
998
1021
  const printNoApiVersionSpecifiedWarning = createWarningPrinter(["Using the Sanity client without specifying an API version is deprecated.", "See ".concat(generateHelpUrl("js-client-api-version"))]);
999
- const printNoDefaultExport = createWarningPrinter(["The default export of @sanity/client has been deprecated. Use the named export `createClient` instead"]);
1022
+ const printNoDefaultExport = createWarningPrinter(["The default export of @sanity/client has been deprecated. Use the named export `createClient` instead."]);
1000
1023
  const defaultCdnHost = "apicdn.sanity.io";
1001
1024
  const defaultConfig = {
1002
1025
  apiHost: "https://api.sanity.io",
@@ -1047,7 +1070,7 @@ const initConfig = (config, prevConfig) => {
1047
1070
  }
1048
1071
  newConfig.apiVersion = "".concat(newConfig.apiVersion).replace(/^v/, "");
1049
1072
  newConfig.isDefaultApi = newConfig.apiHost === defaultConfig.apiHost;
1050
- newConfig.useCdn = Boolean(newConfig.useCdn) && !newConfig.withCredentials;
1073
+ newConfig.useCdn = newConfig.useCdn !== false && !newConfig.withCredentials;
1051
1074
  validateApiVersion(newConfig.apiVersion);
1052
1075
  const hostParts = newConfig.apiHost.split("://", 2);
1053
1076
  const protocol = hostParts[0];
@@ -1724,21 +1747,24 @@ const _SanityClient = class {
1724
1747
  return new Transaction(operations, this);
1725
1748
  }
1726
1749
  /**
1727
- * DEPRECATED: Perform an HTTP request against the Sanity API
1750
+ * Perform a request against the Sanity API
1751
+ * NOTE: Only use this for Sanity API endpoints, not for your own APIs!
1728
1752
  *
1729
- * @deprecated Use your own request library!
1730
1753
  * @param options - Request options
1754
+ * @returns Promise resolving to the response body
1731
1755
  */
1732
1756
  request(options) {
1733
1757
  return rxjs.lastValueFrom(_request(this, __privateGet(this, _httpRequest2), options));
1734
1758
  }
1735
1759
  /**
1736
- * DEPRECATED: Perform an HTTP request a `/data` sub-endpoint
1760
+ * Perform an HTTP request a `/data` sub-endpoint
1761
+ * NOTE: Considered internal, thus marked as deprecated. Use `request` instead.
1737
1762
  *
1738
- * @deprecated Use your own request library!
1763
+ * @deprecated - Use `request()` or your own HTTP library instead
1739
1764
  * @param endpoint - Endpoint to hit (mutate, query etc)
1740
1765
  * @param body - Request body
1741
1766
  * @param options - Request options
1767
+ * @internal
1742
1768
  */
1743
1769
  dataRequest(endpoint, body, options) {
1744
1770
  return rxjs.lastValueFrom(_dataRequest(this, __privateGet(this, _httpRequest2), endpoint, body, options));
@@ -1765,9 +1791,12 @@ const _SanityClient = class {
1765
1791
  let SanityClient = _SanityClient;
1766
1792
  _clientConfig2 = new WeakMap();
1767
1793
  _httpRequest2 = new WeakMap();
1768
- const httpRequest = defineHttpRequest(envMiddleware);
1794
+ const httpRequest = defineHttpRequest(envMiddleware, {});
1769
1795
  const requester = httpRequest.defaultRequester;
1770
- const createClient = config => new SanityClient(httpRequest, config);
1796
+ const createClient = config => new SanityClient(defineHttpRequest(envMiddleware, {
1797
+ maxRetries: config.maxRetries,
1798
+ retryDelay: config.retryDelay
1799
+ }), config);
1771
1800
  function deprecatedCreateClient(config) {
1772
1801
  printNoDefaultExport();
1773
1802
  return new SanityClient(httpRequest, config);