@sanity/client 6.28.4-beta.1 → 6.28.4-resources.4

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.
@@ -123,8 +123,8 @@ function defineHttpRequest(envMiddleware2) {
123
123
  }
124
124
  function shouldRetry(err, attempt, options) {
125
125
  if (options.maxRetries === 0) return !1;
126
- const isSafe = options.method === "GET" || options.method === "HEAD", isQuery = (options.uri || options.url).startsWith("/data/query"), isRetriableResponse = err.response && (err.response.statusCode === 429 || err.response.statusCode === 502 || err.response.statusCode === 503);
127
- return (isSafe || isQuery) && isRetriableResponse ? !0 : middleware.retry.shouldRetry(err, attempt, options);
126
+ 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);
127
+ return (isSafe || isQuery2) && isRetriableResponse ? !0 : middleware.retry.shouldRetry(err, attempt, options);
128
128
  }
129
129
  const BASE_URL = "https://www.sanity.io/help/";
130
130
  function generateHelpUrl(slug) {
@@ -171,6 +171,26 @@ const VALID_ASSET_TYPES = ["image", "file"], VALID_INSERT_LOCATIONS = ["before",
171
171
  "Tag can only contain alphanumeric characters, underscores, dashes and dots, and be between one and 75 characters long."
172
172
  );
173
173
  return tag;
174
+ }, resourceConfig = (config) => {
175
+ if (!config["~experimental_resource"])
176
+ throw new Error("`resource` must be provided to perform resource queries");
177
+ const { type, id } = config["~experimental_resource"];
178
+ switch (type) {
179
+ case "dataset": {
180
+ if (id.split(".").length !== 2)
181
+ throw new Error('Dataset resource ID must be in the format "project.dataset"');
182
+ return;
183
+ }
184
+ case "dashboard":
185
+ case "media-library":
186
+ case "canvas":
187
+ return;
188
+ default:
189
+ throw new Error(`Unsupported resource type: ${type.toString()}`);
190
+ }
191
+ }, resourceGuard = (service, config) => {
192
+ if (config["~experimental_resource"])
193
+ throw new Error(`\`${service}\` does not support resource-based operations`);
174
194
  };
175
195
  function once(fn) {
176
196
  let didCall = !1, returnValue;
@@ -217,21 +237,11 @@ function validateApiVersion(apiVersion) {
217
237
  if (!(/^\d{4}-\d{2}-\d{2}$/.test(apiVersion) && apiDate instanceof Date && apiDate.getTime() > 0))
218
238
  throw new Error("Invalid API version string, expected `1` or date in format `YYYY-MM-DD`");
219
239
  }
220
- const VALID_PERSPECTIVE = /^[a-z0-9_]+$/i;
221
240
  function validateApiPerspective(perspective) {
222
- if (Array.isArray(perspective) && perspective.includes("raw"))
241
+ if (Array.isArray(perspective) && perspective.length > 1 && perspective.includes("raw"))
223
242
  throw new TypeError(
224
243
  'Invalid API perspective value: "raw". The raw-perspective can not be combined with other perspectives'
225
244
  );
226
- const invalid = (Array.isArray(perspective) ? perspective : [perspective]).filter(
227
- (perspectiveName) => typeof perspectiveName != "string" || !VALID_PERSPECTIVE.test(perspectiveName)
228
- );
229
- if (invalid.length > 0) {
230
- const formatted = invalid.map((v) => JSON.stringify(v));
231
- throw new TypeError(
232
- `Invalid API perspective value${invalid.length === 1 ? "" : "s"}: ${formatted.join(", ")}, expected \`published\`, \`drafts\`, \`raw\` or a release identifier string`
233
- );
234
- }
235
245
  }
236
246
  const initConfig = (config, prevConfig) => {
237
247
  const specifiedConfig = {
@@ -246,14 +256,14 @@ const initConfig = (config, prevConfig) => {
246
256
  const newConfig = {
247
257
  ...defaultConfig,
248
258
  ...specifiedConfig
249
- }, projectBased = newConfig.useProjectHostname;
259
+ }, projectBased = newConfig.useProjectHostname && !newConfig["~experimental_resource"];
250
260
  if (typeof Promise > "u") {
251
261
  const helpUrl = generateHelpUrl("js-client-promise-polyfill");
252
262
  throw new Error(`No native Promise-implementation found, polyfill needed - see ${helpUrl}`);
253
263
  }
254
264
  if (projectBased && !newConfig.projectId)
255
265
  throw new Error("Configuration must contain `projectId`");
256
- if (typeof newConfig.perspective < "u" && validateApiPerspective(newConfig.perspective), "encodeSourceMap" in newConfig)
266
+ if (newConfig["~experimental_resource"] && resourceConfig(newConfig), typeof newConfig.perspective < "u" && validateApiPerspective(newConfig.perspective), "encodeSourceMap" in newConfig)
257
267
  throw new Error(
258
268
  "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'?"
259
269
  );
@@ -272,7 +282,7 @@ const initConfig = (config, prevConfig) => {
272
282
  const isBrowser = typeof window < "u" && window.location && window.location.hostname, isLocalhost = isBrowser && isLocal(window.location.hostname), hasToken = !!newConfig.token;
273
283
  newConfig.withCredentials && hasToken && (printCredentialedTokenWarning(), newConfig.withCredentials = !1), isBrowser && isLocalhost && hasToken && newConfig.ignoreBrowserTokenWarning !== !0 ? 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 === !0 && newConfig.withCredentials && printCdnAndWithCredentialsWarning(), newConfig.useCdn = newConfig.useCdn !== !1 && !newConfig.withCredentials, validateApiVersion(newConfig.apiVersion);
274
284
  const hostParts = newConfig.apiHost.split("://", 2), protocol = hostParts[0], host = hostParts[1], cdnHost = newConfig.isDefaultApi ? defaultCdnHost : host;
275
- return newConfig.useProjectHostname ? (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;
285
+ 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;
276
286
  };
277
287
  class ConnectionFailedError extends Error {
278
288
  name = "ConnectionFailedError";
@@ -842,7 +852,7 @@ function _action(client, httpRequest, actions, options) {
842
852
  );
843
853
  }
844
854
  function _dataRequest(client, httpRequest, endpoint, body, options = {}) {
845
- const isMutation = endpoint === "mutate", isAction = endpoint === "actions", isQuery = 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 = {
855
+ 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 = {
846
856
  method: useGet ? "GET" : "POST",
847
857
  uri,
848
858
  json: !0,
@@ -857,7 +867,7 @@ function _dataRequest(client, httpRequest, endpoint, body, options = {}) {
857
867
  resultSourceMap: options.resultSourceMap,
858
868
  lastLiveEventId: Array.isArray(lastLiveEventId) ? lastLiveEventId[0] : lastLiveEventId,
859
869
  cacheMode,
860
- canUseCdn: isQuery,
870
+ canUseCdn: isQuery2,
861
871
  signal: options.signal,
862
872
  fetch: options.fetch,
863
873
  useAbortSignal: options.useAbortSignal,
@@ -885,11 +895,12 @@ function _create(client, httpRequest, doc, op, options = {}) {
885
895
  const mutation = { [op]: doc }, opts = Object.assign({ returnFirst: !0, returnDocuments: !0 }, options);
886
896
  return _dataRequest(client, httpRequest, "mutate", { mutations: [mutation] }, opts);
887
897
  }
898
+ 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);
888
899
  function _requestObservable(client, httpRequest, options) {
889
- const uri = options.url || options.uri, config = client.config(), canUseCdn = typeof options.canUseCdn > "u" ? ["GET", "HEAD"].indexOf(options.method || "GET") >= 0 && uri.indexOf("/data/") === 0 : options.canUseCdn;
900
+ 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;
890
901
  let useCdn = (options.useCdn ?? config.useCdn) && canUseCdn;
891
902
  const tag = options.tag && config.requestTagPrefix ? [config.requestTagPrefix, options.tag].join(".") : options.tag || config.requestTagPrefix;
892
- if (tag && options.tag !== null && (options.query = { tag: requestTag(tag), ...options.query }), ["GET", "HEAD", "POST"].indexOf(options.method || "GET") >= 0 && uri.indexOf("/data/query/") === 0) {
903
+ if (tag && options.tag !== null && (options.query = { tag: requestTag(tag), ...options.query }), ["GET", "HEAD", "POST"].indexOf(options.method || "GET") >= 0 && isQuery(client, uri)) {
893
904
  const resultSourceMap = options.resultSourceMap ?? config.resultSourceMap;
894
905
  resultSourceMap !== void 0 && resultSourceMap !== !1 && (options.query = { resultSourceMap, ...options.query });
895
906
  const perspectiveOption = options.perspective || config.perspective;
@@ -916,8 +927,14 @@ function _request(client, httpRequest, options) {
916
927
  );
917
928
  }
918
929
  function _getDataUrl(client, operation, path) {
919
- const config = client.config(), catalog = hasDataset(config), baseUri = `/${operation}/${catalog}`;
920
- return `/data${path ? `${baseUri}/${path}` : baseUri}`.replace(/\/($|\?)/, "$1");
930
+ const config = client.config();
931
+ if (config["~experimental_resource"]) {
932
+ resourceConfig(config);
933
+ const resourceBase = resourceDataBase(config), uri2 = path !== void 0 ? `${operation}/${path}` : operation;
934
+ return `${resourceBase}/${uri2}`.replace(/\/($|\?)/, "$1");
935
+ }
936
+ const catalog = hasDataset(config), baseUri = `/${operation}/${catalog}`;
937
+ return `/data${path !== void 0 ? `${baseUri}/${path}` : baseUri}`.replace(/\/($|\?)/, "$1");
921
938
  }
922
939
  function _getUrl(client, uri, canUseCdn = !1) {
923
940
  const { url, cdnUrl } = client.config();
@@ -943,6 +960,27 @@ function _createAbortError(signal) {
943
960
  const error = new Error(signal?.reason ?? "The operation was aborted.");
944
961
  return error.name = "AbortError", error;
945
962
  }
963
+ const resourceDataBase = (config) => {
964
+ if (!config["~experimental_resource"])
965
+ throw new Error("`resource` must be provided to perform resource queries");
966
+ const { type, id } = config["~experimental_resource"];
967
+ switch (type) {
968
+ case "dataset": {
969
+ const segments = id.split(".");
970
+ if (segments.length !== 2)
971
+ throw new Error('Dataset ID must be in the format "project.dataset"');
972
+ return `/projects/${segments[0]}/datasets/${segments[1]}`;
973
+ }
974
+ case "canvas":
975
+ return `/canvases/${id}`;
976
+ case "media-library":
977
+ return `/media-libraries/${id}`;
978
+ case "dashboard":
979
+ return `/dashboards/${id}`;
980
+ default:
981
+ throw new Error(`Unsupported resource type: ${type.toString()}`);
982
+ }
983
+ };
946
984
  class ObservableAssetsClient {
947
985
  #client;
948
986
  #httpRequest;
@@ -975,7 +1013,7 @@ function _upload(client, httpRequest, assetType, body, opts = {}) {
975
1013
  validateAssetType(assetType);
976
1014
  let meta = opts.extract || void 0;
977
1015
  meta && !meta.length && (meta = ["none"]);
978
- const dataset2 = hasDataset(client.config()), assetEndpoint = assetType === "image" ? "images" : "files", options = optionsFromFile(opts, body), { tag, label, title, description, creditLine, filename, source } = options, query = {
1016
+ const config = client.config(), options = optionsFromFile(opts, body), { tag, label, title, description, creditLine, filename, source } = options, query = {
979
1017
  label,
980
1018
  title,
981
1019
  description,
@@ -987,12 +1025,34 @@ function _upload(client, httpRequest, assetType, body, opts = {}) {
987
1025
  tag,
988
1026
  method: "POST",
989
1027
  timeout: options.timeout || 0,
990
- uri: `/assets/${assetEndpoint}/${dataset2}`,
1028
+ uri: buildAssetUploadUrl(config, assetType),
991
1029
  headers: options.contentType ? { "Content-Type": options.contentType } : {},
992
1030
  query,
993
1031
  body
994
1032
  });
995
1033
  }
1034
+ function buildAssetUploadUrl(config, assetType) {
1035
+ const assetTypeEndpoint = assetType === "image" ? "images" : "files";
1036
+ if (config["~experimental_resource"]) {
1037
+ const { type, id } = config["~experimental_resource"];
1038
+ switch (type) {
1039
+ case "dataset":
1040
+ throw new Error(
1041
+ "Assets are not supported for dataset resources, yet. Configure the client with `{projectId: <projectId>, dataset: <datasetId>}` instead."
1042
+ );
1043
+ case "canvas":
1044
+ return `/canvases/${id}/assets/${assetTypeEndpoint}`;
1045
+ case "media-library":
1046
+ return `/media-libraries/${id}/upload`;
1047
+ case "dashboard":
1048
+ return `/dashboards/${id}/assets/${assetTypeEndpoint}`;
1049
+ default:
1050
+ throw new Error(`Unsupported resource type: ${type.toString()}`);
1051
+ }
1052
+ }
1053
+ const dataset2 = hasDataset(config);
1054
+ return `assets/${assetTypeEndpoint}/${dataset2}`;
1055
+ }
996
1056
  function optionsFromFile(opts, file) {
997
1057
  return typeof File > "u" || !(file instanceof File) ? opts : Object.assign(
998
1058
  {
@@ -1084,6 +1144,7 @@ class LiveClient {
1084
1144
  includeDrafts = !1,
1085
1145
  tag: _tag
1086
1146
  } = {}) {
1147
+ resourceGuard("live", this.#client.config());
1087
1148
  const {
1088
1149
  projectId: projectId2,
1089
1150
  apiVersion: _apiVersion,
@@ -1213,7 +1274,7 @@ class DatasetsClient {
1213
1274
  * @param options - Options for the dataset
1214
1275
  */
1215
1276
  create(name, options) {
1216
- return rxjs.lastValueFrom(
1277
+ return resourceGuard("dataset", this.#client.config()), rxjs.lastValueFrom(
1217
1278
  _modify(this.#client, this.#httpRequest, "PUT", name, options)
1218
1279
  );
1219
1280
  }
@@ -1224,7 +1285,7 @@ class DatasetsClient {
1224
1285
  * @param options - New options for the dataset
1225
1286
  */
1226
1287
  edit(name, options) {
1227
- return rxjs.lastValueFrom(
1288
+ return resourceGuard("dataset", this.#client.config()), rxjs.lastValueFrom(
1228
1289
  _modify(this.#client, this.#httpRequest, "PATCH", name, options)
1229
1290
  );
1230
1291
  }
@@ -1234,19 +1295,19 @@ class DatasetsClient {
1234
1295
  * @param name - Name of the dataset to delete
1235
1296
  */
1236
1297
  delete(name) {
1237
- return rxjs.lastValueFrom(_modify(this.#client, this.#httpRequest, "DELETE", name));
1298
+ return resourceGuard("dataset", this.#client.config()), rxjs.lastValueFrom(_modify(this.#client, this.#httpRequest, "DELETE", name));
1238
1299
  }
1239
1300
  /**
1240
1301
  * Fetch a list of datasets for the configured project
1241
1302
  */
1242
1303
  list() {
1243
- return rxjs.lastValueFrom(
1304
+ return resourceGuard("dataset", this.#client.config()), rxjs.lastValueFrom(
1244
1305
  _request(this.#client, this.#httpRequest, { uri: "/datasets", tag: null })
1245
1306
  );
1246
1307
  }
1247
1308
  }
1248
1309
  function _modify(client, httpRequest, method, name, options) {
1249
- return dataset(name), _request(client, httpRequest, {
1310
+ return resourceGuard("dataset", client.config()), dataset(name), _request(client, httpRequest, {
1250
1311
  method,
1251
1312
  uri: `/datasets/${name}`,
1252
1313
  body: options,
@@ -1260,6 +1321,7 @@ class ObservableProjectsClient {
1260
1321
  this.#client = client, this.#httpRequest = httpRequest;
1261
1322
  }
1262
1323
  list(options) {
1324
+ resourceGuard("projects", this.#client.config());
1263
1325
  const uri = options?.includeMembers === !1 ? "/projects?includeMembers=false" : "/projects";
1264
1326
  return _request(this.#client, this.#httpRequest, { uri });
1265
1327
  }
@@ -1269,7 +1331,7 @@ class ObservableProjectsClient {
1269
1331
  * @param projectId - ID of the project to fetch
1270
1332
  */
1271
1333
  getById(projectId2) {
1272
- return _request(this.#client, this.#httpRequest, { uri: `/projects/${projectId2}` });
1334
+ return resourceGuard("projects", this.#client.config()), _request(this.#client, this.#httpRequest, { uri: `/projects/${projectId2}` });
1273
1335
  }
1274
1336
  }
1275
1337
  class ProjectsClient {
@@ -1279,6 +1341,7 @@ class ProjectsClient {
1279
1341
  this.#client = client, this.#httpRequest = httpRequest;
1280
1342
  }
1281
1343
  list(options) {
1344
+ resourceGuard("projects", this.#client.config());
1282
1345
  const uri = options?.includeMembers === !1 ? "/projects?includeMembers=false" : "/projects";
1283
1346
  return rxjs.lastValueFrom(_request(this.#client, this.#httpRequest, { uri }));
1284
1347
  }
@@ -1288,7 +1351,7 @@ class ProjectsClient {
1288
1351
  * @param projectId - ID of the project to fetch
1289
1352
  */
1290
1353
  getById(projectId2) {
1291
- return rxjs.lastValueFrom(
1354
+ return resourceGuard("projects", this.#client.config()), rxjs.lastValueFrom(
1292
1355
  _request(this.#client, this.#httpRequest, { uri: `/projects/${projectId2}` })
1293
1356
  );
1294
1357
  }