@sanity/client 6.28.3-instruct.1 → 6.28.3-resources.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/dist/_chunks-cjs/config.cjs +19 -3
- package/dist/_chunks-cjs/config.cjs.map +1 -1
- package/dist/_chunks-es/config.js +19 -3
- package/dist/_chunks-es/config.js.map +1 -1
- package/dist/index.browser.cjs +60 -59
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.d.cts +7 -244
- package/dist/index.browser.d.ts +7 -244
- package/dist/index.browser.js +60 -59
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cjs +44 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -233
- package/dist/index.d.ts +7 -233
- package/dist/index.js +45 -58
- package/dist/index.js.map +1 -1
- package/dist/stega.browser.d.cts +7 -233
- package/dist/stega.browser.d.ts +7 -233
- package/dist/stega.d.cts +7 -233
- package/dist/stega.d.ts +7 -233
- package/package.json +6 -25
- package/src/SanityClient.ts +1 -5
- package/src/assets/AssetsClient.ts +15 -3
- package/src/config.ts +6 -2
- package/src/data/dataMethods.ts +43 -5
- package/src/data/live.ts +2 -0
- package/src/datasets/DatasetsClient.ts +5 -0
- package/src/projects/ProjectsClient.ts +5 -0
- package/src/types.ts +8 -10
- package/src/validators.ts +23 -0
- package/umd/sanityClient.js +60 -59
- package/umd/sanityClient.min.js +2 -2
- package/src/ai/AiClient.ts +0 -93
- package/src/ai/types.ts +0 -206
package/src/SanityClient.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {lastValueFrom, Observable} from 'rxjs'
|
|
2
2
|
|
|
3
|
-
import {AiClient, ObservableAiClient} from './ai/AiClient'
|
|
4
3
|
import {AssetsClient, ObservableAssetsClient} from './assets/AssetsClient'
|
|
5
4
|
import {defaultConfig, initConfig} from './config'
|
|
6
5
|
import * as dataMethods from './data/dataMethods'
|
|
@@ -66,7 +65,7 @@ export class ObservableSanityClient {
|
|
|
66
65
|
live: LiveClient
|
|
67
66
|
projects: ObservableProjectsClient
|
|
68
67
|
users: ObservableUsersClient
|
|
69
|
-
|
|
68
|
+
|
|
70
69
|
/**
|
|
71
70
|
* Private properties
|
|
72
71
|
*/
|
|
@@ -88,7 +87,6 @@ export class ObservableSanityClient {
|
|
|
88
87
|
this.live = new LiveClient(this)
|
|
89
88
|
this.projects = new ObservableProjectsClient(this, this.#httpRequest)
|
|
90
89
|
this.users = new ObservableUsersClient(this, this.#httpRequest)
|
|
91
|
-
this.ai = new ObservableAiClient(this, this.#httpRequest)
|
|
92
90
|
}
|
|
93
91
|
|
|
94
92
|
/**
|
|
@@ -735,7 +733,6 @@ export class SanityClient {
|
|
|
735
733
|
live: LiveClient
|
|
736
734
|
projects: ProjectsClient
|
|
737
735
|
users: UsersClient
|
|
738
|
-
ai: AiClient
|
|
739
736
|
|
|
740
737
|
/**
|
|
741
738
|
* Observable version of the Sanity client, with the same configuration as the promise-based one
|
|
@@ -763,7 +760,6 @@ export class SanityClient {
|
|
|
763
760
|
this.live = new LiveClient(this)
|
|
764
761
|
this.projects = new ProjectsClient(this, this.#httpRequest)
|
|
765
762
|
this.users = new UsersClient(this, this.#httpRequest)
|
|
766
|
-
this.ai = new AiClient(this, this.#httpRequest)
|
|
767
763
|
|
|
768
764
|
this.observable = new ObservableSanityClient(httpRequest, config)
|
|
769
765
|
}
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
Any,
|
|
8
8
|
HttpRequest,
|
|
9
9
|
HttpRequestEvent,
|
|
10
|
+
InitializedClientConfig,
|
|
10
11
|
ResponseEvent,
|
|
11
12
|
SanityAssetDocument,
|
|
12
13
|
SanityImageAssetDocument,
|
|
@@ -149,8 +150,7 @@ function _upload(
|
|
|
149
150
|
meta = ['none']
|
|
150
151
|
}
|
|
151
152
|
|
|
152
|
-
const
|
|
153
|
-
const assetEndpoint = assetType === 'image' ? 'images' : 'files'
|
|
153
|
+
const config = client.config()
|
|
154
154
|
const options = optionsFromFile(opts, body)
|
|
155
155
|
const {tag, label, title, description, creditLine, filename, source} = options
|
|
156
156
|
const query: Any = {
|
|
@@ -166,17 +166,29 @@ function _upload(
|
|
|
166
166
|
query.sourceName = source.name
|
|
167
167
|
query.sourceUrl = source.url
|
|
168
168
|
}
|
|
169
|
+
|
|
169
170
|
return _requestObservable(client, httpRequest, {
|
|
170
171
|
tag,
|
|
171
172
|
method: 'POST',
|
|
172
173
|
timeout: options.timeout || 0,
|
|
173
|
-
uri:
|
|
174
|
+
uri: buildAssetUploadUrl(config, assetType),
|
|
174
175
|
headers: options.contentType ? {'Content-Type': options.contentType} : {},
|
|
175
176
|
query,
|
|
176
177
|
body,
|
|
177
178
|
})
|
|
178
179
|
}
|
|
179
180
|
|
|
181
|
+
function buildAssetUploadUrl(config: InitializedClientConfig, assetType: 'image' | 'file'): string {
|
|
182
|
+
const assetTypeEndpoint = assetType === 'image' ? 'images' : 'files'
|
|
183
|
+
|
|
184
|
+
if (config['~experimental_resource']) {
|
|
185
|
+
return `${config['~experimental_resource'].type}/${config['~experimental_resource'].id}/assets/${assetTypeEndpoint}`
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const dataset = validators.hasDataset(config)
|
|
189
|
+
return `assets/${assetTypeEndpoint}/${dataset}`
|
|
190
|
+
}
|
|
191
|
+
|
|
180
192
|
function optionsFromFile(opts: Record<string, Any>, file: Any) {
|
|
181
193
|
if (typeof File === 'undefined' || !(file instanceof File)) {
|
|
182
194
|
return opts
|
package/src/config.ts
CHANGED
|
@@ -63,7 +63,7 @@ export const initConfig = (
|
|
|
63
63
|
...defaultConfig,
|
|
64
64
|
...specifiedConfig,
|
|
65
65
|
} as InitializedClientConfig
|
|
66
|
-
const projectBased = newConfig.useProjectHostname
|
|
66
|
+
const projectBased = newConfig.useProjectHostname && !newConfig['~experimental_resource']
|
|
67
67
|
|
|
68
68
|
if (typeof Promise === 'undefined') {
|
|
69
69
|
const helpUrl = generateHelpUrl('js-client-promise-polyfill')
|
|
@@ -74,6 +74,10 @@ export const initConfig = (
|
|
|
74
74
|
throw new Error('Configuration must contain `projectId`')
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
if (newConfig['~experimental_resource']) {
|
|
78
|
+
validate.resourceBase(newConfig)
|
|
79
|
+
}
|
|
80
|
+
|
|
77
81
|
if (typeof newConfig.perspective !== 'undefined') {
|
|
78
82
|
validateApiPerspective(newConfig.perspective)
|
|
79
83
|
}
|
|
@@ -151,7 +155,7 @@ export const initConfig = (
|
|
|
151
155
|
const host = hostParts[1]
|
|
152
156
|
const cdnHost = newConfig.isDefaultApi ? defaultCdnHost : host
|
|
153
157
|
|
|
154
|
-
if (
|
|
158
|
+
if (projectBased) {
|
|
155
159
|
newConfig.url = `${protocol}://${newConfig.projectId}.${host}/v${newConfig.apiVersion}`
|
|
156
160
|
newConfig.cdnUrl = `${protocol}://${newConfig.projectId}.${cdnHost}/v${newConfig.apiVersion}`
|
|
157
161
|
} else {
|
package/src/data/dataMethods.ts
CHANGED
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
Any,
|
|
13
13
|
BaseActionOptions,
|
|
14
14
|
BaseMutationOptions,
|
|
15
|
+
ClientConfig,
|
|
15
16
|
FirstDocumentIdMutationOptions,
|
|
16
17
|
FirstDocumentMutationOptions,
|
|
17
18
|
HttpRequest,
|
|
@@ -366,6 +367,41 @@ export function _create<R extends Record<string, Any>>(
|
|
|
366
367
|
const opts = Object.assign({returnFirst: true, returnDocuments: true}, options)
|
|
367
368
|
return _dataRequest(client, httpRequest, 'mutate', {mutations: [mutation]}, opts)
|
|
368
369
|
}
|
|
370
|
+
const resourceDatasetRegex = /^\/projects\/([^/]+)\/datasets\/([^/]+)\/([^/^?]+)\/?/
|
|
371
|
+
const isResourceDataEndpoint = (config: ClientConfig, uri: string, endpoint: string) => {
|
|
372
|
+
if (!config['~experimental_resource']) {
|
|
373
|
+
return false
|
|
374
|
+
}
|
|
375
|
+
if (
|
|
376
|
+
uri.startsWith(
|
|
377
|
+
`/${config['~experimental_resource'].type}/${config['~experimental_resource'].id}/${endpoint}`,
|
|
378
|
+
)
|
|
379
|
+
) {
|
|
380
|
+
return true
|
|
381
|
+
}
|
|
382
|
+
const match = uri.match(resourceDatasetRegex)
|
|
383
|
+
if (!match) {
|
|
384
|
+
return false
|
|
385
|
+
}
|
|
386
|
+
return match[3] === endpoint
|
|
387
|
+
}
|
|
388
|
+
const isQuery = (config: ClientConfig, uri: string) =>
|
|
389
|
+
uri.startsWith('/data/query/') || isResourceDataEndpoint(config, uri, 'query')
|
|
390
|
+
const isMutate = (config: ClientConfig, uri: string) =>
|
|
391
|
+
uri.startsWith('/data/mutate/') || isResourceDataEndpoint(config, uri, 'mutate')
|
|
392
|
+
const isDoc = (config: ClientConfig, uri: string) =>
|
|
393
|
+
uri.startsWith('/data/doc/') || isResourceDataEndpoint(config, uri, 'doc')
|
|
394
|
+
const isListener = (config: ClientConfig, uri: string) =>
|
|
395
|
+
uri.startsWith('/data/listen/') || isResourceDataEndpoint(config, uri, 'listen')
|
|
396
|
+
const isHistory = (config: ClientConfig, uri: string) =>
|
|
397
|
+
uri.startsWith('/data/history/') || isResourceDataEndpoint(config, uri, 'history')
|
|
398
|
+
const isData = (config: ClientConfig, uri: string) =>
|
|
399
|
+
uri.startsWith('/data/') ||
|
|
400
|
+
isQuery(config, uri) ||
|
|
401
|
+
isMutate(config, uri) ||
|
|
402
|
+
isDoc(config, uri) ||
|
|
403
|
+
isListener(config, uri) ||
|
|
404
|
+
isHistory(config, uri)
|
|
369
405
|
|
|
370
406
|
/**
|
|
371
407
|
* @internal
|
|
@@ -382,7 +418,7 @@ export function _requestObservable<R>(
|
|
|
382
418
|
// Only the /data endpoint is currently available through API-CDN.
|
|
383
419
|
const canUseCdn =
|
|
384
420
|
typeof options.canUseCdn === 'undefined'
|
|
385
|
-
? ['GET', 'HEAD'].indexOf(options.method || 'GET') >= 0 && uri
|
|
421
|
+
? ['GET', 'HEAD'].indexOf(options.method || 'GET') >= 0 && isData(config, uri)
|
|
386
422
|
: options.canUseCdn
|
|
387
423
|
|
|
388
424
|
let useCdn = (options.useCdn ?? config.useCdn) && canUseCdn
|
|
@@ -397,10 +433,7 @@ export function _requestObservable<R>(
|
|
|
397
433
|
}
|
|
398
434
|
|
|
399
435
|
// GROQ query-only parameters
|
|
400
|
-
if (
|
|
401
|
-
['GET', 'HEAD', 'POST'].indexOf(options.method || 'GET') >= 0 &&
|
|
402
|
-
uri.indexOf('/data/query/') === 0
|
|
403
|
-
) {
|
|
436
|
+
if (['GET', 'HEAD', 'POST'].indexOf(options.method || 'GET') >= 0 && isQuery(config, uri)) {
|
|
404
437
|
const resultSourceMap = options.resultSourceMap ?? config.resultSourceMap
|
|
405
438
|
if (resultSourceMap !== undefined && resultSourceMap !== false) {
|
|
406
439
|
options.query = {resultSourceMap, ...options.query}
|
|
@@ -482,6 +515,11 @@ export function _getDataUrl(
|
|
|
482
515
|
path?: string,
|
|
483
516
|
): string {
|
|
484
517
|
const config = client.config()
|
|
518
|
+
if (config['~experimental_resource']) {
|
|
519
|
+
const resourceBase = validators.resourceBase(config)
|
|
520
|
+
const uri = path ? `${operation}/${path}` : operation
|
|
521
|
+
return `${resourceBase}/${uri}`.replace(/\/($|\?)/, '$1')
|
|
522
|
+
}
|
|
485
523
|
const catalog = validators.hasDataset(config)
|
|
486
524
|
const baseUri = `/${operation}/${catalog}`
|
|
487
525
|
const uri = path ? `${baseUri}/${path}` : baseUri
|
package/src/data/live.ts
CHANGED
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
SyncTag,
|
|
13
13
|
} from '../types'
|
|
14
14
|
import {shareReplayLatest} from '../util/shareReplayLatest'
|
|
15
|
+
import * as validate from '../validators'
|
|
15
16
|
import {_getDataUrl} from './dataMethods'
|
|
16
17
|
import {connectEventSource} from './eventsource'
|
|
17
18
|
import {eventSourcePolyfill} from './eventsourcePolyfill'
|
|
@@ -43,6 +44,7 @@ export class LiveClient {
|
|
|
43
44
|
*/
|
|
44
45
|
tag?: string
|
|
45
46
|
} = {}): Observable<LiveEvent> {
|
|
47
|
+
validate.resourceGuard('live', this.#client.config())
|
|
46
48
|
const {
|
|
47
49
|
projectId,
|
|
48
50
|
apiVersion: _apiVersion,
|
|
@@ -70,6 +70,7 @@ export class DatasetsClient {
|
|
|
70
70
|
* @param options - Options for the dataset
|
|
71
71
|
*/
|
|
72
72
|
create(name: string, options?: {aclMode?: DatasetAclMode}): Promise<DatasetResponse> {
|
|
73
|
+
validate.resourceGuard('dataset', this.#client.config())
|
|
73
74
|
return lastValueFrom(
|
|
74
75
|
_modify<DatasetResponse>(this.#client, this.#httpRequest, 'PUT', name, options),
|
|
75
76
|
)
|
|
@@ -82,6 +83,7 @@ export class DatasetsClient {
|
|
|
82
83
|
* @param options - New options for the dataset
|
|
83
84
|
*/
|
|
84
85
|
edit(name: string, options?: {aclMode?: DatasetAclMode}): Promise<DatasetResponse> {
|
|
86
|
+
validate.resourceGuard('dataset', this.#client.config())
|
|
85
87
|
return lastValueFrom(
|
|
86
88
|
_modify<DatasetResponse>(this.#client, this.#httpRequest, 'PATCH', name, options),
|
|
87
89
|
)
|
|
@@ -93,6 +95,7 @@ export class DatasetsClient {
|
|
|
93
95
|
* @param name - Name of the dataset to delete
|
|
94
96
|
*/
|
|
95
97
|
delete(name: string): Promise<{deleted: true}> {
|
|
98
|
+
validate.resourceGuard('dataset', this.#client.config())
|
|
96
99
|
return lastValueFrom(_modify<{deleted: true}>(this.#client, this.#httpRequest, 'DELETE', name))
|
|
97
100
|
}
|
|
98
101
|
|
|
@@ -100,6 +103,7 @@ export class DatasetsClient {
|
|
|
100
103
|
* Fetch a list of datasets for the configured project
|
|
101
104
|
*/
|
|
102
105
|
list(): Promise<DatasetsResponse> {
|
|
106
|
+
validate.resourceGuard('dataset', this.#client.config())
|
|
103
107
|
return lastValueFrom(
|
|
104
108
|
_request<DatasetsResponse>(this.#client, this.#httpRequest, {uri: '/datasets', tag: null}),
|
|
105
109
|
)
|
|
@@ -113,6 +117,7 @@ function _modify<R = unknown>(
|
|
|
113
117
|
name: string,
|
|
114
118
|
options?: {aclMode?: DatasetAclMode},
|
|
115
119
|
) {
|
|
120
|
+
validate.resourceGuard('dataset', client.config())
|
|
116
121
|
validate.dataset(name)
|
|
117
122
|
return _request<R>(client, httpRequest, {
|
|
118
123
|
method,
|
|
@@ -3,6 +3,7 @@ import {lastValueFrom, type Observable} from 'rxjs'
|
|
|
3
3
|
import {_request} from '../data/dataMethods'
|
|
4
4
|
import type {ObservableSanityClient, SanityClient} from '../SanityClient'
|
|
5
5
|
import type {HttpRequest, SanityProject} from '../types'
|
|
6
|
+
import * as validate from '../validators'
|
|
6
7
|
|
|
7
8
|
/** @internal */
|
|
8
9
|
export class ObservableProjectsClient {
|
|
@@ -24,6 +25,7 @@ export class ObservableProjectsClient {
|
|
|
24
25
|
list(options?: {
|
|
25
26
|
includeMembers?: boolean
|
|
26
27
|
}): Observable<SanityProject[] | Omit<SanityProject, 'members'>[]> {
|
|
28
|
+
validate.resourceGuard('projects', this.#client.config())
|
|
27
29
|
const uri = options?.includeMembers === false ? '/projects?includeMembers=false' : '/projects'
|
|
28
30
|
return _request<SanityProject[]>(this.#client, this.#httpRequest, {uri})
|
|
29
31
|
}
|
|
@@ -34,6 +36,7 @@ export class ObservableProjectsClient {
|
|
|
34
36
|
* @param projectId - ID of the project to fetch
|
|
35
37
|
*/
|
|
36
38
|
getById(projectId: string): Observable<SanityProject> {
|
|
39
|
+
validate.resourceGuard('projects', this.#client.config())
|
|
37
40
|
return _request<SanityProject>(this.#client, this.#httpRequest, {uri: `/projects/${projectId}`})
|
|
38
41
|
}
|
|
39
42
|
}
|
|
@@ -56,6 +59,7 @@ export class ProjectsClient {
|
|
|
56
59
|
list(options?: {includeMembers?: true}): Promise<SanityProject[]>
|
|
57
60
|
list(options?: {includeMembers?: false}): Promise<Omit<SanityProject, 'members'>[]>
|
|
58
61
|
list(options?: {includeMembers?: boolean}): Promise<SanityProject[]> {
|
|
62
|
+
validate.resourceGuard('projects', this.#client.config())
|
|
59
63
|
const uri = options?.includeMembers === false ? '/projects?includeMembers=false' : '/projects'
|
|
60
64
|
return lastValueFrom(_request<SanityProject[]>(this.#client, this.#httpRequest, {uri}))
|
|
61
65
|
}
|
|
@@ -66,6 +70,7 @@ export class ProjectsClient {
|
|
|
66
70
|
* @param projectId - ID of the project to fetch
|
|
67
71
|
*/
|
|
68
72
|
getById(projectId: string): Promise<SanityProject> {
|
|
73
|
+
validate.resourceGuard('projects', this.#client.config())
|
|
69
74
|
return lastValueFrom(
|
|
70
75
|
_request<SanityProject>(this.#client, this.#httpRequest, {uri: `/projects/${projectId}`}),
|
|
71
76
|
)
|
package/src/types.ts
CHANGED
|
@@ -53,6 +53,11 @@ export type ClientPerspective =
|
|
|
53
53
|
| 'raw'
|
|
54
54
|
| StackablePerspective[]
|
|
55
55
|
|
|
56
|
+
type ClientConfigResource = {
|
|
57
|
+
type: string
|
|
58
|
+
id: string
|
|
59
|
+
}
|
|
60
|
+
|
|
56
61
|
/** @public */
|
|
57
62
|
export interface ClientConfig {
|
|
58
63
|
projectId?: string
|
|
@@ -61,6 +66,9 @@ export interface ClientConfig {
|
|
|
61
66
|
useCdn?: boolean
|
|
62
67
|
token?: string
|
|
63
68
|
|
|
69
|
+
/** @internal */
|
|
70
|
+
'~experimental_resource'?: ClientConfigResource
|
|
71
|
+
|
|
64
72
|
/**
|
|
65
73
|
* What perspective to use for the client. See {@link https://www.sanity.io/docs/perspectives|perspective documentation}
|
|
66
74
|
* @remarks
|
|
@@ -1336,16 +1344,6 @@ export type ClientReturn<
|
|
|
1336
1344
|
Fallback = Any,
|
|
1337
1345
|
> = GroqString extends keyof SanityQueries ? SanityQueries[GroqString] : Fallback
|
|
1338
1346
|
|
|
1339
|
-
export type {
|
|
1340
|
-
InstructAsyncInstruction,
|
|
1341
|
-
InstructConstantInstructionParam,
|
|
1342
|
-
InstructFieldInstructionParam,
|
|
1343
|
-
InstructGroqInstructionParam,
|
|
1344
|
-
InstructInstruction,
|
|
1345
|
-
InstructInstructionParam,
|
|
1346
|
-
InstructInstructionParams,
|
|
1347
|
-
InstructSyncInstruction,
|
|
1348
|
-
} from './ai/types'
|
|
1349
1347
|
export type {
|
|
1350
1348
|
ContentSourceMapParsedPath,
|
|
1351
1349
|
ContentSourceMapParsedPathKeyedSegment,
|
package/src/validators.ts
CHANGED
|
@@ -76,3 +76,26 @@ export const requestTag = (tag: string) => {
|
|
|
76
76
|
|
|
77
77
|
return tag
|
|
78
78
|
}
|
|
79
|
+
|
|
80
|
+
export const resourceBase = (config: InitializedClientConfig): string => {
|
|
81
|
+
if (!config['~experimental_resource']) {
|
|
82
|
+
throw new Error('`resource` must be provided to perform queries')
|
|
83
|
+
}
|
|
84
|
+
const resourceConfig = config['~experimental_resource']
|
|
85
|
+
|
|
86
|
+
if (resourceConfig.type === 'dataset') {
|
|
87
|
+
const segments = resourceConfig.id.split('.')
|
|
88
|
+
if (segments.length !== 2) {
|
|
89
|
+
throw new Error('Dataset ID must be in the format "project.dataset"')
|
|
90
|
+
}
|
|
91
|
+
return `/projects/${segments[0]}/datasets/${segments[1]}`
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return `/${resourceConfig.type}/${resourceConfig.id}`
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export const resourceGuard = (service: string, config: InitializedClientConfig): void => {
|
|
98
|
+
if (config['~experimental_resource']) {
|
|
99
|
+
throw new Error(`\`${service}\` does not support resource-based operations`)
|
|
100
|
+
}
|
|
101
|
+
}
|
package/umd/sanityClient.js
CHANGED
|
@@ -2015,8 +2015,8 @@
|
|
|
2015
2015
|
}
|
|
2016
2016
|
function shouldRetry(err, attempt, options) {
|
|
2017
2017
|
if (options.maxRetries === 0) return false;
|
|
2018
|
-
const isSafe = options.method === "GET" || options.method === "HEAD",
|
|
2019
|
-
return (isSafe ||
|
|
2018
|
+
const isSafe = options.method === "GET" || options.method === "HEAD", isQuery2 = (options.uri || options.url).startsWith("/data/query"), isRetriableResponse = err.response && (err.response.statusCode === 429 || err.response.statusCode === 502 || err.response.statusCode === 503);
|
|
2019
|
+
return (isSafe || isQuery2) && isRetriableResponse ? true : P.shouldRetry(err, attempt, options);
|
|
2020
2020
|
}
|
|
2021
2021
|
const BASE_URL = "https://www.sanity.io/help/";
|
|
2022
2022
|
function generateHelpUrl(slug) {
|
|
@@ -2063,6 +2063,20 @@
|
|
|
2063
2063
|
"Tag can only contain alphanumeric characters, underscores, dashes and dots, and be between one and 75 characters long."
|
|
2064
2064
|
);
|
|
2065
2065
|
return tag;
|
|
2066
|
+
}, resourceBase = (config) => {
|
|
2067
|
+
if (!config["~experimental_resource"])
|
|
2068
|
+
throw new Error("`resource` must be provided to perform queries");
|
|
2069
|
+
const resourceConfig = config["~experimental_resource"];
|
|
2070
|
+
if (resourceConfig.type === "dataset") {
|
|
2071
|
+
const segments = resourceConfig.id.split(".");
|
|
2072
|
+
if (segments.length !== 2)
|
|
2073
|
+
throw new Error('Dataset ID must be in the format "project.dataset"');
|
|
2074
|
+
return `/projects/${segments[0]}/datasets/${segments[1]}`;
|
|
2075
|
+
}
|
|
2076
|
+
return `/${resourceConfig.type}/${resourceConfig.id}`;
|
|
2077
|
+
}, resourceGuard = (service, config) => {
|
|
2078
|
+
if (config["~experimental_resource"])
|
|
2079
|
+
throw new Error(`\`${service}\` does not support resource-based operations`);
|
|
2066
2080
|
};
|
|
2067
2081
|
function once(fn) {
|
|
2068
2082
|
let didCall = false, returnValue;
|
|
@@ -2128,14 +2142,14 @@
|
|
|
2128
2142
|
const newConfig = {
|
|
2129
2143
|
...defaultConfig,
|
|
2130
2144
|
...specifiedConfig
|
|
2131
|
-
}, projectBased = newConfig.useProjectHostname;
|
|
2145
|
+
}, projectBased = newConfig.useProjectHostname && !newConfig["~experimental_resource"];
|
|
2132
2146
|
if (typeof Promise > "u") {
|
|
2133
2147
|
const helpUrl = generateHelpUrl("js-client-promise-polyfill");
|
|
2134
2148
|
throw new Error(`No native Promise-implementation found, polyfill needed - see ${helpUrl}`);
|
|
2135
2149
|
}
|
|
2136
2150
|
if (projectBased && !newConfig.projectId)
|
|
2137
2151
|
throw new Error("Configuration must contain `projectId`");
|
|
2138
|
-
if (typeof newConfig.perspective < "u" && validateApiPerspective(newConfig.perspective), "encodeSourceMap" in newConfig)
|
|
2152
|
+
if (newConfig["~experimental_resource"] && resourceBase(newConfig), typeof newConfig.perspective < "u" && validateApiPerspective(newConfig.perspective), "encodeSourceMap" in newConfig)
|
|
2139
2153
|
throw new Error(
|
|
2140
2154
|
"It looks like you're using options meant for '@sanity/preview-kit/client'. 'encodeSourceMap' is not supported in '@sanity/client'. Did you mean 'stega.enabled'?"
|
|
2141
2155
|
);
|
|
@@ -2154,7 +2168,7 @@
|
|
|
2154
2168
|
const isBrowser = typeof window < "u" && window.location && window.location.hostname, isLocalhost = isBrowser && isLocal(window.location.hostname), hasToken = !!newConfig.token;
|
|
2155
2169
|
newConfig.withCredentials && hasToken && (printCredentialedTokenWarning(), newConfig.withCredentials = false), isBrowser && isLocalhost && hasToken && newConfig.ignoreBrowserTokenWarning !== true ? printBrowserTokenWarning() : typeof newConfig.useCdn > "u" && printCdnWarning(), projectBased && projectId(newConfig.projectId), newConfig.dataset && dataset(newConfig.dataset), "requestTagPrefix" in newConfig && (newConfig.requestTagPrefix = newConfig.requestTagPrefix ? requestTag(newConfig.requestTagPrefix).replace(/\.+$/, "") : void 0), newConfig.apiVersion = `${newConfig.apiVersion}`.replace(/^v/, ""), newConfig.isDefaultApi = newConfig.apiHost === defaultConfig.apiHost, newConfig.useCdn === true && newConfig.withCredentials && printCdnAndWithCredentialsWarning(), newConfig.useCdn = newConfig.useCdn !== false && !newConfig.withCredentials, validateApiVersion(newConfig.apiVersion);
|
|
2156
2170
|
const hostParts = newConfig.apiHost.split("://", 2), protocol = hostParts[0], host = hostParts[1], cdnHost = newConfig.isDefaultApi ? defaultCdnHost : host;
|
|
2157
|
-
return
|
|
2171
|
+
return projectBased ? (newConfig.url = `${protocol}://${newConfig.projectId}.${host}/v${newConfig.apiVersion}`, newConfig.cdnUrl = `${protocol}://${newConfig.projectId}.${cdnHost}/v${newConfig.apiVersion}`) : (newConfig.url = `${newConfig.apiHost}/v${newConfig.apiVersion}`, newConfig.cdnUrl = newConfig.url), newConfig;
|
|
2158
2172
|
};
|
|
2159
2173
|
class ConnectionFailedError extends Error {
|
|
2160
2174
|
name = "ConnectionFailedError";
|
|
@@ -2722,7 +2736,7 @@ ${selectionOpts}`);
|
|
|
2722
2736
|
);
|
|
2723
2737
|
}
|
|
2724
2738
|
function _dataRequest(client, httpRequest, endpoint, body, options = {}) {
|
|
2725
|
-
const isMutation = endpoint === "mutate", isAction = endpoint === "actions",
|
|
2739
|
+
const isMutation = endpoint === "mutate", isAction = endpoint === "actions", isQuery2 = endpoint === "query", strQuery = isMutation || isAction ? "" : encodeQueryString(body), useGet = !isMutation && !isAction && strQuery.length < getQuerySizeLimit, stringQuery = useGet ? strQuery : "", returnFirst = options.returnFirst, { timeout, token, tag, headers, returnQuery, lastLiveEventId, cacheMode } = options, uri = _getDataUrl(client, endpoint, stringQuery), reqOptions = {
|
|
2726
2740
|
method: useGet ? "GET" : "POST",
|
|
2727
2741
|
uri,
|
|
2728
2742
|
json: true,
|
|
@@ -2737,7 +2751,7 @@ ${selectionOpts}`);
|
|
|
2737
2751
|
resultSourceMap: options.resultSourceMap,
|
|
2738
2752
|
lastLiveEventId: Array.isArray(lastLiveEventId) ? lastLiveEventId[0] : lastLiveEventId,
|
|
2739
2753
|
cacheMode,
|
|
2740
|
-
canUseCdn:
|
|
2754
|
+
canUseCdn: isQuery2,
|
|
2741
2755
|
signal: options.signal,
|
|
2742
2756
|
fetch: options.fetch,
|
|
2743
2757
|
useAbortSignal: options.useAbortSignal,
|
|
@@ -2765,11 +2779,21 @@ ${selectionOpts}`);
|
|
|
2765
2779
|
const mutation = { [op]: doc }, opts = Object.assign({ returnFirst: true, returnDocuments: true }, options);
|
|
2766
2780
|
return _dataRequest(client, httpRequest, "mutate", { mutations: [mutation] }, opts);
|
|
2767
2781
|
}
|
|
2782
|
+
const resourceDatasetRegex = /^\/projects\/([^/]+)\/datasets\/([^/]+)\/([^/^?]+)\/?/, isResourceDataEndpoint = (config, uri, endpoint) => {
|
|
2783
|
+
if (!config["~experimental_resource"])
|
|
2784
|
+
return false;
|
|
2785
|
+
if (uri.startsWith(
|
|
2786
|
+
`/${config["~experimental_resource"].type}/${config["~experimental_resource"].id}/${endpoint}`
|
|
2787
|
+
))
|
|
2788
|
+
return true;
|
|
2789
|
+
const match = uri.match(resourceDatasetRegex);
|
|
2790
|
+
return match ? match[3] === endpoint : false;
|
|
2791
|
+
}, isQuery = (config, uri) => uri.startsWith("/data/query/") || isResourceDataEndpoint(config, uri, "query"), isMutate = (config, uri) => uri.startsWith("/data/mutate/") || isResourceDataEndpoint(config, uri, "mutate"), isDoc = (config, uri) => uri.startsWith("/data/doc/") || isResourceDataEndpoint(config, uri, "doc"), isListener = (config, uri) => uri.startsWith("/data/listen/") || isResourceDataEndpoint(config, uri, "listen"), isHistory = (config, uri) => uri.startsWith("/data/history/") || isResourceDataEndpoint(config, uri, "history"), isData = (config, uri) => uri.startsWith("/data/") || isQuery(config, uri) || isMutate(config, uri) || isDoc(config, uri) || isListener(config, uri) || isHistory(config, uri);
|
|
2768
2792
|
function _requestObservable(client, httpRequest, options) {
|
|
2769
|
-
const uri = options.url || options.uri, config = client.config(), canUseCdn = typeof options.canUseCdn > "u" ? ["GET", "HEAD"].indexOf(options.method || "GET") >= 0 && uri
|
|
2793
|
+
const uri = options.url || options.uri, config = client.config(), canUseCdn = typeof options.canUseCdn > "u" ? ["GET", "HEAD"].indexOf(options.method || "GET") >= 0 && isData(config, uri) : options.canUseCdn;
|
|
2770
2794
|
let useCdn = (options.useCdn ?? config.useCdn) && canUseCdn;
|
|
2771
2795
|
const tag = options.tag && config.requestTagPrefix ? [config.requestTagPrefix, options.tag].join(".") : options.tag || config.requestTagPrefix;
|
|
2772
|
-
if (tag && options.tag !== null && (options.query = { tag: requestTag(tag), ...options.query }), ["GET", "HEAD", "POST"].indexOf(options.method || "GET") >= 0 &&
|
|
2796
|
+
if (tag && options.tag !== null && (options.query = { tag: requestTag(tag), ...options.query }), ["GET", "HEAD", "POST"].indexOf(options.method || "GET") >= 0 && isQuery(config, uri)) {
|
|
2773
2797
|
const resultSourceMap = options.resultSourceMap ?? config.resultSourceMap;
|
|
2774
2798
|
resultSourceMap !== void 0 && resultSourceMap !== false && (options.query = { resultSourceMap, ...options.query });
|
|
2775
2799
|
const perspectiveOption = options.perspective || config.perspective;
|
|
@@ -2796,7 +2820,12 @@ ${selectionOpts}`);
|
|
|
2796
2820
|
);
|
|
2797
2821
|
}
|
|
2798
2822
|
function _getDataUrl(client, operation, path) {
|
|
2799
|
-
const config = client.config()
|
|
2823
|
+
const config = client.config();
|
|
2824
|
+
if (config["~experimental_resource"]) {
|
|
2825
|
+
const resourceBase$1 = resourceBase(config), uri2 = path ? `${operation}/${path}` : operation;
|
|
2826
|
+
return `${resourceBase$1}/${uri2}`.replace(/\/($|\?)/, "$1");
|
|
2827
|
+
}
|
|
2828
|
+
const catalog = hasDataset(config), baseUri = `/${operation}/${catalog}`;
|
|
2800
2829
|
return `/data${path ? `${baseUri}/${path}` : baseUri}`.replace(/\/($|\?)/, "$1");
|
|
2801
2830
|
}
|
|
2802
2831
|
function _getUrl(client, uri, canUseCdn = false) {
|
|
@@ -2823,42 +2852,6 @@ ${selectionOpts}`);
|
|
|
2823
2852
|
const error = new Error(signal?.reason ?? "The operation was aborted.");
|
|
2824
2853
|
return error.name = "AbortError", error;
|
|
2825
2854
|
}
|
|
2826
|
-
function _instruct(client, httpRequest, request) {
|
|
2827
|
-
const dataset2 = hasDataset(client.config());
|
|
2828
|
-
return _request(client, httpRequest, {
|
|
2829
|
-
method: "POST",
|
|
2830
|
-
uri: `/assist/tasks/instruct/${dataset2}`,
|
|
2831
|
-
body: request
|
|
2832
|
-
});
|
|
2833
|
-
}
|
|
2834
|
-
class ObservableAiClient {
|
|
2835
|
-
#client;
|
|
2836
|
-
#httpRequest;
|
|
2837
|
-
constructor(client, httpRequest) {
|
|
2838
|
-
this.#client = client, this.#httpRequest = httpRequest;
|
|
2839
|
-
}
|
|
2840
|
-
/**
|
|
2841
|
-
* Run an ad-hoc instruction for a target document.
|
|
2842
|
-
* @param request instruction request
|
|
2843
|
-
*/
|
|
2844
|
-
instruct(request) {
|
|
2845
|
-
return _instruct(this.#client, this.#httpRequest, request);
|
|
2846
|
-
}
|
|
2847
|
-
}
|
|
2848
|
-
class AiClient {
|
|
2849
|
-
#client;
|
|
2850
|
-
#httpRequest;
|
|
2851
|
-
constructor(client, httpRequest) {
|
|
2852
|
-
this.#client = client, this.#httpRequest = httpRequest;
|
|
2853
|
-
}
|
|
2854
|
-
/**
|
|
2855
|
-
* Run an ad-hoc instruction for a target document.
|
|
2856
|
-
* @param request instruction request
|
|
2857
|
-
*/
|
|
2858
|
-
instruct(request) {
|
|
2859
|
-
return lastValueFrom(_instruct(this.#client, this.#httpRequest, request));
|
|
2860
|
-
}
|
|
2861
|
-
}
|
|
2862
2855
|
class ObservableAssetsClient {
|
|
2863
2856
|
#client;
|
|
2864
2857
|
#httpRequest;
|
|
@@ -2891,7 +2884,7 @@ ${selectionOpts}`);
|
|
|
2891
2884
|
validateAssetType(assetType);
|
|
2892
2885
|
let meta = opts.extract || void 0;
|
|
2893
2886
|
meta && !meta.length && (meta = ["none"]);
|
|
2894
|
-
const
|
|
2887
|
+
const config = client.config(), options = optionsFromFile(opts, body), { tag, label, title, description, creditLine, filename, source } = options, query = {
|
|
2895
2888
|
label,
|
|
2896
2889
|
title,
|
|
2897
2890
|
description,
|
|
@@ -2903,12 +2896,19 @@ ${selectionOpts}`);
|
|
|
2903
2896
|
tag,
|
|
2904
2897
|
method: "POST",
|
|
2905
2898
|
timeout: options.timeout || 0,
|
|
2906
|
-
uri:
|
|
2899
|
+
uri: buildAssetUploadUrl(config, assetType),
|
|
2907
2900
|
headers: options.contentType ? { "Content-Type": options.contentType } : {},
|
|
2908
2901
|
query,
|
|
2909
2902
|
body
|
|
2910
2903
|
});
|
|
2911
2904
|
}
|
|
2905
|
+
function buildAssetUploadUrl(config, assetType) {
|
|
2906
|
+
const assetTypeEndpoint = assetType === "image" ? "images" : "files";
|
|
2907
|
+
if (config["~experimental_resource"])
|
|
2908
|
+
return `${config["~experimental_resource"].type}/${config["~experimental_resource"].id}/assets/${assetTypeEndpoint}`;
|
|
2909
|
+
const dataset2 = hasDataset(config);
|
|
2910
|
+
return `assets/${assetTypeEndpoint}/${dataset2}`;
|
|
2911
|
+
}
|
|
2912
2912
|
function optionsFromFile(opts, file) {
|
|
2913
2913
|
return typeof File > "u" || !(file instanceof File) ? opts : Object.assign(
|
|
2914
2914
|
{
|
|
@@ -3000,6 +3000,7 @@ ${selectionOpts}`);
|
|
|
3000
3000
|
includeDrafts = false,
|
|
3001
3001
|
tag: _tag
|
|
3002
3002
|
} = {}) {
|
|
3003
|
+
resourceGuard("live", this.#client.config());
|
|
3003
3004
|
const {
|
|
3004
3005
|
projectId: projectId2,
|
|
3005
3006
|
apiVersion: _apiVersion,
|
|
@@ -3129,7 +3130,7 @@ ${selectionOpts}`);
|
|
|
3129
3130
|
* @param options - Options for the dataset
|
|
3130
3131
|
*/
|
|
3131
3132
|
create(name, options) {
|
|
3132
|
-
return lastValueFrom(
|
|
3133
|
+
return resourceGuard("dataset", this.#client.config()), lastValueFrom(
|
|
3133
3134
|
_modify(this.#client, this.#httpRequest, "PUT", name, options)
|
|
3134
3135
|
);
|
|
3135
3136
|
}
|
|
@@ -3140,7 +3141,7 @@ ${selectionOpts}`);
|
|
|
3140
3141
|
* @param options - New options for the dataset
|
|
3141
3142
|
*/
|
|
3142
3143
|
edit(name, options) {
|
|
3143
|
-
return lastValueFrom(
|
|
3144
|
+
return resourceGuard("dataset", this.#client.config()), lastValueFrom(
|
|
3144
3145
|
_modify(this.#client, this.#httpRequest, "PATCH", name, options)
|
|
3145
3146
|
);
|
|
3146
3147
|
}
|
|
@@ -3150,19 +3151,19 @@ ${selectionOpts}`);
|
|
|
3150
3151
|
* @param name - Name of the dataset to delete
|
|
3151
3152
|
*/
|
|
3152
3153
|
delete(name) {
|
|
3153
|
-
return lastValueFrom(_modify(this.#client, this.#httpRequest, "DELETE", name));
|
|
3154
|
+
return resourceGuard("dataset", this.#client.config()), lastValueFrom(_modify(this.#client, this.#httpRequest, "DELETE", name));
|
|
3154
3155
|
}
|
|
3155
3156
|
/**
|
|
3156
3157
|
* Fetch a list of datasets for the configured project
|
|
3157
3158
|
*/
|
|
3158
3159
|
list() {
|
|
3159
|
-
return lastValueFrom(
|
|
3160
|
+
return resourceGuard("dataset", this.#client.config()), lastValueFrom(
|
|
3160
3161
|
_request(this.#client, this.#httpRequest, { uri: "/datasets", tag: null })
|
|
3161
3162
|
);
|
|
3162
3163
|
}
|
|
3163
3164
|
}
|
|
3164
3165
|
function _modify(client, httpRequest, method, name, options) {
|
|
3165
|
-
return dataset(name), _request(client, httpRequest, {
|
|
3166
|
+
return resourceGuard("dataset", client.config()), dataset(name), _request(client, httpRequest, {
|
|
3166
3167
|
method,
|
|
3167
3168
|
uri: `/datasets/${name}`,
|
|
3168
3169
|
body: options,
|
|
@@ -3176,6 +3177,7 @@ ${selectionOpts}`);
|
|
|
3176
3177
|
this.#client = client, this.#httpRequest = httpRequest;
|
|
3177
3178
|
}
|
|
3178
3179
|
list(options) {
|
|
3180
|
+
resourceGuard("projects", this.#client.config());
|
|
3179
3181
|
const uri = options?.includeMembers === false ? "/projects?includeMembers=false" : "/projects";
|
|
3180
3182
|
return _request(this.#client, this.#httpRequest, { uri });
|
|
3181
3183
|
}
|
|
@@ -3185,7 +3187,7 @@ ${selectionOpts}`);
|
|
|
3185
3187
|
* @param projectId - ID of the project to fetch
|
|
3186
3188
|
*/
|
|
3187
3189
|
getById(projectId2) {
|
|
3188
|
-
return _request(this.#client, this.#httpRequest, { uri: `/projects/${projectId2}` });
|
|
3190
|
+
return resourceGuard("projects", this.#client.config()), _request(this.#client, this.#httpRequest, { uri: `/projects/${projectId2}` });
|
|
3189
3191
|
}
|
|
3190
3192
|
}
|
|
3191
3193
|
class ProjectsClient {
|
|
@@ -3195,6 +3197,7 @@ ${selectionOpts}`);
|
|
|
3195
3197
|
this.#client = client, this.#httpRequest = httpRequest;
|
|
3196
3198
|
}
|
|
3197
3199
|
list(options) {
|
|
3200
|
+
resourceGuard("projects", this.#client.config());
|
|
3198
3201
|
const uri = options?.includeMembers === false ? "/projects?includeMembers=false" : "/projects";
|
|
3199
3202
|
return lastValueFrom(_request(this.#client, this.#httpRequest, { uri }));
|
|
3200
3203
|
}
|
|
@@ -3204,7 +3207,7 @@ ${selectionOpts}`);
|
|
|
3204
3207
|
* @param projectId - ID of the project to fetch
|
|
3205
3208
|
*/
|
|
3206
3209
|
getById(projectId2) {
|
|
3207
|
-
return lastValueFrom(
|
|
3210
|
+
return resourceGuard("projects", this.#client.config()), lastValueFrom(
|
|
3208
3211
|
_request(this.#client, this.#httpRequest, { uri: `/projects/${projectId2}` })
|
|
3209
3212
|
);
|
|
3210
3213
|
}
|
|
@@ -3253,7 +3256,6 @@ ${selectionOpts}`);
|
|
|
3253
3256
|
live;
|
|
3254
3257
|
projects;
|
|
3255
3258
|
users;
|
|
3256
|
-
ai;
|
|
3257
3259
|
/**
|
|
3258
3260
|
* Private properties
|
|
3259
3261
|
*/
|
|
@@ -3264,7 +3266,7 @@ ${selectionOpts}`);
|
|
|
3264
3266
|
*/
|
|
3265
3267
|
listen = _listen;
|
|
3266
3268
|
constructor(httpRequest, config = defaultConfig) {
|
|
3267
|
-
this.config(config), this.#httpRequest = httpRequest, this.assets = new ObservableAssetsClient(this, this.#httpRequest), this.datasets = new ObservableDatasetsClient(this, this.#httpRequest), this.live = new LiveClient(this), this.projects = new ObservableProjectsClient(this, this.#httpRequest), this.users = new ObservableUsersClient(this, this.#httpRequest)
|
|
3269
|
+
this.config(config), this.#httpRequest = httpRequest, this.assets = new ObservableAssetsClient(this, this.#httpRequest), this.datasets = new ObservableDatasetsClient(this, this.#httpRequest), this.live = new LiveClient(this), this.projects = new ObservableProjectsClient(this, this.#httpRequest), this.users = new ObservableUsersClient(this, this.#httpRequest);
|
|
3268
3270
|
}
|
|
3269
3271
|
/**
|
|
3270
3272
|
* Clone the client - returns a new instance
|
|
@@ -3403,7 +3405,6 @@ ${selectionOpts}`);
|
|
|
3403
3405
|
live;
|
|
3404
3406
|
projects;
|
|
3405
3407
|
users;
|
|
3406
|
-
ai;
|
|
3407
3408
|
/**
|
|
3408
3409
|
* Observable version of the Sanity client, with the same configuration as the promise-based one
|
|
3409
3410
|
*/
|
|
@@ -3418,7 +3419,7 @@ ${selectionOpts}`);
|
|
|
3418
3419
|
*/
|
|
3419
3420
|
listen = _listen;
|
|
3420
3421
|
constructor(httpRequest, config = defaultConfig) {
|
|
3421
|
-
this.config(config), this.#httpRequest = httpRequest, this.assets = new AssetsClient(this, this.#httpRequest), this.datasets = new DatasetsClient(this, this.#httpRequest), this.live = new LiveClient(this), this.projects = new ProjectsClient(this, this.#httpRequest), this.users = new UsersClient(this, this.#httpRequest), this.
|
|
3422
|
+
this.config(config), this.#httpRequest = httpRequest, this.assets = new AssetsClient(this, this.#httpRequest), this.datasets = new DatasetsClient(this, this.#httpRequest), this.live = new LiveClient(this), this.projects = new ProjectsClient(this, this.#httpRequest), this.users = new UsersClient(this, this.#httpRequest), this.observable = new ObservableSanityClient(httpRequest, config);
|
|
3422
3423
|
}
|
|
3423
3424
|
/**
|
|
3424
3425
|
* Clone the client - returns a new instance
|