@sanity/client 4.0.1-1 → 5.0.0-esm.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.
Files changed (68) hide show
  1. package/dist/index.browser.cjs +1335 -0
  2. package/dist/index.browser.cjs.map +1 -0
  3. package/dist/index.browser.js +1312 -0
  4. package/dist/index.browser.js.map +1 -0
  5. package/dist/index.cjs +1344 -0
  6. package/dist/index.cjs.js +15 -0
  7. package/dist/index.cjs.map +1 -0
  8. package/{sanityClient.d.ts → dist/index.d.ts} +991 -1117
  9. package/dist/index.js +1321 -0
  10. package/dist/index.js.map +1 -0
  11. package/package.json +81 -73
  12. package/src/SanityClient.ts +1261 -0
  13. package/src/assets/AssetsClient.ts +164 -0
  14. package/src/auth/AuthClient.ts +43 -0
  15. package/src/config.ts +95 -0
  16. package/src/data/dataMethods.ts +328 -0
  17. package/src/data/encodeQueryString.ts +28 -0
  18. package/src/data/listen.ts +195 -0
  19. package/src/data/patch.ts +353 -0
  20. package/src/data/transaction.ts +352 -0
  21. package/src/datasets/DatasetsClient.ts +97 -0
  22. package/src/generateHelpUrl.ts +5 -0
  23. package/src/http/browserMiddleware.ts +1 -0
  24. package/src/http/errors.ts +68 -0
  25. package/src/http/nodeMiddleware.ts +11 -0
  26. package/src/http/request.ts +50 -0
  27. package/src/http/requestOptions.ts +31 -0
  28. package/src/index.browser.ts +18 -0
  29. package/src/index.ts +57 -0
  30. package/src/projects/ProjectsClient.ts +45 -0
  31. package/src/types.ts +502 -0
  32. package/src/users/UsersClient.ts +46 -0
  33. package/src/util/defaults.ts +8 -0
  34. package/src/util/getSelection.ts +21 -0
  35. package/src/util/once.ts +12 -0
  36. package/src/util/pick.ts +9 -0
  37. package/src/validators.ts +76 -0
  38. package/src/warnings.ts +25 -0
  39. package/umd/sanityClient.js +5199 -5302
  40. package/umd/sanityClient.min.js +13 -13
  41. package/dist/sanityClient.browser.mjs +0 -2806
  42. package/dist/sanityClient.browser.mjs.map +0 -7
  43. package/index.js +0 -7
  44. package/lib/assets/assetsClient.js +0 -145
  45. package/lib/auth/authClient.js +0 -26
  46. package/lib/config.js +0 -88
  47. package/lib/data/dataMethods.js +0 -205
  48. package/lib/data/encodeQueryString.js +0 -31
  49. package/lib/data/listen.js +0 -164
  50. package/lib/data/patch.js +0 -121
  51. package/lib/data/transaction.js +0 -117
  52. package/lib/datasets/datasetsClient.js +0 -41
  53. package/lib/generateHelpUrl.js +0 -11
  54. package/lib/http/browserMiddleware.js +0 -9
  55. package/lib/http/errors.js +0 -56
  56. package/lib/http/nodeMiddleware.js +0 -22
  57. package/lib/http/queryString.js +0 -17
  58. package/lib/http/request.js +0 -52
  59. package/lib/http/requestOptions.js +0 -30
  60. package/lib/projects/projectsClient.js +0 -25
  61. package/lib/sanityClient.js +0 -118
  62. package/lib/users/usersClient.js +0 -20
  63. package/lib/util/defaults.js +0 -14
  64. package/lib/util/getSelection.js +0 -24
  65. package/lib/util/once.js +0 -20
  66. package/lib/util/pick.js +0 -17
  67. package/lib/validators.js +0 -76
  68. package/lib/warnings.js +0 -27
@@ -0,0 +1,352 @@
1
+ import type {Observable} from 'rxjs'
2
+
3
+ import type {ObservableSanityClient, SanityClient} from '../SanityClient'
4
+ import type {
5
+ BaseMutationOptions,
6
+ IdentifiedSanityDocumentStub,
7
+ MultipleMutationResult,
8
+ Mutation,
9
+ PatchOperations,
10
+ SanityDocument,
11
+ SanityDocumentStub,
12
+ SingleMutationResult,
13
+ TransactionAllDocumentIdsMutationOptions,
14
+ TransactionAllDocumentsMutationOptions,
15
+ TransactionFirstDocumentIdMutationOptions,
16
+ TransactionFirstDocumentMutationOptions,
17
+ } from '../types'
18
+ import * as validators from '../validators'
19
+ import {ObservablePatch, Patch} from './patch'
20
+
21
+ export type PatchBuilder = (patch: Patch) => Patch
22
+ export type ObservablePatchBuilder = (patch: ObservablePatch) => ObservablePatch
23
+
24
+ const defaultMutateOptions = {returnDocuments: false}
25
+
26
+ export class BaseTransaction {
27
+ protected operations: Mutation[]
28
+ protected trxId?: string
29
+ constructor(operations: Mutation[] = [], transactionId?: string) {
30
+ this.operations = operations
31
+ this.trxId = transactionId
32
+ }
33
+ /**
34
+ * Creates a new Sanity document. If `_id` is provided and already exists, the mutation will fail. If no `_id` is given, one will automatically be generated by the database.
35
+ * The operation is added to the current transaction, ready to be commited by `commit()`
36
+ *
37
+ * @param doc - Document to create. Requires a `_type` property.
38
+ */
39
+ create<R extends Record<string, any> = Record<string, any>>(doc: SanityDocumentStub<R>): this {
40
+ validators.validateObject('create', doc)
41
+ return this._add({create: doc})
42
+ }
43
+
44
+ /**
45
+ * Creates a new Sanity document. If a document with the same `_id` already exists, the create operation will be ignored.
46
+ * The operation is added to the current transaction, ready to be commited by `commit()`
47
+ *
48
+ * @param doc - Document to create if it does not already exist. Requires `_id` and `_type` properties.
49
+ */
50
+ createIfNotExists<R extends Record<string, any> = Record<string, any>>(
51
+ doc: IdentifiedSanityDocumentStub<R>
52
+ ): this {
53
+ const op = 'createIfNotExists'
54
+ validators.validateObject(op, doc)
55
+ validators.requireDocumentId(op, doc)
56
+ return this._add({[op]: doc})
57
+ }
58
+
59
+ /**
60
+ * Creates a new Sanity document, or replaces an existing one if the same `_id` is already used.
61
+ * The operation is added to the current transaction, ready to be commited by `commit()`
62
+ *
63
+ * @param doc - Document to create or replace. Requires `_id` and `_type` properties.
64
+ */
65
+ createOrReplace<R extends Record<string, any> = Record<string, any>>(
66
+ doc: IdentifiedSanityDocumentStub<R>
67
+ ): this {
68
+ const op = 'createOrReplace'
69
+ validators.validateObject(op, doc)
70
+ validators.requireDocumentId(op, doc)
71
+ return this._add({[op]: doc})
72
+ }
73
+
74
+ /**
75
+ * Deletes the document with the given document ID
76
+ * The operation is added to the current transaction, ready to be commited by `commit()`
77
+ *
78
+ * @param documentId - Document ID to delete
79
+ */
80
+ delete(documentId: string): this {
81
+ validators.validateDocumentId('delete', documentId)
82
+ return this._add({delete: {id: documentId}})
83
+ }
84
+
85
+ /**
86
+ * Gets the current transaction ID, if any
87
+ */
88
+ transactionId(): string | undefined
89
+ /**
90
+ * Set the ID of this transaction.
91
+ *
92
+ * @param id - Transaction ID
93
+ */
94
+ transactionId(id: string): this
95
+ transactionId(id?: string): this | string | undefined {
96
+ if (!id) {
97
+ return this.trxId
98
+ }
99
+
100
+ this.trxId = id
101
+ return this
102
+ }
103
+
104
+ /**
105
+ * Return a plain JSON representation of the transaction
106
+ */
107
+ serialize(): Mutation[] {
108
+ return [...this.operations]
109
+ }
110
+
111
+ /**
112
+ * Return a plain JSON representation of the transaction
113
+ */
114
+ toJSON(): Mutation[] {
115
+ return this.serialize()
116
+ }
117
+
118
+ /**
119
+ * Clears the transaction of all operations
120
+ */
121
+ reset(): this {
122
+ this.operations = []
123
+ return this
124
+ }
125
+
126
+ protected _add(mut: Mutation): this {
127
+ this.operations.push(mut)
128
+ return this
129
+ }
130
+ }
131
+
132
+ export class Transaction extends BaseTransaction {
133
+ #client?: SanityClient
134
+ constructor(operations?: Mutation[], client?: SanityClient, transactionId?: string) {
135
+ super(operations, transactionId)
136
+ this.#client = client
137
+ }
138
+
139
+ /**
140
+ * Clones the transaction
141
+ */
142
+ clone(): Transaction {
143
+ return new Transaction([...this.operations], this.#client, this.trxId)
144
+ }
145
+
146
+ /**
147
+ * Commit the transaction, returning a promise that resolves to the first mutated document
148
+ *
149
+ * @param options - Options for the mutation operation
150
+ */
151
+ commit<R extends Record<string, any>>(
152
+ options: TransactionFirstDocumentMutationOptions
153
+ ): Promise<SanityDocument<R>>
154
+ /**
155
+ * Commit the transaction, returning a promise that resolves to an array of the mutated documents
156
+ *
157
+ * @param options - Options for the mutation operation
158
+ */
159
+ commit<R extends Record<string, any>>(
160
+ options: TransactionAllDocumentsMutationOptions
161
+ ): Promise<SanityDocument<R>[]>
162
+ /**
163
+ * Commit the transaction, returning a promise that resolves to a mutation result object
164
+ *
165
+ * @param options - Options for the mutation operation
166
+ */
167
+ commit(options: TransactionFirstDocumentIdMutationOptions): Promise<SingleMutationResult>
168
+ /**
169
+ * Commit the transaction, returning a promise that resolves to a mutation result object
170
+ *
171
+ * @param options - Options for the mutation operation
172
+ */
173
+ commit(options: TransactionAllDocumentIdsMutationOptions): Promise<MultipleMutationResult>
174
+ /**
175
+ * Commit the transaction, returning a promise that resolves to a mutation result object
176
+ *
177
+ * @param options - Options for the mutation operation
178
+ */
179
+ commit(options?: BaseMutationOptions): Promise<MultipleMutationResult>
180
+ commit<R extends Record<string, any> = Record<string, any>>(
181
+ options?:
182
+ | TransactionFirstDocumentMutationOptions
183
+ | TransactionAllDocumentsMutationOptions
184
+ | TransactionFirstDocumentIdMutationOptions
185
+ | TransactionAllDocumentIdsMutationOptions
186
+ | BaseMutationOptions
187
+ ): Promise<
188
+ SanityDocument<R> | SanityDocument<R>[] | SingleMutationResult | MultipleMutationResult
189
+ > {
190
+ if (!this.#client) {
191
+ throw new Error(
192
+ 'No `client` passed to transaction, either provide one or pass the ' +
193
+ 'transaction to a clients `mutate()` method'
194
+ )
195
+ }
196
+
197
+ return this.#client.mutate<R>(
198
+ this.serialize() as any,
199
+ Object.assign({transactionId: this.trxId}, defaultMutateOptions, options || {})
200
+ )
201
+ }
202
+
203
+ /**
204
+ * Performs a patch on the given document ID. Can either be a builder function or an object of patch operations.
205
+ * The operation is added to the current transaction, ready to be commited by `commit()`
206
+ *
207
+ * @param documentId - Document ID to perform the patch operation on
208
+ * @param patchOps - Operations to perform, or a builder function
209
+ */
210
+ patch(documentId: string, patchOps?: PatchBuilder | PatchOperations): this
211
+ /**
212
+ * Adds the given patch instance to the transaction.
213
+ * The operation is added to the current transaction, ready to be commited by `commit()`
214
+ *
215
+ * @param patch - Patch to execute
216
+ */
217
+ patch(patch: Patch): this
218
+ patch(patchOrDocumentId: Patch | string, patchOps?: PatchBuilder | PatchOperations): this {
219
+ const isBuilder = typeof patchOps === 'function'
220
+ const isPatch = typeof patchOrDocumentId !== 'string' && patchOrDocumentId instanceof Patch
221
+
222
+ // transaction.patch(client.patch('documentId').inc({visits: 1}))
223
+ if (isPatch) {
224
+ return this._add({patch: patchOrDocumentId.serialize()})
225
+ }
226
+
227
+ // patch => patch.inc({visits: 1}).set({foo: 'bar'})
228
+ if (isBuilder) {
229
+ const patch = patchOps(new Patch(patchOrDocumentId, {}, this.#client))
230
+ if (!(patch instanceof Patch)) {
231
+ throw new Error('function passed to `patch()` must return the patch')
232
+ }
233
+
234
+ return this._add({patch: patch.serialize()})
235
+ }
236
+
237
+ return this._add({patch: {id: patchOrDocumentId, ...patchOps}})
238
+ }
239
+ }
240
+
241
+ export class ObservableTransaction extends BaseTransaction {
242
+ #client?: ObservableSanityClient
243
+ constructor(operations?: Mutation[], client?: ObservableSanityClient, transactionId?: string) {
244
+ super(operations, transactionId)
245
+ this.#client = client
246
+ }
247
+
248
+ /**
249
+ * Clones the transaction
250
+ */
251
+ clone(): ObservableTransaction {
252
+ return new ObservableTransaction([...this.operations], this.#client, this.trxId)
253
+ }
254
+
255
+ /**
256
+ * Commit the transaction, returning an observable that produces the first mutated document
257
+ *
258
+ * @param options - Options for the mutation operation
259
+ */
260
+ commit<R extends Record<string, any>>(
261
+ options: TransactionFirstDocumentMutationOptions
262
+ ): Observable<SanityDocument<R>>
263
+ /**
264
+ * Commit the transaction, returning an observable that produces an array of the mutated documents
265
+ *
266
+ * @param options - Options for the mutation operation
267
+ */
268
+ commit<R extends Record<string, any>>(
269
+ options: TransactionAllDocumentsMutationOptions
270
+ ): Observable<SanityDocument<R>[]>
271
+ /**
272
+ * Commit the transaction, returning an observable that produces a mutation result object
273
+ *
274
+ * @param options - Options for the mutation operation
275
+ */
276
+ commit(options: TransactionFirstDocumentIdMutationOptions): Observable<SingleMutationResult>
277
+ /**
278
+ * Commit the transaction, returning an observable that produces a mutation result object
279
+ *
280
+ * @param options - Options for the mutation operation
281
+ */
282
+ commit(options: TransactionAllDocumentIdsMutationOptions): Observable<MultipleMutationResult>
283
+ /**
284
+ * Commit the transaction, returning an observable that produces a mutation result object
285
+ *
286
+ * @param options - Options for the mutation operation
287
+ */
288
+ commit(options?: BaseMutationOptions): Observable<MultipleMutationResult>
289
+ commit<R extends Record<string, any> = Record<string, any>>(
290
+ options?:
291
+ | TransactionFirstDocumentMutationOptions
292
+ | TransactionAllDocumentsMutationOptions
293
+ | TransactionFirstDocumentIdMutationOptions
294
+ | TransactionAllDocumentIdsMutationOptions
295
+ | BaseMutationOptions
296
+ ): Observable<
297
+ SanityDocument<R> | SanityDocument<R>[] | SingleMutationResult | MultipleMutationResult
298
+ > {
299
+ if (!this.#client) {
300
+ throw new Error(
301
+ 'No `client` passed to transaction, either provide one or pass the ' +
302
+ 'transaction to a clients `mutate()` method'
303
+ )
304
+ }
305
+
306
+ return this.#client.mutate<R>(
307
+ this.serialize() as any,
308
+ Object.assign({transactionId: this.trxId}, defaultMutateOptions, options || {})
309
+ )
310
+ }
311
+
312
+ /**
313
+ * Performs a patch on the given document ID. Can either be a builder function or an object of patch operations.
314
+ * The operation is added to the current transaction, ready to be commited by `commit()`
315
+ *
316
+ * @param documentId - Document ID to perform the patch operation on
317
+ * @param patchOps - Operations to perform, or a builder function
318
+ */
319
+ patch(documentId: string, patchOps?: ObservablePatchBuilder | PatchOperations): this
320
+ /**
321
+ * Adds the given patch instance to the transaction.
322
+ * The operation is added to the current transaction, ready to be commited by `commit()`
323
+ *
324
+ * @param patch - ObservablePatch to execute
325
+ */
326
+ patch(patch: ObservablePatch): this
327
+ patch(
328
+ patchOrDocumentId: ObservablePatch | string,
329
+ patchOps?: ObservablePatchBuilder | PatchOperations
330
+ ): this {
331
+ const isBuilder = typeof patchOps === 'function'
332
+ const isPatch =
333
+ typeof patchOrDocumentId !== 'string' && patchOrDocumentId instanceof ObservablePatch
334
+
335
+ // transaction.patch(client.patch('documentId').inc({visits: 1}))
336
+ if (isPatch) {
337
+ return this._add({patch: patchOrDocumentId.serialize()})
338
+ }
339
+
340
+ // patch => patch.inc({visits: 1}).set({foo: 'bar'})
341
+ if (isBuilder) {
342
+ const patch = patchOps(new ObservablePatch(patchOrDocumentId, {}, this.#client))
343
+ if (!(patch instanceof ObservablePatch)) {
344
+ throw new Error('function passed to `patch()` must return the patch')
345
+ }
346
+
347
+ return this._add({patch: patch.serialize()})
348
+ }
349
+
350
+ return this._add({patch: {id: patchOrDocumentId, ...patchOps}})
351
+ }
352
+ }
@@ -0,0 +1,97 @@
1
+ import {type Observable} from 'rxjs'
2
+
3
+ import type {ObservableSanityClient, SanityClient} from '../SanityClient'
4
+ import type {DatasetAclMode, DatasetResponse, DatasetsResponse} from '../types'
5
+ import * as validate from '../validators'
6
+
7
+ export class BaseDatasetsClient {
8
+ client: SanityClient | ObservableSanityClient
9
+
10
+ /**
11
+ * Create a new dataset with the given name
12
+ *
13
+ * @param name - Name of the dataset to create
14
+ * @param options - Options for the dataset
15
+ */
16
+ create(
17
+ this: DatasetsClient,
18
+ name: string,
19
+ options?: {aclMode?: DatasetAclMode}
20
+ ): Promise<DatasetResponse>
21
+ create(
22
+ this: ObservableDatasetsClient,
23
+ name: string,
24
+ options?: {aclMode?: DatasetAclMode}
25
+ ): Observable<DatasetResponse>
26
+ create(
27
+ name: string,
28
+ options?: {aclMode?: DatasetAclMode}
29
+ ): Promise<DatasetResponse> | Observable<DatasetResponse> {
30
+ return this.#_modify('PUT', name, options)
31
+ }
32
+
33
+ /**
34
+ * Edit a dataset with the given name
35
+ *
36
+ * @param name - Name of the dataset to edit
37
+ * @param options - New options for the dataset
38
+ */
39
+ edit(
40
+ this: DatasetsClient,
41
+ name: string,
42
+ options?: {aclMode?: DatasetAclMode}
43
+ ): Promise<DatasetResponse>
44
+ edit(
45
+ this: ObservableDatasetsClient,
46
+ name: string,
47
+ options?: {aclMode?: DatasetAclMode}
48
+ ): Observable<DatasetResponse>
49
+ edit(
50
+ name: string,
51
+ options?: {aclMode?: DatasetAclMode}
52
+ ): Promise<DatasetResponse> | Observable<DatasetResponse> {
53
+ return this.#_modify('PATCH', name, options)
54
+ }
55
+
56
+ /**
57
+ * Delete a dataset with the given name
58
+ *
59
+ * @param name - Name of the dataset to delete
60
+ */
61
+ delete(this: DatasetsClient, name: string): Promise<{deleted: true}>
62
+ delete(this: ObservableDatasetsClient, name: string): Observable<{deleted: true}>
63
+ delete(name: string): Promise<{deleted: true}> | Observable<{deleted: true}> {
64
+ return this.#_modify('DELETE', name)
65
+ }
66
+
67
+ /**
68
+ * Fetch a list of datasets for the configured project
69
+ */
70
+ list(this: DatasetsClient): Promise<DatasetsResponse>
71
+ list(this: ObservableDatasetsClient): Observable<DatasetsResponse>
72
+ list(): Promise<DatasetsResponse> | Observable<DatasetsResponse> {
73
+ return this.client.request({uri: '/datasets'})
74
+ }
75
+
76
+ #_modify(method: 'DELETE' | 'PATCH' | 'PUT', name: string, options?: {aclMode?: DatasetAclMode}) {
77
+ validate.dataset(name)
78
+ return this.client.request({method, uri: `/datasets/${name}`, body: options})
79
+ }
80
+ }
81
+
82
+ export class ObservableDatasetsClient extends BaseDatasetsClient {
83
+ client: ObservableSanityClient
84
+
85
+ constructor(client: ObservableSanityClient) {
86
+ super()
87
+ this.client = client
88
+ }
89
+ }
90
+
91
+ export class DatasetsClient extends BaseDatasetsClient {
92
+ client: SanityClient
93
+ constructor(client: SanityClient) {
94
+ super()
95
+ this.client = client
96
+ }
97
+ }
@@ -0,0 +1,5 @@
1
+ const BASE_URL = 'https://docs.sanity.io/help/'
2
+
3
+ export default function generateHelpUrl(slug: string) {
4
+ return BASE_URL + slug
5
+ }
@@ -0,0 +1 @@
1
+ export default []
@@ -0,0 +1,68 @@
1
+ import {BaseError} from 'make-error'
2
+
3
+ import {ErrorProps} from '../types'
4
+
5
+ export class ClientError extends BaseError {
6
+ response: ErrorProps['response']
7
+ statusCode: ErrorProps['statusCode'] = 400
8
+ responseBody: ErrorProps['responseBody']
9
+ details: ErrorProps['details']
10
+
11
+ constructor(res: any) {
12
+ const props = extractErrorProps(res)
13
+ super(props.message)
14
+ Object.assign(this, props)
15
+ }
16
+ }
17
+
18
+ export class ServerError extends BaseError {
19
+ response: ErrorProps['response']
20
+ statusCode: ErrorProps['statusCode'] = 500
21
+ responseBody: ErrorProps['responseBody']
22
+ details: ErrorProps['details']
23
+
24
+ constructor(res: any) {
25
+ const props = extractErrorProps(res)
26
+ super(props.message)
27
+ Object.assign(this, props)
28
+ }
29
+ }
30
+
31
+ function extractErrorProps(res: any): ErrorProps {
32
+ const body = res.body
33
+ const props = {
34
+ response: res,
35
+ statusCode: res.statusCode,
36
+ responseBody: stringifyBody(body, res),
37
+ message: '',
38
+ details: undefined as any,
39
+ }
40
+
41
+ // API/Boom style errors ({statusCode, error, message})
42
+ if (body.error && body.message) {
43
+ props.message = `${body.error} - ${body.message}`
44
+ return props
45
+ }
46
+
47
+ // Query/database errors ({error: {description, other, arb, props}})
48
+ if (body.error && body.error.description) {
49
+ props.message = body.error.description
50
+ props.details = body.error
51
+ return props
52
+ }
53
+
54
+ // Other, more arbitrary errors
55
+ props.message = body.error || body.message || httpErrorMessage(res)
56
+ return props
57
+ }
58
+
59
+ function httpErrorMessage(res: any) {
60
+ const statusMessage = res.statusMessage ? ` ${res.statusMessage}` : ''
61
+ return `${res.method}-request to ${res.url} resulted in HTTP ${res.statusCode}${statusMessage}`
62
+ }
63
+
64
+ function stringifyBody(body: any, res: any) {
65
+ const contentType = (res.headers['content-type'] || '').toLowerCase()
66
+ const isJson = contentType.indexOf('application/json') !== -1
67
+ return isJson ? JSON.stringify(body, null, 2) : body
68
+ }
@@ -0,0 +1,11 @@
1
+ import {debug, headers, retry} from 'get-it/middleware'
2
+
3
+ import {name, version} from '../../package.json'
4
+
5
+ const middleware = [
6
+ debug({verbose: true, namespace: 'sanity:client'}),
7
+ headers({'User-Agent': `${name} ${version}`}),
8
+ retry({maxRetries: 3}),
9
+ ]
10
+
11
+ export default middleware
@@ -0,0 +1,50 @@
1
+ import {type Middlewares, getIt} from 'get-it'
2
+ import {jsonRequest, jsonResponse, observable, progress} from 'get-it/middleware'
3
+ import {Observable} from 'rxjs'
4
+
5
+ import type {HttpRequest, RequestOptions} from '../types'
6
+ import {ClientError, ServerError} from './errors'
7
+
8
+ const httpError = {
9
+ onResponse: (res: any) => {
10
+ if (res.statusCode >= 500) {
11
+ throw new ServerError(res)
12
+ } else if (res.statusCode >= 400) {
13
+ throw new ClientError(res)
14
+ }
15
+
16
+ return res
17
+ },
18
+ }
19
+
20
+ const printWarnings = {
21
+ onResponse: (res: any) => {
22
+ const warn = res.headers['x-sanity-warning']
23
+ const warnings = Array.isArray(warn) ? warn : [warn]
24
+ warnings.filter(Boolean).forEach((msg) => console.warn(msg)) // eslint-disable-line no-console
25
+ return res
26
+ },
27
+ }
28
+
29
+ /**
30
+ * @param envMiddleware Environment-specific middleware.
31
+ */
32
+ export function defineHttpRequest(envMiddleware: Middlewares): HttpRequest {
33
+ const request = getIt([
34
+ ...envMiddleware,
35
+ printWarnings,
36
+ jsonRequest(),
37
+ jsonResponse(),
38
+ progress(),
39
+ httpError,
40
+ observable({implementation: Observable}),
41
+ ])
42
+
43
+ function httpRequest(options: RequestOptions, requester = request) {
44
+ return requester({maxRedirects: 0, ...options} as any)
45
+ }
46
+
47
+ httpRequest.defaultRequester = request
48
+
49
+ return httpRequest
50
+ }
@@ -0,0 +1,31 @@
1
+ import type {RequestOptions} from 'get-it'
2
+
3
+ const projectHeader = 'X-Sanity-Project-ID'
4
+
5
+ export default (config: any, overrides: any = {}): Omit<RequestOptions, 'url'> => {
6
+ const headers: any = {}
7
+
8
+ const token = overrides.token || config.token
9
+ if (token) {
10
+ headers.Authorization = `Bearer ${token}`
11
+ }
12
+
13
+ if (!overrides.useGlobalApi && !config.useProjectHostname && config.projectId) {
14
+ headers[projectHeader] = config.projectId
15
+ }
16
+
17
+ const withCredentials = Boolean(
18
+ typeof overrides.withCredentials === 'undefined'
19
+ ? config.token || config.withCredentials
20
+ : overrides.withCredentials
21
+ )
22
+
23
+ const timeout = typeof overrides.timeout === 'undefined' ? config.timeout : overrides.timeout
24
+ return Object.assign({}, overrides, {
25
+ headers: Object.assign({}, headers, overrides.headers || {}),
26
+ timeout: typeof timeout === 'undefined' ? 5 * 60 * 1000 : timeout,
27
+ proxy: overrides.proxy || config.proxy,
28
+ json: true,
29
+ withCredentials,
30
+ })
31
+ }
@@ -0,0 +1,18 @@
1
+ import envMiddleware from './http/browserMiddleware'
2
+ import {defineHttpRequest} from './http/request'
3
+ import {SanityClient} from './SanityClient'
4
+ import type {ClientConfig} from './types'
5
+
6
+ export * from './data/patch'
7
+ export * from './data/transaction'
8
+ export {ClientError, ServerError} from './http/errors'
9
+ export * from './SanityClient'
10
+ export * from './types'
11
+
12
+ // Set the http client to use for requests, and its environment specific middleware
13
+ const httpRequest = defineHttpRequest(envMiddleware)
14
+ export const requester = httpRequest.defaultRequester
15
+
16
+ export function createClient(config: ClientConfig) {
17
+ return new SanityClient(httpRequest, config)
18
+ }
package/src/index.ts ADDED
@@ -0,0 +1,57 @@
1
+ import envMiddleware from './http/nodeMiddleware'
2
+ import {defineHttpRequest} from './http/request'
3
+ import {SanityClient} from './SanityClient'
4
+ import type {ClientConfig} from './types'
5
+
6
+ export * from './data/patch'
7
+ export * from './data/transaction'
8
+ export {ClientError, ServerError} from './http/errors'
9
+ export * from './SanityClient'
10
+ export * from './types'
11
+
12
+ // Set the http client to use for requests, and its environment specific middleware
13
+ const httpRequest = defineHttpRequest(envMiddleware)
14
+ export const requester = httpRequest.defaultRequester
15
+
16
+ export function createClient(config: ClientConfig) {
17
+ return new SanityClient(httpRequest, config)
18
+ }
19
+
20
+ /*
21
+ const client = createClient({})
22
+
23
+ client.auth.getLoginProviders().then
24
+ client.observable.auth.getLoginProviders().subscribe
25
+
26
+ client.create({_id: 'id', _type: 'document'}, {}).then()
27
+ client.observable.create({_id: 'id', _type: 'document'}, {}).subscribe()
28
+
29
+ client.delete('id', {returnFirst: true}).then
30
+
31
+ client.config({projectId: 'my-project-id'})
32
+ // @ts-expect-error -- isPromiseAPI isn't allowed
33
+ client.config({projectId: 'my-project-id', isPromiseAPI: false})
34
+ client.fetch('', {}).then
35
+ // @ts-expect-error -- observable is not allowed
36
+ client.fetch('', {}).subscribe
37
+ client.observable.fetch('', {}).subscribe
38
+ // @ts-expect-error -- promise is not allowed
39
+ client.observable.fetch('', {}).then
40
+
41
+ client.assets.upload('image', Buffer.from('')).then
42
+ client.observable.assets.upload('image', Buffer.from('')).subscribe
43
+ // @ts-expect-error -- promise not allowed
44
+ client.observable.assets.upload('image', Buffer.from('')).then
45
+ // @ts-expect-error -- protected property
46
+ client.assets.isPromiseAPI()
47
+
48
+ const observableClient = new ObservableSanityClient(httpRequest, {})
49
+ observableClient.config({projectId: 'my-project-id'})
50
+ // eslint-disable-next-line no-console
51
+ console.log(observableClient.isPromiseAPI() === false)
52
+ observableClient.fetch('', {}).subscribe
53
+ // @ts-expect-error -- promise is not allowed
54
+ observableClient.fetch('', {}).then
55
+ // @ts-expect-error -- observable is not allowed
56
+ observableClient.observable.fetch
57
+ // */