@sanity/client 3.2.2 → 4.0.0-alpha.esm.2

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 (62) hide show
  1. package/README.md +43 -26
  2. package/dist/browser/sanityClient.js +956 -0
  3. package/dist/node/sanityClient.js +969 -0
  4. package/lib/assets/assetsClient.js +132 -106
  5. package/lib/auth/authClient.js +38 -19
  6. package/lib/config.js +25 -13
  7. package/lib/data/dataMethods.js +35 -30
  8. package/lib/data/encodeQueryString.js +8 -2
  9. package/lib/data/listen.js +25 -21
  10. package/lib/data/patch.js +169 -118
  11. package/lib/data/transaction.js +134 -88
  12. package/lib/datasets/datasetsClient.js +63 -32
  13. package/lib/http/browserMiddleware.js +6 -1
  14. package/lib/http/errors.js +12 -8
  15. package/lib/http/nodeMiddleware.js +16 -9
  16. package/lib/http/queryString.js +9 -2
  17. package/lib/http/request.js +27 -24
  18. package/lib/http/requestOptions.js +10 -6
  19. package/lib/projects/projectsClient.js +37 -18
  20. package/lib/sanityClient.js +143 -105
  21. package/lib/users/usersClient.js +28 -11
  22. package/lib/util/defaults.js +12 -4
  23. package/lib/util/getSelection.js +7 -2
  24. package/lib/util/observable.js +24 -13
  25. package/lib/util/once.js +9 -2
  26. package/lib/util/pick.js +9 -2
  27. package/lib/validators.js +38 -15
  28. package/lib/warnings.js +14 -6
  29. package/package.json +22 -3
  30. package/sanityClient.d.ts +3 -13
  31. package/src/assets/assetsClient.js +132 -0
  32. package/src/auth/authClient.js +13 -0
  33. package/src/config.js +93 -0
  34. package/src/data/dataMethods.js +182 -0
  35. package/src/data/encodeQueryString.js +18 -0
  36. package/src/data/listen.js +159 -0
  37. package/src/data/patch.js +119 -0
  38. package/src/data/transaction.js +103 -0
  39. package/src/datasets/datasetsClient.js +28 -0
  40. package/src/http/browserMiddleware.js +1 -0
  41. package/src/http/errors.js +53 -0
  42. package/src/http/nodeMiddleware.js +11 -0
  43. package/src/http/queryString.js +10 -0
  44. package/src/http/request.js +50 -0
  45. package/src/http/requestOptions.js +29 -0
  46. package/src/projects/projectsClient.js +13 -0
  47. package/src/sanityClient.js +124 -0
  48. package/src/users/usersClient.js +9 -0
  49. package/src/util/defaults.js +9 -0
  50. package/src/util/getSelection.js +17 -0
  51. package/src/util/observable.js +6 -0
  52. package/src/util/once.js +12 -0
  53. package/src/util/pick.js +9 -0
  54. package/src/validators.js +76 -0
  55. package/src/warnings.js +25 -0
  56. package/test/client.test.js +188 -41
  57. package/test/encodeQueryString.test.js +3 -1
  58. package/test/helpers/sseServer.js +2 -1
  59. package/test/listen.test.js +4 -2
  60. package/test/warnings.test.disabled.js +8 -4
  61. package/umd/sanityClient.js +38 -38
  62. package/umd/sanityClient.min.js +1 -1
@@ -0,0 +1,76 @@
1
+ const VALID_ASSET_TYPES = ['image', 'file']
2
+ const VALID_INSERT_LOCATIONS = ['before', 'after', 'replace']
3
+
4
+ export const dataset = (name) => {
5
+ if (!/^(~[a-z0-9]{1}[-\w]{0,63}|[a-z0-9]{1}[-\w]{0,63})$/.test(name)) {
6
+ throw new Error(
7
+ 'Datasets can only contain lowercase characters, numbers, underscores and dashes, and start with tilde, and be maximum 64 characters'
8
+ )
9
+ }
10
+ }
11
+
12
+ export const projectId = (id) => {
13
+ if (!/^[-a-z0-9]+$/i.test(id)) {
14
+ throw new Error('`projectId` can only contain only a-z, 0-9 and dashes')
15
+ }
16
+ }
17
+
18
+ export const validateAssetType = (type) => {
19
+ if (VALID_ASSET_TYPES.indexOf(type) === -1) {
20
+ throw new Error(`Invalid asset type: ${type}. Must be one of ${VALID_ASSET_TYPES.join(', ')}`)
21
+ }
22
+ }
23
+
24
+ export const validateObject = (op, val) => {
25
+ if (val === null || typeof val !== 'object' || Array.isArray(val)) {
26
+ throw new Error(`${op}() takes an object of properties`)
27
+ }
28
+ }
29
+
30
+ export const validateDocumentId = (op, id) => {
31
+ if (typeof id !== 'string' || !/^[a-z0-9_.-]+$/i.test(id)) {
32
+ throw new Error(`${op}(): "${id}" is not a valid document ID`)
33
+ }
34
+ }
35
+
36
+ export const requireDocumentId = (op, doc) => {
37
+ if (!doc._id) {
38
+ throw new Error(`${op}() requires that the document contains an ID ("_id" property)`)
39
+ }
40
+
41
+ validateDocumentId(op, doc._id)
42
+ }
43
+
44
+ export const validateInsert = (at, selector, items) => {
45
+ const signature = 'insert(at, selector, items)'
46
+ if (VALID_INSERT_LOCATIONS.indexOf(at) === -1) {
47
+ const valid = VALID_INSERT_LOCATIONS.map((loc) => `"${loc}"`).join(', ')
48
+ throw new Error(`${signature} takes an "at"-argument which is one of: ${valid}`)
49
+ }
50
+
51
+ if (typeof selector !== 'string') {
52
+ throw new Error(`${signature} takes a "selector"-argument which must be a string`)
53
+ }
54
+
55
+ if (!Array.isArray(items)) {
56
+ throw new Error(`${signature} takes an "items"-argument which must be an array`)
57
+ }
58
+ }
59
+
60
+ export const hasDataset = (config) => {
61
+ if (!config.dataset) {
62
+ throw new Error('`dataset` must be provided to perform queries')
63
+ }
64
+
65
+ return config.dataset || ''
66
+ }
67
+
68
+ export const requestTag = (tag) => {
69
+ if (typeof tag !== 'string' || !/^[a-z0-9._-]{1,75}$/i.test(tag)) {
70
+ throw new Error(
71
+ `Tag can only contain alphanumeric characters, underscores, dashes and dots, and be between one and 75 characters long.`
72
+ )
73
+ }
74
+
75
+ return tag
76
+ }
@@ -0,0 +1,25 @@
1
+ import {generateHelpUrl} from '@sanity/generate-help-url'
2
+ import {once} from './util/once'
3
+
4
+ const createWarningPrinter = (message) =>
5
+ // eslint-disable-next-line no-console
6
+ once((...args) => console.warn(message.join(' '), ...args))
7
+
8
+ export const printCdnWarning = createWarningPrinter([
9
+ 'You are not using the Sanity CDN. That means your data is always fresh, but the CDN is faster and',
10
+ `cheaper. Think about it! For more info, see ${generateHelpUrl('js-client-cdn-configuration')}.`,
11
+ 'To hide this warning, please set the `useCdn` option to either `true` or `false` when creating',
12
+ 'the client.',
13
+ ])
14
+
15
+ export const printBrowserTokenWarning = createWarningPrinter([
16
+ 'You have configured Sanity client to use a token in the browser. This may cause unintentional security issues.',
17
+ `See ${generateHelpUrl(
18
+ 'js-client-browser-token'
19
+ )} for more information and how to hide this warning.`,
20
+ ])
21
+
22
+ export const printNoApiVersionSpecifiedWarning = createWarningPrinter([
23
+ 'Using the Sanity client without specifying an API version is deprecated.',
24
+ `See ${generateHelpUrl('js-client-api-version')}`,
25
+ ])
@@ -1,3 +1,5 @@
1
+ // eslint-disable-next-line no-global-assign -- we know what we're doing ESlint ;)
2
+ require = require('esm')(module)
1
3
  const test = require('tape')
2
4
  const nock = require('nock')
3
5
  const assign = require('xtend')
@@ -6,9 +8,7 @@ const fs = require('fs')
6
8
  const validators = require('../src/validators')
7
9
  const observableOf = require('rxjs').of
8
10
  const {filter} = require('rxjs/operators')
9
- const sanityClient = require('../src/sanityClient')
10
-
11
- const SanityClient = sanityClient
11
+ const {createClient, SanityClient} = require('../src/sanityClient')
12
12
  const noop = () => {
13
13
  /* intentional noop */
14
14
  }
@@ -26,7 +26,7 @@ const clientConfig = {
26
26
  useCdn: false,
27
27
  }
28
28
 
29
- const getClient = (conf) => sanityClient(assign({}, clientConfig, conf || {}))
29
+ const getClient = (conf) => createClient(assign({}, clientConfig, conf || {}))
30
30
  const fixture = (name) => path.join(__dirname, 'fixtures', name)
31
31
  const ifError = (t) => (err) => {
32
32
  t.ifError(err)
@@ -38,20 +38,20 @@ const ifError = (t) => (err) => {
38
38
  /*****************
39
39
  * BASE CLIENT *
40
40
  *****************/
41
- test('can construct client with new keyword', (t) => {
41
+ test('can create a client with new keyword', (t) => {
42
42
  const client = new SanityClient({projectId: 'abc123'})
43
43
  t.equal(client.config().projectId, 'abc123', 'constructor opts are set')
44
44
  t.end()
45
45
  })
46
46
 
47
47
  test('can construct client without new keyword', (t) => {
48
- const client = sanityClient({projectId: 'abc123'})
48
+ const client = createClient({projectId: 'abc123'})
49
49
  t.equal(client.config().projectId, 'abc123', 'constructor opts are set')
50
50
  t.end()
51
51
  })
52
52
 
53
53
  test('can get and set config', (t) => {
54
- const client = sanityClient({projectId: 'abc123'})
54
+ const client = createClient({projectId: 'abc123'})
55
55
  t.equal(client.config().projectId, 'abc123', 'constructor opts are set')
56
56
  t.equal(client.config({projectId: 'def456'}), client, 'returns client on set')
57
57
  t.equal(client.config().projectId, 'def456', 'new config is set')
@@ -59,7 +59,7 @@ test('can get and set config', (t) => {
59
59
  })
60
60
 
61
61
  test('config getter returns a cloned object', (t) => {
62
- const client = sanityClient({projectId: 'abc123'})
62
+ const client = createClient({projectId: 'abc123'})
63
63
  t.equal(client.config().projectId, 'abc123', 'constructor opts are set')
64
64
  const config = client.config()
65
65
  config.projectId = 'def456'
@@ -68,7 +68,7 @@ test('config getter returns a cloned object', (t) => {
68
68
  })
69
69
 
70
70
  test('calling config() reconfigures observable API too', (t) => {
71
- const client = sanityClient({projectId: 'abc123'})
71
+ const client = createClient({projectId: 'abc123'})
72
72
 
73
73
  client.config({projectId: 'def456'})
74
74
  t.equal(client.observable.config().projectId, 'def456', 'Observable API gets reconfigured')
@@ -76,7 +76,7 @@ test('calling config() reconfigures observable API too', (t) => {
76
76
  })
77
77
 
78
78
  test('can clone client', (t) => {
79
- const client = sanityClient({projectId: 'abc123'})
79
+ const client = createClient({projectId: 'abc123'})
80
80
  t.equal(client.config().projectId, 'abc123', 'constructor opts are set')
81
81
 
82
82
  const client2 = client.clone()
@@ -87,7 +87,7 @@ test('can clone client', (t) => {
87
87
  })
88
88
 
89
89
  test('can clone client with new config', (t) => {
90
- const client = sanityClient({projectId: 'abc123', apiVersion: 'v2021-03-25'})
90
+ const client = createClient({projectId: 'abc123', apiVersion: 'v2021-03-25'})
91
91
  t.equal(client.config().projectId, 'abc123', 'constructor opts are set')
92
92
  t.equal(client.config().apiVersion, '2021-03-25', 'constructor opts are set')
93
93
 
@@ -101,18 +101,18 @@ test('can clone client with new config', (t) => {
101
101
  })
102
102
 
103
103
  test('throws if no projectId is set', (t) => {
104
- t.throws(sanityClient, /projectId/)
104
+ t.throws(createClient, /projectId/)
105
105
  t.end()
106
106
  })
107
107
 
108
108
  test('throws on invalid project ids', (t) => {
109
- t.throws(() => sanityClient({projectId: '*foo*'}), /projectId.*?can only contain/i)
109
+ t.throws(() => createClient({projectId: '*foo*'}), /projectId.*?can only contain/i)
110
110
  t.end()
111
111
  })
112
112
 
113
113
  test('throws on invalid dataset names', (t) => {
114
114
  t.throws(
115
- () => sanityClient({projectId: 'abc123', dataset: '*foo*'}),
115
+ () => createClient({projectId: 'abc123', dataset: '*foo*'}),
116
116
  /Datasets can only contain/i
117
117
  )
118
118
  t.end()
@@ -120,7 +120,7 @@ test('throws on invalid dataset names', (t) => {
120
120
 
121
121
  test('throws on invalid request tag prefix', (t) => {
122
122
  t.throws(
123
- () => sanityClient({projectId: 'abc123', dataset: 'foo', requestTagPrefix: 'no#shot'}),
123
+ () => createClient({projectId: 'abc123', dataset: 'foo', requestTagPrefix: 'no#shot'}),
124
124
  /tag can only contain alphanumeric/i
125
125
  )
126
126
  t.end()
@@ -128,7 +128,7 @@ test('throws on invalid request tag prefix', (t) => {
128
128
 
129
129
  test('accepts alias in dataset field', (t) => {
130
130
  t.doesNotThrow(
131
- () => sanityClient({projectId: 'abc123', dataset: '~alias'}),
131
+ () => createClient({projectId: 'abc123', dataset: '~alias'}),
132
132
  /Datasets can only contain/i
133
133
  )
134
134
  t.end()
@@ -244,7 +244,7 @@ test('can request list of projects', (t) => {
244
244
  .get('/v1/projects')
245
245
  .reply(200, [{projectId: 'foo'}, {projectId: 'bar'}])
246
246
 
247
- const client = sanityClient({useProjectHostname: false, apiHost: `https://${apiHost}`})
247
+ const client = createClient({useProjectHostname: false, apiHost: `https://${apiHost}`})
248
248
  client.projects
249
249
  .list()
250
250
  .then((projects) => {
@@ -260,7 +260,7 @@ test('can request list of projects (custom api version)', (t) => {
260
260
  .get('/v2019-01-29/projects')
261
261
  .reply(200, [{projectId: 'foo'}, {projectId: 'bar'}])
262
262
 
263
- const client = sanityClient({
263
+ const client = createClient({
264
264
  useProjectHostname: false,
265
265
  apiHost: `https://${apiHost}`,
266
266
  apiVersion: '2019-01-29',
@@ -291,7 +291,7 @@ test('can request project by id', (t) => {
291
291
 
292
292
  nock(`https://${apiHost}`).get('/v1/projects/n1f7y').reply(200, doc)
293
293
 
294
- const client = sanityClient({useProjectHostname: false, apiHost: `https://${apiHost}`})
294
+ const client = createClient({useProjectHostname: false, apiHost: `https://${apiHost}`})
295
295
  client.projects
296
296
  .getById('n1f7y')
297
297
  .then((project) => t.deepEqual(project, doc))
@@ -627,7 +627,7 @@ test('populates response body on errors', (t) => {
627
627
 
628
628
  test('throws if trying to perform data request without dataset', (t) => {
629
629
  t.throws(
630
- () => sanityClient({projectId: 'foo'}).fetch('blah'),
630
+ () => createClient({projectId: 'foo'}).fetch('blah'),
631
631
  Error,
632
632
  /dataset.*?must be provided/
633
633
  )
@@ -748,6 +748,64 @@ test('can tell create() to use non-default visibility mode', (t) => {
748
748
  .then(t.end)
749
749
  })
750
750
 
751
+ test('can tell create() to auto-generate array keys', (t) => {
752
+ const doc = {
753
+ _id: 'abc123',
754
+ name: 'Dromaeosauridae',
755
+ genus: [{_type: 'dino', name: 'Velociraptor'}],
756
+ }
757
+ nock(projectHost())
758
+ .post(
759
+ '/v1/data/mutate/foo?returnIds=true&returnDocuments=true&autoGenerateArrayKeys=true&visibility=sync',
760
+ {
761
+ mutations: [{create: doc}],
762
+ }
763
+ )
764
+ .reply(200, {
765
+ transactionId: 'abc123',
766
+ results: [
767
+ {
768
+ id: 'abc123',
769
+ document: {...doc, genus: [{...doc.genus[0], _key: 'r4p70r'}]},
770
+ operation: 'create',
771
+ },
772
+ ],
773
+ })
774
+
775
+ getClient()
776
+ .create(doc, {autoGenerateArrayKeys: true})
777
+ .then((res) => {
778
+ t.equal(res._id, 'abc123', 'document id returned')
779
+ t.equal(res.genus[0]._key, 'r4p70r', 'array keys generated returned')
780
+ })
781
+ .catch(t.ifError)
782
+ .then(t.end)
783
+ })
784
+
785
+ test('can tell create() to do a dry-run', (t) => {
786
+ const doc = {_id: 'abc123', name: 'Dromaeosauridae'}
787
+ nock(projectHost())
788
+ .post('/v1/data/mutate/foo?dryRun=true&returnIds=true&returnDocuments=true&visibility=sync', {
789
+ mutations: [{create: doc}],
790
+ })
791
+ .reply(200, {
792
+ transactionId: 'abc123',
793
+ results: [
794
+ {
795
+ id: 'abc123',
796
+ document: doc,
797
+ operation: 'create',
798
+ },
799
+ ],
800
+ })
801
+
802
+ getClient()
803
+ .create(doc, {dryRun: true})
804
+ .then((res) => t.equal(res._id, 'abc123', 'document id returned'))
805
+ .catch(t.ifError)
806
+ .then(t.end)
807
+ })
808
+
751
809
  test('createIfNotExists() sends correct mutation', (t) => {
752
810
  const doc = {_id: 'abc123', name: 'Raptor'}
753
811
  const expectedBody = {mutations: [{createIfNotExists: doc}]}
@@ -940,7 +998,52 @@ test('mutate() accepts request tag', (t) => {
940
998
  .then(() => t.end())
941
999
  })
942
1000
 
943
- test('mutate() accepts skipCrossDatasetReferenceValidation', (t) => {
1001
+ test('mutate() accepts `autoGenerateArrayKeys`', (t) => {
1002
+ const mutations = [
1003
+ {
1004
+ create: {
1005
+ _id: 'abc123',
1006
+ _type: 'post',
1007
+ items: [{_type: 'block', children: [{_type: 'span', text: 'Hello there'}]}],
1008
+ },
1009
+ },
1010
+ ]
1011
+
1012
+ nock(projectHost())
1013
+ .post(
1014
+ '/v1/data/mutate/foo?returnIds=true&returnDocuments=true&visibility=sync&autoGenerateArrayKeys=true',
1015
+ {mutations}
1016
+ )
1017
+ .reply(200, {
1018
+ transactionId: 'foo',
1019
+ results: [{id: 'abc123', operation: 'create', document: {_id: 'abc123'}}],
1020
+ })
1021
+
1022
+ getClient()
1023
+ .mutate(mutations, {autoGenerateArrayKeys: true})
1024
+ .catch(t.ifError)
1025
+ .then(() => t.end())
1026
+ })
1027
+
1028
+ test('mutate() accepts `dryRun`', (t) => {
1029
+ const mutations = [{create: {_id: 'abc123', _type: 'post'}}]
1030
+
1031
+ nock(projectHost())
1032
+ .post('/v1/data/mutate/foo?dryRun=true&returnIds=true&returnDocuments=true&visibility=sync', {
1033
+ mutations,
1034
+ })
1035
+ .reply(200, {
1036
+ transactionId: 'foo',
1037
+ results: [{id: 'abc123', operation: 'create', document: {_id: 'abc123'}}],
1038
+ })
1039
+
1040
+ getClient()
1041
+ .mutate(mutations, {dryRun: true})
1042
+ .catch(t.ifError)
1043
+ .then(() => t.end())
1044
+ })
1045
+
1046
+ test('mutate() accepts `skipCrossDatasetReferenceValidation`', (t) => {
944
1047
  const mutations = [{delete: {id: 'abc123'}}]
945
1048
 
946
1049
  nock(projectHost())
@@ -959,6 +1062,29 @@ test('mutate() accepts skipCrossDatasetReferenceValidation', (t) => {
959
1062
  .then(() => t.end())
960
1063
  })
961
1064
 
1065
+ test('mutate() skips/falls back to defaults on undefined but known properties', (t) => {
1066
+ const mutations = [{delete: {id: 'abc123'}}]
1067
+
1068
+ nock(projectHost())
1069
+ .post('/v1/data/mutate/foo?tag=foobar&returnIds=true&returnDocuments=true&visibility=sync', {
1070
+ mutations,
1071
+ })
1072
+ .reply(200, {
1073
+ transactionId: 'foo',
1074
+ results: [{id: 'abc123', operation: 'delete', document: {_id: 'abc123'}}],
1075
+ })
1076
+
1077
+ getClient()
1078
+ .mutate(mutations, {
1079
+ tag: 'foobar',
1080
+ skipCrossDatasetReferenceValidation: undefined,
1081
+ returnDocuments: undefined,
1082
+ autoGenerateArrayKeys: undefined,
1083
+ })
1084
+ .catch(t.ifError)
1085
+ .then(() => t.end())
1086
+ })
1087
+
962
1088
  test('uses GET for queries below limit', (t) => {
963
1089
  // Please dont ever do this. Just... don't.
964
1090
  const clause = []
@@ -1054,7 +1180,7 @@ test('uses POST for long queries, but puts request tag as query param', (t) => {
1054
1180
  })
1055
1181
 
1056
1182
  test('uses POST for long queries also towards CDN', (t) => {
1057
- const client = sanityClient({projectId: 'abc123', dataset: 'foo', useCdn: true})
1183
+ const client = createClient({projectId: 'abc123', dataset: 'foo', useCdn: true})
1058
1184
 
1059
1185
  const clause = []
1060
1186
  const params = {}
@@ -1316,6 +1442,25 @@ test('executes patch with request tag when commit() is called with tag', (t) =>
1316
1442
  .then(t.end)
1317
1443
  })
1318
1444
 
1445
+ test('executes patch with auto generate key option if specified commit()', (t) => {
1446
+ const expectedPatch = {patch: {id: 'abc123', set: {visited: true}}}
1447
+ nock(projectHost())
1448
+ .post('/v1/data/mutate/foo?returnIds=true&autoGenerateArrayKeys=true&visibility=sync', {
1449
+ mutations: [expectedPatch],
1450
+ })
1451
+ .reply(200, {transactionId: 'blatti'})
1452
+
1453
+ getClient()
1454
+ .patch('abc123')
1455
+ .set({visited: true})
1456
+ .commit({returnDocuments: false, autoGenerateArrayKeys: true})
1457
+ .then((res) => {
1458
+ t.equal(res.transactionId, 'blatti', 'applies given patch')
1459
+ })
1460
+ .catch(t.ifError)
1461
+ .then(t.end)
1462
+ })
1463
+
1319
1464
  test('executes patch with given token override commit() is called', (t) => {
1320
1465
  const expectedPatch = {patch: {id: 'abc123', inc: {count: 1}, set: {visited: true}}}
1321
1466
  nock(projectHost(), {reqheaders: {Authorization: 'Bearer abc123'}})
@@ -1424,7 +1569,7 @@ test('patch has toJSON() which serializes patch', (t) => {
1424
1569
  })
1425
1570
 
1426
1571
  test('Patch is available on client and can be used without instantiated client', (t) => {
1427
- const patch = new sanityClient.Patch('foo.bar')
1572
+ const patch = new createClient.Patch('foo.bar')
1428
1573
  t.deepEqual(
1429
1574
  patch.inc({foo: 1}).dec({bar: 2}).serialize(),
1430
1575
  {id: 'foo.bar', inc: {foo: 1}, dec: {bar: 2}},
@@ -1434,7 +1579,7 @@ test('Patch is available on client and can be used without instantiated client',
1434
1579
  })
1435
1580
 
1436
1581
  test('patch commit() throws if called without a client', (t) => {
1437
- const patch = new sanityClient.Patch('foo.bar')
1582
+ const patch = new createClient.Patch('foo.bar')
1438
1583
  t.throws(() => patch.dec({bar: 2}).commit(), /client.*mutate/i)
1439
1584
  t.end()
1440
1585
  })
@@ -1646,7 +1791,7 @@ test('transaction has toJSON() which serializes patch', (t) => {
1646
1791
  })
1647
1792
 
1648
1793
  test('Transaction is available on client and can be used without instantiated client', (t) => {
1649
- const trans = new sanityClient.Transaction()
1794
+ const trans = new createClient.Transaction()
1650
1795
  t.deepEqual(
1651
1796
  trans.delete('barfoo').serialize(),
1652
1797
  [{delete: {id: 'barfoo'}}],
@@ -1656,7 +1801,7 @@ test('Transaction is available on client and can be used without instantiated cl
1656
1801
  })
1657
1802
 
1658
1803
  test('transaction can be created without client and passed to mutate()', (t) => {
1659
- const trx = new sanityClient.Transaction()
1804
+ const trx = new createClient.Transaction()
1660
1805
  trx.delete('foo')
1661
1806
 
1662
1807
  const mutations = [{delete: {id: 'foo'}}]
@@ -1671,7 +1816,7 @@ test('transaction can be created without client and passed to mutate()', (t) =>
1671
1816
  })
1672
1817
 
1673
1818
  test('transaction commit() throws if called without a client', (t) => {
1674
- const trans = new sanityClient.Transaction()
1819
+ const trans = new createClient.Transaction()
1675
1820
  t.throws(() => trans.delete('foo.bar').commit(), /client.*mutate/i)
1676
1821
  t.end()
1677
1822
  })
@@ -2193,7 +2338,7 @@ test('can retrieve user by id', (t) => {
2193
2338
  * CDN API USAGE *
2194
2339
  *****************/
2195
2340
  test('will use live API by default', (t) => {
2196
- const client = sanityClient({projectId: 'abc123', dataset: 'foo'})
2341
+ const client = createClient({projectId: 'abc123', dataset: 'foo'})
2197
2342
 
2198
2343
  const response = {result: []}
2199
2344
  nock('https://abc123.api.sanity.io').get('/v1/data/query/foo?query=*').reply(200, response)
@@ -2208,7 +2353,7 @@ test('will use live API by default', (t) => {
2208
2353
  })
2209
2354
 
2210
2355
  test('will use CDN API if told to', (t) => {
2211
- const client = sanityClient({projectId: 'abc123', dataset: 'foo', useCdn: true})
2356
+ const client = createClient({projectId: 'abc123', dataset: 'foo', useCdn: true})
2212
2357
 
2213
2358
  const response = {result: []}
2214
2359
  nock('https://abc123.apicdn.sanity.io').get('/v1/data/query/foo?query=*').reply(200, response)
@@ -2223,7 +2368,7 @@ test('will use CDN API if told to', (t) => {
2223
2368
  })
2224
2369
 
2225
2370
  test('will use live API for mutations', (t) => {
2226
- const client = sanityClient({projectId: 'abc123', dataset: 'foo', useCdn: true})
2371
+ const client = createClient({projectId: 'abc123', dataset: 'foo', useCdn: true})
2227
2372
 
2228
2373
  nock('https://abc123.api.sanity.io')
2229
2374
  .post('/v1/data/mutate/foo?returnIds=true&returnDocuments=true&visibility=sync')
@@ -2233,7 +2378,7 @@ test('will use live API for mutations', (t) => {
2233
2378
  })
2234
2379
 
2235
2380
  test('will use cdn for queries even when with token specified', (t) => {
2236
- const client = sanityClient({
2381
+ const client = createClient({
2237
2382
  projectId: 'abc123',
2238
2383
  dataset: 'foo',
2239
2384
  useCdn: true,
@@ -2249,8 +2394,7 @@ test('will use cdn for queries even when with token specified', (t) => {
2249
2394
  })
2250
2395
 
2251
2396
  test('allows overriding headers', (t) => {
2252
-
2253
- const client = sanityClient({
2397
+ const client = createClient({
2254
2398
  projectId: 'abc123',
2255
2399
  dataset: 'foo',
2256
2400
  token: 'foo',
@@ -2261,12 +2405,15 @@ test('allows overriding headers', (t) => {
2261
2405
  .get('/v1/data/query/foo?query=*')
2262
2406
  .reply(200, {result: []})
2263
2407
 
2264
- client.fetch('*', {}, {headers: {foo: 'bar'}}).then(noop).catch(t.ifError).then(t.end)
2265
-
2408
+ client
2409
+ .fetch('*', {}, {headers: {foo: 'bar'}})
2410
+ .then(noop)
2411
+ .catch(t.ifError)
2412
+ .then(t.end)
2266
2413
  })
2267
2414
 
2268
2415
  test('will use live API if withCredentials is set to true', (t) => {
2269
- const client = sanityClient({
2416
+ const client = createClient({
2270
2417
  withCredentials: true,
2271
2418
  projectId: 'abc123',
2272
2419
  dataset: 'foo',
@@ -2371,24 +2518,24 @@ test('ServerError includes message in stack', (t) => {
2371
2518
  })
2372
2519
 
2373
2520
  test('exposes ClientError', (t) => {
2374
- t.equal(typeof sanityClient.ClientError, 'function')
2521
+ t.equal(typeof createClient.ClientError, 'function')
2375
2522
  const error = new SanityClient.ClientError({statusCode: 400, headers: {}, body: {}})
2376
2523
  t.ok(error instanceof Error)
2377
- t.ok(error instanceof sanityClient.ClientError)
2524
+ t.ok(error instanceof createClient.ClientError)
2378
2525
  t.end()
2379
2526
  })
2380
2527
 
2381
2528
  test('exposes ServerError', (t) => {
2382
- t.equal(typeof sanityClient.ServerError, 'function')
2529
+ t.equal(typeof createClient.ServerError, 'function')
2383
2530
  const error = new SanityClient.ServerError({statusCode: 500, headers: {}, body: {}})
2384
2531
  t.ok(error instanceof Error)
2385
- t.ok(error instanceof sanityClient.ServerError)
2532
+ t.ok(error instanceof createClient.ServerError)
2386
2533
  t.end()
2387
2534
  })
2388
2535
 
2389
2536
  // Don't rely on this unless you're working at Sanity Inc ;)
2390
2537
  test('exposes default requester', (t) => {
2391
- t.equal(typeof sanityClient.requester, 'function')
2538
+ t.equal(typeof createClient.requester, 'function')
2392
2539
  t.end()
2393
2540
  })
2394
2541
 
@@ -1,5 +1,7 @@
1
+ // eslint-disable-next-line no-global-assign -- we know what we're doing ESlint ;)
2
+ require = require('esm')(module)
1
3
  const test = require('tape')
2
- const encode = require('../src/data/encodeQueryString')
4
+ const {encodeQueryString: encode} = require('../src/data/encodeQueryString')
3
5
 
4
6
  test('can encode basic query without parameters', (t) => {
5
7
  const query = 'gamedb.game[maxPlayers == 64]'
@@ -2,7 +2,8 @@
2
2
  // (Node 4 compat)
3
3
 
4
4
  'use strict'
5
-
5
+ // eslint-disable-next-line no-global-assign -- we know what we're doing ESlint ;)
6
+ require = require('esm')(module)
6
7
  const http = require('http')
7
8
  const SseChannel = require('sse-channel')
8
9
 
@@ -2,14 +2,16 @@
2
2
  // (Node 4 compat)
3
3
 
4
4
  'use strict'
5
+ // eslint-disable-next-line no-global-assign -- we know what we're doing ESlint ;)
6
+ require = require('esm')(module)
5
7
 
6
8
  const test = require('tape')
7
9
  const assign = require('xtend')
8
- const sanityClient = require('../src/sanityClient')
10
+ const {createClient} = require('../src/sanityClient')
9
11
  const sseServer = require('./helpers/sseServer')
10
12
 
11
13
  const getClient = (options) =>
12
- sanityClient(
14
+ createClient(
13
15
  assign(
14
16
  {
15
17
  dataset: 'prod',
@@ -1,3 +1,5 @@
1
+ // eslint-disable-next-line no-global-assign -- we know what we're doing ESlint ;)
2
+ require = require('esm')(module)
1
3
  // This test suite fails using tape but should pass if running with as a node script
2
4
  const test = require('tape')
3
5
  const nock = require('nock')
@@ -11,10 +13,12 @@ const stub = (target, prop, stubbed) => {
11
13
  }
12
14
  }
13
15
 
14
- const combine = (...fns) => () => {
15
- const [head, ...tail] = fns
16
- return tail.reduce((acc, fn) => fn(acc), head())
17
- }
16
+ const combine =
17
+ (...fns) =>
18
+ () => {
19
+ const [head, ...tail] = fns
20
+ return tail.reduce((acc, fn) => fn(acc), head())
21
+ }
18
22
 
19
23
  /**************************
20
24
  * CLIENT CONFIG WARNINGS *