UNPKG

sanity

Version:

Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches

1,322 lines (1,292 loc) • 148 kB
import { jsx, Fragment, jsxs } from "react/jsx-runtime"; import * as PathUtils from "@sanity/util/paths"; import { pathFor, isEqual as isEqual$1, toString, trimChildPath as trimChildPath$1, startsWith } from "@sanity/util/paths"; import { useRef, useContext, useState, useCallback, useMemo, useEffect, createElement, StrictMode, useLayoutEffect } from "react"; import deepCompare from "react-fast-compare"; import { C as ConnectorContext, a as useReporter, S as ScrollContext, r as resizeObserver, b as useReportedValues, d as SvgWrapper, e as Connector, D as DEBUG_LAYER_BOUNDS, i as isNonNullable$1, T as Tracker, f as ScrollContainer, h as useUserColorManager, j as useTranslation, k as getAnnotationColor, l as DiffTooltip, m as Checkbox, F as FromToArrow, P as Preview, n as DiffFromTo, o as SlugPreview, p as StringPreview, q as DatetimeFieldDiff, s as pathToString, H as HoveredFieldContext, t as FormFieldPresenceContext, A as ArrayOfObjectsItem, M as MemberItemError, R as ReviewChangesContext, v as defaultResolveAnnotationComponent, w as defaultResolveBlockComponent, x as defaultResolveInlineBlockComponent, y as defaultResolveFieldComponent, z as defaultResolveInputComponent, B as defaultResolveItemComponent, E as ArrayOfObjectsFunctions, G as DefaultMarkers, I as FormBuilderContext, J as FormCallbacksProvider, K as DocumentIdProvider, L as PresenceProvider, V as ValidationProvider, N as EMPTY_ARRAY$2, O as useSource, Q as useInputComponent, U as useFieldComponent, W as usePreviewComponent, X as useItemComponent, Y as useBlockComponent, Z as useInlineBlockComponent, _ as useAnnotationComponent, $ as PreviewLoader, a0 as PatchEvent, a1 as GetFormValueProvider, a2 as FormValueProvider, a3 as DocumentFieldActionsProvider, a4 as memoize, a5 as memoizeKeyGen, a6 as memoizedPair, a7 as validateTemplates, a8 as isBuilder, a9 as useDocumentStore, aa as getPublishedId, ab as useHistoryStore, ac as useClient, ad as DEFAULT_STUDIO_CLIENT_OPTIONS, ae as useProjectStore, af as prepareConfig, ag as useWorkspace, ah as AddonDatasetContext, ai as StudioProvider, aj as GlobalStyle, ak as StudioLayout, al as useListFormat, am as intlCache, an as useRelativeTime, ao as useUserStore, ap as grantsPermissionOn, aq as HookStateContainer, ar as useReferringDocuments, as as ZIndexContext, at as defaults, au as getFieldLevel, av as isRecord, aw as useCurrentUser, ax as immutableReconcile, ay as isMemberArrayOfObjects, az as isMemberObject, aA as SANITY_PATCH_TYPE } from "./_chunks-es/TransformPatches.js"; import { et, eu, ch, cd, ci, cj, cb, ck, cy, b6, cc, aR, aS, cm, dJ, bo, aC, aD, bp, bq, br, aV, b5, b7, eB, eA, ez, ey, ex, aE, aN, b9, ba, aF, dM, cR, fd, fm, cn, co, aO, aP, bs, bF, bt, bu, bw, bv, bG, dm, aG, aH, fy, cp, f2, bx, c5, c6, c7, by, dr, dn, dp, dq, cT, cN, b_, b$, c0, c1, c2, c3, bz, bA, cU, b1, aT, aI, b2, aW, aJ, df, dg, aQ, cz, cA, cB, bB, eW, bC, cq, cr, cC, cD, cE, ds, aK, cc as cc2, dt, aM, cS, cQ, ep, bD, fM, em, dy, bf, eQ, eL, eR, eJ, eM, eK, cs, ct, eV, a_, cu, eX, eS, eT, cv, aU, cw, a$, ei, ej, eU, b0, d2, dl, cl, f0, eZ, e$, e_, eY, cx, b3, fk, bE, ce, cg, f4, f1, fb, fc, en, dE, eD, fJ, dU, fw, dF, dS, dL, dz, d_, ft, ec, eh, fl, dD, dT, eo, fv, dB, fB, aX, aY, fj, er, cL, dk, fh, db, dc, dd, eH, eI, eP, cJ, bc, fn, dV, dW, fD, fC, bP, bd, bj, bk, e6, e9, fs, fq, e1, bW, bX, f6, d$, du, dv, dw, dG, dC, ed, bO, bZ, f5, fz, cK, bb, cG, bK, c$, c_, d0, dH, cZ, dI, bg, fo, fp, bY, bI, bJ, cY, cW, cV, bh, fr, bL, fA, cX, bM, fE, e2, ev, fu, bH, bS, bU, bT, bR, dK, dX, eO, bV, cM, dx, fx, eg, de, bN, fe, ff, fg, be, cH, cF, fG, dY, bQ, fF, fH, cI, dA, dj, ew, bm, eF, eG, eC, eE, dP, d3, d4, ca, bn, bi, d5, e8, e7, ek, dO, eb, ea, e0, d6, c8, d1, cO, c4, dh, el, dN, c9, di, e3, e4, dR, fI, b8, dQ, aL, d7, cP, e5, eq, aZ, d8, eN, ef, ee, d9, fL, da, es, fi, cf, f3, f7, b4, fK, fa, aB, f9, f8, dZ, bl } from "./_chunks-es/TransformPatches.js"; import sortBy from "lodash/sortBy.js"; import { useMemoObservable } from "react-rx"; import { of, merge, BehaviorSubject, tap, map, distinctUntilChanged, catchError, combineLatest, firstValueFrom, timer, share, take, skip, debounce, switchMap as switchMap$1, forkJoin, mergeMap, concat } from "rxjs"; import { switchMap, map as map$1, mapTo, startWith, distinctUntilChanged as distinctUntilChanged$1 } from "rxjs/operators"; import isEqual$2 from "lodash/isEqual.js"; import throttle from "lodash/throttle.js"; import { isKeyedObject, isKeySegment, isObjectSchemaType, isArraySchemaType, isArrayOfObjectsSchemaType } from "@sanity/types"; export * from "@sanity/types"; import { Badge, Flex, Box, Text, studioTheme, Hotkeys as Hotkeys$1, TextInput } from "@sanity/ui"; import { IntentLink } from "sanity/router"; import { u as useCurrentLocale, B as Button } from "./_chunks-es/getJsonStream.js"; import { a } from "./_chunks-es/getJsonStream.js"; import isString from "lodash/isString.js"; import "dataloader"; import "history"; import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector"; import "lodash/escapeRegExp.js"; import "lodash/isEqual"; import "lodash/startCase"; import "react-dom/server"; import "@sanity/schema/_internal"; import "lodash/compact.js"; import "lodash/intersection.js"; import "lodash/keyBy.js"; import "lodash/partition.js"; import "lodash/toLower.js"; import "lodash/union.js"; import "lodash/uniq.js"; import "lodash/words.js"; import "lodash/isFinite.js"; import "lodash/intersection"; import "lodash/isEmpty"; import "date-fns"; import "react-i18next"; import "@sanity/portable-text-editor"; import "@sanity/icons"; import "lodash/omit.js"; import "@sanity/diff-match-patch"; import flatten from "lodash/flatten.js"; import "lodash/orderBy.js"; import "lodash/xor.js"; import "sanity-diff-patch"; import "lodash/startCase.js"; import "lodash/debounce.js"; import "nano-pubsub"; import "shallow-equals"; import "scroll-into-view-if-needed"; import "lodash/get.js"; import "get-random-values-esm"; import { resolveTypeName as resolveTypeName$1 } from "@sanity/util/content"; import "lodash/isPlainObject.js"; import "@tanstack/react-virtual"; import "@sanity/util/legacyDateFormat"; import "speakingurl"; import "@sanity/telemetry/react"; import "lodash/find.js"; import castArray from "lodash/castArray.js"; import pick from "lodash/pick.js"; import { arrayToJSONMatchPath } from "@sanity/mutator"; import "@sanity/schema"; import "@sanity/asset-utils"; import "@sanity/image-url"; import "@sanity/uuid"; import "exif-component"; import "react-is"; import "lodash/difference.js"; import "lodash/memoize.js"; import "lodash/identity.js"; import "lodash/values.js"; import "lodash/assignWith.js"; import "lodash/capitalize.js"; import { createRoot } from "react-dom/client"; import "lodash/groupBy.js"; import "json-reduce"; import "rxjs-exhaustmap-with-trailing"; import "groq-js"; import "rxjs-etc/operators"; import "mendoza"; import "@sanity/diff"; import "raf"; import "@sanity/bifur-client"; import "@sanity/client"; import "i18next"; import { hues, black, white, blue, gray, red, green, yellow } from "@sanity/color"; import { parseColor, rgbToHex, multiply, screen, createColorTheme, rgba } from "@sanity/ui/theme"; import { getLuminance, mix, parseToRgb, rgb } from "polished"; function noop() { } function NoopTracker({ children }) { return /* @__PURE__ */ jsx(Fragment, { children }); } function createNoopTrackerScope() { return { useReportedValues: noop, Tracker: NoopTracker, useReporter: noop }; } const ChangeFieldWrapper = (props) => { const ref = useRef(null), { onSetFocus } = useContext(ConnectorContext), [isHover, setHover] = useState(!1), onMouseEnter = useCallback(() => { setHover(!0); }, []), onMouseLeave = useCallback(() => { setHover(!1); }, []); useReporter( `change-${PathUtils.toString(props.path)}`, () => ({ element: ref.current, path: props.path, isChanged: !0, hasFocus: !1, hasHover: isHover, hasRevertHover: props.hasHover }), // note: deepCompare should be ok here since we're not comparing deep values deepCompare ); const handleClick = useCallback( (event) => { setFocusWithStopPropagation(event, onSetFocus, props.path); }, [onSetFocus, props.path] ); return /* @__PURE__ */ jsx("div", { ref, onClick: handleClick, onMouseLeave, onMouseEnter, children: props.children }); }; function setFocusWithStopPropagation(event, onSetFocus, path) { event.stopPropagation(), onSetFocus(path); } function isArray(value) { return Array.isArray(value); } function isTruthy(value) { return !!value; } const BUNDLED_DOC_TYPES = ["sanity.imageAsset", "sanity.fileAsset"]; function _isSanityDocumentTypeDefinition(def) { return def.type === "document" && BUNDLED_DOC_TYPES.includes(def.name); } function _isCustomDocumentTypeDefinition(def) { return def.type === "document" && !_isSanityDocumentTypeDefinition(def); } const FONT_SANS_SERIF = "-apple-system, BlinkMacSystemFont, \\'Segoe UI\\', Roboto, \\'Helvetica Neue\\', Helvetica, Arial, system-ui, sans-serif", FONT_MONOSPACE = "-apple-system-ui-monospace, \\'SF Mono\\', Menlo, Monaco, Consolas, monospace", uncaughtErrorHandler = () => ( // prettier-ignore [ "window.onerror = function(m,u,l,c,e) {", "var p=window.location.port;", "var h=window.location.protocol+'//'+window.location.hostname+(p?':'+p:'');", "var r=document.getElementById('sanity');", "while(r.firstChild){r.removeChild(r.firstChild);}", "var s=document.createElement('style');", "s.appendChild(document.createTextNode('", "html,body,#sanityBody,#sanity,#sanityError{height:100%;}", "body{-webkit-font-smoothing:antialiased;margin:0;}", `#sanityError{position:fixed;top:0;left:0;width:100%;height:100%;overflow:auto;background-color:#fff;color:#121923;font-family:${FONT_SANS_SERIF};font-size:16px;line-height:21px;min-height:100%;}`, "#sanityError>div{background-color:#fff;max-width:960px;margin:0 auto;padding:47px 32px 52px;}", "@media(min-width:512px){", "#sanityError>div{", "padding:47px 84px;", "}", "}", "#sanityError button{-webkit-font-smoothing:inherit;font:inherit;font-weight:500;background-color:#2276FC;color:#fff;padding:7px 12px;border-radius:3px;border:0;}", "#sanityError button:hover{background-color:#1E63D0;}", "#sanityError button:active{background-color:#1B50A5;}", "'));", "document.head.appendChild(s);", "var f=document.createElement('div');", "f.id='sanityError';", "f.innerHTML='", "<div>", '<h1 style="font-size:21px;line-height:27px;margin: 0 0 10px;">Unhandled error</h1>', '<p style="color:#66758D;margin:10px 0 14px;">Encountered an unhandled error in this Studio.</p>', '<button class="sanity-error-handler__reload-btn" type="button">Reload page</button>', '<pre style="background-color:#FDEBEA;color:#C3362C;font-size:13px;line-height:17px;padding:8px 12px;border-radius:3px;margin:32px 0 0;overflow:auto;">', `<code style="font-family:${FONT_MONOSPACE};">`, "'+e.stack.replaceAll(h,'')+'", "</code>", "</pre>", "</div>", "';", "var b=f.querySelector('.sanity-error-handler__reload-btn');", "if(b){", "b.onclick=function() {", "window.location.reload();", "}", "};", "r.appendChild(f);", "};" ].join("") ); function useThrottledCallback(callback, wait, options) { return useMemo( () => throttle(callback, wait, options), [callback, options, wait] ); } function useOnScroll(callback) { const parentContext = useContext(ScrollContext); useEffect(() => parentContext == null ? void 0 : parentContext.subscribe(callback), [callback, parentContext]); } function ScrollMonitor({ onScroll, children }) { return useOnScroll(onScroll), /* @__PURE__ */ jsx(Fragment, { children }); } function findMostSpecificTarget(targetType, id, values) { const pathString = id.slice(id.indexOf("-") + 1) || "[]", path = PathUtils.fromString(pathString), exactId = `${targetType}-${PathUtils.toString(path)}`; if (values.has(exactId)) return values.get(exactId); let mostSpecific; for (const [targetId, target] of values) { if (!("path" in target) || !targetId.startsWith(targetType)) continue; const numEqual = PathUtils.numEqualSegments(path, target.path), lastPathSegment = target.path[target.path.length - 1], pathOnlyDiffersByKey = numEqual === target.path.length - 1 && isKeyedObject(lastPathSegment); if (numEqual !== 0 && !(numEqual !== target.path.length && !pathOnlyDiffersByKey) && (mostSpecific = target, numEqual === path.length)) break; } return mostSpecific; } function hasOverflowScroll(el2) { const overflow = getComputedStyle(el2).overflow; return overflow.includes("auto") || overflow.includes("scroll"); } function isScrollable(el2) { return (el2.scrollHeight !== el2.offsetHeight || el2.scrollWidth !== el2.offsetWidth) && hasOverflowScroll(el2); } const getOffsetsTo = (source, target) => { const bounds = { top: 0, left: 0, height: target.offsetHeight, width: target.offsetWidth }, rect = { top: 0, left: 0, height: source.offsetHeight, width: source.offsetWidth }; let foundScrollContainer = !1, el2 = source; for (; el2 && el2 !== target && target.contains(el2); ) foundScrollContainer && (bounds.top += el2.offsetTop, bounds.left += el2.offsetLeft), hasOverflowScroll(el2) && (bounds.top = el2.offsetTop, bounds.height = el2.offsetHeight, bounds.left = el2.offsetLeft, bounds.width = el2.offsetWidth, foundScrollContainer = !0), rect.top += el2.offsetTop - el2.scrollTop, rect.left += el2.offsetLeft - el2.scrollLeft, el2 = el2.offsetParent; return { rect, bounds }; }; function isChangeBar(v) { return v[0] !== "changePanel"; } const SCROLL_INTO_VIEW_TOP_PADDING = -15; function scrollIntoView(field) { let parentElementWithScroll = field.element; for (; !isScrollable(parentElementWithScroll); ) if (parentElementWithScroll = parentElementWithScroll.parentElement, !parentElementWithScroll) return; parentElementWithScroll.scroll({ top: parentElementWithScroll.scrollTop + field.rect.top - field.bounds.top + SCROLL_INTO_VIEW_TOP_PADDING, left: 0, behavior: "smooth" }); } function useResizeObserver(element, onResize) { useEffect(() => resizeObserver.observe(element, onResize), [element, onResize]); } function getState(allReportedValues, hovered, byId, rootElement) { const changeBarsWithHover = [], changeBarsWithFocus = []; for (const value of allReportedValues) { if (!isChangeBar(value) || !value[1].isChanged) continue; const [id, reportedChangeBar] = value; if (id === hovered) { changeBarsWithHover.push(value); continue; } if (reportedChangeBar.hasHover) { changeBarsWithHover.push(value); continue; } if (reportedChangeBar.hasFocus) { changeBarsWithFocus.push(value); continue; } } const isHoverConnector = changeBarsWithHover.length > 0; return { connectors: (isHoverConnector ? changeBarsWithHover : changeBarsWithFocus).map(([id]) => { const field = findMostSpecificTarget("field", id, byId), change = findMostSpecificTarget("change", id, byId); return !field || !change ? null : { field: { id, ...field }, change: { id, ...change } }; }).filter(isNonNullable$1).map(({ field, change }) => ({ hasHover: field.hasHover || change.hasHover, hasFocus: field.hasFocus, hasRevertHover: change.hasRevertHover, field: { ...field, ...getOffsetsTo(field.element, rootElement) }, change: { ...change, ...getOffsetsTo(change.element, rootElement) } })), isHoverConnector }; } function ConnectorsOverlay(props) { const { rootElement, onSetFocus } = props, [hovered, setHovered] = useState(null), allReportedValues = useReportedValues(), byId = useMemo( () => new Map(allReportedValues), [allReportedValues] ), [{ connectors }, setState] = useState( () => getState(allReportedValues, hovered, byId, rootElement) ), visibleConnectors = useMemo( () => sortBy(connectors, (c) => 0 - c.field.path.length).slice(0, 1), [connectors] ), handleScrollOrResize = useCallback(() => { setState(getState(allReportedValues, hovered, byId, rootElement)); }, [byId, allReportedValues, hovered, rootElement]); return useResizeObserver(rootElement, handleScrollOrResize), /* @__PURE__ */ jsx(ScrollMonitor, { onScroll: handleScrollOrResize, children: /* @__PURE__ */ jsx(SvgWrapper, { style: { zIndex: visibleConnectors[0] && visibleConnectors[0].field.zIndex }, children: visibleConnectors.map(({ field, change }) => change ? /* @__PURE__ */ jsx( ConnectorGroup, { field, change, onSetFocus, setHovered }, field.id ) : null) }) }); } function ConnectorGroup(props) { const { change, field, onSetFocus, setHovered } = props, onConnectorClick = useCallback(() => { scrollIntoView(field), scrollIntoView(change), onSetFocus(field.path); }, [field, change, onSetFocus]), handleMouseEnter = useCallback(() => setHovered(field.id), [field, setHovered]), handleMouseLeave = useCallback(() => setHovered(null), [setHovered]), from = useMemo( () => ({ rect: { ...field.rect, left: field.rect.left + 3 }, bounds: field.bounds }), [field.bounds, field.rect] ), to = useMemo( () => ({ rect: { ...change.rect, left: change.rect.left + 1 }, bounds: change.bounds }), [change.bounds, change.rect] ); return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx("g", { onClick: onConnectorClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: /* @__PURE__ */ jsx(Connector, { from, to }) }), DEBUG_LAYER_BOUNDS ] }); } function EnabledChangeConnectorRoot({ children, className, isReviewChangesOpen, onOpenReviewChanges, onSetFocus, ...restProps }) { const [rootElement, setRootElement] = useState(), contextValue = useMemo( () => ({ isReviewChangesOpen, onOpenReviewChanges, onSetFocus }), [isReviewChangesOpen, onOpenReviewChanges, onSetFocus] ); return /* @__PURE__ */ jsx(ConnectorContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(Tracker, { children: /* @__PURE__ */ jsxs(ScrollContainer, { ...restProps, ref: setRootElement, className, children: [ children, rootElement && /* @__PURE__ */ jsx(ConnectorsOverlay, { rootElement, onSetFocus }) ] }) }) }); } function DisabledChangeConnectorRoot({ children, className }) { return /* @__PURE__ */ jsx(ScrollContainer, { className, children }); } const ChangeConnectorRoot = EnabledChangeConnectorRoot; function BetaBadge(props) { const { fontSize = 1, children = "Beta", ...rest } = props; return /* @__PURE__ */ jsx(Badge, { ...rest, fontSize, radius: 2, tone: "primary", children }); } function Favicons({ basePath }) { const base = `${basePath.replace(/\/+$/, "")}/static`; return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx("link", { rel: "icon", href: `${base}/favicon.ico`, sizes: "any" }), /* @__PURE__ */ jsx("link", { rel: "icon", href: `${base}/favicon.svg`, type: "image/svg+xml" }), /* @__PURE__ */ jsx("link", { rel: "apple-touch-icon", href: `${base}/apple-touch-icon.png` }), /* @__PURE__ */ jsx("link", { rel: "manifest", href: `${base}/manifest.webmanifest` }) ] }); } const errorHandlerScript = ` ;(function () { var _caughtErrors = [] var errorChannel = (function () { var subscribers = [] function publish(msg) { for (var i = 0; i < subscribers.length; i += 1) { subscribers[i](msg) } } function subscribe(subscriber) { subscribers.push(subscriber) return function () { var idx = subscribers.indexOf(subscriber) if (idx > -1) { subscribers.splice(idx, 1) } } } return {publish, subscribe, subscribers} })() // NOTE: Store the error channel instance in the global scope so that the Studio application can // access it and subscribe to errors. window.__sanityErrorChannel = { subscribe: errorChannel.subscribe, } function _nextTick(callback) { setTimeout(callback, 0) } function _handleError(error, params) { _nextTick(function () { // - If there are error channel subscribers, then we notify them (no console error). // - If there are no subscribers, then we log the error to the console and render the error overlay. if (errorChannel.subscribers.length) { errorChannel.publish({error, params}) } else { console.error(error) _renderErrorOverlay(error, params) } }) } var ERROR_BOX_STYLE = [ 'background: #fff', 'border-radius: 6px', 'box-sizing: border-box', 'color: #121923', 'flex: 1', "font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue','Liberation Sans',Helvetica,Arial,system-ui,sans-serif", 'font-size: 16px', 'line-height: 21px', 'margin: 0 auto', 'max-width: 960px', 'overflow: auto', 'padding: 20px', 'width: 100%', ].join(';') var ERROR_CODE_STYLE = [ 'color: #972E2A', "font-family: -apple-system-ui-monospace, 'SF Mono', Menlo, Monaco, Consolas, monospace", 'font-size: 13px', 'line-height: 17px', 'margin: 0', ].join(';') function _renderErrorOverlay(error, params) { var errorElement = document.querySelector('#__sanityError') || document.createElement('div') var colno = params.event.colno var lineno = params.event.lineno var filename = params.event.filename errorElement.id = '__sanityError' errorElement.innerHTML = [ '<div style="' + ERROR_BOX_STYLE + '">', '<div style="font-weight: 700;">Uncaught error: ' + error.message + '</div>', '<div style="color: #515E72; font-size: 13px; line-height: 17px; margin: 10px 0;">' + filename + ':' + lineno + ':' + colno + '</div>', '<pre style="' + ERROR_CODE_STYLE + '">' + error.stack + '</pre>', '</div>', ].join('') errorElement.style.position = 'fixed' errorElement.style.zIndex = 1000000 errorElement.style.top = 0 errorElement.style.left = 0 errorElement.style.right = 0 errorElement.style.bottom = 0 errorElement.style.padding = '20px' errorElement.style.background = 'rgba(16,17,18,0.66)' errorElement.style.display = 'flex' errorElement.style.alignItems = 'center' errorElement.style.justifyContent = 'center' document.body.appendChild(errorElement) } // NOTE: // Yes \u2013 we're attaching 2 error listeners below \u{1F440} // This is because React makes the same error throw twice (in development mode). // See: https://github.com/facebook/react/issues/10384 // Error listener #1 window.onerror = function (event, source, lineno, colno, error) { _nextTick(function () { if (_caughtErrors.indexOf(error) !== -1) return _caughtErrors.push(error) _handleError(error, { event, lineno, colno, source, }) _nextTick(function () { var idx = _caughtErrors.indexOf(error) if (idx > -1) _caughtErrors.splice(idx, 1) }) }) // IMPORTANT: this callback must return \`true\` to prevent the error from being rendered in // the browser\u2019s console. return true } // Error listener #2 window.addEventListener('error', function (event) { if (_caughtErrors.indexOf(event.error) !== -1) return true _caughtErrors.push(event.error) _handleError(event.error, { event, lineno: event.lineno, colno: event.colno, }) _nextTick(function () { _nextTick(function () { var idx = _caughtErrors.indexOf(event.error) if (idx > -1) _caughtErrors.splice(idx, 1) }) }) return true }) })() `; function GlobalErrorHandler() { return /* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: errorHandlerScript } }); } const NoJsStyles = ` .sanity-app-no-js__root { position: absolute; top: 0; right: 0; left: 0; bottom: 0; background: #fff; } .sanity-app-no-js__content { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; font-family: helvetica, arial, sans-serif; } `; function NoJavascript() { return /* @__PURE__ */ jsx("noscript", { children: /* @__PURE__ */ jsx("div", { className: "sanity-app-no-js__root", children: /* @__PURE__ */ jsxs("div", { className: "sanity-app-no-js__content", children: [ /* @__PURE__ */ jsx("style", { type: "text/css", children: NoJsStyles }), /* @__PURE__ */ jsx("h1", { children: "JavaScript disabled" }), /* @__PURE__ */ jsxs("p", { children: [ "Please ", /* @__PURE__ */ jsx("a", { href: "https://www.enable-javascript.com/", children: "enable JavaScript" }), " in your browser and reload the page to proceed." ] }) ] }) }) }); } const globalStyles = ` @font-face { font-family: Inter; font-style: normal; font-weight: 400; font-display: swap; src: url("https://studio-static.sanity.io/Inter-Regular.woff2") format("woff2"); } @font-face { font-family: Inter; font-style: italic; font-weight: 400; font-display: swap; src: url("https://studio-static.sanity.io/Inter-Italic.woff2") format("woff2"); } @font-face { font-family: Inter; font-style: normal; font-weight: 500; font-display: swap; src: url("https://studio-static.sanity.io/Inter-Medium.woff2") format("woff2"); } @font-face { font-family: Inter; font-style: italic; font-weight: 500; font-display: swap; src: url("https://studio-static.sanity.io/Inter-MediumItalic.woff2") format("woff2"); } @font-face { font-family: Inter; font-style: normal; font-weight: 600; font-display: swap; src: url("https://studio-static.sanity.io/Inter-SemiBold.woff2") format("woff2"); } @font-face { font-family: Inter; font-style: italic; font-weight: 600; font-display: swap; src: url("https://studio-static.sanity.io/Inter-SemiBoldItalic.woff2") format("woff2"); } @font-face { font-family: Inter; font-style: normal; font-weight: 700; font-display: swap; src: url("https://studio-static.sanity.io/Inter-Bold.woff2") format("woff2"); } @font-face { font-family: Inter; font-style: italic; font-weight: 700; font-display: swap; src: url("https://studio-static.sanity.io/Inter-BoldItalic.woff2") format("woff2"); } @font-face { font-family: Inter; font-style: normal; font-weight: 800; font-display: swap; src: url("https://studio-static.sanity.io/Inter-ExtraBold.woff2") format("woff2"); } @font-face { font-family: Inter; font-style: italic; font-weight: 800; font-display: swap; src: url("https://studio-static.sanity.io/Inter-ExtraBoldItalic.woff2") format("woff2"); } @font-face { font-family: Inter; font-style: normal; font-weight: 900; font-display: swap; src: url("https://studio-static.sanity.io/Inter-Black.woff2") format("woff2"); } @font-face { font-family: Inter; font-style: italic; font-weight: 900; font-display: swap; src: url("https://studio-static.sanity.io/Inter-BlackItalic.woff2") format("woff2"); } html { background-color: #f1f3f6; } html, body, #sanity { height: 100%; } body { margin: 0; -webkit-font-smoothing: antialiased; } `, EMPTY_ARRAY$1 = []; function DefaultDocument(props) { const { entryPath, css = EMPTY_ARRAY$1, basePath = "/" } = props; return /* @__PURE__ */ jsxs("html", { lang: "en", children: [ /* @__PURE__ */ jsxs("head", { children: [ /* @__PURE__ */ jsx("meta", { charSet: "utf-8" }), /* @__PURE__ */ jsx( "meta", { name: "viewport", content: "width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover" } ), /* @__PURE__ */ jsx("meta", { name: "robots", content: "noindex" }), /* @__PURE__ */ jsx("meta", { name: "referrer", content: "same-origin" }), /* @__PURE__ */ jsx(Favicons, { basePath }), /* @__PURE__ */ jsx("title", { children: "Sanity Studio" }), /* @__PURE__ */ jsx(GlobalErrorHandler, {}), css.map((href) => /* @__PURE__ */ jsx("link", { rel: "stylesheet", href }, href)), /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: globalStyles } }) ] }), /* @__PURE__ */ jsxs("body", { children: [ /* @__PURE__ */ jsx("div", { id: "sanity" }), /* @__PURE__ */ jsx("script", { type: "module", src: entryPath }), /* @__PURE__ */ jsx(NoJavascript, {}) ] }) ] }); } function defineConfig(config) { return config; } function createConfig(config) { return config; } function validatePlugin(pluginResult) { const messages = [ "projectId" in pluginResult && "`projectId` not allowed in plugin configuration", "dataset" in pluginResult && "`dataset` not allowed in plugin configuration" ].filter(isString); if (messages.length) throw new Error( `Invalid plugin configuration: ${messages.map((message) => ` ${message}`).join(` `)}` ); } function definePlugin(arg) { if (typeof arg == "function") { const pluginFactory = arg; return (options) => { const result = pluginFactory(options); return validatePlugin(result), result; }; } return validatePlugin(arg), () => arg; } function createPlugin(arg) { return definePlugin(arg); } function defineDocumentFieldAction(fieldAction) { return fieldAction; } function defineDocumentInspector(inspector) { return inspector; } function createMockAuthStore({ client, currentUser = null }) { return { state: of({ authenticated: !0, client, currentUser }) }; } function isEqual(item, otherItem) { if (item === otherItem) return !0; if (typeof item != typeof otherItem) return !1; if (typeof item != "object" && !Array.isArray(item)) return item === otherItem; if (isKeyedObject(item) && isKeyedObject(otherItem) && item._key === otherItem._key) return !0; if (Array.isArray(item) && Array.isArray(otherItem)) return item.length !== otherItem.length ? !1 : item.every((child, i) => isEqual(child, otherItem[i])); if (item === null || otherItem === null) return item === otherItem; const obj = item, otherObj = otherItem, keys = Object.keys(obj), otherKeys = Object.keys(otherObj); return keys.length !== otherKeys.length ? !1 : keys.every((keyName) => isEqual(obj[keyName], otherObj[keyName])); } const ArrayOfOptionsFieldDiff = ({ diff, schemaType }) => { var _a; const options = (_a = schemaType.options) == null ? void 0 : _a.list, colorManager = useUserColorManager(), { t } = useTranslation(); return Array.isArray(options) ? /* @__PURE__ */ jsx("div", { children: diff.items.map((item) => normalizeItems(item, diff, schemaType)).filter((item) => item !== null).sort(sortItems).map((item, index) => { const { annotation, isPresent, value, memberType, title } = item, color = getAnnotationColor(colorManager, annotation), action = t(isPresent ? "changes.added-label" : "changes.removed-label"); return /* @__PURE__ */ jsxs(Flex, { align: "center", children: [ /* @__PURE__ */ jsx(DiffTooltip, { annotations: annotation ? [annotation] : [], description: action, children: /* @__PURE__ */ jsxs(Flex, { align: "center", children: [ /* @__PURE__ */ jsx(Checkbox, { checked: !isPresent, color }), /* @__PURE__ */ jsx(Box, { margin: 2, children: /* @__PURE__ */ jsx(FromToArrow, {}) }), /* @__PURE__ */ jsx(Checkbox, { checked: isPresent, color }) ] }) }), /* @__PURE__ */ jsx(Flex, { align: "center", children: /* @__PURE__ */ jsx(ItemPreview, { value: title || value, memberType }) }) ] }, getItemKey(diff, index)); }) }) : null; }; function normalizeItems(item, parentDiff, schemaType) { if (item.diff.action === "unchanged") return null; const { fromValue, toValue } = parentDiff, value = getValue(item.diff), wasPresent = isInArray(value, fromValue), isPresent = isInArray(value, toValue); return wasPresent === isPresent ? null : { title: getItemTitle(value, schemaType), memberType: resolveMemberType(getValue(item.diff), schemaType), itemIndex: getOptionIndex(value, schemaType), annotation: item.annotation, isPresent, value }; } function sortItems(itemA, itemB) { return itemA.itemIndex - itemB.itemIndex; } function ItemPreview({ value, memberType }) { return /* @__PURE__ */ jsx(Box, { marginX: 2, marginY: 1, children: typeof value == "string" || typeof value == "number" ? value : /* @__PURE__ */ jsx(Preview, { schemaType: memberType, value, layout: "default" }) }); } function isInArray(value, parent) { const array = parent || []; return typeof value == "object" && value !== null ? array.some((item) => isEqual(item, value)) : array.includes(value); } function getItemKey(diff, index) { const value = diff.toValue || diff.fromValue; return isKeyedObject(value) ? value._key : index; } function getValue(diff) { return typeof diff.toValue > "u" ? diff.fromValue : diff.toValue; } function resolveMemberType(item, schemaType) { const itemTypeName = resolveTypeName(item); return schemaType.of.find((memberType) => memberType.name === itemTypeName); } function resolveTypeName(value) { const jsType = resolveJSType(value); if (jsType !== "object") return jsType; const obj = value; return "_type" in obj && obj._type || jsType; } function resolveJSType(val) { return val === null ? "null" : Array.isArray(val) ? "array" : typeof val; } function isNamedOption(item) { return typeof item == "object" && item !== null && "title" in item; } function getOptionIndex(item, schemaType) { var _a; return (((_a = schemaType.options) == null ? void 0 : _a.list) || []).findIndex((opt) => isEqual(isNamedOption(opt) ? opt.value : opt, item)); } function getItemTitle(item, schemaType) { var _a; const list = ((_a = schemaType.options) == null ? void 0 : _a.list) || [], index = getOptionIndex(item, schemaType); return index === -1 ? void 0 : list[index].title || void 0; } const SlugFieldDiff = ({ diff, schemaType }) => /* @__PURE__ */ jsx( DiffFromTo, { layout: "inline", diff, schemaType, previewComponent: SlugPreview } ), UrlFieldDiff = ({ diff, schemaType }) => /* @__PURE__ */ jsx(DiffFromTo, { diff, schemaType, previewComponent: StringPreview }), diffResolver = ({ schemaType }) => { var _a; if (["datetime", "date"].includes(schemaType.name)) return DatetimeFieldDiff; if (schemaType.name === "url") return UrlFieldDiff; if (schemaType.name === "slug") return SlugFieldDiff; if (schemaType.jsonType === "array" && Array.isArray((_a = schemaType.options) == null ? void 0 : _a.list)) return ArrayOfOptionsFieldDiff; }; function HoveredFieldProvider(props) { const { children } = props, [hoveredStack, setHoveredStack] = useState([]), handleMouseEnter = useCallback((path) => { const pathString = pathToString(path); setHoveredStack((prev) => prev.includes(pathString) ? prev : [pathString, ...prev]); }, []), handleMouseLeave = useCallback((path) => { const pathString = pathToString(path); setHoveredStack((prev) => prev.includes(pathString) ? prev.filter((item) => item !== pathString) : prev); }, []), context = useMemo( () => ({ hoveredStack, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave }), [handleMouseEnter, handleMouseLeave, hoveredStack] ); return /* @__PURE__ */ jsx(HoveredFieldContext.Provider, { value: context, children }); } const EMPTY_ARRAY = []; function trimChildPath(path, childPath) { return PathUtils.startsWith(path, childPath) ? PathUtils.trimLeft(path, childPath) : EMPTY_ARRAY; } function PresenceScope(props) { const { readOnly, path, children } = props, contextPresence = useContext(FormFieldPresenceContext), childPresence = useMemo(() => readOnly ? EMPTY_ARRAY : (contextPresence || EMPTY_ARRAY).filter((presence) => PathUtils.startsWith(path, presence.path)).map((presence) => ({ ...presence, path: trimChildPath(path, presence.path) })), [contextPresence, path, readOnly]); return /* @__PURE__ */ jsx(FormFieldPresenceContext.Provider, { value: childPresence, children }); } function createPatchChannel() { const _subscribers = []; return { publish(msg) { for (const subscriber of _subscribers) subscriber(msg); }, subscribe(subscriber) { return _subscribers.push(subscriber), () => { const idx = _subscribers.indexOf(subscriber); idx > -1 && _subscribers.splice(idx, 1); }; } }; } function ArrayOfObjectsInputMember(props) { const { member, renderAnnotation, renderBlock, renderField, renderInlineBlock, renderInput, renderItem, renderPreview } = props; return member.kind === "item" ? /* @__PURE__ */ jsx( ArrayOfObjectsItem, { member, renderAnnotation, renderBlock, renderField, renderInlineBlock, renderInput, renderItem, renderPreview }, member.key ) : member.kind === "error" ? /* @__PURE__ */ jsx(MemberItemError, { member }, member.key) : (console.warn(new Error(`Unhandled member kind ${member.kind}`)), null); } function ArrayOfObjectsInputMembers(props) { const { members, ...rest } = props; return /* @__PURE__ */ jsx(Fragment, { children: members.map((member) => /* @__PURE__ */ jsx(ArrayOfObjectsInputMember, { member, ...rest }, member.key)) }); } function useReviewChanges() { const reviewChanges = useContext(ReviewChangesContext); if (!reviewChanges) throw new Error("Review changes: missing context value"); return reviewChanges; } const defaultRenderAnnotation = (props) => createElement(defaultResolveAnnotationComponent(props.schemaType), props), defaultRenderBlock = (props) => createElement(defaultResolveBlockComponent(props.schemaType), props), defaultRenderInlineBlock = (props) => createElement(defaultResolveInlineBlockComponent(props.schemaType), props), defaultRenderField = (props) => createElement(defaultResolveFieldComponent(props.schemaType), props), defaultRenderInput = (props) => createElement(defaultResolveInputComponent(props.schemaType), props), defaultRenderItem = (props) => createElement(defaultResolveItemComponent(props.schemaType), props), defaultRenderPreview = (props) => createElement(Preview, props); function DefaultCustomMarkers() { return /* @__PURE__ */ jsxs(Text, { size: 1, children: [ "This is a example custom marker, please implement ", /* @__PURE__ */ jsx("code", { children: "renderCustomMarkers" }), " function." ] }); } const missingPatchChannel = { publish: () => { }, subscribe: () => (console.warn( "No patch channel provided to form-builder. If you need input based patch updates, please provide one" ), () => { }) }; function FormBuilderProvider(props) { const { __internal_fieldActions: fieldActions = EMPTY_ARRAY$2, __internal_patchChannel: patchChannel = missingPatchChannel, autoFocus, changesOpen, children, collapsedFieldSets, collapsedPaths, file, filterField, focusPath, focused, groups, id, image, onChange, onFieldGroupSelect, onPathBlur, onPathFocus, onPathOpen, onSetFieldSetCollapsed, onSetPathCollapsed, presence, readOnly, renderAnnotation, renderBlock, renderField, renderInlineBlock, renderInput, renderItem, renderPreview, schemaType, unstable, validation } = props, __internal = useMemo( () => ({ patchChannel, // eslint-disable-line camelcase components: { ArrayFunctions: ArrayOfObjectsFunctions, CustomMarkers: (unstable == null ? void 0 : unstable.CustomMarkers) || DefaultCustomMarkers, Markers: (unstable == null ? void 0 : unstable.Markers) || DefaultMarkers }, field: { actions: fieldActions }, file: { assetSources: file.assetSources, directUploads: (file == null ? void 0 : file.directUploads) !== !1 }, filterField: filterField || (() => !0), image: { assetSources: image.assetSources, directUploads: (image == null ? void 0 : image.directUploads) !== !1 }, onChange }), [ fieldActions, file.assetSources, file == null ? void 0 : file.directUploads, filterField, image.assetSources, image == null ? void 0 : image.directUploads, onChange, patchChannel, unstable == null ? void 0 : unstable.CustomMarkers, unstable == null ? void 0 : unstable.Markers ] ), formBuilder = useMemo( () => ({ __internal, autoFocus, changesOpen, collapsedFieldSets, collapsedPaths, focusPath, focused, groups, id, readOnly, renderAnnotation, renderBlock, renderField, renderInlineBlock, renderInput, renderItem, renderPreview, schemaType }), [ __internal, autoFocus, changesOpen, collapsedFieldSets, collapsedPaths, focusPath, focused, groups, id, readOnly, renderAnnotation, renderBlock, renderField, renderInlineBlock, renderInput, renderItem, renderPreview, schemaType ] ); return /* @__PURE__ */ jsx(FormBuilderContext.Provider, { value: formBuilder, children: /* @__PURE__ */ jsx( FormCallbacksProvider, { onChange, onFieldGroupSelect, onPathBlur, onPathFocus, onPathOpen, onSetPathCollapsed, onSetFieldSetCollapsed, children: /* @__PURE__ */ jsx(DocumentIdProvider, { id, children: /* @__PURE__ */ jsx(PresenceProvider, { presence, children: /* @__PURE__ */ jsx(ValidationProvider, { validation, children: /* @__PURE__ */ jsx(HoveredFieldProvider, { children }) }) }) }) } ) }); } function FormProvider(props) { const { __internal_fieldActions: fieldActions, __internal_patchChannel: patchChannel, autoFocus, changesOpen, children, collapsedFieldSets, collapsedPaths, focusPath, focused, groups, id, onChange, onPathBlur, onPathFocus, onPathOpen, onFieldGroupSelect, onSetPathCollapsed, onSetFieldSetCollapsed, presence, readOnly, schemaType, validation } = props, { file, image } = useSource().form, Input = useInputComponent(), Field = useFieldComponent(), Preview2 = usePreviewComponent(), Item = useItemComponent(), Block = useBlockComponent(), InlineBlock = useInlineBlockComponent(), Annotation = useAnnotationComponent(), renderInput = useCallback( (inputProps) => /* @__PURE__ */ jsx(Input, { ...inputProps }), [Input] ), renderField = useCallback( (fieldProps) => /* @__PURE__ */ jsx(Field, { ...fieldProps }), [Field] ), renderItem = useCallback( (itemProps) => /* @__PURE__ */ jsx(Item, { ...itemProps }), [Item] ), renderPreview = useCallback( (previewProps) => /* @__PURE__ */ jsx(PreviewLoader, { component: Preview2, ...previewProps }), [Preview2] ), renderBlock = useCallback( (blockProps) => /* @__PURE__ */ jsx(Block, { ...blockProps }), [Block] ), renderInlineBlock = useCallback( (blockProps) => /* @__PURE__ */ jsx(InlineBlock, { ...blockProps }), [InlineBlock] ), renderAnnotation = useCallback( (annotationProps) => /* @__PURE__ */ jsx(Annotation, { ...annotationProps }), [Annotation] ); return /* @__PURE__ */ jsx( FormBuilderProvider, { __internal_fieldActions: fieldActions, __internal_patchChannel: patchChannel, autoFocus, changesOpen, collapsedFieldSets, collapsedPaths, file, focusPath, focused, groups, id, image, onChange, onPathBlur, onPathFocus, onPathOpen, onFieldGroupSelect, onSetPathCollapsed, onSetFieldSetCollapsed, presence, readOnly, renderAnnotation, renderBlock, renderField, renderInlineBlock, renderInput, renderItem, renderPreview, schemaType, validation, children } ); } function FormBuilder(props) { const { __internal_fieldActions: fieldActions, __internal_patchChannel: patchChannel, autoFocus, changesOpen, collapsedFieldSets, collapsedPaths, focusPath, focused, groups, id, members, onChange, onPathBlur, onPathFocus, onPathOpen, onFieldGroupSelect, onSetFieldSetCollapsed, onSetPathCollapsed, presence, readOnly, schemaType, validation, value } = props, handleCollapseField = useCallback( (fieldName) => onSetPathCollapsed([fieldName], !0), [onSetPathCollapsed] ), handleExpandField = useCallback( (fieldName) => onSetPathCollapsed([fieldName], !1), [onSetPathCollapsed] ), handleBlur = useCallback(() => onPathBlur(EMPTY_ARRAY$2), [onPathBlur]), handleFocus = useCallback(() => onPathFocus(EMPTY_ARRAY$2), [onPathFocus]), handleChange = useCallback( (patch) => onChange(PatchEvent.from(patch)), [onChange] ), focusRef = useRef(null), handleSelectFieldGroup = useCallback( (groupName) => onFieldGroupSelect(EMPTY_ARRAY$2, groupName), [onFieldGroupSelect] ), handleOpenField = useCallback((fieldName) => onPathOpen([fieldName]), [onPathOpen]), handleCloseField = useCallback(() => onPathOpen([]), [onPathOpen]), handleCollapseFieldSet = useCallback( (fieldSetName) => onSetFieldSetCollapsed([fieldSetName], !0), [onSetFieldSetCollapsed] ), handleExpandFieldSet = useCallback( (fieldSetName) => onSetFieldSetCollapsed([fieldSetName], !1), [onSetFieldSetCollapsed] ), Input = useInputComponent(), Field = useFieldComponent(), Preview2 = usePreviewComponent(), Item = useItemComponent(), Block = useBlockComponent(), InlineBlock = useInlineBlockComponent(), Annotation = useAnnotationComponent(), renderInput = useCallback( (inputProps) => /* @__PURE__ */ jsx(Input, { ...inputProps }), [Input] ), renderField = useCallback( (fieldProps) => /* @__PURE__ */ jsx(Field, { ...fieldProps }), [Field] ), renderItem = useCallback( (itemProps) => /* @__PURE__ */ jsx(Item, { ...itemProps }), [Item] ), renderPreview = useCallback( (previewProps) => /* @__PURE__ */ jsx(PreviewLoader, { component: Preview2, ...previewProps }), [Preview2] ), renderBlock = useCallback( (blockProps) => /* @__PURE__ */ jsx(Block, { ...blockProps }), [Block] ), renderInlineBlock = useCallback( (blockProps) => /* @__PURE__ */ jsx(InlineBlock, { ...blockProps }), [InlineBlock] ), renderAnnotation = useCallback( (annotationProps) => /* @__PURE__ */ jsx(Annotation, { ...annotationProps }), [Annotation] ), rootInputProps = { focusPath, elementProps: { ref: focusRef, id, onBlur: handleBlur, onFocus: handleFocus, "aria-describedby": void 0 // Root input should not have any aria-describedby }, changed: members.some((m) => m.kind === "field" && m.field.changed), focused, groups, id, level: 0, members, onChange: handleChange, onFieldClose: handleCloseField, onFieldCollapse: handleCollapseField, onFieldSetCollapse: handleCollapseFieldSet, onFieldExpand: handleExpandField, onFieldSetExpand: handleExpandFieldSet, onPathFocus, onFieldOpen: handleOpenField, onFieldGroupSelect: handleSelectFieldGroup, path: EMPTY_ARRAY$2, presence: EMPTY_ARRAY$2, readOnly, renderAnnotation, renderBlock, renderField, renderInlineBlock, renderInput, renderItem, renderPreview, schemaType, validation: EMPTY_ARRAY$2, value }; return /* @__PURE__ */ jsx( FormProvider, { __internal_fieldActions: fieldActions, __internal_patchChannel: patchChannel, autoFocus, changesOpen, collapsedFieldSets, collapsedPaths, focusPath, focused, groups, id, onChange, onPathBlur, onPathFocus, onPathOpen, onFieldGroupSelect, onSetPathCollapsed, onSetFieldSetCollapsed, presence, validation, readOnly, schemaType, children: /* @__PURE__ */ jsx(GetFormValueProvider, { value, children: /* @__PURE__ */ jsx(FormValueProvider, { value, children: /* @__PURE__ */ jsx(DocumentFieldActionsProvider, { actions: fieldActions, children: renderInput(rootInputProps) }) }) }) } ); } const remoteSnapshots = memoize( (client, idPair, typeName) => memoizedPair(client, idPair, typeName).pipe( switchMap(({ published, draft }) => merge(published.remoteSnapshot$, draft.remoteSnapshot$)) ), memoizeKeyGen ); function maybeSerialize(template) { return isBuilder(template) ? template.serialize() : template; } function isNonNullable(t) { return !!t; } function prepareTemplates(schema, initialValueTemplates) { const serialized = initialValueTemplates.map(maybeSerialize); return validateTemplates(schema, serialized); } function defaultTemplateForType(schemaType) { return { id: schemaType.name, schemaType: schemaType.name, title: schemaType.title || schemaType.name, icon: schemaType.icon, value: schemaType.initialValue || { _type: schemaType.name } }; } function defaultTemplatesForSchema(schema) { const schemaTypes = schema.getTypeNames().filter((typeName) => !/^sanity\./.test(t