@sanity/client 7.13.2 → 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.
@@ -429,6 +429,7 @@ export declare type AssetMetadataType =
429
429
  | 'palette'
430
430
  | 'lqip'
431
431
  | 'blurhash'
432
+ | 'thumbhash'
432
433
  | 'none'
433
434
 
434
435
  /** @internal */
@@ -696,7 +697,26 @@ export declare interface ClientConfig {
696
697
  /** @defaultValue true */
697
698
  useCdn?: boolean
698
699
  token?: string
699
- /** @internal */
700
+ /**
701
+ * Configure the client to work with a specific Sanity resource (Media Library, Canvas, etc.)
702
+ * @remarks
703
+ * This allows the client to interact with resources beyond traditional project datasets.
704
+ * When configured, methods like `fetch()`, `assets.upload()`, and mutations will operate on the specified resource.
705
+ * @example
706
+ * ```ts
707
+ * createClient({
708
+ * resource: {
709
+ * type: 'media-library',
710
+ * id: 'your-media-library-id'
711
+ * }
712
+ * })
713
+ * ```
714
+ */
715
+ resource?: ClientConfigResource
716
+ /**
717
+ * @deprecated Use `resource` instead
718
+ * @internal
719
+ */
700
720
  '~experimental_resource'?: ClientConfigResource
701
721
  /**
702
722
  * What perspective to use for the client. See {@link https://www.sanity.io/docs/perspectives|perspective documentation}
@@ -5573,6 +5593,7 @@ export declare interface SanityImageAssetDocument extends SanityAssetDocument {
5573
5593
  isOpaque: boolean
5574
5594
  lqip?: string
5575
5595
  blurHash?: string
5596
+ thumbHash?: string
5576
5597
  dimensions: {
5577
5598
  _type: 'sanity.imageDimensions'
5578
5599
  aspectRatio: number
@@ -429,6 +429,7 @@ export declare type AssetMetadataType =
429
429
  | 'palette'
430
430
  | 'lqip'
431
431
  | 'blurhash'
432
+ | 'thumbhash'
432
433
  | 'none'
433
434
 
434
435
  /** @internal */
@@ -696,7 +697,26 @@ export declare interface ClientConfig {
696
697
  /** @defaultValue true */
697
698
  useCdn?: boolean
698
699
  token?: string
699
- /** @internal */
700
+ /**
701
+ * Configure the client to work with a specific Sanity resource (Media Library, Canvas, etc.)
702
+ * @remarks
703
+ * This allows the client to interact with resources beyond traditional project datasets.
704
+ * When configured, methods like `fetch()`, `assets.upload()`, and mutations will operate on the specified resource.
705
+ * @example
706
+ * ```ts
707
+ * createClient({
708
+ * resource: {
709
+ * type: 'media-library',
710
+ * id: 'your-media-library-id'
711
+ * }
712
+ * })
713
+ * ```
714
+ */
715
+ resource?: ClientConfigResource
716
+ /**
717
+ * @deprecated Use `resource` instead
718
+ * @internal
719
+ */
700
720
  '~experimental_resource'?: ClientConfigResource
701
721
  /**
702
722
  * What perspective to use for the client. See {@link https://www.sanity.io/docs/perspectives|perspective documentation}
@@ -5573,6 +5593,7 @@ export declare interface SanityImageAssetDocument extends SanityAssetDocument {
5573
5593
  isOpaque: boolean
5574
5594
  lqip?: string
5575
5595
  blurHash?: string
5596
+ thumbHash?: string
5576
5597
  dimensions: {
5577
5598
  _type: 'sanity.imageDimensions'
5578
5599
  aspectRatio: number
@@ -257,9 +257,16 @@ const VALID_ASSET_TYPES = ["image", "file"], VALID_INSERT_LOCATIONS = ["before",
257
257
  if (!Array.isArray(items))
258
258
  throw new Error(`${signature} takes an "items"-argument which must be an array`);
259
259
  }, hasDataset = (config) => {
260
- if (!config.dataset)
261
- throw new Error("`dataset` must be provided to perform queries");
262
- return config.dataset || "";
260
+ if (config.dataset)
261
+ return config.dataset;
262
+ const resource = config.resource;
263
+ if (resource && resource.type === "dataset") {
264
+ const segments = resource.id.split(".");
265
+ if (segments.length !== 2)
266
+ throw new Error('Dataset resource ID must be in the format "project.dataset"');
267
+ return segments[1];
268
+ }
269
+ throw new Error("`dataset` must be provided to perform queries");
263
270
  }, requestTag = (tag) => {
264
271
  if (typeof tag != "string" || !/^[a-z0-9._-]{1,75}$/i.test(tag))
265
272
  throw new Error(
@@ -267,9 +274,10 @@ const VALID_ASSET_TYPES = ["image", "file"], VALID_INSERT_LOCATIONS = ["before",
267
274
  );
268
275
  return tag;
269
276
  }, resourceConfig = (config) => {
270
- if (!config["~experimental_resource"])
277
+ const resource = config.resource;
278
+ if (!resource)
271
279
  throw new Error("`resource` must be provided to perform resource queries");
272
- const { type, id } = config["~experimental_resource"];
280
+ const { type, id } = resource;
273
281
  switch (type) {
274
282
  case "dataset": {
275
283
  if (id.split(".").length !== 2)
@@ -284,7 +292,7 @@ const VALID_ASSET_TYPES = ["image", "file"], VALID_INSERT_LOCATIONS = ["before",
284
292
  throw new Error(`Unsupported resource type: ${type.toString()}`);
285
293
  }
286
294
  }, resourceGuard = (service, config) => {
287
- if (config["~experimental_resource"])
295
+ if (config.resource)
288
296
  throw new Error(`\`${service}\` does not support resource-based operations`);
289
297
  }, EXPERIMENTAL_API_WARNING = "This is an experimental API version";
290
298
  function once(fn) {
@@ -321,6 +329,9 @@ const createWarningPrinter = (message) => (
321
329
  "The default export of @sanity/client has been deprecated. Use the named export `createClient` instead."
322
330
  ]), printCreateVersionWithBaseIdWarning = createWarningPrinter([
323
331
  "You have called `createVersion()` with a defined `document`. The recommended approach is to provide a `baseId` and `releaseId` instead."
332
+ ]), printDeprecatedResourceConfigWarning = createWarningPrinter([
333
+ "The `~experimental_resource` configuration property has been renamed to `resource`.",
334
+ "Please update your client configuration to use `resource` instead. Support for `~experimental_resource` will be removed in a future version."
324
335
  ]), defaultCdnHost = "apicdn.sanity.io", defaultConfig = {
325
336
  apiHost: "https://api.sanity.io",
326
337
  apiVersion: "1",
@@ -353,14 +364,16 @@ const initConfig = (config, prevConfig) => {
353
364
  const newConfig = {
354
365
  ...defaultConfig,
355
366
  ...specifiedConfig
356
- }, projectBased = newConfig.useProjectHostname && !newConfig["~experimental_resource"];
367
+ };
368
+ newConfig["~experimental_resource"] && !newConfig.resource && (printDeprecatedResourceConfigWarning(), newConfig.resource = newConfig["~experimental_resource"]);
369
+ const resourceConfig$1 = newConfig.resource, projectBased = newConfig.useProjectHostname && !resourceConfig$1;
357
370
  if (typeof Promise > "u") {
358
371
  const helpUrl = generateHelpUrl("js-client-promise-polyfill");
359
372
  throw new Error(`No native Promise-implementation found, polyfill needed - see ${helpUrl}`);
360
373
  }
361
374
  if (projectBased && !newConfig.projectId)
362
375
  throw new Error("Configuration must contain `projectId`");
363
- if (newConfig["~experimental_resource"] && resourceConfig(newConfig), typeof newConfig.perspective < "u" && validateApiPerspective(newConfig.perspective), "encodeSourceMap" in newConfig)
376
+ if (resourceConfig$1 && resourceConfig(newConfig), typeof newConfig.perspective < "u" && validateApiPerspective(newConfig.perspective), "encodeSourceMap" in newConfig)
364
377
  throw new Error(
365
378
  "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'?"
366
379
  );
@@ -1074,7 +1087,10 @@ function _create(client, httpRequest, doc, op, options = {}) {
1074
1087
  const mutation = { [op]: doc }, opts = Object.assign({ returnFirst: !0, returnDocuments: !0 }, options);
1075
1088
  return _dataRequest(client, httpRequest, "mutate", { mutations: [mutation] }, opts);
1076
1089
  }
1077
- const hasDataConfig = (client) => client.config().dataset !== void 0 && client.config().projectId !== void 0 || client.config()["~experimental_resource"] !== void 0, isQuery = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "query")), isMutate = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "mutate")), isDoc = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "doc", "")), isListener = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "listen")), isHistory = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "history", "")), isData = (client, uri) => uri.startsWith("/data/") || isQuery(client, uri) || isMutate(client, uri) || isDoc(client, uri) || isListener(client, uri) || isHistory(client, uri);
1090
+ const hasDataConfig = (client) => {
1091
+ const config = client.config();
1092
+ return config.dataset !== void 0 && config.projectId !== void 0 || config.resource !== void 0;
1093
+ }, isQuery = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "query")), isMutate = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "mutate")), isDoc = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "doc", "")), isListener = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "listen")), isHistory = (client, uri) => hasDataConfig(client) && uri.startsWith(_getDataUrl(client, "history", "")), isData = (client, uri) => uri.startsWith("/data/") || isQuery(client, uri) || isMutate(client, uri) || isDoc(client, uri) || isListener(client, uri) || isHistory(client, uri);
1078
1094
  function _requestObservable(client, httpRequest, options) {
1079
1095
  const uri = options.url || options.uri, config = client.config(), canUseCdn = typeof options.canUseCdn > "u" ? ["GET", "HEAD"].indexOf(options.method || "GET") >= 0 && isData(client, uri) : options.canUseCdn;
1080
1096
  let useCdn = (options.useCdn ?? config.useCdn) && canUseCdn;
@@ -1107,7 +1123,7 @@ function _request(client, httpRequest, options) {
1107
1123
  }
1108
1124
  function _getDataUrl(client, operation, path) {
1109
1125
  const config = client.config();
1110
- if (config["~experimental_resource"]) {
1126
+ if (config.resource) {
1111
1127
  resourceConfig(config);
1112
1128
  const resourceBase = resourceDataBase(config), uri2 = path !== void 0 ? `${operation}/${path}` : operation;
1113
1129
  return `${resourceBase}/${uri2}`.replace(/\/($|\?)/, "$1");
@@ -1140,9 +1156,10 @@ function _createAbortError(signal) {
1140
1156
  return error.name = "AbortError", error;
1141
1157
  }
1142
1158
  const resourceDataBase = (config) => {
1143
- if (!config["~experimental_resource"])
1159
+ const resource = config.resource;
1160
+ if (!resource)
1144
1161
  throw new Error("`resource` must be provided to perform resource queries");
1145
- const { type, id } = config["~experimental_resource"];
1162
+ const { type, id } = resource;
1146
1163
  switch (type) {
1147
1164
  case "dataset": {
1148
1165
  const segments = id.split(".");
@@ -1303,7 +1320,12 @@ function _upload(client, httpRequest, assetType, body, opts = {}) {
1303
1320
  validateAssetType(assetType);
1304
1321
  let meta = opts.extract || void 0;
1305
1322
  meta && !meta.length && (meta = ["none"]);
1306
- const config = client.config(), options = optionsFromFile(opts, body), { tag, label, title, description, creditLine, filename, source } = options, query = {
1323
+ const config = client.config(), options = optionsFromFile(opts, body), { tag, label, title, description, creditLine, filename, source } = options, isMediaLibrary = config.resource?.type === "media-library", query = isMediaLibrary ? {
1324
+ // Media Library only supports basic parameters
1325
+ title,
1326
+ filename
1327
+ } : {
1328
+ // Content Lake supports full set of parameters
1307
1329
  label,
1308
1330
  title,
1309
1331
  description,
@@ -1311,7 +1333,7 @@ function _upload(client, httpRequest, assetType, body, opts = {}) {
1311
1333
  meta,
1312
1334
  creditLine
1313
1335
  };
1314
- return source && (query.sourceId = source.id, query.sourceName = source.name, query.sourceUrl = source.url), _requestObservable(client, httpRequest, {
1336
+ return source && !isMediaLibrary && (query.sourceId = source.id, query.sourceName = source.name, query.sourceUrl = source.url), _requestObservable(client, httpRequest, {
1315
1337
  tag,
1316
1338
  method: "POST",
1317
1339
  timeout: options.timeout || 0,
@@ -1322,9 +1344,9 @@ function _upload(client, httpRequest, assetType, body, opts = {}) {
1322
1344
  });
1323
1345
  }
1324
1346
  function buildAssetUploadUrl(config, assetType) {
1325
- const assetTypeEndpoint = assetType === "image" ? "images" : "files";
1326
- if (config["~experimental_resource"]) {
1327
- const { type, id } = config["~experimental_resource"];
1347
+ const assetTypeEndpoint = assetType === "image" ? "images" : "files", resource = config.resource;
1348
+ if (resource) {
1349
+ const { type, id } = resource;
1328
1350
  switch (type) {
1329
1351
  case "dataset":
1330
1352
  throw new Error(
@@ -1624,7 +1646,7 @@ class ObservableMediaLibraryVideoClient {
1624
1646
  * @param options - Options for transformations and expiration
1625
1647
  */
1626
1648
  getPlaybackInfo(assetIdentifier, options = {}) {
1627
- const configMediaLibraryId = this.#client.config()["~experimental_resource"]?.id, { instanceId, libraryId } = parseAssetInstanceId(assetIdentifier), effectiveLibraryId = libraryId || configMediaLibraryId;
1649
+ const config = this.#client.config(), configMediaLibraryId = (config.resource || config["~experimental_resource"])?.id, { instanceId, libraryId } = parseAssetInstanceId(assetIdentifier), effectiveLibraryId = libraryId || configMediaLibraryId;
1628
1650
  if (!effectiveLibraryId)
1629
1651
  throw new Error(
1630
1652
  "Could not determine Media Library ID - you need to provide a valid Media Library ID in the client config or a Media Library GDR"