@sanity/client 7.13.1 → 7.14.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 (40) hide show
  1. package/README.md +67 -5
  2. package/dist/_chunks-cjs/config.cjs +21 -8
  3. package/dist/_chunks-cjs/config.cjs.map +1 -1
  4. package/dist/_chunks-cjs/resolveEditInfo.cjs +1 -1
  5. package/dist/_chunks-cjs/resolveEditInfo.cjs.map +1 -1
  6. package/dist/_chunks-cjs/stegaEncodeSourceMap.cjs +1 -1
  7. package/dist/_chunks-cjs/stegaEncodeSourceMap.cjs.map +1 -1
  8. package/dist/_chunks-es/config.js +21 -8
  9. package/dist/_chunks-es/config.js.map +1 -1
  10. package/dist/_chunks-es/resolveEditInfo.js +1 -1
  11. package/dist/_chunks-es/resolveEditInfo.js.map +1 -1
  12. package/dist/_chunks-es/stegaEncodeSourceMap.js +1 -1
  13. package/dist/_chunks-es/stegaEncodeSourceMap.js.map +1 -1
  14. package/dist/index.browser.cjs +40 -18
  15. package/dist/index.browser.cjs.map +1 -1
  16. package/dist/index.browser.d.cts +22 -1
  17. package/dist/index.browser.d.ts +22 -1
  18. package/dist/index.browser.js +40 -18
  19. package/dist/index.browser.js.map +1 -1
  20. package/dist/index.cjs +20 -11
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +22 -1
  23. package/dist/index.d.ts +22 -1
  24. package/dist/index.js +20 -11
  25. package/dist/index.js.map +1 -1
  26. package/dist/stega.browser.d.cts +22 -1
  27. package/dist/stega.browser.d.ts +22 -1
  28. package/dist/stega.d.cts +22 -1
  29. package/dist/stega.d.ts +22 -1
  30. package/package.json +3 -3
  31. package/src/assets/AssetsClient.ts +25 -11
  32. package/src/config.ts +10 -2
  33. package/src/csm/resolveMapping.ts +1 -1
  34. package/src/data/dataMethods.ts +12 -6
  35. package/src/mediaLibrary/MediaLibraryVideoClient.ts +3 -1
  36. package/src/types.ts +23 -1
  37. package/src/validators.ts +22 -6
  38. package/src/warnings.ts +5 -0
  39. package/umd/sanityClient.js +43 -21
  40. package/umd/sanityClient.min.js +2 -2
@@ -423,6 +423,7 @@ export declare type AssetMetadataType =
423
423
  | 'palette'
424
424
  | 'lqip'
425
425
  | 'blurhash'
426
+ | 'thumbhash'
426
427
  | 'none'
427
428
 
428
429
  /** @internal */
@@ -690,7 +691,26 @@ export declare interface ClientConfig {
690
691
  /** @defaultValue true */
691
692
  useCdn?: boolean
692
693
  token?: string
693
- /** @internal */
694
+ /**
695
+ * Configure the client to work with a specific Sanity resource (Media Library, Canvas, etc.)
696
+ * @remarks
697
+ * This allows the client to interact with resources beyond traditional project datasets.
698
+ * When configured, methods like `fetch()`, `assets.upload()`, and mutations will operate on the specified resource.
699
+ * @example
700
+ * ```ts
701
+ * createClient({
702
+ * resource: {
703
+ * type: 'media-library',
704
+ * id: 'your-media-library-id'
705
+ * }
706
+ * })
707
+ * ```
708
+ */
709
+ resource?: ClientConfigResource
710
+ /**
711
+ * @deprecated Use `resource` instead
712
+ * @internal
713
+ */
694
714
  '~experimental_resource'?: ClientConfigResource
695
715
  /**
696
716
  * What perspective to use for the client. See {@link https://www.sanity.io/docs/perspectives|perspective documentation}
@@ -5749,6 +5769,7 @@ export declare interface SanityImageAssetDocument extends SanityAssetDocument {
5749
5769
  isOpaque: boolean
5750
5770
  lqip?: string
5751
5771
  blurHash?: string
5772
+ thumbHash?: string
5752
5773
  dimensions: {
5753
5774
  _type: 'sanity.imageDimensions'
5754
5775
  aspectRatio: number
@@ -423,6 +423,7 @@ export declare type AssetMetadataType =
423
423
  | 'palette'
424
424
  | 'lqip'
425
425
  | 'blurhash'
426
+ | 'thumbhash'
426
427
  | 'none'
427
428
 
428
429
  /** @internal */
@@ -690,7 +691,26 @@ export declare interface ClientConfig {
690
691
  /** @defaultValue true */
691
692
  useCdn?: boolean
692
693
  token?: string
693
- /** @internal */
694
+ /**
695
+ * Configure the client to work with a specific Sanity resource (Media Library, Canvas, etc.)
696
+ * @remarks
697
+ * This allows the client to interact with resources beyond traditional project datasets.
698
+ * When configured, methods like `fetch()`, `assets.upload()`, and mutations will operate on the specified resource.
699
+ * @example
700
+ * ```ts
701
+ * createClient({
702
+ * resource: {
703
+ * type: 'media-library',
704
+ * id: 'your-media-library-id'
705
+ * }
706
+ * })
707
+ * ```
708
+ */
709
+ resource?: ClientConfigResource
710
+ /**
711
+ * @deprecated Use `resource` instead
712
+ * @internal
713
+ */
694
714
  '~experimental_resource'?: ClientConfigResource
695
715
  /**
696
716
  * What perspective to use for the client. See {@link https://www.sanity.io/docs/perspectives|perspective documentation}
@@ -5749,6 +5769,7 @@ export declare interface SanityImageAssetDocument extends SanityAssetDocument {
5749
5769
  isOpaque: boolean
5750
5770
  lqip?: string
5751
5771
  blurHash?: string
5772
+ thumbHash?: string
5752
5773
  dimensions: {
5753
5774
  _type: 'sanity.imageDimensions'
5754
5775
  aspectRatio: number
package/dist/stega.d.cts CHANGED
@@ -423,6 +423,7 @@ export declare type AssetMetadataType =
423
423
  | 'palette'
424
424
  | 'lqip'
425
425
  | 'blurhash'
426
+ | 'thumbhash'
426
427
  | 'none'
427
428
 
428
429
  /** @internal */
@@ -690,7 +691,26 @@ export declare interface ClientConfig {
690
691
  /** @defaultValue true */
691
692
  useCdn?: boolean
692
693
  token?: string
693
- /** @internal */
694
+ /**
695
+ * Configure the client to work with a specific Sanity resource (Media Library, Canvas, etc.)
696
+ * @remarks
697
+ * This allows the client to interact with resources beyond traditional project datasets.
698
+ * When configured, methods like `fetch()`, `assets.upload()`, and mutations will operate on the specified resource.
699
+ * @example
700
+ * ```ts
701
+ * createClient({
702
+ * resource: {
703
+ * type: 'media-library',
704
+ * id: 'your-media-library-id'
705
+ * }
706
+ * })
707
+ * ```
708
+ */
709
+ resource?: ClientConfigResource
710
+ /**
711
+ * @deprecated Use `resource` instead
712
+ * @internal
713
+ */
694
714
  '~experimental_resource'?: ClientConfigResource
695
715
  /**
696
716
  * What perspective to use for the client. See {@link https://www.sanity.io/docs/perspectives|perspective documentation}
@@ -5749,6 +5769,7 @@ export declare interface SanityImageAssetDocument extends SanityAssetDocument {
5749
5769
  isOpaque: boolean
5750
5770
  lqip?: string
5751
5771
  blurHash?: string
5772
+ thumbHash?: string
5752
5773
  dimensions: {
5753
5774
  _type: 'sanity.imageDimensions'
5754
5775
  aspectRatio: number
package/dist/stega.d.ts CHANGED
@@ -423,6 +423,7 @@ export declare type AssetMetadataType =
423
423
  | 'palette'
424
424
  | 'lqip'
425
425
  | 'blurhash'
426
+ | 'thumbhash'
426
427
  | 'none'
427
428
 
428
429
  /** @internal */
@@ -690,7 +691,26 @@ export declare interface ClientConfig {
690
691
  /** @defaultValue true */
691
692
  useCdn?: boolean
692
693
  token?: string
693
- /** @internal */
694
+ /**
695
+ * Configure the client to work with a specific Sanity resource (Media Library, Canvas, etc.)
696
+ * @remarks
697
+ * This allows the client to interact with resources beyond traditional project datasets.
698
+ * When configured, methods like `fetch()`, `assets.upload()`, and mutations will operate on the specified resource.
699
+ * @example
700
+ * ```ts
701
+ * createClient({
702
+ * resource: {
703
+ * type: 'media-library',
704
+ * id: 'your-media-library-id'
705
+ * }
706
+ * })
707
+ * ```
708
+ */
709
+ resource?: ClientConfigResource
710
+ /**
711
+ * @deprecated Use `resource` instead
712
+ * @internal
713
+ */
694
714
  '~experimental_resource'?: ClientConfigResource
695
715
  /**
696
716
  * What perspective to use for the client. See {@link https://www.sanity.io/docs/perspectives|perspective documentation}
@@ -5749,6 +5769,7 @@ export declare interface SanityImageAssetDocument extends SanityAssetDocument {
5749
5769
  isOpaque: boolean
5750
5770
  lqip?: string
5751
5771
  blurHash?: string
5772
+ thumbHash?: string
5752
5773
  dimensions: {
5753
5774
  _type: 'sanity.imageDimensions'
5754
5775
  aspectRatio: number
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/client",
3
- "version": "7.13.1",
3
+ "version": "7.14.0",
4
4
  "description": "Client for retrieving, creating and patching data from Sanity.io",
5
5
  "keywords": [
6
6
  "sanity",
@@ -130,7 +130,7 @@
130
130
  },
131
131
  "dependencies": {
132
132
  "@sanity/eventsource": "^5.0.2",
133
- "get-it": "^8.6.9",
133
+ "get-it": "^8.7.0",
134
134
  "nanoid": "^3.3.11",
135
135
  "rxjs": "^7.0.0"
136
136
  },
@@ -161,7 +161,7 @@
161
161
  "json-diff": "^1.0.6",
162
162
  "ls-engines": "^0.9.3",
163
163
  "msw": "^2.7.3",
164
- "next": "^15.3.0",
164
+ "next": "15.5.8",
165
165
  "nock": "^13.5.6",
166
166
  "pkg-pr-new": "^0.0.60",
167
167
  "prettier": "^3.5.3",
@@ -153,15 +153,28 @@ function _upload(
153
153
  const config = client.config()
154
154
  const options = optionsFromFile(opts, body)
155
155
  const {tag, label, title, description, creditLine, filename, source} = options
156
- const query: Any = {
157
- label,
158
- title,
159
- description,
160
- filename,
161
- meta,
162
- creditLine,
163
- }
164
- if (source) {
156
+ const resource = config.resource
157
+ const isMediaLibrary = resource?.type === 'media-library'
158
+
159
+ // Media Library has a simpler upload API with fewer supported parameters
160
+ const query: Any = isMediaLibrary
161
+ ? {
162
+ // Media Library only supports basic parameters
163
+ title,
164
+ filename,
165
+ }
166
+ : {
167
+ // Content Lake supports full set of parameters
168
+ label,
169
+ title,
170
+ description,
171
+ filename,
172
+ meta,
173
+ creditLine,
174
+ }
175
+
176
+ // Source parameters are only for Content Lake
177
+ if (source && !isMediaLibrary) {
165
178
  query.sourceId = source.id
166
179
  query.sourceName = source.name
167
180
  query.sourceUrl = source.url
@@ -180,9 +193,10 @@ function _upload(
180
193
 
181
194
  function buildAssetUploadUrl(config: InitializedClientConfig, assetType: 'image' | 'file'): string {
182
195
  const assetTypeEndpoint = assetType === 'image' ? 'images' : 'files'
196
+ const resource = config.resource
183
197
 
184
- if (config['~experimental_resource']) {
185
- const {type, id} = config['~experimental_resource']
198
+ if (resource) {
199
+ const {type, id} = resource
186
200
  switch (type) {
187
201
  case 'dataset': {
188
202
  throw new Error(
package/src/config.ts CHANGED
@@ -63,7 +63,15 @@ export const initConfig = (
63
63
  ...defaultConfig,
64
64
  ...specifiedConfig,
65
65
  } as InitializedClientConfig
66
- const projectBased = newConfig.useProjectHostname && !newConfig['~experimental_resource']
66
+
67
+ // Normalize resource configuration - prefer `resource` over deprecated `~experimental_resource`
68
+ if (newConfig['~experimental_resource'] && !newConfig.resource) {
69
+ warnings.printDeprecatedResourceConfigWarning()
70
+ newConfig.resource = newConfig['~experimental_resource']
71
+ }
72
+
73
+ const resourceConfig = newConfig.resource
74
+ const projectBased = newConfig.useProjectHostname && !resourceConfig
67
75
 
68
76
  if (typeof Promise === 'undefined') {
69
77
  const helpUrl = generateHelpUrl('js-client-promise-polyfill')
@@ -74,7 +82,7 @@ export const initConfig = (
74
82
  throw new Error('Configuration must contain `projectId`')
75
83
  }
76
84
 
77
- if (newConfig['~experimental_resource']) {
85
+ if (resourceConfig) {
78
86
  validate.resourceConfig(newConfig)
79
87
  }
80
88
 
@@ -28,7 +28,7 @@ export function resolveMapping(
28
28
  }
29
29
 
30
30
  const resultMappingPathArray = jsonPathArray(jsonPathToMappingPath(resultPath))
31
- for (let i = resultMappingPathArray.length - 1; i > 0; i--) {
31
+ for (let i = resultMappingPathArray.length - 1; i >= 0; i--) {
32
32
  const key = `$${resultMappingPathArray.slice(0, i).join('')}`
33
33
  const mappingFound = csm.mappings[key]
34
34
  if (mappingFound) {
@@ -559,9 +559,13 @@ export function _create<R extends Record<string, Any>>(
559
559
  return _dataRequest(client, httpRequest, 'mutate', {mutations: [mutation]}, opts)
560
560
  }
561
561
 
562
- const hasDataConfig = (client: Client) =>
563
- (client.config().dataset !== undefined && client.config().projectId !== undefined) ||
564
- client.config()['~experimental_resource'] !== undefined
562
+ const hasDataConfig = (client: Client) => {
563
+ const config = client.config()
564
+ return (
565
+ (config.dataset !== undefined && config.projectId !== undefined) ||
566
+ config.resource !== undefined
567
+ )
568
+ }
565
569
 
566
570
  const isQuery = (client: Client, uri: string) =>
567
571
  hasDataConfig(client) && uri.startsWith(_getDataUrl(client, 'query'))
@@ -690,7 +694,8 @@ export function _request<R>(client: Client, httpRequest: HttpRequest, options: A
690
694
  */
691
695
  export function _getDataUrl(client: Client, operation: string, path?: string): string {
692
696
  const config = client.config()
693
- if (config['~experimental_resource']) {
697
+ const resource = config.resource
698
+ if (resource) {
694
699
  validators.resourceConfig(config)
695
700
  const resourceBase = resourceDataBase(config)
696
701
  const uri = path !== undefined ? `${operation}/${path}` : operation
@@ -759,10 +764,11 @@ function _createAbortError(signal?: AbortSignal) {
759
764
  }
760
765
 
761
766
  const resourceDataBase = (config: InitializedClientConfig): string => {
762
- if (!config['~experimental_resource']) {
767
+ const resource = config.resource
768
+ if (!resource) {
763
769
  throw new Error('`resource` must be provided to perform resource queries')
764
770
  }
765
- const {type, id} = config['~experimental_resource']
771
+ const {type, id} = resource
766
772
 
767
773
  switch (type) {
768
774
  case 'dataset': {
@@ -29,7 +29,9 @@ export class ObservableMediaLibraryVideoClient {
29
29
  assetIdentifier: MediaLibraryAssetInstanceIdentifier,
30
30
  options: MediaLibraryPlaybackInfoOptions = {},
31
31
  ): Observable<VideoPlaybackInfo> {
32
- const configMediaLibraryId = this.#client.config()['~experimental_resource']?.id
32
+ const config = this.#client.config()
33
+ const resource = config.resource || config['~experimental_resource']
34
+ const configMediaLibraryId = resource?.id
33
35
 
34
36
  const {instanceId, libraryId} = parseAssetInstanceId(assetIdentifier)
35
37
  const effectiveLibraryId = libraryId || configMediaLibraryId
package/src/types.ts CHANGED
@@ -79,7 +79,27 @@ export interface ClientConfig {
79
79
  useCdn?: boolean
80
80
  token?: string
81
81
 
82
- /** @internal */
82
+ /**
83
+ * Configure the client to work with a specific Sanity resource (Media Library, Canvas, etc.)
84
+ * @remarks
85
+ * This allows the client to interact with resources beyond traditional project datasets.
86
+ * When configured, methods like `fetch()`, `assets.upload()`, and mutations will operate on the specified resource.
87
+ * @example
88
+ * ```ts
89
+ * createClient({
90
+ * resource: {
91
+ * type: 'media-library',
92
+ * id: 'your-media-library-id'
93
+ * }
94
+ * })
95
+ * ```
96
+ */
97
+ resource?: ClientConfigResource
98
+
99
+ /**
100
+ * @deprecated Use `resource` instead
101
+ * @internal
102
+ */
83
103
  '~experimental_resource'?: ClientConfigResource
84
104
 
85
105
  /**
@@ -225,6 +245,7 @@ export type AssetMetadataType =
225
245
  | 'palette'
226
246
  | 'lqip'
227
247
  | 'blurhash'
248
+ | 'thumbhash'
228
249
  | 'none'
229
250
 
230
251
  /** @public */
@@ -349,6 +370,7 @@ export interface SanityImageAssetDocument extends SanityAssetDocument {
349
370
  isOpaque: boolean
350
371
  lqip?: string
351
372
  blurHash?: string
373
+ thumbHash?: string
352
374
  dimensions: {
353
375
  _type: 'sanity.imageDimensions'
354
376
  aspectRatio: number
package/src/validators.ts CHANGED
@@ -82,11 +82,23 @@ export const validateInsert = (at: string, selector: string, items: Any[]) => {
82
82
  }
83
83
 
84
84
  export const hasDataset = (config: InitializedClientConfig): string => {
85
- if (!config.dataset) {
86
- throw new Error('`dataset` must be provided to perform queries')
85
+ // Check if dataset is directly on the config
86
+ if (config.dataset) {
87
+ return config.dataset
88
+ }
89
+
90
+ // Check if dataset is in resource configuration
91
+ // Note: ~experimental_resource is normalized to resource during client initialization
92
+ const resource = config.resource
93
+ if (resource && resource.type === 'dataset') {
94
+ const segments = resource.id.split('.')
95
+ if (segments.length !== 2) {
96
+ throw new Error('Dataset resource ID must be in the format "project.dataset"')
97
+ }
98
+ return segments[1]
87
99
  }
88
100
 
89
- return config.dataset || ''
101
+ throw new Error('`dataset` must be provided to perform queries')
90
102
  }
91
103
 
92
104
  export const requestTag = (tag: string) => {
@@ -100,10 +112,12 @@ export const requestTag = (tag: string) => {
100
112
  }
101
113
 
102
114
  export const resourceConfig = (config: InitializedClientConfig): void => {
103
- if (!config['~experimental_resource']) {
115
+ // Note: ~experimental_resource is normalized to resource during client initialization
116
+ const resource = config.resource
117
+ if (!resource) {
104
118
  throw new Error('`resource` must be provided to perform resource queries')
105
119
  }
106
- const {type, id} = config['~experimental_resource']
120
+ const {type, id} = resource
107
121
 
108
122
  switch (type) {
109
123
  case 'dataset': {
@@ -125,7 +139,9 @@ export const resourceConfig = (config: InitializedClientConfig): void => {
125
139
  }
126
140
 
127
141
  export const resourceGuard = (service: string, config: InitializedClientConfig): void => {
128
- if (config['~experimental_resource']) {
142
+ // Note: ~experimental_resource is normalized to resource during client initialization
143
+ const resource = config.resource
144
+ if (resource) {
129
145
  throw new Error(`\`${service}\` does not support resource-based operations`)
130
146
  }
131
147
  }
package/src/warnings.ts CHANGED
@@ -50,3 +50,8 @@ export const printNoDefaultExport = createWarningPrinter([
50
50
  export const printCreateVersionWithBaseIdWarning = createWarningPrinter([
51
51
  'You have called `createVersion()` with a defined `document`. The recommended approach is to provide a `baseId` and `releaseId` instead.',
52
52
  ])
53
+
54
+ export const printDeprecatedResourceConfigWarning = createWarningPrinter([
55
+ 'The `~experimental_resource` configuration property has been renamed to `resource`.',
56
+ 'Please update your client configuration to use `resource` instead. Support for `~experimental_resource` will be removed in a future version.',
57
+ ])