@sanity/client
Version:
Client for retrieving, creating and patching data from Sanity.io
191 lines (190 loc) • 11.2 kB
JavaScript
const BASE_URL = "https://www.sanity.io/help/";
function generateHelpUrl(slug) {
return BASE_URL + slug;
}
const VALID_ASSET_TYPES = ["image", "file"], VALID_INSERT_LOCATIONS = ["before", "after", "replace"], dataset = (name) => {
if (!/^(~[a-z0-9]{1}[-\w]{0,63}|[a-z0-9]{1}[-\w]{0,63})$/.test(name))
throw new Error(
"Datasets can only contain lowercase characters, numbers, underscores and dashes, and start with tilde, and be maximum 64 characters"
);
}, projectId = (id) => {
if (!/^[-a-z0-9]+$/i.test(id))
throw new Error("`projectId` can only contain only a-z, 0-9 and dashes");
}, validateAssetType = (type) => {
if (VALID_ASSET_TYPES.indexOf(type) === -1)
throw new Error(`Invalid asset type: ${type}. Must be one of ${VALID_ASSET_TYPES.join(", ")}`);
}, validateObject = (op, val) => {
if (val === null || typeof val != "object" || Array.isArray(val))
throw new Error(`${op}() takes an object of properties`);
}, validateDocumentId = (op, id) => {
if (typeof id != "string" || !/^[a-z0-9_][a-z0-9_.-]{0,127}$/i.test(id) || id.includes(".."))
throw new Error(`${op}(): "${id}" is not a valid document ID`);
}, requireDocumentId = (op, doc) => {
if (!doc._id)
throw new Error(`${op}() requires that the document contains an ID ("_id" property)`);
validateDocumentId(op, doc._id);
}, validateDocumentType = (op, type) => {
if (typeof type != "string")
throw new Error(`\`${op}()\`: \`${type}\` is not a valid document type`);
}, requireDocumentType = (op, doc) => {
if (!doc._type)
throw new Error(`\`${op}()\` requires that the document contains a type (\`_type\` property)`);
validateDocumentType(op, doc._type);
}, validateVersionIdMatch = (builtVersionId, document) => {
if (document._id && document._id !== builtVersionId)
throw new Error(
`The provided document ID (\`${document._id}\`) does not match the generated version ID (\`${builtVersionId}\`)`
);
}, validateInsert = (at, selector, items) => {
const signature = "insert(at, selector, items)";
if (VALID_INSERT_LOCATIONS.indexOf(at) === -1) {
const valid = VALID_INSERT_LOCATIONS.map((loc) => `"${loc}"`).join(", ");
throw new Error(`${signature} takes an "at"-argument which is one of: ${valid}`);
}
if (typeof selector != "string")
throw new Error(`${signature} takes a "selector"-argument which must be a string`);
if (!Array.isArray(items))
throw new Error(`${signature} takes an "items"-argument which must be an array`);
}, hasDataset = (config) => {
if (!config.dataset)
throw new Error("`dataset` must be provided to perform queries");
return config.dataset || "";
}, requestTag = (tag) => {
if (typeof tag != "string" || !/^[a-z0-9._-]{1,75}$/i.test(tag))
throw new Error(
"Tag can only contain alphanumeric characters, underscores, dashes and dots, and be between one and 75 characters long."
);
return tag;
}, resourceConfig = (config) => {
if (!config["~experimental_resource"])
throw new Error("`resource` must be provided to perform resource queries");
const { type, id } = config["~experimental_resource"];
switch (type) {
case "dataset": {
if (id.split(".").length !== 2)
throw new Error('Dataset resource ID must be in the format "project.dataset"');
return;
}
case "dashboard":
case "media-library":
case "canvas":
return;
default:
throw new Error(`Unsupported resource type: ${type.toString()}`);
}
}, resourceGuard = (service, config) => {
if (config["~experimental_resource"])
throw new Error(`\`${service}\` does not support resource-based operations`);
};
function once(fn) {
let didCall = !1, returnValue;
return (...args) => (didCall || (returnValue = fn(...args), didCall = !0), returnValue);
}
const createWarningPrinter = (message) => (
// eslint-disable-next-line no-console
once((...args) => console.warn(message.join(" "), ...args))
), printCdnAndWithCredentialsWarning = createWarningPrinter([
"Because you set `withCredentials` to true, we will override your `useCdn`",
"setting to be false since (cookie-based) credentials are never set on the CDN"
]), printCdnWarning = createWarningPrinter([
"Since you haven't set a value for `useCdn`, we will deliver content using our",
"global, edge-cached API-CDN. If you wish to have content delivered faster, set",
"`useCdn: false` to use the Live API. Note: You may incur higher costs using the live API."
]), printCdnPreviewDraftsWarning = createWarningPrinter([
"The Sanity client is configured with the `perspective` set to `drafts` or `previewDrafts`, which doesn't support the API-CDN.",
"The Live API will be used instead. Set `useCdn: false` in your configuration to hide this warning."
]), printPreviewDraftsDeprecationWarning = createWarningPrinter([
"The `previewDrafts` perspective has been renamed to `drafts` and will be removed in a future API version"
]), printBrowserTokenWarning = createWarningPrinter([
"You have configured Sanity client to use a token in the browser. This may cause unintentional security issues.",
`See ${generateHelpUrl(
"js-client-browser-token"
)} for more information and how to hide this warning.`
]), printCredentialedTokenWarning = createWarningPrinter([
"You have configured Sanity client to use a token, but also provided `withCredentials: true`.",
"This is no longer supported - only token will be used - remove `withCredentials: true`."
]), printNoApiVersionSpecifiedWarning = createWarningPrinter([
"Using the Sanity client without specifying an API version is deprecated.",
`See ${generateHelpUrl("js-client-api-version")}`
]), printNoDefaultExport = createWarningPrinter([
"The default export of @sanity/client has been deprecated. Use the named export `createClient` instead."
]), defaultCdnHost = "apicdn.sanity.io", defaultConfig = {
apiHost: "https://api.sanity.io",
apiVersion: "1",
useProjectHostname: !0,
stega: { enabled: !1 }
}, LOCALHOSTS = ["localhost", "127.0.0.1", "0.0.0.0"], isLocal = (host) => LOCALHOSTS.indexOf(host) !== -1;
function validateApiVersion(apiVersion) {
if (apiVersion === "1" || apiVersion === "X")
return;
const apiDate = new Date(apiVersion);
if (!(/^\d{4}-\d{2}-\d{2}$/.test(apiVersion) && apiDate instanceof Date && apiDate.getTime() > 0))
throw new Error("Invalid API version string, expected `1` or date in format `YYYY-MM-DD`");
}
function validateApiPerspective(perspective) {
if (Array.isArray(perspective) && perspective.length > 1 && perspective.includes("raw"))
throw new TypeError(
'Invalid API perspective value: "raw". The raw-perspective can not be combined with other perspectives'
);
}
const initConfig = (config, prevConfig) => {
const specifiedConfig = {
...prevConfig,
...config,
stega: {
...typeof prevConfig.stega == "boolean" ? { enabled: prevConfig.stega } : prevConfig.stega || defaultConfig.stega,
...typeof config.stega == "boolean" ? { enabled: config.stega } : config.stega || {}
}
};
specifiedConfig.apiVersion || printNoApiVersionSpecifiedWarning();
const newConfig = {
...defaultConfig,
...specifiedConfig
}, projectBased = newConfig.useProjectHostname && !newConfig["~experimental_resource"];
if (typeof Promise > "u") {
const helpUrl = generateHelpUrl("js-client-promise-polyfill");
throw new Error(`No native Promise-implementation found, polyfill needed - see ${helpUrl}`);
}
if (projectBased && !newConfig.projectId)
throw new Error("Configuration must contain `projectId`");
if (newConfig["~experimental_resource"] && resourceConfig(newConfig), typeof newConfig.perspective < "u" && validateApiPerspective(newConfig.perspective), "encodeSourceMap" in newConfig)
throw new Error(
"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'?"
);
if ("encodeSourceMapAtPath" in newConfig)
throw new Error(
"It looks like you're using options meant for '@sanity/preview-kit/client'. 'encodeSourceMapAtPath' is not supported in '@sanity/client'. Did you mean 'stega.filter'?"
);
if (typeof newConfig.stega.enabled != "boolean")
throw new Error(`stega.enabled must be a boolean, received ${newConfig.stega.enabled}`);
if (newConfig.stega.enabled && newConfig.stega.studioUrl === void 0)
throw new Error("stega.studioUrl must be defined when stega.enabled is true");
if (newConfig.stega.enabled && typeof newConfig.stega.studioUrl != "string" && typeof newConfig.stega.studioUrl != "function")
throw new Error(
`stega.studioUrl must be a string or a function, received ${newConfig.stega.studioUrl}`
);
const isBrowser = typeof window < "u" && window.location && window.location.hostname, isLocalhost = isBrowser && isLocal(window.location.hostname), hasToken = !!newConfig.token;
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);
const hostParts = newConfig.apiHost.split("://", 2), protocol = hostParts[0], host = hostParts[1], cdnHost = newConfig.isDefaultApi ? defaultCdnHost : host;
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;
};
exports.dataset = dataset;
exports.defaultConfig = defaultConfig;
exports.hasDataset = hasDataset;
exports.initConfig = initConfig;
exports.printCdnPreviewDraftsWarning = printCdnPreviewDraftsWarning;
exports.printNoDefaultExport = printNoDefaultExport;
exports.printPreviewDraftsDeprecationWarning = printPreviewDraftsDeprecationWarning;
exports.requestTag = requestTag;
exports.requireDocumentId = requireDocumentId;
exports.requireDocumentType = requireDocumentType;
exports.resourceConfig = resourceConfig;
exports.resourceGuard = resourceGuard;
exports.validateApiPerspective = validateApiPerspective;
exports.validateAssetType = validateAssetType;
exports.validateDocumentId = validateDocumentId;
exports.validateInsert = validateInsert;
exports.validateObject = validateObject;
exports.validateVersionIdMatch = validateVersionIdMatch;
//# sourceMappingURL=config.cjs.map
;