@sanity/client
Version:
Client for retrieving, creating and patching data from Sanity.io
339 lines (338 loc) • 12.7 kB
JavaScript
import { t as __exportAll } from "./rolldown-runtime-vyAXikos.js";
import { t as isRecord } from "./isRecord-Kfmt-nk-.js";
var studioPath_exports = /* @__PURE__ */ __exportAll({
fromString: () => fromString,
get: () => get,
isIndexSegment: () => isIndexSegment,
isIndexTuple: () => isIndexTuple,
isKeySegment: () => isKeySegment,
reKeySegment: () => reKeySegment,
toString: () => toString
});
const rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g, reKeySegment = /_key\s*==\s*['"](.*)['"]/, reIndexTuple = /^\d*:\d*$/;
/** @internal */
function isIndexSegment(segment) {
return typeof segment == "number" || typeof segment == "string" && /^\[\d+\]$/.test(segment);
}
/** @internal */
function isKeySegment(segment) {
return typeof segment == "string" ? reKeySegment.test(segment.trim()) : typeof segment == "object" && "_key" in segment;
}
/** @internal */
function isIndexTuple(segment) {
if (typeof segment == "string" && reIndexTuple.test(segment)) return !0;
if (!Array.isArray(segment) || segment.length !== 2) return !1;
let [from, to] = segment;
return (typeof from == "number" || from === "") && (typeof to == "number" || to === "");
}
/** @internal */
function get(obj, path, defaultVal) {
let select = typeof path == "string" ? fromString(path) : path;
if (!Array.isArray(select)) throw Error("Path must be an array or a string");
let acc = obj;
for (let i = 0; i < select.length; i++) {
let segment = select[i];
if (isIndexSegment(segment)) {
if (!Array.isArray(acc)) return defaultVal;
acc = acc[segment];
}
if (isKeySegment(segment)) {
if (!Array.isArray(acc)) return defaultVal;
acc = acc.find((item) => item._key === segment._key);
}
if (typeof segment == "string" && (acc = typeof acc == "object" && acc ? acc[segment] : void 0), acc === void 0) return defaultVal;
}
return acc;
}
/** @alpha */
function toString(path) {
if (!Array.isArray(path)) throw Error("Path is not an array");
return path.reduce((target, segment, i) => {
let segmentType = typeof segment;
if (segmentType === "number") return `${target}[${segment}]`;
if (segmentType === "string") return `${target}${i === 0 ? "" : "."}${segment}`;
if (isKeySegment(segment) && segment._key) return `${target}[_key=="${segment._key}"]`;
if (Array.isArray(segment)) {
let [from, to] = segment;
return `${target}[${from}:${to}]`;
}
throw Error(`Unsupported path segment \`${JSON.stringify(segment)}\``);
}, "");
}
/** @alpha */
function fromString(path) {
if (typeof path != "string") throw Error("Path is not a string");
let segments = path.match(rePropName);
if (!segments) throw Error("Invalid path string");
return segments.map(parsePathSegment);
}
function parsePathSegment(segment) {
return isIndexSegment(segment) ? parseIndexSegment(segment) : isKeySegment(segment) ? parseKeySegment(segment) : isIndexTuple(segment) ? parseIndexTupleSegment(segment) : segment;
}
function parseIndexSegment(segment) {
return Number(segment.replace(/[^\d]/g, ""));
}
function parseKeySegment(segment) {
return { _key: segment.match(reKeySegment)[1] };
}
function parseIndexTupleSegment(segment) {
let [from, to] = segment.split(":").map((seg) => seg === "" ? seg : Number(seg));
return [from, to];
}
/** @internal */
const DRAFTS_FOLDER = "drafts", VERSION_FOLDER = "versions", DRAFTS_PREFIX = `${DRAFTS_FOLDER}.`, VERSION_PREFIX = `${VERSION_FOLDER}.`;
/** @internal */
function isDraftId(id) {
return id.startsWith(DRAFTS_PREFIX);
}
/** @internal */
function isVersionId(id) {
return id.startsWith(VERSION_PREFIX);
}
/** @internal */
function isPublishedId(id) {
return !isDraftId(id) && !isVersionId(id);
}
/**
* A phantom brand like `DraftId` has no runtime representation, so it can never be produced
* by narrowing a string - there's nothing to check. These two functions are the only places
* allowed to assert a plain string into a branded id.
*/
function asDraftId(value) {
return value;
}
function asPublishedId(value) {
return value;
}
/** @internal */
function getDraftId(id) {
if (isVersionId(id)) {
let publishedId = getPublishedId(id);
return asDraftId(DRAFTS_PREFIX + publishedId);
}
return isDraftId(id) ? id : DRAFTS_PREFIX + id;
}
/** @internal */
function getVersionId(id, version) {
if (version === "drafts" || version === "published") throw Error("Version can not be \"published\" or \"drafts\"");
return `${VERSION_PREFIX}${version}.${getPublishedId(id)}`;
}
/**
* @internal
* Given an id, returns the versionId if it exists.
* e.g. `versions.summer-drop.foo` = `summer-drop`
* e.g. `drafts.foo` = `undefined`
* e.g. `foo` = `undefined`
*/
function getVersionFromId(id) {
if (!isVersionId(id)) return;
let [_versionPrefix, versionId, ..._publishedId] = id.split(".");
return versionId;
}
/** @internal */
function getPublishedId(id) {
if (isVersionId(id)) return asPublishedId(id.split(".").slice(2).join("."));
if (isDraftId(id)) return asPublishedId(id.slice(DRAFTS_PREFIX.length));
if (isPublishedId(id)) return id;
throw Error(`Unable to resolve a published id from "${id}"`);
}
const ESCAPE = {
"\f": "\\f",
"\n": "\\n",
"\r": "\\r",
" ": "\\t",
"'": "\\'",
"\\": "\\\\"
}, UNESCAPE = {
"\\f": "\f",
"\\n": "\n",
"\\r": "\r",
"\\t": " ",
"\\'": "'",
"\\\\": "\\"
};
/**
* @internal
*/
function jsonPath(path) {
return `$${path.map((segment) => typeof segment == "string" ? `['${segment.replace(/[\f\n\r\t'\\]/g, (match) => ESCAPE[match])}']` : typeof segment == "number" ? `[${segment}]` : segment._key === "" ? `[${segment._index}]` : `[?(@._key=='${segment._key.replace(/['\\]/g, (match) => ESCAPE[match])}')]`).join("")}`;
}
/**
* @internal
*/
function jsonPathArray(path) {
return path.map((segment) => typeof segment == "string" ? `['${segment.replace(/[\f\n\r\t'\\]/g, (match) => ESCAPE[match])}']` : typeof segment == "number" ? `[${segment}]` : segment._key === "" ? `[${segment._index}]` : `[?(@._key=='${segment._key.replace(/['\\]/g, (match) => ESCAPE[match])}')]`);
}
/**
* @internal
*/
function parseJsonPath(path) {
let parsed = [], parseRe = /\['(.*?)'\]|\[(\d+)\]|\[\?\(@\._key=='(.*?)'\)\]/g, match;
for (; (match = parseRe.exec(path)) !== null;) {
if (match[1] !== void 0) {
let key = match[1].replace(/\\(\\|f|n|r|t|')/g, (m) => UNESCAPE[m]);
parsed.push(key);
continue;
}
if (match[2] !== void 0) {
parsed.push(parseInt(match[2], 10));
continue;
}
if (match[3] !== void 0) {
let _key = match[3].replace(/\\(\\')/g, (m) => UNESCAPE[m]);
parsed.push({
_key,
_index: -1
});
continue;
}
}
return parsed;
}
/**
* @internal
*/
function jsonPathToStudioPath(path) {
return path.map((segment) => {
if (typeof segment == "string" || typeof segment == "number") return segment;
if (segment._key !== "") return { _key: segment._key };
if (segment._index !== -1) return segment._index;
throw Error(`invalid segment:${JSON.stringify(segment)}`);
});
}
/**
* @internal
*/
function studioPathToJsonPath(path) {
return (typeof path == "string" ? fromString(path) : path).map((segment) => {
if (typeof segment == "string" || typeof segment == "number") return segment;
if (Array.isArray(segment)) throw Error(`IndexTuple segments aren't supported:${JSON.stringify(segment)}`);
if (isContentSourceMapParsedPathKeyedSegment(segment)) return segment;
if (segment._key) return {
_key: segment._key,
_index: -1
};
throw Error(`invalid segment:${JSON.stringify(segment)}`);
});
}
function isContentSourceMapParsedPathKeyedSegment(segment) {
return typeof segment == "object" && "_key" in segment && "_index" in segment;
}
/**
* @internal
*/
function jsonPathToMappingPath(path) {
return path.map((segment) => {
if (typeof segment == "string" || typeof segment == "number") return segment;
if (segment._index !== -1) return segment._index;
throw Error(`invalid segment:${JSON.stringify(segment)}`);
});
}
/**
* @internal
*/
function resolveMapping(resultPath, csm) {
if (!csm?.mappings) return;
let resultMappingPath = jsonPath(jsonPathToMappingPath(resultPath));
if (csm.mappings[resultMappingPath] !== void 0) return {
mapping: csm.mappings[resultMappingPath],
matchedPath: resultMappingPath,
pathSuffix: ""
};
let resultMappingPathArray = jsonPathArray(jsonPathToMappingPath(resultPath));
for (let i = resultMappingPathArray.length - 1; i >= 0; i--) {
let key = `$${resultMappingPathArray.slice(0, i).join("")}`, mappingFound = csm.mappings[key];
if (mappingFound) return {
mapping: mappingFound,
matchedPath: key,
pathSuffix: resultMappingPath.substring(key.length)
};
}
}
/** @internal */
function isArray(value) {
return value !== null && Array.isArray(value);
}
/**
* generic way to walk a nested object or array and apply a mapping function to each value
* @internal
*/
function walkMap(value, mappingFn, path = []) {
if (isArray(value)) return value.map((v, idx) => {
if (isRecord(v)) {
let _key = v._key;
if (typeof _key == "string") return walkMap(v, mappingFn, path.concat({
_key,
_index: idx
}));
}
return walkMap(v, mappingFn, path.concat(idx));
});
if (isRecord(value)) {
if (value._type === "block" || value._type === "span") {
let result = { ...value };
return value._type === "block" ? result.children = walkMap(value.children, mappingFn, path.concat("children")) : value._type === "span" && (result.text = walkMap(value.text, mappingFn, path.concat("text"))), result;
}
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, walkMap(v, mappingFn, path.concat(k))]));
}
return mappingFn(value, path);
}
/** @internal */
function createEditUrl(options) {
let { baseUrl, workspace: _workspace = "default", tool: _tool = "default", id: _id, type, path, projectId, dataset } = options;
if (!baseUrl) throw Error("baseUrl is required");
if (!path) throw Error("path is required");
if (!_id) throw Error("id is required");
if (baseUrl !== "/" && baseUrl.endsWith("/")) throw Error("baseUrl must not end with a slash");
let workspace = _workspace === "default" ? void 0 : _workspace, tool = _tool === "default" ? void 0 : _tool, id = getPublishedId(_id), stringifiedPath = Array.isArray(path) ? toString(jsonPathToStudioPath(path)) : path, searchParams = new URLSearchParams({
baseUrl,
id,
type,
path: stringifiedPath
});
if (workspace && searchParams.set("workspace", workspace), tool && searchParams.set("tool", tool), projectId && searchParams.set("projectId", projectId), dataset && searchParams.set("dataset", dataset), isPublishedId(_id)) searchParams.set("perspective", "published");
else if (isVersionId(_id)) {
let versionId = getVersionFromId(_id);
searchParams.set("perspective", versionId);
}
let segments = [baseUrl === "/" ? "" : baseUrl];
workspace && segments.push(workspace);
let routerParams = [
"mode=presentation",
`id=${id}`,
`type=${type}`,
`path=${encodeURIComponent(stringifiedPath)}`
];
return tool && routerParams.push(`tool=${tool}`), segments.push("intent", "edit", `${routerParams.join(";")}?${searchParams}`), segments.join("/");
}
/** @internal */
function resolveEditInfo(options) {
let { resultSourceMap: csm, resultPath } = options, { mapping, pathSuffix } = resolveMapping(resultPath, csm) || {};
if (!mapping || mapping.source.type === "literal" || mapping.source.type === "unknown") return;
let sourceDoc = csm.documents[mapping.source.document], sourcePath = csm.paths[mapping.source.path];
if (sourceDoc && sourcePath) {
let { baseUrl, workspace, tool } = resolveStudioBaseRoute(typeof options.studioUrl == "function" ? options.studioUrl(sourceDoc) : options.studioUrl);
if (!baseUrl) return;
let { _id, _type, _projectId, _dataset } = sourceDoc;
return {
baseUrl,
workspace,
tool,
id: _id,
type: _type,
path: parseJsonPath(sourcePath + pathSuffix),
projectId: _projectId,
dataset: _dataset
};
}
}
/** @internal */
function resolveStudioBaseRoute(studioUrl) {
let baseUrl = typeof studioUrl == "string" ? studioUrl : studioUrl.baseUrl;
return baseUrl !== "/" && (baseUrl = baseUrl.replace(/\/$/, "")), typeof studioUrl == "string" ? { baseUrl } : {
...studioUrl,
baseUrl
};
}
export { toString as S, isPublishedId as _, resolveMapping as a, reKeySegment as b, parseJsonPath as c, VERSION_FOLDER as d, getDraftId as f, isDraftId as g, getVersionId as h, walkMap as i, studioPathToJsonPath as l, getVersionFromId as m, resolveStudioBaseRoute as n, jsonPath as o, getPublishedId as p, createEditUrl as r, jsonPathToStudioPath as s, resolveEditInfo as t, DRAFTS_FOLDER as u, isVersionId as v, studioPath_exports as x, get as y };
//# sourceMappingURL=resolveEditInfo-Cz-smq3a.js.map