@sanity/client 5.0.0-esm.9 → 5.1.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 CHANGED
@@ -19,7 +19,7 @@ Import and create a new client instance, and use its methods to interact with yo
19
19
 
20
20
  ```js
21
21
  // sanity.js
22
- import {createClient} from '@sanity/client'
22
+ import {createClient} from '@sanity/client'
23
23
  // Import using ESM URL imports in environments that supports it:
24
24
  // import {createClient} from 'https://esm.sh/@sanity/client'
25
25
 
@@ -98,7 +98,7 @@ export async function updateDocumentTitle(_id, title) {
98
98
 
99
99
  Sanity Client transpiles syntax for [modern browsers]. The JavaScript runtime must support ES6 features such as [class](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes), [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters), [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) and more. Most modern web frameworks, [browsers][modern browsers], and developer tooling supports ES6 today.
100
100
 
101
- For legacy ES5 environments you'll need to transpile `@sanity/client` and its `dependencies` with your own bundler, and have a global ES6-compliant `Promise` available. If your runtime environment doesn't provide a spec compliant `Promise` implementation, we recommend using [native-promise-only](https://www.npmjs.com/package/native-promise-only), [es6-promise](https://www.npmjs.com/package/es6-promise) or another [spec-compliant](https://promisesaplus.com/implementations) implementation. See [this article](https://www.sanity.io/help/js-client-promise-polyfill) for more information.
101
+ [For legacy ES5 environments we recommend v4.](https://github.com/sanity-io/client/tree/v4.0.0#sanityclient)
102
102
 
103
103
  ## Installation
104
104
 
@@ -127,13 +127,13 @@ import {createClient} from '@sanity/client'
127
127
 
128
128
  const client = createClient({
129
129
  projectId: 'your-project-id',
130
- dataset: 'bikeshop',
131
- apiVersion: '2021-03-25', // use current UTC date - see "specifying API version"!
132
- token: 'sanity-auth-token', // or leave blank for unauthenticated usage
133
- useCdn: true, // `false` if you want to ensure fresh data
130
+ dataset: 'your-dataset-name',
131
+ useCdn: false, // set to `true` to fetch from edge cache
132
+ apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
134
133
  })
135
134
 
136
- export default client
135
+ const data = await client.fetch(`count(*)`)
136
+ console.log(`Number of documents: ${data}`)
137
137
  ```
138
138
 
139
139
  #### [CommonJS]
@@ -143,13 +143,15 @@ const {createClient} = require('@sanity/client')
143
143
 
144
144
  const client = createClient({
145
145
  projectId: 'your-project-id',
146
- dataset: 'bikeshop',
147
- apiVersion: '2021-03-25', // use current UTC date - see "specifying API version"!
148
- token: 'sanity-auth-token', // or leave blank for unauthenticated usage
149
- useCdn: true, // `false` if you want to ensure fresh data
146
+ dataset: 'your-dataset-name',
147
+ useCdn: false, // set to `true` to fetch from edge cache
148
+ apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
150
149
  })
151
150
 
152
- module.exports = client
151
+ client
152
+ .fetch(`count(*)`)
153
+ .then((data) => console.log(`Number of documents: ${data}`))
154
+ .catch(console.error)
153
155
  ```
154
156
 
155
157
  #### [TypeScript]
@@ -157,17 +159,41 @@ module.exports = client
157
159
  ```ts
158
160
  import {createClient, type ClientConfig} from '@sanity/client'
159
161
 
160
- const client: ClientConfig = {
162
+ const config: ClientConfig = {
161
163
  projectId: 'your-project-id',
162
- dataset: 'bikeshop',
163
- apiVersion: '2021-03-25', // use current UTC date - see "specifying API version"!
164
- token: 'sanity-auth-token', // or leave blank for unauthenticated usage
165
- useCdn: true, // `false` if you want to ensure fresh data
164
+ dataset: 'your-dataset-name',
165
+ useCdn: false, // set to `true` to fetch from edge cache
166
+ apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
166
167
  }
168
+ const client = createClient(config)
167
169
 
168
- export default createClient(config)
170
+ const data = await client.fetch<number>(`count(*)`)
171
+ // data is typed as `number`
172
+ console.log(`Number of documents: ${data}`)
169
173
  ```
170
174
 
175
+ We're currently exploring typed GROQ queries that are runtime safe, and will share more when we've landed on a solution we're satisifed with.
176
+ Until then you can achieve this using [Zod]:
177
+
178
+ ```ts
179
+ import {createClient} from '@sanity/client'
180
+ import {z} from 'zod'
181
+
182
+ const client = createClient({
183
+ projectId: 'your-project-id',
184
+ dataset: 'your-dataset-name',
185
+ useCdn: false, // set to `true` to fetch from edge cache
186
+ apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
187
+ })
188
+
189
+ const schema = z.number()
190
+ const data = schema.parse(await client.fetch(`count(*)`))
191
+ // data is guaranteed to be `number`, or zod will throw an error
192
+ console.log(`Number of documents: ${data}`)
193
+ ```
194
+
195
+ Another alternative is [groqd].
196
+
171
197
  #### [Bun]
172
198
 
173
199
  ```bash
@@ -182,13 +208,12 @@ import {createClient} from '@sanity/client'
182
208
 
183
209
  const client = createClient({
184
210
  projectId: 'your-project-id',
185
- dataset: 'bikeshop',
186
- apiVersion: '2021-03-25', // use current UTC date - see "specifying API version"!
187
- token: 'sanity-auth-token', // or leave blank for unauthenticated usage
188
- useCdn: true, // `false` if you want to ensure fresh data
211
+ dataset: 'your-dataset-name',
212
+ useCdn: false, // set to `true` to fetch from edge cache
213
+ apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
189
214
  })
190
215
 
191
- const data = await client.fetch(`count(*[])`)
216
+ const data = await client.fetch<number>(`count(*)`)
192
217
 
193
218
  console.write(`Number of documents: ${data}`)
194
219
  ```
@@ -211,13 +236,12 @@ import {createClient} from 'https://esm.sh/@sanity/client'
211
236
 
212
237
  const client = createClient({
213
238
  projectId: 'your-project-id',
214
- dataset: 'bikeshop',
215
- apiVersion: '2021-03-25', // use current UTC date - see "specifying API version"!
216
- token: 'sanity-auth-token', // or leave blank for unauthenticated usage
217
- useCdn: true, // `false` if you want to ensure fresh data
239
+ dataset: 'your-dataset-name',
240
+ useCdn: false, // set to `true` to fetch from edge cache
241
+ apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
218
242
  })
219
243
 
220
- const data = await client.fetch(`count(*[])`)
244
+ const data = await client.fetch<number>(`count(*)`)
221
245
 
222
246
  console.log(`Number of documents: ${data}`)
223
247
  ```
@@ -245,23 +269,18 @@ export const config = {
245
269
  export default async function handler(req: NextRequest) {
246
270
  const client = createClient({
247
271
  projectId: 'your-project-id',
248
- dataset: 'bikeshop',
249
- apiVersion: '2021-03-25', // use current UTC date - see "specifying API version"!
250
- token: 'sanity-auth-token', // or leave blank for unauthenticated usage
251
- useCdn: true, // `false` if you want to ensure fresh data
272
+ dataset: 'your-dataset-name',
273
+ useCdn: false, // set to `true` to fetch from edge cache
274
+ apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
252
275
  })
253
276
 
254
- return new Response(
255
- JSON.stringify({
256
- count: await client.fetch(`count(*[])`),
257
- }),
258
- {
259
- status: 200,
260
- headers: {
261
- 'content-type': 'application/json',
262
- },
263
- }
264
- )
277
+ const count = await client.fetch<number>(`count(*)`)
278
+ return new Response(JSON.stringify({count}), {
279
+ status: 200,
280
+ headers: {
281
+ 'content-type': 'application/json',
282
+ },
283
+ })
265
284
  }
266
285
  ```
267
286
 
@@ -281,13 +300,12 @@ Using [esm.sh] you can either load the client using a `<script type="module">` t
281
300
 
282
301
  const client = createClient({
283
302
  projectId: 'your-project-id',
284
- dataset: 'bikeshop',
285
- apiVersion: '2021-03-25', // use current UTC date - see "specifying API version"!
286
- token: 'sanity-auth-token', // or leave blank for unauthenticated usage
287
- useCdn: true, // `false` if you want to ensure fresh data
303
+ dataset: 'your-dataset-name',
304
+ useCdn: false, // set to `true` to fetch from edge cache
305
+ apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
288
306
  })
289
307
 
290
- const data = await client.fetch(`count(*[])`)
308
+ const data = await client.fetch(`count(*)`)
291
309
  document.getElementById('results').innerText = `Number of documents: ${data}`
292
310
  </script>
293
311
  <div id="results"></div>
@@ -296,18 +314,17 @@ Using [esm.sh] you can either load the client using a `<script type="module">` t
296
314
  Or from anywhere using a dynamic `import()`:
297
315
 
298
316
  ```js
299
- // You can run this snippet from your browwser DevTools console.
317
+ // You can run this snippet from your browser DevTools console.
300
318
  // Super handy when you're quickly testing out queries.
301
319
  const {createClient} = await import('https://esm.sh/@sanity/client')
302
320
  const client = createClient({
303
321
  projectId: 'your-project-id',
304
- dataset: 'bikeshop',
305
- apiVersion: '2021-03-25', // use current UTC date - see "specifying API version"!
306
- token: 'sanity-auth-token', // or leave blank for unauthenticated usage
307
- useCdn: true, // `false` if you want to ensure fresh data
322
+ dataset: 'your-dataset-name',
323
+ useCdn: false, // set to `true` to fetch from edge cache
324
+ apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
308
325
  })
309
326
 
310
- const data = await client.fetch(`count(*[])`)
327
+ const data = await client.fetch(`count(*)`)
311
328
  console.log(`Number of documents: ${data}`)
312
329
  ```
313
330
 
@@ -324,13 +341,12 @@ Loading the UMD script creates a `SanityClient` global that have the same export
324
341
 
325
342
  const client = createClient({
326
343
  projectId: 'your-project-id',
327
- dataset: 'bikeshop',
328
- apiVersion: '2021-03-25', // use current UTC date - see "specifying API version"!
329
- token: 'sanity-auth-token', // or leave blank for unauthenticated usage
330
- useCdn: true, // `false` if you want to ensure fresh data
344
+ dataset: 'your-dataset-name',
345
+ useCdn: false, // set to `true` to fetch from edge cache
346
+ apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
331
347
  })
332
348
 
333
- client.fetch(`count(*[])`).then((data) => console.log(`Number of documents: ${data}`))
349
+ client.fetch(`count(*)`).then((data) => console.log(`Number of documents: ${data}`))
334
350
  </script>
335
351
  ```
336
352
 
@@ -346,13 +362,12 @@ The `require-unpkg` library lets you consume `npm` packages from `unpkg.com` sim
346
362
 
347
363
  const client = createClient({
348
364
  projectId: 'your-project-id',
349
- dataset: 'bikeshop',
350
- apiVersion: '2021-03-25', // use current UTC date - see "specifying API version"!
351
- useCdn: true, // `false` if you want to ensure fresh data
352
- token: 'sanity-secret-auth-token', // leave blank for unauthenticated usage
365
+ dataset: 'your-dataset-name',
366
+ useCdn: false, // set to `true` to fetch from edge cache
367
+ apiVersion: '2022-01-12', // use current date (YYYY-MM-DD) to target the latest API version
353
368
  })
354
369
 
355
- const data = await client.fetch(`count(*[])`)
370
+ const data = await client.fetch(`count(*)`)
356
371
  $('#results').text(`Number of documents: ${data}`)
357
372
  })()
358
373
  </script>
@@ -831,6 +846,49 @@ The following options are available for mutations, and can be applied either as
831
846
  - `dryRun` (`true|false`) - default `false`. If true, the mutation will be a dry run - the response will be identical to the one returned had this property been omitted or false (including error responses) but no documents will be affected.
832
847
  - `autoGenerateArrayKeys` (`true|false`) - default `false`. If true, the mutation API will automatically add `_key` attributes to objects in arrays that is missing them. This makes array operations more robust by having a unique key within the array available for selections, which helps prevent race conditions in real-time, collaborative editing.
833
848
 
849
+ ### Aborting a request
850
+
851
+ Requests can be aborted (or cancelled) in two ways:
852
+
853
+ #### 1. Abort a request by passing an [AbortSignal] with the request options
854
+
855
+ Sanity Client supports the [AbortController] API and supports receiving an abort signal that can be used to cancel the request. Here's an example that will abort the request if it takes more than 200ms to complete:
856
+
857
+ ```js
858
+ const abortController = new AbortController()
859
+
860
+ // note the lack of await here
861
+ const request = getClient().fetch('*[_type == "movie"]', {}, {signal: abortController.signal})
862
+
863
+ // this will abort the request after 200ms
864
+ setTimeout(() => abortController.abort(), 200)
865
+
866
+ try {
867
+ const response = await request
868
+ //…
869
+ } catch (error) {
870
+ if (error.name === 'AbortError') {
871
+ console.log('Request was aborted')
872
+ } else {
873
+ // rethrow in case of other errors
874
+ throw error
875
+ }
876
+ }
877
+ ```
878
+
879
+ #### 2. Cancel a request by unsubscribing from the Observable
880
+
881
+ When using the Observable API (e.g. `client.observable.fetch()`), you can cancel the request by simply `unsubscribe` from the returned observable:
882
+
883
+ ```js
884
+ const subscription = client.observable.fetch('*[_type == "movie"]').subscribe((result) => {
885
+ /* do something with the result */
886
+ })
887
+
888
+ // this will cancel the request
889
+ subscription.unsubscribe()
890
+ ```
891
+
834
892
  ### Get client configuration
835
893
 
836
894
  ```js
@@ -1142,6 +1200,65 @@ client.createIfNotExists(doc, options)
1142
1200
  client.createOrReplace(doc, options)
1143
1201
  ```
1144
1202
 
1203
+ ### `client.patch.replace` is removed, replace with `client.createOrReplace`<!-- omit in toc -->
1204
+
1205
+ Before:
1206
+
1207
+ ```ts
1208
+ import createClient from '@sanity/client'
1209
+ const client = createClient()
1210
+
1211
+ client.patch('tropic-hab').replace({name: 'Tropical Habanero', ingredients: []}).commit()
1212
+ ```
1213
+
1214
+ After:
1215
+
1216
+ ```ts
1217
+ import {createClient} from '@sanity/client'
1218
+ const client = createClient()
1219
+
1220
+ client.createOrReplace({
1221
+ _id: 'tropic-hab',
1222
+ _type: 'hotsauce',
1223
+ name: 'Tropical Habanero',
1224
+ ingredients: [],
1225
+ })
1226
+ ```
1227
+
1228
+ ### `client.auth` is removed, replace with `client.request`<!-- omit in toc -->
1229
+
1230
+ Before:
1231
+
1232
+ ```ts
1233
+ import createClient from '@sanity/client'
1234
+ const client = createClient()
1235
+
1236
+ /**
1237
+ * Fetch available login providers
1238
+ */
1239
+ const loginProviders = await client.auth.getLoginProviders()
1240
+ /**
1241
+ * Revoke the configured session/token
1242
+ */
1243
+ await client.auth.logout()
1244
+ ```
1245
+
1246
+ After:
1247
+
1248
+ ```ts
1249
+ import {createclient, type AuthProviderResponse} from '@sanity/client'
1250
+ const client = createClient()
1251
+
1252
+ /**
1253
+ * Fetch available login providers
1254
+ */
1255
+ const loginProviders = await client.request<AuthProviderResponse>({uri: '/auth/providers'})
1256
+ /**
1257
+ * Revoke the configured session/token
1258
+ */
1259
+ await client.request<void>({uri: '/auth/logout', method: 'POST'})
1260
+ ```
1261
+
1145
1262
  [modern browsers]: https://browsersl.ist/#q=%3E+0.2%25+and+supports+es6-module+and+supports+es6-module-dynamic-import+and+not+dead+and+not+IE+11
1146
1263
  [Deno]: https://deno.land/
1147
1264
  [Edge Runtime]: https://edge-runtime.vercel.sh/
@@ -1157,4 +1274,8 @@ client.createOrReplace(doc, options)
1157
1274
  [api-cdn]: https://www.sanity.io/docs/api-cdn
1158
1275
  [CommonJS]: https://nodejs.org/api/modules.html#modules-commonjs-modules
1159
1276
  [TypeScript]: https://www.typescriptlang.org/
1160
- [api-versioning]: http://sanity.io/docs/api-versioning
1277
+ [api-versioning]: http://sanity.io/docs/api-versioning
1278
+ [zod]: https://zod.dev/
1279
+ [groqd]: https://github.com/FormidableLabs/groqd#readme
1280
+ [AbortSignal]: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
1281
+ [AbortController]: https://developer.mozilla.org/en-US/docs/Web/API/AbortController