@riverbankcms/sdk 0.60.7 → 0.60.9

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.
Files changed (33) hide show
  1. package/dist/_dts/api/src/navigation/linkValue.d.ts +1 -1
  2. package/dist/_dts/blocks/src/index.d.ts +2 -1
  3. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +185 -0
  4. package/dist/_dts/blocks/src/system/manifest/index.d.ts +1 -0
  5. package/dist/_dts/blocks/src/system/manifest/validation.d.ts +2 -84
  6. package/dist/_dts/blocks/src/system/types/link.d.ts +93 -1
  7. package/dist/_dts/db/src/schemas/forms.d.ts +24 -3
  8. package/dist/_dts/editor-blocks/src/widgets/link/LinkSummary.d.ts +1 -1
  9. package/dist/_dts/editor-blocks/src/widgets/link/LinkWidget.d.ts +1 -1
  10. package/dist/_dts/editor-blocks/src/widgets/link/utils.d.ts +1 -1
  11. package/dist/_dts/sdk/src/config/typed-entries.d.ts +36 -1
  12. package/dist/_dts/sdk/src/contracts/content.d.ts +6 -1
  13. package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
  14. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +1 -0
  15. package/dist/_dts/sdk/src/version.d.ts +1 -1
  16. package/dist/cli/index.mjs +676 -428
  17. package/dist/client/client.mjs +39991 -39754
  18. package/dist/client/hooks.mjs +1737 -1735
  19. package/dist/client/rendering.mjs +1463 -1226
  20. package/dist/preview-next/client/runtime.mjs +1052 -799
  21. package/dist/server/components.mjs +2983 -2745
  22. package/dist/server/config-validation.mjs +1727 -1725
  23. package/dist/server/config.mjs +1727 -1725
  24. package/dist/server/data.mjs +1737 -1735
  25. package/dist/server/index.mjs +1 -1
  26. package/dist/server/next.mjs +3026 -2788
  27. package/dist/server/page-converter.mjs +10 -10
  28. package/dist/server/prebuild.mjs +1 -1
  29. package/dist/server/rendering/server.mjs +2996 -2758
  30. package/dist/server/rendering.mjs +2996 -2758
  31. package/dist/server/routing.mjs +256 -285
  32. package/dist/server/server.mjs +1738 -1736
  33. package/package.json +1 -1
@@ -5,7 +5,7 @@ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
  import * as ReactDOM5 from 'react-dom';
6
6
  import ReactDOM5__default, { createPortal, unstable_batchedUpdates } from 'react-dom';
7
7
  import deepEqual6 from 'fast-deep-equal';
8
- import z37, { z } from 'zod';
8
+ import z38, { z } from 'zod';
9
9
  import { QueryClient, MutationCache, QueryCache, QueryClientProvider, useQueryClient, useMutation, useQuery } from '@tanstack/react-query';
10
10
  import { createRoot } from 'react-dom/client';
11
11
  import { useRouter } from 'next/navigation';
@@ -57782,7 +57782,7 @@ var init_index_esm = __esm({
57782
57782
  const isRadio = isRadioInput(ref);
57783
57783
  const isCheckBox = isCheckBoxInput(ref);
57784
57784
  const isRadioOrCheckbox = isRadio || isCheckBox;
57785
- const isEmpty2 = (valueAsNumber || isFileInput(ref)) && isUndefined(ref.value) && isUndefined(inputValue) || isHTMLElement2(ref) && ref.value === "" || inputValue === "" || Array.isArray(inputValue) && !inputValue.length;
57785
+ const isEmpty = (valueAsNumber || isFileInput(ref)) && isUndefined(ref.value) && isUndefined(inputValue) || isHTMLElement2(ref) && ref.value === "" || inputValue === "" || Array.isArray(inputValue) && !inputValue.length;
57786
57786
  const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
57787
57787
  const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
57788
57788
  const message2 = exceedMax ? maxLengthMessage : minLengthMessage;
@@ -57793,7 +57793,7 @@ var init_index_esm = __esm({
57793
57793
  ...appendErrorsCurry(exceedMax ? maxType : minType, message2)
57794
57794
  };
57795
57795
  };
57796
- if (isFieldArray ? !Array.isArray(inputValue) || !inputValue.length : required && (!isRadioOrCheckbox && (isEmpty2 || isNullOrUndefined(inputValue)) || isBoolean(inputValue) && !inputValue || isCheckBox && !getCheckboxValue(refs).isValid || isRadio && !getRadioValue(refs).isValid)) {
57796
+ if (isFieldArray ? !Array.isArray(inputValue) || !inputValue.length : required && (!isRadioOrCheckbox && (isEmpty || isNullOrUndefined(inputValue)) || isBoolean(inputValue) && !inputValue || isCheckBox && !getCheckboxValue(refs).isValid || isRadio && !getRadioValue(refs).isValid)) {
57797
57797
  const { value, message: message2 } = isString(required) ? { value: !!required, message: required } : getValueAndMessage(required);
57798
57798
  if (value) {
57799
57799
  error[name] = {
@@ -57808,7 +57808,7 @@ var init_index_esm = __esm({
57808
57808
  }
57809
57809
  }
57810
57810
  }
57811
- if (!isEmpty2 && (!isNullOrUndefined(min3) || !isNullOrUndefined(max3))) {
57811
+ if (!isEmpty && (!isNullOrUndefined(min3) || !isNullOrUndefined(max3))) {
57812
57812
  let exceedMax;
57813
57813
  let exceedMin;
57814
57814
  const maxOutput = getValueAndMessage(max3);
@@ -57841,7 +57841,7 @@ var init_index_esm = __esm({
57841
57841
  }
57842
57842
  }
57843
57843
  }
57844
- if ((maxLength || minLength) && !isEmpty2 && (isString(inputValue) || isFieldArray && Array.isArray(inputValue))) {
57844
+ if ((maxLength || minLength) && !isEmpty && (isString(inputValue) || isFieldArray && Array.isArray(inputValue))) {
57845
57845
  const maxLengthOutput = getValueAndMessage(maxLength);
57846
57846
  const minLengthOutput = getValueAndMessage(minLength);
57847
57847
  const exceedMax = !isNullOrUndefined(maxLengthOutput.value) && inputValue.length > +maxLengthOutput.value;
@@ -57854,7 +57854,7 @@ var init_index_esm = __esm({
57854
57854
  }
57855
57855
  }
57856
57856
  }
57857
- if (pattern && !isEmpty2 && isString(inputValue)) {
57857
+ if (pattern && !isEmpty && isString(inputValue)) {
57858
57858
  const { value: patternValue, message: message2 } = getValueAndMessage(pattern);
57859
57859
  if (isRegex(patternValue) && !inputValue.match(patternValue)) {
57860
57860
  error[name] = {
@@ -88167,8 +88167,8 @@ var init_dist57 = __esm({
88167
88167
  if (empty2 || !allWasSelected) {
88168
88168
  return;
88169
88169
  }
88170
- const isEmpty2 = isNodeEmpty(newState.doc);
88171
- if (!isEmpty2) {
88170
+ const isEmpty = isNodeEmpty(newState.doc);
88171
+ if (!isEmpty) {
88172
88172
  return;
88173
88173
  }
88174
88174
  const tr3 = newState.tr;
@@ -91152,8 +91152,8 @@ var init_dist84 = __esm({
91152
91152
  const isEmptyDoc = this.editor.isEmpty;
91153
91153
  doc3.descendants((node, pos) => {
91154
91154
  const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
91155
- const isEmpty2 = !node.isLeaf && isNodeEmpty(node);
91156
- if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty2) {
91155
+ const isEmpty = !node.isLeaf && isNodeEmpty(node);
91156
+ if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {
91157
91157
  const classes = [this.options.emptyNodeClass];
91158
91158
  if (isEmptyDoc) {
91159
91159
  classes.push(this.options.emptyEditorClass);
@@ -94380,7 +94380,7 @@ var init_dist86 = __esm({
94380
94380
  function RichTextEditorSurface({
94381
94381
  editor,
94382
94382
  config,
94383
- isEmpty: isEmpty2,
94383
+ isEmpty,
94384
94384
  className,
94385
94385
  contentClassName,
94386
94386
  placeholderClassName,
@@ -94414,7 +94414,7 @@ function RichTextEditorSurface({
94414
94414
  onClick,
94415
94415
  ...interactiveContentProps,
94416
94416
  children: [
94417
- isEmpty2 ? /* @__PURE__ */ jsx(
94417
+ isEmpty ? /* @__PURE__ */ jsx(
94418
94418
  "span",
94419
94419
  {
94420
94420
  className: cn2(
@@ -94660,7 +94660,7 @@ function useRichTextEditor({ content, editable, variant }) {
94660
94660
  const baseConfig = richTextConfigs[variant];
94661
94661
  const config = baseConfig;
94662
94662
  const [warnings, setWarnings] = useState({ unsupportedNodes: [], unsupportedMarks: [] });
94663
- const [isEmpty2, setIsEmpty] = useState(() => isDocEmpty(content));
94663
+ const [isEmpty, setIsEmpty] = useState(() => isDocEmpty(content));
94664
94664
  const editor = useEditor2(
94665
94665
  {
94666
94666
  extensions: config.extensions,
@@ -94704,7 +94704,7 @@ function useRichTextEditor({ content, editable, variant }) {
94704
94704
  };
94705
94705
  }, [editor]);
94706
94706
  const warningSummary = hasUnsupportedRichTextContent(warnings) ? formatUnsupportedRichTextSummary(warnings) : null;
94707
- return { editor, isEmpty: isEmpty2, config, warnings, warningSummary };
94707
+ return { editor, isEmpty, config, warnings, warningSummary };
94708
94708
  }
94709
94709
  function deepEqual4(a2, b3) {
94710
94710
  try {
@@ -98517,19 +98517,65 @@ var init_fieldPath = __esm({
98517
98517
  "../blocks/src/system/manifest/fieldPath.ts"() {
98518
98518
  }
98519
98519
  });
98520
-
98521
- // ../blocks/src/system/manifest/registry.ts
98522
- function registerManifest(manifest) {
98523
- manifestStore.set(manifest.name, manifest);
98524
- return manifest;
98520
+ function isInternalResolvedLinkValue(value) {
98521
+ return value?.kind === "internal" && "entityId" in value && "entityType" in value && "href" in value && "title" in value && "typeLabel" in value && typeof value.entityId === "string" && typeof value.entityType === "string" && typeof value.href === "string" && typeof value.title === "string" && typeof value.typeLabel === "string";
98525
98522
  }
98526
- var REGISTRY_SYMBOL, isVitest, globalScope, manifestStore;
98527
- var init_registry2 = __esm({
98528
- "../blocks/src/system/manifest/registry.ts"() {
98529
- REGISTRY_SYMBOL = /* @__PURE__ */ Symbol.for("@riverbankcms/blocks/manifest-registry");
98530
- isVitest = typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.VITEST === "true";
98531
- globalScope = globalThis;
98532
- manifestStore = isVitest ? /* @__PURE__ */ new Map() : globalScope[REGISTRY_SYMBOL] ?? (globalScope[REGISTRY_SYMBOL] = /* @__PURE__ */ new Map());
98523
+ var nullableString, resolvedInternalLinkKeys, internalRouteOnlyLinkSchema, internalResolvedLinkSchema, internalLinkSchema, externalLinkSchema, customLinkSchema, pageLinkSchema, entryLinkSchema, linkSchema;
98524
+ var init_link2 = __esm({
98525
+ "../blocks/src/system/types/link.ts"() {
98526
+ nullableString = z.union([z.string().min(1), z.null()]);
98527
+ resolvedInternalLinkKeys = ["entityId", "entityType", "href", "title", "typeLabel"];
98528
+ internalRouteOnlyLinkSchema = z.object({
98529
+ kind: z.literal("internal"),
98530
+ routeId: z.string().min(1)
98531
+ }).passthrough().superRefine((value, ctx) => {
98532
+ const hasResolvedMetadata = resolvedInternalLinkKeys.some((key) => value[key] != null);
98533
+ if (!hasResolvedMetadata) return;
98534
+ ctx.addIssue({
98535
+ code: "custom",
98536
+ message: "Internal links with resolved metadata must include entityId, entityType, href, title, and typeLabel"
98537
+ });
98538
+ });
98539
+ internalResolvedLinkSchema = z.object({
98540
+ kind: z.literal("internal"),
98541
+ routeId: z.string().min(1),
98542
+ entityId: z.string().min(1),
98543
+ entityType: z.enum(["page", "content"]),
98544
+ href: z.string().min(1),
98545
+ title: z.string().min(1),
98546
+ typeLabel: z.string().min(1),
98547
+ contentTypeKey: nullableString.optional(),
98548
+ contentTypeName: nullableString.optional(),
98549
+ updatedAt: nullableString.optional()
98550
+ }).passthrough();
98551
+ internalLinkSchema = z.union([
98552
+ internalResolvedLinkSchema,
98553
+ internalRouteOnlyLinkSchema
98554
+ ]);
98555
+ externalLinkSchema = z.object({
98556
+ kind: z.literal("external"),
98557
+ href: z.string().min(1)
98558
+ }).passthrough();
98559
+ customLinkSchema = z.object({
98560
+ kind: z.literal("url"),
98561
+ href: z.string().min(1)
98562
+ }).passthrough();
98563
+ pageLinkSchema = z.object({
98564
+ kind: z.literal("page"),
98565
+ identifier: z.string().min(1)
98566
+ }).passthrough();
98567
+ entryLinkSchema = z.object({
98568
+ kind: z.literal("entry"),
98569
+ contentType: z.string().min(1),
98570
+ identifier: z.string().min(1)
98571
+ }).passthrough();
98572
+ linkSchema = z.union([
98573
+ internalLinkSchema,
98574
+ externalLinkSchema,
98575
+ customLinkSchema,
98576
+ pageLinkSchema,
98577
+ entryLinkSchema
98578
+ ]);
98533
98579
  }
98534
98580
  });
98535
98581
 
@@ -100591,385 +100637,569 @@ var init_schema3 = __esm({
100591
100637
  });
100592
100638
  }
100593
100639
  });
100594
-
100595
- // ../blocks/src/lib/typeGuards.ts
100596
- function isRecord5(value) {
100597
- return typeof value === "object" && value !== null && !Array.isArray(value);
100640
+ function assertNever5(value) {
100641
+ throw new Error(`Unhandled field validation variant: ${JSON.stringify(value)}`);
100598
100642
  }
100599
- function isObjectRecord(value) {
100600
- return typeof value === "object" && value !== null;
100601
- }
100602
- var init_typeGuards2 = __esm({
100603
- "../blocks/src/lib/typeGuards.ts"() {
100604
- }
100605
- });
100606
- function buildRichTextSchema(options) {
100607
- let schema = RichTextValueSchema;
100608
- if (options?.required) {
100609
- const label = options.label ?? "This field";
100610
- schema = schema.refine(
100611
- (val) => {
100612
- const doc3 = isRecord5(val) && "doc" in val ? val.doc : val;
100613
- const content = isRecord5(doc3) ? doc3.content : void 0;
100614
- if (!Array.isArray(content) || content.length === 0) return false;
100615
- const first2 = content[0];
100616
- if (content.length === 1 && isRecord5(first2) && first2.type === "paragraph" && (!("content" in first2) || first2.content == null)) {
100617
- return false;
100618
- }
100619
- return true;
100620
- },
100621
- {
100622
- message: `${label} is required`
100623
- }
100624
- );
100643
+ function validationContext(options = {}) {
100644
+ const isDraft = options.mode === "draft";
100645
+ return {
100646
+ allowNull: options.allowNull ?? true,
100647
+ allowIncomplete: isDraft || (options.allowIncomplete ?? false)
100648
+ };
100649
+ }
100650
+ function fieldIssueToMessage(issue2) {
100651
+ switch (issue2.kind) {
100652
+ case "required":
100653
+ return "This field is required";
100654
+ case "wrongType":
100655
+ return `${issue2.label} needs ${issue2.expected}`;
100656
+ case "tooLong":
100657
+ return `Use ${issue2.maximum} characters or fewer`;
100658
+ case "invalidEmail":
100659
+ return "Enter a valid email address";
100660
+ case "invalidPhone":
100661
+ return "Enter a valid phone number";
100662
+ case "invalidPattern":
100663
+ return "Check the format and try again";
100664
+ case "invalidUrl":
100665
+ return "Enter a valid web address";
100666
+ case "invalidNumber":
100667
+ return `${issue2.label} needs a number`;
100668
+ case "tooSmall":
100669
+ return `${issue2.label} must be ${issue2.minimum} or more`;
100670
+ case "tooLarge":
100671
+ return `${issue2.label} must be ${issue2.maximum} or less`;
100672
+ case "invalidSlug":
100673
+ return `${issue2.label} can only use lowercase letters, numbers, and dashes`;
100674
+ case "invalidOption":
100675
+ return `Choose one of the available options for ${issue2.label}`;
100676
+ case "tooFewItems":
100677
+ return `${issue2.label} must have at least ${issue2.minimum} ${pluralize(issue2.itemLabel, issue2.minimum)}`;
100678
+ case "tooManyItems":
100679
+ return `${issue2.label} must have at most ${issue2.maximum} ${pluralize(issue2.itemLabel, issue2.maximum)}`;
100680
+ case "invalidRichText":
100681
+ return `${issue2.label} must be valid rich text`;
100682
+ case "invalidMedia":
100683
+ return `${issue2.label} must be a valid media item`;
100684
+ case "invalidLink":
100685
+ return `${issue2.label} must be a valid link`;
100686
+ case "invalidReference":
100687
+ return `${issue2.label} must reference a valid item`;
100688
+ default:
100689
+ return assertNever5(issue2);
100625
100690
  }
100626
- return schema;
100627
100691
  }
100628
- var TipTapMarkSchema, TipTapNodeSchema, RichTextValueSchema;
100629
- var init_richTextSchema = __esm({
100630
- "../blocks/src/system/manifest/richTextSchema.ts"() {
100631
- init_typeGuards2();
100632
- TipTapMarkSchema = z.object({
100633
- type: z.string(),
100634
- attrs: z.record(z.string(), z.unknown()).optional()
100635
- });
100636
- TipTapNodeSchema = z.lazy(
100637
- () => z.object({
100638
- type: z.string(),
100639
- content: z.array(TipTapNodeSchema).optional(),
100640
- text: z.string().optional(),
100641
- attrs: z.record(z.string(), z.unknown()).optional(),
100642
- marks: z.array(TipTapMarkSchema).optional()
100643
- })
100644
- );
100645
- RichTextValueSchema = z.union([
100646
- // New format: TipTap document directly
100647
- TipTapNodeSchema,
100648
- // Legacy format: wrapped in { doc: {...} }
100649
- z.object({
100650
- doc: TipTapNodeSchema
100651
- })
100652
- ]);
100653
- }
100654
- });
100655
- function isEmpty(value) {
100656
- if (typeof value === "string" && value.trim() === "") return true;
100657
- if (value === null || value === void 0) return true;
100658
- if (Array.isArray(value) && value.length === 0) return true;
100659
- if (isEmptyRichTextDoc(value)) return true;
100660
- return false;
100692
+ function pluralize(label, count3) {
100693
+ if (count3 === 1) return label;
100694
+ return label.endsWith("s") ? label : `${label}s`;
100661
100695
  }
100662
- function isEmptyRichTextDoc(value) {
100663
- if (!value || typeof value !== "object") return false;
100664
- const obj = value;
100665
- const doc3 = "doc" in obj ? obj.doc : obj;
100666
- if (!doc3 || typeof doc3 !== "object") return false;
100667
- const docObj = doc3;
100668
- if (docObj.type !== "doc") return false;
100669
- const content = docObj.content;
100670
- if (!Array.isArray(content) || content.length === 0) return true;
100671
- if (content.length === 1) {
100672
- const first2 = content[0];
100673
- if (first2.type === "paragraph" && (!first2.content || first2.content.length === 0)) {
100674
- return true;
100696
+ function deriveFieldValidationPlan(field, path = [field.id]) {
100697
+ const required = Boolean(field.required);
100698
+ switch (field.type) {
100699
+ case "text": {
100700
+ const inputType = field.ui?.inputType;
100701
+ if (inputType === "number") {
100702
+ const constraints2 = commonConstraints(required, { kind: "numberType" });
100703
+ if (typeof field.ui?.min === "number") constraints2.push({ kind: "numberMin", minimum: field.ui.min });
100704
+ if (typeof field.ui?.max === "number") constraints2.push({ kind: "numberMax", maximum: field.ui.max });
100705
+ return makePlan("number", "number", field, path, required, constraints2);
100706
+ }
100707
+ const constraints = commonConstraints(required, { kind: "textType" });
100708
+ if (inputType === "email") constraints.push({ kind: "emailFormat" });
100709
+ if (inputType === "tel") constraints.push({ kind: "phoneFormat" });
100710
+ if (field.ui?.pattern) constraints.push({ kind: "patternFormat", pattern: field.ui.pattern });
100711
+ if (typeof field.maxLength === "number") constraints.push({ kind: "maxLength", maximum: field.maxLength });
100712
+ return makePlan("string", "string", field, path, required, constraints);
100713
+ }
100714
+ case "number": {
100715
+ const constraints = commonConstraints(required, { kind: "numberType" });
100716
+ if (typeof field.min === "number") constraints.push({ kind: "numberMin", minimum: field.min });
100717
+ if (typeof field.max === "number") constraints.push({ kind: "numberMax", maximum: field.max });
100718
+ return makePlan("number", "number", field, path, required, constraints);
100719
+ }
100720
+ case "slug": {
100721
+ const constraints = commonConstraints(required, { kind: "textType" }, { kind: "slugFormat" });
100722
+ if (typeof field.maxLength === "number") constraints.push({ kind: "maxLength", maximum: field.maxLength });
100723
+ return makePlan("string", "string", field, path, required, constraints);
100675
100724
  }
100725
+ case "url":
100726
+ return makePlan("string", "string", field, path, required, commonConstraints(
100727
+ required,
100728
+ { kind: "textType" },
100729
+ { kind: "urlFormat", allowRelative: Boolean(field.allowRelative) }
100730
+ ));
100731
+ case "reference":
100732
+ return makePlan("string", "string", field, path, required, commonConstraints(required, { kind: "referenceText" }));
100733
+ case "date":
100734
+ case "time":
100735
+ case "datetime":
100736
+ return makePlan("string", "string", field, path, required, commonConstraints(required, { kind: "textType" }));
100737
+ case "select":
100738
+ return makePlan("select", "select", field, path, required, commonConstraints(required, {
100739
+ kind: "selectOption",
100740
+ source: resolveSelectConstraintSource(field),
100741
+ multiple: Boolean(field.multiple)
100742
+ }));
100743
+ case "richText":
100744
+ return makePlan("richText", "object", field, path, required, commonConstraints(required, { kind: "richTextDoc" }));
100745
+ case "media":
100746
+ return makePlan("media", "object", field, path, required, commonConstraints(required, { kind: "mediaObject" }));
100747
+ case "link":
100748
+ return makePlan("link", "object", field, path, required, commonConstraints(required, { kind: "linkObject" }));
100749
+ case "boolean":
100750
+ return makePlan("boolean", "boolean", field, path, required, requiredConstraints(required));
100751
+ case "repeater":
100752
+ return {
100753
+ ...makePlan("repeater", "array", field, path, required, commonConstraints(required, { kind: "arrayType" })),
100754
+ ...field.polymorphic && field.itemTypes ? { repeatedItemVariants: deriveRepeatedItemVariants(field, [...path, 0]) } : { repeatedItemPlan: deriveNestedFieldPlans(getRepeaterFields(field), [...path, 0]) },
100755
+ constraints: withRepeaterItemConstraints(field, commonConstraints(required, { kind: "arrayType" }))
100756
+ };
100757
+ case "group":
100758
+ case "modal":
100759
+ return {
100760
+ ...makePlan("group", "object", field, path, required, requiredConstraints(required)),
100761
+ children: deriveNestedFieldPlans(field.schema?.fields ?? [], path),
100762
+ allowNullChildren: field.type === "group" && field.ui?.widget === "locationPicker"
100763
+ };
100764
+ case "tabGroup":
100765
+ return {
100766
+ ...makePlan("group", "object", field, path, required, requiredConstraints(required)),
100767
+ children: field.tabs.flatMap((tab) => deriveNestedFieldPlans(tab.fields, path))
100768
+ };
100769
+ case "presetOrCustom":
100770
+ case "contentTypeSelect":
100771
+ case "entryPicker":
100772
+ return makePlan("passthrough", "unknown", field, path, false, []);
100773
+ default:
100774
+ return assertNever5(field);
100676
100775
  }
100677
- return false;
100678
100776
  }
100679
- function preprocessEmptyValues(content) {
100680
- if (!content || typeof content !== "object" || Array.isArray(content)) {
100681
- return {};
100682
- }
100683
- const result = {};
100684
- for (const [key, value] of Object.entries(content)) {
100685
- result[key] = isEmpty(value) ? void 0 : value;
100777
+ function commonConstraints(required, ...specific) {
100778
+ return required ? [{ kind: "required" }, ...specific] : [...specific];
100779
+ }
100780
+ function requiredConstraints(required) {
100781
+ return required ? [{ kind: "required" }] : [];
100782
+ }
100783
+ function makePlan(kind, valueKind, field, path, required, constraints) {
100784
+ return {
100785
+ kind,
100786
+ valueKind,
100787
+ fieldId: field.id,
100788
+ label: field.label,
100789
+ fieldType: field.type,
100790
+ path,
100791
+ required,
100792
+ constraints
100793
+ };
100794
+ }
100795
+ function withRepeaterItemConstraints(field, constraints) {
100796
+ const next = [...constraints];
100797
+ if (typeof field.minItems === "number") next.push({ kind: "minItems", minimum: field.minItems });
100798
+ if (typeof field.maxItems === "number") next.push({ kind: "maxItems", maximum: field.maxItems });
100799
+ return next;
100800
+ }
100801
+ function deriveRepeatedItemVariants(field, parentPath) {
100802
+ return Object.entries(field.itemTypes ?? {}).map(([typeId, itemType]) => ({
100803
+ typeId,
100804
+ fields: deriveNestedFieldPlans(getFlattenedRepeaterFields(itemType.fields), parentPath)
100805
+ }));
100806
+ }
100807
+ function deriveNestedFieldPlans(fields3, parentPath) {
100808
+ return fields3.map((field) => deriveFieldValidationPlan(field, [...parentPath, field.id]));
100809
+ }
100810
+ function getRepeaterFields(field) {
100811
+ const fields3 = field.polymorphic && field.itemTypes ? Object.values(field.itemTypes).flatMap((itemType) => itemType.fields) : field.schema?.fields ?? [];
100812
+ return getFlattenedRepeaterFields(fields3);
100813
+ }
100814
+ function getFlattenedRepeaterFields(fields3) {
100815
+ return fields3.flatMap((child) => {
100816
+ if (child.type === "group" && child.ui?.flattenInRepeater) {
100817
+ return child.schema?.fields ?? [];
100818
+ }
100819
+ return child;
100820
+ });
100821
+ }
100822
+ function resolveSelectConstraintSource(field) {
100823
+ const source = normalizeSelectSource(field);
100824
+ switch (source.kind) {
100825
+ case "static":
100826
+ return { kind: "static", values: field.options.map((option) => option.value) };
100827
+ case "site":
100828
+ case "sdk":
100829
+ return { kind: "runtime", source: source.kind };
100830
+ default:
100831
+ return assertNever5(source);
100686
100832
  }
100687
- return result;
100688
100833
  }
100689
- function createManifestValidator(manifestOrFields, options = {}) {
100690
- const allowNull = options.allowNull ?? true;
100691
- const isDraft = options.mode === "draft";
100692
- const allowIncomplete = isDraft || (options.allowIncomplete ?? false);
100693
- const shape = {};
100694
- const fields3 = Array.isArray(manifestOrFields) ? manifestOrFields : manifestOrFields.fields ?? [];
100695
- for (const field of fields3) {
100696
- shape[field.id] = buildFieldSchema(field, allowNull, allowIncomplete);
100834
+ function normalizeFieldValue(plan, value, ctx) {
100835
+ switch (plan.kind) {
100836
+ case "number":
100837
+ return normalizeNumberInput(value, ctx.allowNull);
100838
+ case "string":
100839
+ return acceptsOptionalBlankAsMissing(plan, value) ? void 0 : value;
100840
+ case "group":
100841
+ return normalizeObjectChildren(plan.children, value, childValidationContext(plan, ctx));
100842
+ case "repeater":
100843
+ return normalizeRepeaterItems(plan, value, ctx);
100844
+ case "boolean":
100845
+ case "richText":
100846
+ case "media":
100847
+ case "link":
100848
+ case "select":
100849
+ case "passthrough":
100850
+ return value;
100851
+ default:
100852
+ return assertNever5(plan);
100697
100853
  }
100698
- const baseSchema = z.object(shape).catchall(z.unknown()).passthrough();
100699
- if (isDraft) {
100700
- return z.preprocess(preprocessEmptyValues, baseSchema);
100854
+ }
100855
+ function normalizeObjectChildren(children, value, ctx) {
100856
+ if (!value || typeof value !== "object" || Array.isArray(value)) return value;
100857
+ const normalized = { ...value };
100858
+ for (const child of children) {
100859
+ normalized[child.fieldId] = normalizeFieldValue(child, normalized[child.fieldId], ctx);
100701
100860
  }
100702
- return baseSchema;
100861
+ return normalized;
100703
100862
  }
100704
- function buildFieldSchema(field, allowNull, allowIncomplete = false) {
100705
- const required = Boolean(field.required);
100706
- let schema;
100707
- switch (field.type) {
100708
- case "text":
100709
- schema = buildTextSchema(field);
100710
- break;
100711
- case "richText":
100712
- schema = buildRichTextSchema2();
100713
- break;
100714
- case "media": {
100715
- const baseMediaSchema = z.record(z.string(), z.unknown());
100716
- const isRequired = Boolean(field.required);
100717
- schema = isRequired ? baseMediaSchema : baseMediaSchema.nullable();
100718
- break;
100719
- }
100863
+ function normalizeRepeaterItems(plan, value, ctx) {
100864
+ if (!Array.isArray(value)) return value;
100865
+ return value.map((item) => {
100866
+ if (!item || typeof item !== "object" || Array.isArray(item)) return item;
100867
+ const itemRecord = item;
100868
+ const fields3 = plan.repeatedItemVariants ? plan.repeatedItemVariants.find((variant) => variant.typeId === itemRecord._type)?.fields : plan.repeatedItemPlan;
100869
+ if (!fields3) return item;
100870
+ return normalizeObjectChildren(fields3, itemRecord, ctx);
100871
+ });
100872
+ }
100873
+ function normalizeNumberInput(value, allowNull) {
100874
+ if (value === "") return void 0;
100875
+ if (typeof value === "string" && value.trim() !== "") return Number(value);
100876
+ return value;
100877
+ }
100878
+ function acceptsOptionalBlankAsMissing(plan, value) {
100879
+ if (plan.required || typeof value !== "string" || value.trim() !== "") return false;
100880
+ return plan.constraints.some(
100881
+ (constraint) => constraint.kind === "urlFormat" || constraint.kind === "slugFormat" || constraint.kind === "emailFormat" || constraint.kind === "phoneFormat" || constraint.kind === "patternFormat"
100882
+ );
100883
+ }
100884
+ function validateNormalizedFieldValue(plan, value, ctx) {
100885
+ if (value === null && (ctx.allowNull || acceptsOptionalNullValue(plan))) return [];
100886
+ if (isMissingForPlan(plan, value)) {
100887
+ return shouldRequireValue(plan, value, ctx) ? [requiredIssue(plan, value)] : [];
100888
+ }
100889
+ switch (plan.kind) {
100890
+ case "string":
100891
+ return validateStringPlan(plan, value);
100892
+ case "number":
100893
+ return validateNumberPlan(plan, value);
100720
100894
  case "boolean":
100721
- schema = z.boolean();
100722
- break;
100723
- case "slug":
100724
- schema = buildSlugSchema(field);
100725
- break;
100726
- case "url":
100727
- schema = buildUrlSchema(field);
100728
- break;
100729
- case "link":
100730
- schema = buildLinkSchema();
100731
- break;
100895
+ return typeof value === "boolean" ? [] : [issue(plan, "wrongType", { expected: "a true/false value" })];
100732
100896
  case "select":
100733
- schema = buildSelectSchema(field);
100734
- break;
100735
- case "reference":
100736
- schema = buildReferenceSchema(field);
100737
- break;
100897
+ return validateSelectPlan(plan, value);
100898
+ case "richText":
100899
+ return isValidRichTextDoc(value) ? [] : [issue(plan, "invalidRichText")];
100900
+ case "media":
100901
+ return isPlainObject3(value) ? [] : [issue(plan, "invalidMedia")];
100902
+ case "link":
100903
+ return linkSchema.safeParse(value).success ? [] : [issue(plan, "invalidLink")];
100738
100904
  case "repeater":
100739
- schema = buildRepeaterSchema(field, allowNull, allowIncomplete);
100740
- break;
100905
+ return validateRepeaterPlan(plan, value, ctx);
100741
100906
  case "group":
100742
- schema = buildGroupSchema(field, allowNull, allowIncomplete);
100743
- break;
100907
+ return validateGroupPlan(plan, value, ctx);
100908
+ case "passthrough":
100909
+ return [];
100744
100910
  default:
100745
- schema = z.unknown();
100746
- break;
100911
+ return assertNever5(plan);
100747
100912
  }
100748
- return finalizeSchema(schema, required, allowNull, allowIncomplete);
100749
100913
  }
100750
- function buildFriendlyStringSchema(field) {
100751
- return z.string({
100752
- error: (issue) => issue.input === void 0 || issue.input === null ? "This field is required" : `${field.label} needs text`
100753
- });
100914
+ function shouldRequireValue(plan, value, ctx) {
100915
+ if (!plan.required || ctx.allowIncomplete) return false;
100916
+ if (value === null && ctx.allowNull) return false;
100917
+ return true;
100754
100918
  }
100755
- function buildTextSchema(field) {
100756
- const ui = field.ui ?? {};
100757
- const inputType = ui?.inputType;
100758
- let schema;
100759
- if (inputType === "number") {
100760
- schema = z.coerce.number({
100761
- error: (issue) => issue.input === void 0 ? `${field.label} is required` : `${field.label} needs a number`
100762
- });
100763
- if (typeof ui?.min === "number") {
100764
- schema = schema.min(
100765
- ui.min,
100766
- `${field.label} must be ${ui.min} or more`
100767
- );
100768
- }
100769
- if (typeof ui?.max === "number") {
100770
- schema = schema.max(
100771
- ui.max,
100772
- `${field.label} must be ${ui.max} or less`
100773
- );
100774
- }
100775
- } else {
100776
- schema = buildFriendlyStringSchema(field);
100777
- if (inputType === "email") {
100778
- schema = schema.email("Enter a valid email address");
100779
- }
100780
- if (inputType === "tel") {
100781
- const TEL_RE = /^[+()0-9\s\-]{3,}$/;
100782
- schema = schema.regex(
100783
- TEL_RE,
100784
- "Enter a valid phone number"
100785
- );
100786
- }
100787
- if (ui?.pattern) {
100788
- try {
100789
- const re2 = new RegExp(ui.pattern);
100790
- schema = schema.regex(
100791
- re2,
100792
- `${field.label} is not in the right format`
100793
- );
100794
- } catch {
100795
- }
100796
- }
100797
- if (field.maxLength) {
100798
- schema = schema.max(
100799
- field.maxLength,
100800
- `${field.label} must be ${field.maxLength} characters or less`
100801
- );
100802
- }
100803
- if (field.required) {
100804
- schema = schema.min(1, { message: `${field.label} is required` }).refine((v2) => v2.trim().length > 0, { message: `${field.label} is required` });
100805
- }
100806
- }
100807
- return schema;
100919
+ function acceptsOptionalNullValue(plan) {
100920
+ return !plan.required && (plan.kind === "media" || plan.kind === "number");
100921
+ }
100922
+ function isMissingForPlan(plan, value) {
100923
+ if (value === void 0) return true;
100924
+ if (value === null) return plan.required;
100925
+ if (typeof value === "string" && value.trim() === "") return true;
100926
+ if (Array.isArray(value) && value.length === 0) return true;
100927
+ return false;
100808
100928
  }
100809
- function buildRichTextSchema2() {
100810
- return buildRichTextSchema();
100929
+ function validateStringPlan(plan, value) {
100930
+ if (typeof value !== "string") return [issue(plan, "wrongType", { expected: "text" })];
100931
+ return plan.constraints.flatMap((constraint) => validateStringConstraint(plan, constraint, value));
100811
100932
  }
100812
- function buildSlugSchema(field) {
100813
- const message2 = `${field.label} can only use lowercase letters, numbers, and dashes`;
100814
- let schema = buildFriendlyStringSchema(field).regex(SLUG_PATTERN, message2);
100815
- if (field.maxLength) {
100816
- schema = schema.max(
100817
- field.maxLength,
100818
- `${field.label} must be ${field.maxLength} characters or less`
100819
- );
100933
+ function validateStringConstraint(plan, constraint, value) {
100934
+ switch (constraint.kind) {
100935
+ case "required":
100936
+ case "textType":
100937
+ case "referenceText":
100938
+ return [];
100939
+ case "maxLength":
100940
+ return value.length > constraint.maximum ? [issue(plan, "tooLong", { maximum: constraint.maximum })] : [];
100941
+ case "emailFormat":
100942
+ return z.email().safeParse(value).success ? [] : [issue(plan, "invalidEmail")];
100943
+ case "phoneFormat":
100944
+ return TEL_RE.test(value) ? [] : [issue(plan, "invalidPhone")];
100945
+ case "patternFormat": {
100946
+ const re2 = compilePattern(constraint.pattern);
100947
+ return re2 && !re2.test(value) ? [issue(plan, "invalidPattern")] : [];
100948
+ }
100949
+ case "urlFormat":
100950
+ return isValidUrl(value, constraint.allowRelative) ? [] : [issue(plan, "invalidUrl")];
100951
+ case "slugFormat":
100952
+ return SLUG_PATTERN.test(value) ? [] : [issue(plan, "invalidSlug")];
100953
+ default:
100954
+ return assertNever5(constraint);
100820
100955
  }
100821
- if (field.required) {
100822
- schema = schema.min(1, { message: `${field.label} is required` });
100956
+ }
100957
+ function validateNumberPlan(plan, value) {
100958
+ if (!isValidNumber(value)) return [issue(plan, "invalidNumber")];
100959
+ return plan.constraints.flatMap((constraint) => validateNumberConstraint(plan, constraint, Number(value)));
100960
+ }
100961
+ function validateNumberConstraint(plan, constraint, value) {
100962
+ switch (constraint.kind) {
100963
+ case "required":
100964
+ case "numberType":
100965
+ return [];
100966
+ case "numberMin":
100967
+ return value < constraint.minimum ? [issue(plan, "tooSmall", { minimum: constraint.minimum })] : [];
100968
+ case "numberMax":
100969
+ return value > constraint.maximum ? [issue(plan, "tooLarge", { maximum: constraint.maximum })] : [];
100970
+ default:
100971
+ return assertNever5(constraint);
100823
100972
  }
100824
- return schema;
100825
100973
  }
100826
- function buildUrlSchema(field) {
100827
- const message2 = "Enter a valid web address";
100828
- const validate = (value) => {
100829
- if (!value) {
100830
- return !field.required;
100831
- }
100832
- if (field.allowRelative && value.startsWith("/")) {
100833
- return true;
100834
- }
100835
- try {
100836
- const parsed = new URL(value);
100837
- return ALLOWED_URL_PROTOCOLS.includes(
100838
- parsed.protocol
100839
- );
100840
- } catch {
100841
- return false;
100974
+ function validateSelectPlan(plan, value) {
100975
+ const constraint = plan.constraints.find((candidate) => candidate.kind === "selectOption");
100976
+ if (!constraint || constraint.source.kind === "runtime") return [];
100977
+ return isValidSelectValue(value, constraint.source.values, constraint.multiple) ? [] : [issue(plan, "invalidOption")];
100978
+ }
100979
+ function validateRepeaterPlan(plan, value, ctx) {
100980
+ if (!Array.isArray(value)) return [issue(plan, "wrongType", { expected: "a list" })];
100981
+ const constraintIssues = plan.constraints.flatMap((constraint) => {
100982
+ switch (constraint.kind) {
100983
+ case "required":
100984
+ case "arrayType":
100985
+ return [];
100986
+ case "minItems":
100987
+ return value.length < constraint.minimum ? [issue(plan, "tooFewItems", { minimum: constraint.minimum, itemLabel: "item" })] : [];
100988
+ case "maxItems":
100989
+ return value.length > constraint.maximum ? [issue(plan, "tooManyItems", { maximum: constraint.maximum, itemLabel: "item" })] : [];
100990
+ default:
100991
+ return assertNever5(constraint);
100842
100992
  }
100993
+ });
100994
+ return [
100995
+ ...constraintIssues,
100996
+ ...value.flatMap((item, index2) => validateRepeaterItem(plan, item, index2, ctx))
100997
+ ];
100998
+ }
100999
+ function validateRepeaterItem(plan, item, index2, ctx) {
101000
+ if (!isPlainObject3(item)) return [];
101001
+ const itemType = item._type;
101002
+ const fields3 = plan.repeatedItemVariants ? plan.repeatedItemVariants.find((variant) => variant.typeId === itemType)?.fields : plan.repeatedItemPlan;
101003
+ if (!fields3) return [];
101004
+ return fields3.flatMap((childPlan) => {
101005
+ const indexedPlan = withIndexedPath(childPlan, plan.path, index2);
101006
+ return validateNormalizedFieldValue(indexedPlan, item[childPlan.fieldId], ctx);
101007
+ });
101008
+ }
101009
+ function validateGroupPlan(plan, value, ctx) {
101010
+ if (!isPlainObject3(value)) return [issue(plan, "wrongType", { expected: "an object" })];
101011
+ const childCtx = childValidationContext(plan, ctx);
101012
+ return plan.children.flatMap((childPlan) => validateNormalizedFieldValue(childPlan, value[childPlan.fieldId], childCtx));
101013
+ }
101014
+ function childValidationContext(plan, ctx) {
101015
+ return plan.allowNullChildren ? { ...ctx, allowNull: true } : ctx;
101016
+ }
101017
+ function withIndexedPath(plan, parentPath, index2) {
101018
+ const suffix = plan.path.slice(parentPath.length + 1);
101019
+ return {
101020
+ ...plan,
101021
+ path: [...parentPath, index2, plan.fieldId, ...suffix]
100843
101022
  };
100844
- let schema = buildFriendlyStringSchema(field).trim().refine(validate, message2);
100845
- if (field.required) {
100846
- schema = schema.min(1, { message: `${field.label} is required` });
100847
- }
100848
- return schema;
100849
101023
  }
100850
- function buildLinkSchema() {
100851
- return linkSchema;
101024
+ function issue(plan, kind, extra) {
101025
+ return {
101026
+ kind,
101027
+ path: plan.path,
101028
+ fieldId: plan.fieldId,
101029
+ label: plan.label,
101030
+ ...extra ?? {}
101031
+ };
100852
101032
  }
100853
- function assertNeverSelectSource2(value) {
100854
- throw new Error(`Unhandled select source: ${JSON.stringify(value)}`);
101033
+ function requiredIssue(plan, value) {
101034
+ if (typeof value === "string") return issue(plan, "required", { emptyOrigin: "string" });
101035
+ if (Array.isArray(value)) return issue(plan, "required", { emptyOrigin: "array" });
101036
+ return issue(plan, "required");
100855
101037
  }
100856
- function buildSelectSchema(field) {
100857
- const source = normalizeSelectSource(field);
100858
- const singleValueSchema = (() => {
100859
- switch (source.kind) {
100860
- case "sdk":
100861
- case "site":
100862
- return buildFriendlyStringSchema(field);
100863
- case "static": {
100864
- const values = field.options.map((option) => option.value);
100865
- return buildFriendlyStringSchema(field).refine(
100866
- (value) => values.includes(value),
100867
- `Choose one of the available options for ${field.label}`
100868
- );
100869
- }
100870
- default:
100871
- return assertNeverSelectSource2(source);
101038
+ function fieldPlanToZod(plan, options = {}) {
101039
+ const ctx = validationContext(options);
101040
+ return z.any().transform((value) => normalizeFieldValue(plan, value, ctx)).superRefine((value, zodCtx) => {
101041
+ for (const validationIssue of validateNormalizedFieldValue(plan, value, ctx)) {
101042
+ addFieldIssueToZodContext(zodCtx, validationIssue);
100872
101043
  }
100873
- })();
100874
- if (field.multiple) {
100875
- const arraySchema = z.array(singleValueSchema);
100876
- return field.required ? arraySchema.min(1, { message: "This field is required" }) : arraySchema.nullable();
101044
+ });
101045
+ }
101046
+ function addFieldIssueToZodContext(zodCtx, validationIssue) {
101047
+ const message2 = fieldIssueToMessage(validationIssue);
101048
+ switch (validationIssue.kind) {
101049
+ case "required":
101050
+ if (validationIssue.emptyOrigin) {
101051
+ zodCtx.addIssue({
101052
+ code: "too_small",
101053
+ origin: validationIssue.emptyOrigin,
101054
+ minimum: 1,
101055
+ inclusive: true,
101056
+ message: message2
101057
+ });
101058
+ return;
101059
+ }
101060
+ zodCtx.addIssue({ code: "invalid_type", expected: "nonoptional", message: message2 });
101061
+ return;
101062
+ case "tooLong":
101063
+ zodCtx.addIssue({
101064
+ code: "too_big",
101065
+ origin: "string",
101066
+ maximum: validationIssue.maximum,
101067
+ inclusive: true,
101068
+ message: message2
101069
+ });
101070
+ return;
101071
+ case "invalidOption":
101072
+ zodCtx.addIssue({ code: "invalid_value", values: [], message: message2 });
101073
+ return;
101074
+ case "wrongType":
101075
+ case "invalidEmail":
101076
+ case "invalidPhone":
101077
+ case "invalidPattern":
101078
+ case "invalidUrl":
101079
+ case "invalidNumber":
101080
+ case "tooSmall":
101081
+ case "tooLarge":
101082
+ case "invalidSlug":
101083
+ case "tooFewItems":
101084
+ case "tooManyItems":
101085
+ case "invalidRichText":
101086
+ case "invalidMedia":
101087
+ case "invalidLink":
101088
+ case "invalidReference":
101089
+ zodCtx.addIssue({ code: "custom", message: message2 });
101090
+ return;
101091
+ default:
101092
+ assertNever5(validationIssue);
100877
101093
  }
100878
- return field.required ? singleValueSchema : singleValueSchema.nullable();
100879
101094
  }
100880
- function buildReferenceSchema(field) {
100881
- let schema = z.string({
100882
- error: (issue) => issue.input === void 0 || issue.input === null ? "This field is required" : `${field.label} needs text`
100883
- });
100884
- if (field.required) {
100885
- schema = schema.min(1, { message: `${field.label} is required` });
101095
+ function compilePattern(pattern) {
101096
+ try {
101097
+ return new RegExp(pattern);
101098
+ } catch {
101099
+ return null;
100886
101100
  }
100887
- return schema;
100888
101101
  }
100889
- function buildRepeaterSchema(field, allowNull, allowIncomplete) {
100890
- const parsed = fieldSchema.array().parse(field.schema?.fields ?? []);
100891
- const childShape = {};
100892
- for (const child of parsed) {
100893
- if (child.type === "group" && child.ui?.flattenInRepeater) {
100894
- const groupParsed = fieldSchema.array().parse(child.schema?.fields ?? []);
100895
- for (const gc of groupParsed) {
100896
- childShape[gc.id] = buildFieldSchema(gc, allowNull, allowIncomplete);
100897
- }
100898
- } else {
100899
- childShape[child.id] = buildFieldSchema(child, allowNull, allowIncomplete);
100900
- }
101102
+ function isValidNumber(value) {
101103
+ return typeof value === "number" && Number.isFinite(value);
101104
+ }
101105
+ function isValidUrl(value, allowRelative) {
101106
+ if (!value) return false;
101107
+ if (allowRelative && value.startsWith("/")) return true;
101108
+ try {
101109
+ const parsed = new URL(value);
101110
+ return ALLOWED_URL_PROTOCOLS.includes(parsed.protocol);
101111
+ } catch {
101112
+ return false;
100901
101113
  }
100902
- let schema = z.object(childShape).catchall(z.unknown()).passthrough();
100903
- let arraySchema = z.array(schema);
100904
- if (typeof field.minItems === "number") {
100905
- arraySchema = arraySchema.min(field.minItems);
101114
+ }
101115
+ function isValidSelectValue(value, values, multiple) {
101116
+ if (multiple) {
101117
+ return Array.isArray(value) && value.every((item) => typeof item === "string" && values.includes(item));
100906
101118
  }
100907
- if (typeof field.maxItems === "number") {
100908
- arraySchema = arraySchema.max(field.maxItems);
101119
+ return typeof value === "string" && values.includes(value);
101120
+ }
101121
+ function isEmptyValue(value) {
101122
+ if (value === null || value === void 0) return true;
101123
+ if (typeof value === "string" && value.trim() === "") return true;
101124
+ if (Array.isArray(value) && value.length === 0) return true;
101125
+ if (isEmptyRichTextDoc(value)) return true;
101126
+ return false;
101127
+ }
101128
+ function isPlainObject3(value) {
101129
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
101130
+ }
101131
+ function isValidRichTextDoc(value) {
101132
+ const doc3 = richTextDoc(value);
101133
+ return Boolean(isPlainObject3(doc3) && doc3.type === "doc");
101134
+ }
101135
+ function isEmptyRichTextDoc(value) {
101136
+ const doc3 = richTextDoc(value);
101137
+ if (!isPlainObject3(doc3)) return false;
101138
+ if (doc3.type !== "doc") return false;
101139
+ const content = doc3.content;
101140
+ if (!Array.isArray(content) || content.length === 0) return true;
101141
+ if (content.length !== 1) return false;
101142
+ const first2 = content[0];
101143
+ return first2?.type === "paragraph" && (!Array.isArray(first2.content) || first2.content.length === 0);
101144
+ }
101145
+ function richTextDoc(value) {
101146
+ if (!isPlainObject3(value)) return value;
101147
+ return isPlainObject3(value.doc) ? value.doc : value;
101148
+ }
101149
+ var TEL_RE, SLUG_PATTERN, ALLOWED_URL_PROTOCOLS;
101150
+ var init_fieldValidation = __esm({
101151
+ "../blocks/src/system/manifest/fieldValidation/index.ts"() {
101152
+ init_link2();
101153
+ init_schema3();
101154
+ TEL_RE = /^[+()0-9\s-]{3,}$/;
101155
+ SLUG_PATTERN = /^(?:[a-z0-9]+(?:-[a-z0-9]+)*)(?:\/(?:[a-z0-9]+(?:-[a-z0-9]+)*))*$/;
101156
+ ALLOWED_URL_PROTOCOLS = ["http:", "https:"];
100909
101157
  }
100910
- return arraySchema;
101158
+ });
101159
+
101160
+ // ../blocks/src/system/manifest/registry.ts
101161
+ function registerManifest(manifest) {
101162
+ manifestStore.set(manifest.name, manifest);
101163
+ return manifest;
100911
101164
  }
100912
- function buildGroupSchema(field, allowNull, allowIncomplete) {
100913
- const parsed = fieldSchema.array().parse(field.schema?.fields ?? []);
100914
- const childShape = {};
100915
- for (const child of parsed) {
100916
- childShape[child.id] = buildFieldSchema(child, allowNull, allowIncomplete);
101165
+ var REGISTRY_SYMBOL, isVitest, globalScope, manifestStore;
101166
+ var init_registry2 = __esm({
101167
+ "../blocks/src/system/manifest/registry.ts"() {
101168
+ REGISTRY_SYMBOL = /* @__PURE__ */ Symbol.for("@riverbankcms/blocks/manifest-registry");
101169
+ isVitest = typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.VITEST === "true";
101170
+ globalScope = globalThis;
101171
+ manifestStore = isVitest ? /* @__PURE__ */ new Map() : globalScope[REGISTRY_SYMBOL] ?? (globalScope[REGISTRY_SYMBOL] = /* @__PURE__ */ new Map());
101172
+ }
101173
+ });
101174
+ function preprocessEmptyValues(content) {
101175
+ if (!content || typeof content !== "object" || Array.isArray(content)) {
101176
+ return {};
101177
+ }
101178
+ const result = {};
101179
+ for (const [key, value] of Object.entries(content)) {
101180
+ result[key] = isEmptyValue(value) ? void 0 : value;
100917
101181
  }
100918
- return z.object(childShape).catchall(z.unknown()).passthrough();
101182
+ return result;
100919
101183
  }
100920
- function finalizeSchema(schema, required, allowNull, allowIncomplete = false) {
100921
- if (required) {
100922
- if (allowIncomplete) {
100923
- return allowNull ? schema.or(z.null()).optional() : schema.optional();
100924
- }
100925
- return allowNull ? schema.or(z.null()) : schema;
101184
+ function createManifestValidator(manifestOrFields, options = {}) {
101185
+ const isDraft = options.mode === "draft";
101186
+ const shape = {};
101187
+ const fields3 = Array.isArray(manifestOrFields) ? manifestOrFields : manifestOrFields.fields ?? [];
101188
+ for (const field of fields3) {
101189
+ shape[field.id] = buildFieldSchema(field, options);
100926
101190
  }
100927
- return allowNull ? schema.optional().nullable() : schema.optional();
101191
+ const baseSchema = z.object(shape).catchall(z.unknown()).passthrough();
101192
+ if (isDraft) {
101193
+ return z.preprocess(preprocessEmptyValues, baseSchema);
101194
+ }
101195
+ return baseSchema;
101196
+ }
101197
+ function buildFieldSchema(field, options) {
101198
+ return fieldPlanToZod(deriveFieldValidationPlan(field), options);
100928
101199
  }
100929
- var SLUG_PATTERN, ALLOWED_URL_PROTOCOLS, nullableString, internalLinkSchema, externalLinkSchema, customLinkSchema, pageLinkSchema, entryLinkSchema, linkSchema;
100930
101200
  var init_validation = __esm({
100931
101201
  "../blocks/src/system/manifest/validation.ts"() {
100932
- init_schema3();
100933
- init_richTextSchema();
100934
- SLUG_PATTERN = /^(?:[a-z0-9]+(?:-[a-z0-9]+)*)(?:\/(?:[a-z0-9]+(?:-[a-z0-9]+)*))*$/;
100935
- ALLOWED_URL_PROTOCOLS = ["http:", "https:"];
100936
- nullableString = z.union([z.string().min(1), z.null()]);
100937
- internalLinkSchema = z.object({
100938
- kind: z.literal("internal"),
100939
- routeId: z.string().min(1),
100940
- entityId: z.string().min(1).optional(),
100941
- entityType: z.enum(["page", "content"]).optional(),
100942
- href: nullableString.optional(),
100943
- title: nullableString.optional(),
100944
- typeLabel: nullableString.optional(),
100945
- contentTypeKey: nullableString.optional(),
100946
- contentTypeName: nullableString.optional(),
100947
- updatedAt: nullableString.optional()
100948
- }).passthrough();
100949
- externalLinkSchema = z.object({
100950
- kind: z.literal("external"),
100951
- href: z.string().min(1)
100952
- }).passthrough();
100953
- customLinkSchema = z.object({
100954
- kind: z.literal("url"),
100955
- href: z.string().min(1)
100956
- }).passthrough();
100957
- pageLinkSchema = z.object({
100958
- kind: z.literal("page"),
100959
- identifier: z.string().min(1)
100960
- }).passthrough();
100961
- entryLinkSchema = z.object({
100962
- kind: z.literal("entry"),
100963
- contentType: z.string().min(1),
100964
- identifier: z.string().min(1)
100965
- }).passthrough();
100966
- linkSchema = z.union([
100967
- internalLinkSchema,
100968
- externalLinkSchema,
100969
- customLinkSchema,
100970
- pageLinkSchema,
100971
- entryLinkSchema
100972
- ]);
101202
+ init_fieldValidation();
100973
101203
  }
100974
101204
  });
100975
101205
 
@@ -101006,6 +101236,7 @@ var init_manifest = __esm({
101006
101236
  "../blocks/src/system/manifest/index.ts"() {
101007
101237
  init_augmentManifest();
101008
101238
  init_fieldPath();
101239
+ init_fieldValidation();
101009
101240
  init_registry2();
101010
101241
  init_schema3();
101011
101242
  init_validation();
@@ -101072,7 +101303,7 @@ function makeBoundaryId(previousBlockId, nextBlockId) {
101072
101303
  const next = encodeURIComponent(nextBlockId);
101073
101304
  return asDesignBoundaryId(`boundary:${previous}:${next}`);
101074
101305
  }
101075
- function assertNever5(value, message2 = "Unhandled Theme V2 variant") {
101306
+ function assertNever6(value, message2 = "Unhandled Theme V2 variant") {
101076
101307
  throw new Error(`${message2}: ${String(value)}`);
101077
101308
  }
101078
101309
  function brandNonEmptyString(value, label) {
@@ -102177,44 +102408,44 @@ var init_personalities = __esm({
102177
102408
  var hotspotSchema, rotationSchema, rectSchema, aspectCropSchema, transformSchema, mediaSchema;
102178
102409
  var init_media = __esm({
102179
102410
  "../theme-core/src/lib/media.ts"() {
102180
- hotspotSchema = z37.object({
102181
- x: z37.number().min(0).max(1),
102182
- y: z37.number().min(0).max(1),
102183
- radius: z37.number().optional()
102184
- });
102185
- rotationSchema = z37.union([z37.literal(0), z37.literal(90), z37.literal(180), z37.literal(270)]);
102186
- rectSchema = z37.tuple([z37.number(), z37.number(), z37.number(), z37.number()]);
102187
- aspectCropSchema = z37.object({
102188
- aspect: z37.preprocess((value) => value == null ? void 0 : value, z37.string().optional()),
102189
- rect: z37.preprocess((value) => value == null ? void 0 : value, rectSchema.optional()),
102190
- hotspot: z37.preprocess((value) => value == null ? void 0 : value, hotspotSchema.optional()),
102191
- rotation: z37.preprocess((value) => value == null ? void 0 : value, rotationSchema.optional())
102192
- });
102193
- transformSchema = z37.object({
102194
- aspectCrops: z37.preprocess((value) => {
102411
+ hotspotSchema = z38.object({
102412
+ x: z38.number().min(0).max(1),
102413
+ y: z38.number().min(0).max(1),
102414
+ radius: z38.number().optional()
102415
+ });
102416
+ rotationSchema = z38.union([z38.literal(0), z38.literal(90), z38.literal(180), z38.literal(270)]);
102417
+ rectSchema = z38.tuple([z38.number(), z38.number(), z38.number(), z38.number()]);
102418
+ aspectCropSchema = z38.object({
102419
+ aspect: z38.preprocess((value) => value == null ? void 0 : value, z38.string().optional()),
102420
+ rect: z38.preprocess((value) => value == null ? void 0 : value, rectSchema.optional()),
102421
+ hotspot: z38.preprocess((value) => value == null ? void 0 : value, hotspotSchema.optional()),
102422
+ rotation: z38.preprocess((value) => value == null ? void 0 : value, rotationSchema.optional())
102423
+ });
102424
+ transformSchema = z38.object({
102425
+ aspectCrops: z38.preprocess((value) => {
102195
102426
  if (!value || typeof value !== "object" || Array.isArray(value)) {
102196
102427
  return void 0;
102197
102428
  }
102198
102429
  return value;
102199
- }, z37.record(z37.string(), aspectCropSchema.catch({}))).optional(),
102430
+ }, z38.record(z38.string(), aspectCropSchema.catch({}))).optional(),
102200
102431
  rect: rectSchema.optional(),
102201
102432
  hotspot: hotspotSchema.optional(),
102202
102433
  rotation: rotationSchema.optional()
102203
102434
  });
102204
- mediaSchema = z37.object({
102205
- type: z37.enum(["image", "video", "audio", "document", "spreadsheet", "archive"]),
102206
- purpose: z37.string().optional(),
102207
- placeholder: z37.boolean().default(true).optional(),
102208
- assetId: z37.string().optional(),
102209
- identifier: z37.string().optional(),
102210
- src: z37.string().optional(),
102211
- alt: z37.string().optional(),
102212
- filename: z37.string().optional(),
102213
- mimeType: z37.string().optional(),
102214
- width: z37.number().optional(),
102215
- height: z37.number().optional(),
102216
- storageBucket: z37.string().optional(),
102217
- storagePath: z37.string().optional(),
102435
+ mediaSchema = z38.object({
102436
+ type: z38.enum(["image", "video", "audio", "document", "spreadsheet", "archive"]),
102437
+ purpose: z38.string().optional(),
102438
+ placeholder: z38.boolean().default(true).optional(),
102439
+ assetId: z38.string().optional(),
102440
+ identifier: z38.string().optional(),
102441
+ src: z38.string().optional(),
102442
+ alt: z38.string().optional(),
102443
+ filename: z38.string().optional(),
102444
+ mimeType: z38.string().optional(),
102445
+ width: z38.number().optional(),
102446
+ height: z38.number().optional(),
102447
+ storageBucket: z38.string().optional(),
102448
+ storagePath: z38.string().optional(),
102218
102449
  transform: transformSchema.optional()
102219
102450
  });
102220
102451
  }
@@ -106800,7 +107031,7 @@ function compileContainerStyles(contentFrame, rules) {
106800
107031
  })
106801
107032
  };
106802
107033
  default:
106803
- return assertNever5(contentFrame);
107034
+ return assertNever6(contentFrame);
106804
107035
  }
106805
107036
  }
106806
107037
  function compileBlockRuntimeFields(input) {
@@ -107184,8 +107415,8 @@ var init_generatedDesignPipeline = __esm({
107184
107415
  }
107185
107416
  });
107186
107417
  function validateBlockSequence(snapshots, ctx) {
107187
- for (const issue of collectBlockSequenceIssues(snapshots)) {
107188
- ctx.addIssue(issue);
107418
+ for (const issue2 of collectBlockSequenceIssues(snapshots)) {
107419
+ ctx.addIssue(issue2);
107189
107420
  }
107190
107421
  }
107191
107422
  function collectBlockSequenceIssues(snapshots) {
@@ -113741,9 +113972,9 @@ function createZodCodec(schema) {
113741
113972
  return decodeSuccess(parsed.data);
113742
113973
  }
113743
113974
  return decodeFailure(
113744
- parsed.error.issues.map((issue) => ({
113745
- path: zodIssuePath(issue.path),
113746
- message: issue.message
113975
+ parsed.error.issues.map((issue2) => ({
113976
+ path: zodIssuePath(issue2.path),
113977
+ message: issue2.message
113747
113978
  }))
113748
113979
  );
113749
113980
  }
@@ -114151,7 +114382,7 @@ function getNavStyleClasses(navStyle) {
114151
114382
  return baseClasses;
114152
114383
  }
114153
114384
  }
114154
- function isPlainObject3(value) {
114385
+ function isPlainObject4(value) {
114155
114386
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
114156
114387
  }
114157
114388
  function readString(obj, key) {
@@ -114279,7 +114510,7 @@ var init_ui = __esm({
114279
114510
  summary: "Resolve hero content wrapper className from alignment + max width controls",
114280
114511
  schema: heroContentWrapperClassSchema,
114281
114512
  run: (value, options, context) => {
114282
- const content = isPlainObject3(value) ? value : isPlainObject3(context.data) ? context.data : {};
114513
+ const content = isPlainObject4(value) ? value : isPlainObject4(context.data) ? context.data : {};
114283
114514
  const alignment = resolveHeroContentAlignment(content);
114284
114515
  const maxWidth = resolveHeroContentMaxWidth(content);
114285
114516
  const textAlignClass = alignment === "center" ? "rb-text-center" : alignment === "right" ? "rb-text-right" : "rb-text-left";
@@ -114298,7 +114529,7 @@ var init_ui = __esm({
114298
114529
  kind: "string",
114299
114530
  summary: "Map hero contentAlignment to CTA row justify value",
114300
114531
  run: (value, _options, context) => {
114301
- const content = isPlainObject3(value) ? value : isPlainObject3(context.data) ? context.data : {};
114532
+ const content = isPlainObject4(value) ? value : isPlainObject4(context.data) ? context.data : {};
114302
114533
  const alignment = resolveHeroContentAlignment(content);
114303
114534
  return alignment === "left" ? "start" : alignment === "right" ? "end" : "center";
114304
114535
  }
@@ -114308,7 +114539,7 @@ var init_ui = __esm({
114308
114539
  kind: "string",
114309
114540
  summary: "Map hero verticalAlignment to stack justify value",
114310
114541
  run: (value, _options, context) => {
114311
- const content = isPlainObject3(value) ? value : isPlainObject3(context.data) ? context.data : {};
114542
+ const content = isPlainObject4(value) ? value : isPlainObject4(context.data) ? context.data : {};
114312
114543
  const vertical = resolveHeroVerticalAlignment(content);
114313
114544
  return vertical === "top" ? "start" : vertical === "bottom" ? "end" : "center";
114314
114545
  }
@@ -114322,7 +114553,7 @@ var init_ui = __esm({
114322
114553
  summary: "Append align-items class for hero split layouts based on verticalAlignment",
114323
114554
  schema: heroGridClassFromVerticalAlignmentSchema,
114324
114555
  run: (value, options, context) => {
114325
- const content = isPlainObject3(value) ? value : isPlainObject3(context.data) ? context.data : {};
114556
+ const content = isPlainObject4(value) ? value : isPlainObject4(context.data) ? context.data : {};
114326
114557
  const vertical = resolveHeroVerticalAlignment(content);
114327
114558
  const itemsClass = vertical === "top" ? "rb-items-start" : vertical === "bottom" ? "rb-items-end" : "rb-items-center";
114328
114559
  return joinClasses3([options.base, itemsClass]);
@@ -115202,6 +115433,18 @@ var init_media2 = __esm({
115202
115433
  mediaTransforms = [mediaFromUrl];
115203
115434
  }
115204
115435
  });
115436
+
115437
+ // ../blocks/src/lib/typeGuards.ts
115438
+ function isRecord5(value) {
115439
+ return typeof value === "object" && value !== null && !Array.isArray(value);
115440
+ }
115441
+ function isObjectRecord2(value) {
115442
+ return typeof value === "object" && value !== null;
115443
+ }
115444
+ var init_typeGuards2 = __esm({
115445
+ "../blocks/src/lib/typeGuards.ts"() {
115446
+ }
115447
+ });
115205
115448
  function getSiteName(context) {
115206
115449
  const viewModel = context.viewModel;
115207
115450
  if (!isRecord5(viewModel)) return null;
@@ -117286,52 +117529,52 @@ var init_media3 = __esm({
117286
117529
  "audio",
117287
117530
  "video"
117288
117531
  ];
117289
- hotspotSchema2 = z37.object({
117290
- x: z37.number().min(0).max(1),
117291
- y: z37.number().min(0).max(1),
117292
- radius: z37.number().optional()
117293
- });
117294
- rotationSchema2 = z37.union([z37.literal(0), z37.literal(90), z37.literal(180), z37.literal(270)]);
117295
- rectSchema2 = z37.tuple([z37.number(), z37.number(), z37.number(), z37.number()]);
117296
- aspectCropSchema2 = z37.object({
117297
- aspect: z37.preprocess((value) => value == null ? void 0 : value, z37.string().optional()),
117298
- rect: z37.preprocess((value) => value == null ? void 0 : value, rectSchema2.optional()),
117299
- hotspot: z37.preprocess((value) => value == null ? void 0 : value, hotspotSchema2.optional()),
117300
- rotation: z37.preprocess((value) => value == null ? void 0 : value, rotationSchema2.optional())
117301
- });
117302
- transformSchema2 = z37.object({
117303
- aspectCrops: z37.preprocess((value) => {
117532
+ hotspotSchema2 = z38.object({
117533
+ x: z38.number().min(0).max(1),
117534
+ y: z38.number().min(0).max(1),
117535
+ radius: z38.number().optional()
117536
+ });
117537
+ rotationSchema2 = z38.union([z38.literal(0), z38.literal(90), z38.literal(180), z38.literal(270)]);
117538
+ rectSchema2 = z38.tuple([z38.number(), z38.number(), z38.number(), z38.number()]);
117539
+ aspectCropSchema2 = z38.object({
117540
+ aspect: z38.preprocess((value) => value == null ? void 0 : value, z38.string().optional()),
117541
+ rect: z38.preprocess((value) => value == null ? void 0 : value, rectSchema2.optional()),
117542
+ hotspot: z38.preprocess((value) => value == null ? void 0 : value, hotspotSchema2.optional()),
117543
+ rotation: z38.preprocess((value) => value == null ? void 0 : value, rotationSchema2.optional())
117544
+ });
117545
+ transformSchema2 = z38.object({
117546
+ aspectCrops: z38.preprocess((value) => {
117304
117547
  if (!value || typeof value !== "object" || Array.isArray(value)) {
117305
117548
  return void 0;
117306
117549
  }
117307
117550
  return value;
117308
- }, z37.record(z37.string(), aspectCropSchema2.catch({}))).optional(),
117551
+ }, z38.record(z38.string(), aspectCropSchema2.catch({}))).optional(),
117309
117552
  rect: rectSchema2.optional(),
117310
117553
  hotspot: hotspotSchema2.optional(),
117311
117554
  rotation: rotationSchema2.optional()
117312
117555
  });
117313
- mediaBaseSchema = z37.object({
117314
- purpose: z37.string().optional(),
117315
- placeholder: z37.boolean().default(true).optional(),
117316
- assetId: z37.string().optional(),
117317
- identifier: z37.string().optional(),
117318
- src: z37.string().optional(),
117319
- alt: z37.string().optional(),
117320
- filename: z37.string().optional(),
117321
- mimeType: z37.string().optional(),
117322
- width: z37.number().optional(),
117323
- height: z37.number().optional(),
117324
- storageBucket: z37.string().optional(),
117325
- storagePath: z37.string().optional(),
117556
+ mediaBaseSchema = z38.object({
117557
+ purpose: z38.string().optional(),
117558
+ placeholder: z38.boolean().default(true).optional(),
117559
+ assetId: z38.string().optional(),
117560
+ identifier: z38.string().optional(),
117561
+ src: z38.string().optional(),
117562
+ alt: z38.string().optional(),
117563
+ filename: z38.string().optional(),
117564
+ mimeType: z38.string().optional(),
117565
+ width: z38.number().optional(),
117566
+ height: z38.number().optional(),
117567
+ storageBucket: z38.string().optional(),
117568
+ storagePath: z38.string().optional(),
117326
117569
  transform: transformSchema2.optional()
117327
117570
  });
117328
- imageMediaSchema = mediaBaseSchema.extend({ type: z37.literal("image") });
117329
- videoMediaSchema = mediaBaseSchema.extend({ type: z37.literal("video") });
117330
- audioMediaSchema = mediaBaseSchema.extend({ type: z37.literal("audio") });
117331
- documentMediaSchema = mediaBaseSchema.extend({ type: z37.literal("document") });
117332
- spreadsheetMediaSchema = mediaBaseSchema.extend({ type: z37.literal("spreadsheet") });
117333
- archiveMediaSchema = mediaBaseSchema.extend({ type: z37.literal("archive") });
117334
- mediaSchema2 = z37.discriminatedUnion("type", [
117571
+ imageMediaSchema = mediaBaseSchema.extend({ type: z38.literal("image") });
117572
+ videoMediaSchema = mediaBaseSchema.extend({ type: z38.literal("video") });
117573
+ audioMediaSchema = mediaBaseSchema.extend({ type: z38.literal("audio") });
117574
+ documentMediaSchema = mediaBaseSchema.extend({ type: z38.literal("document") });
117575
+ spreadsheetMediaSchema = mediaBaseSchema.extend({ type: z38.literal("spreadsheet") });
117576
+ archiveMediaSchema = mediaBaseSchema.extend({ type: z38.literal("archive") });
117577
+ mediaSchema2 = z38.discriminatedUnion("type", [
117335
117578
  imageMediaSchema,
117336
117579
  videoMediaSchema,
117337
117580
  audioMediaSchema,
@@ -123749,7 +123992,7 @@ var init_shared8 = __esm({
123749
123992
  });
123750
123993
 
123751
123994
  // ../blocks/src/system/runtime/api/creditProducts.ts
123752
- function assertNever6(value) {
123995
+ function assertNever7(value) {
123753
123996
  throw new Error(`Unhandled credit product case: ${String(value)}`);
123754
123997
  }
123755
123998
  function useCasesFromModules(modules) {
@@ -123782,7 +124025,7 @@ function getCreditProductCreditUnit(useCase) {
123782
124025
  perCreditSuffix: "credit"
123783
124026
  };
123784
124027
  default:
123785
- return assertNever6(useCase);
124028
+ return assertNever7(useCase);
123786
124029
  }
123787
124030
  }
123788
124031
  function deriveCreditProductLabels(products, options = {}) {
@@ -129075,7 +129318,7 @@ function okWith(data) {
129075
129318
  function err2(error) {
129076
129319
  return { ok: false, error };
129077
129320
  }
129078
- function assertNever7(value, message2) {
129321
+ function assertNever8(value, message2) {
129079
129322
  throw new Error(`Unexpected value: ${String(value)}`);
129080
129323
  }
129081
129324
  var init_dist88 = __esm({
@@ -129220,7 +129463,7 @@ function deriveBookingFormViewState(input) {
129220
129463
  resourceName: input.verificationState.resourceName
129221
129464
  };
129222
129465
  default:
129223
- return assertNever7(input.verificationState);
129466
+ return assertNever8(input.verificationState);
129224
129467
  }
129225
129468
  }
129226
129469
  function resolveBookingSiteId(siteId, form2) {
@@ -129303,7 +129546,7 @@ function getBookingServicePaymentSelectionMode(service) {
129303
129546
  case "flexible_balance":
129304
129547
  return "implicit_flexible_balance";
129305
129548
  default:
129306
- return assertNever7(onlyKind);
129549
+ return assertNever8(onlyKind);
129307
129550
  }
129308
129551
  }
129309
129552
  if (allowedKinds.length === 2 && allowedKinds.includes("upfront") && (allowedKinds.includes("deferred_manual") || allowedKinds.includes("instalment_plan") || allowedKinds.includes("flexible_balance"))) {
@@ -129505,7 +129748,7 @@ function formatBookingSubmissionPreparationError(error) {
129505
129748
  case "service-missing-duration":
129506
129749
  return `Service "${error.serviceTitle}" is missing duration. Please update the service in the dashboard to include a duration (e.g., 30 minutes).`;
129507
129750
  default:
129508
- return assertNever7(error);
129751
+ return assertNever8(error);
129509
129752
  }
129510
129753
  }
129511
129754
  function getBookingSuccessMessage(successMessage) {
@@ -132637,7 +132880,7 @@ function readFromSource(source, segments) {
132637
132880
  return void 0;
132638
132881
  }, source);
132639
132882
  }
132640
- function isPlainObject4(value) {
132883
+ function isPlainObject5(value) {
132641
132884
  return typeof value === "object" && value !== null && !Array.isArray(value);
132642
132885
  }
132643
132886
  function parseRouteEntry(routeId, value) {
@@ -132647,35 +132890,35 @@ function parseRouteEntry(routeId, value) {
132647
132890
  if (typeof value === "string") {
132648
132891
  return [routeId, value];
132649
132892
  }
132650
- if (isPlainObject4(value)) {
132893
+ if (isPlainObject5(value)) {
132651
132894
  return [routeId, value];
132652
132895
  }
132653
132896
  return null;
132654
132897
  }
132655
132898
  function extractRouteMapFromViewModel(viewModel) {
132656
- if (!isPlainObject4(viewModel)) return void 0;
132899
+ if (!isPlainObject5(viewModel)) return void 0;
132657
132900
  const root = viewModel.$root;
132658
- if (!isPlainObject4(root)) return void 0;
132901
+ if (!isPlainObject5(root)) return void 0;
132659
132902
  const routes = root.routes;
132660
- if (!isPlainObject4(routes)) return void 0;
132903
+ if (!isPlainObject5(routes)) return void 0;
132661
132904
  const entries = Object.entries(routes).map(([routeId, value]) => parseRouteEntry(routeId, value)).filter((entry) => entry !== null);
132662
132905
  if (entries.length === 0) return void 0;
132663
132906
  return Object.fromEntries(entries);
132664
132907
  }
132665
132908
  function extractPagesByIdentifierFromViewModel(viewModel) {
132666
- if (!isPlainObject4(viewModel)) return void 0;
132909
+ if (!isPlainObject5(viewModel)) return void 0;
132667
132910
  const root = viewModel.$root;
132668
- if (!isPlainObject4(root)) return void 0;
132911
+ if (!isPlainObject5(root)) return void 0;
132669
132912
  const pagesByIdentifier = root.pagesByIdentifier;
132670
- if (!isPlainObject4(pagesByIdentifier)) return void 0;
132913
+ if (!isPlainObject5(pagesByIdentifier)) return void 0;
132671
132914
  return pagesByIdentifier;
132672
132915
  }
132673
132916
  function extractEntriesByIdentifierFromViewModel(viewModel) {
132674
- if (!isPlainObject4(viewModel)) return void 0;
132917
+ if (!isPlainObject5(viewModel)) return void 0;
132675
132918
  const root = viewModel.$root;
132676
- if (!isPlainObject4(root)) return void 0;
132919
+ if (!isPlainObject5(root)) return void 0;
132677
132920
  const entriesByIdentifier = root.entriesByIdentifier;
132678
- if (!isPlainObject4(entriesByIdentifier)) return void 0;
132921
+ if (!isPlainObject5(entriesByIdentifier)) return void 0;
132679
132922
  return entriesByIdentifier;
132680
132923
  }
132681
132924
  function parseBinding(raw, origin) {
@@ -132691,7 +132934,7 @@ function applyTransformsAndFallback(value, binding, context) {
132691
132934
  const routeMap = context.routes ?? extractRouteMapFromViewModel(context.viewModel);
132692
132935
  const pagesByIdentifier = context.pagesByIdentifier ?? extractPagesByIdentifierFromViewModel(context.viewModel);
132693
132936
  const entriesByIdentifier = context.entriesByIdentifier ?? extractEntriesByIdentifierFromViewModel(context.viewModel);
132694
- const root = isPlainObject4(context.viewModel.$root) ? context.viewModel.$root : null;
132937
+ const root = isPlainObject5(context.viewModel.$root) ? context.viewModel.$root : null;
132695
132938
  const stage = root?.previewStage === "preview" ? "preview" : "published";
132696
132939
  const transformed = runTransforms(
132697
132940
  value,
@@ -132728,21 +132971,21 @@ function resolveTransformData(context, bindingPath) {
132728
132971
  const [first2] = segments;
132729
132972
  if (typeof first2 === "string" && first2 !== "$root") {
132730
132973
  const namedScope = context.scopes.find((entry) => entry.name === first2);
132731
- if (namedScope && isPlainObject4(namedScope.value)) {
132974
+ if (namedScope && isPlainObject5(namedScope.value)) {
132732
132975
  return namedScope.value;
132733
132976
  }
132734
132977
  }
132735
132978
  for (let i2 = context.scopes.length - 1; i2 >= 0; i2 -= 1) {
132736
132979
  const scope = context.scopes[i2];
132737
- if (scope && isPlainObject4(scope.value)) {
132980
+ if (scope && isPlainObject5(scope.value)) {
132738
132981
  return scope.value;
132739
132982
  }
132740
132983
  }
132741
132984
  const content = context.viewModel.content;
132742
- if (isPlainObject4(content)) {
132985
+ if (isPlainObject5(content)) {
132743
132986
  return content;
132744
132987
  }
132745
- if (isPlainObject4(context.viewModel)) {
132988
+ if (isPlainObject5(context.viewModel)) {
132746
132989
  return context.viewModel;
132747
132990
  }
132748
132991
  return void 0;
@@ -132877,7 +133120,7 @@ function getNestedBinding(bindings, path) {
132877
133120
  const segments = path.split(".");
132878
133121
  let current = bindings;
132879
133122
  for (const segment of segments) {
132880
- if (!isPlainObject4(current)) return void 0;
133123
+ if (!isPlainObject5(current)) return void 0;
132881
133124
  current = current[segment];
132882
133125
  }
132883
133126
  return current;
@@ -132891,7 +133134,7 @@ function resolveBindingToEditorPath(fieldName, bindings, editableRouteMetadataFi
132891
133134
  };
132892
133135
  const binding = bindings[fieldName] ?? getNestedBinding(bindings, fieldName);
132893
133136
  if (!binding) return null;
132894
- if (isPlainObject4(binding) && "source" in binding) {
133137
+ if (isPlainObject5(binding) && "source" in binding) {
132895
133138
  const source = binding.source;
132896
133139
  if (source === "field" && "path" in binding) {
132897
133140
  const path = binding.path;
@@ -132910,7 +133153,7 @@ function resolveBindingToEditorPath(fieldName, bindings, editableRouteMetadataFi
132910
133153
  if (typeof option === "string") {
132911
133154
  return `content.${option}`;
132912
133155
  }
132913
- if (isPlainObject4(option) && "source" in option) {
133156
+ if (isPlainObject5(option) && "source" in option) {
132914
133157
  const optSource = option.source;
132915
133158
  if (optSource === "field" && "path" in option) {
132916
133159
  const path = option.path;
@@ -132955,7 +133198,7 @@ function injectEditorPath(props2, node, parsedBinding, context) {
132955
133198
  }
132956
133199
  }
132957
133200
  const root = context.viewModel?.$root;
132958
- const isEntryTemplatePage = isPlainObject4(root) && root.contentEntry != null;
133201
+ const isEntryTemplatePage = isPlainObject5(root) && root.contentEntry != null;
132959
133202
  if (isEntryTemplatePage && context.pathBase) return props2;
132960
133203
  const prefix = context.pathBase ?? "";
132961
133204
  const injectedPath = `${prefix}${fieldPath}`;
@@ -132984,7 +133227,7 @@ function injectMediaSlotPath(props2, node, parsedBinding, context) {
132984
133227
  if (entryPath) return props2;
132985
133228
  }
132986
133229
  const root = context.viewModel?.$root;
132987
- const isEntryTemplatePage = isPlainObject4(root) && root.contentEntry != null;
133230
+ const isEntryTemplatePage = isPlainObject5(root) && root.contentEntry != null;
132988
133231
  if (isEntryTemplatePage && context.pathBase) return props2;
132989
133232
  return {
132990
133233
  ...props2,
@@ -133088,7 +133331,7 @@ function getNodeProps(node) {
133088
133331
  if (key.startsWith("$")) continue;
133089
133332
  legacy[key] = value;
133090
133333
  }
133091
- const props2 = isPlainObject4(node.props) ? node.props : {};
133334
+ const props2 = isPlainObject5(node.props) ? node.props : {};
133092
133335
  return { ...legacy, ...props2 };
133093
133336
  }
133094
133337
  function resolveTree(node, options) {
@@ -133155,14 +133398,14 @@ var init_runtime2 = __esm({
133155
133398
  });
133156
133399
 
133157
133400
  // ../theme-core/src/blockOverrides.ts
133158
- function isPlainObject5(value) {
133401
+ function isPlainObject6(value) {
133159
133402
  return typeof value === "object" && value !== null && !Array.isArray(value);
133160
133403
  }
133161
133404
  function cloneValue(value) {
133162
133405
  if (Array.isArray(value)) {
133163
133406
  return value.map((item) => cloneValue(item));
133164
133407
  }
133165
- if (isPlainObject5(value)) {
133408
+ if (isPlainObject6(value)) {
133166
133409
  const cloned = {};
133167
133410
  for (const [key, child] of Object.entries(value)) {
133168
133411
  cloned[key] = cloneValue(child);
@@ -133178,7 +133421,7 @@ function mergeDeep2(defaultValue2, overrideValue) {
133178
133421
  if (overrideValue === null) {
133179
133422
  return null;
133180
133423
  }
133181
- if (isPlainObject5(defaultValue2) && isPlainObject5(overrideValue)) {
133424
+ if (isPlainObject6(defaultValue2) && isPlainObject6(overrideValue)) {
133182
133425
  const merged = {};
133183
133426
  const keys2 = /* @__PURE__ */ new Set([...Object.keys(defaultValue2), ...Object.keys(overrideValue)]);
133184
133427
  for (const key of keys2) {
@@ -133370,12 +133613,6 @@ var init_ai = __esm({
133370
133613
  }
133371
133614
  });
133372
133615
 
133373
- // ../blocks/src/system/types/link.ts
133374
- var init_link2 = __esm({
133375
- "../blocks/src/system/types/link.ts"() {
133376
- }
133377
- });
133378
-
133379
133616
  // ../blocks/src/system/index.ts
133380
133617
  var init_system = __esm({
133381
133618
  "../blocks/src/system/index.ts"() {
@@ -137473,7 +137710,7 @@ function resolveBlockData({
137473
137710
  }
137474
137711
  function getRenderableContent(block) {
137475
137712
  const source = block.draftContent ?? block.content ?? {};
137476
- if (!isObjectRecord(source)) {
137713
+ if (!isObjectRecord2(source)) {
137477
137714
  return {};
137478
137715
  }
137479
137716
  return source;
@@ -137492,8 +137729,8 @@ function summarizeValue(value) {
137492
137729
  for (const k of keys2.slice(0, 8)) {
137493
137730
  const v2 = rec[k];
137494
137731
  if (k === "body" || k === "content") {
137495
- const isDocWrapper = !!(v2 && typeof v2 === "object" && isObjectRecord(v2) && "doc" in v2);
137496
- const isDoc = !!(v2 && typeof v2 === "object" && isObjectRecord(v2) && v2.type === "doc");
137732
+ const isDocWrapper = !!(v2 && typeof v2 === "object" && isObjectRecord2(v2) && "doc" in v2);
137733
+ const isDoc = !!(v2 && typeof v2 === "object" && isObjectRecord2(v2) && v2.type === "doc");
137497
137734
  preview[k] = isDocWrapper ? "{doc}" : isDoc ? "{type:doc}" : summarizeValue(v2);
137498
137735
  } else {
137499
137736
  preview[k] = summarizeValue(v2);
@@ -139372,25 +139609,25 @@ var init_Button2 = __esm({
139372
139609
  var BlockKind, blockSchema, pagePath;
139373
139610
  var init_schema5 = __esm({
139374
139611
  "../blocks/src/structure/schema.ts"() {
139375
- BlockKind = z37.string();
139376
- blockSchema = z37.object({
139377
- id: z37.string().nullable(),
139612
+ BlockKind = z38.string();
139613
+ blockSchema = z38.object({
139614
+ id: z38.string().nullable(),
139378
139615
  // optional ID for reference in toggle ops
139379
139616
  kind: BlockKind,
139380
- purpose: z37.string().min(1),
139617
+ purpose: z38.string().min(1),
139381
139618
  // Optional content fields used by PageRenderer / block runtime.
139382
- content: z37.record(z37.string(), z37.unknown()).optional(),
139619
+ content: z38.record(z38.string(), z38.unknown()).optional(),
139383
139620
  // Nullable because some persisted sources store "no draft" as null.
139384
- draftContent: z37.record(z37.string(), z37.unknown()).nullable().optional(),
139621
+ draftContent: z38.record(z38.string(), z38.unknown()).nullable().optional(),
139385
139622
  // Optional template bindings for reverse field mapping (entry editing)
139386
- bindings: z37.record(z37.string(), z37.unknown()).optional()
139623
+ bindings: z38.record(z38.string(), z38.unknown()).optional()
139387
139624
  }).passthrough();
139388
- pagePath = z37.string().regex(/^\/[\S]*$/, 'path must start with "/" and contain no spaces');
139389
- z37.object({
139390
- name: z37.string().min(1),
139625
+ pagePath = z38.string().regex(/^\/[\S]*$/, 'path must start with "/" and contain no spaces');
139626
+ z38.object({
139627
+ name: z38.string().min(1),
139391
139628
  path: pagePath,
139392
- purpose: z37.string().min(1),
139393
- blocks: z37.array(blockSchema).min(1)
139629
+ purpose: z38.string().min(1),
139630
+ blocks: z38.array(blockSchema).min(1)
139394
139631
  });
139395
139632
  }
139396
139633
  });
@@ -148782,6 +149019,7 @@ var init_src6 = __esm({
148782
149019
  init_buildThemeRuntimeFromBridge();
148783
149020
  init_blocks4();
148784
149021
  init_system();
149022
+ init_link2();
148785
149023
  init_validation();
148786
149024
  init_primitives();
148787
149025
  init_media4();
@@ -148832,10 +149070,10 @@ function deriveBlockDraftSaveability(input) {
148832
149070
  issues
148833
149071
  };
148834
149072
  }
148835
- function withNormalizedManifestMessage(issue) {
149073
+ function withNormalizedManifestMessage(issue2) {
148836
149074
  return {
148837
- ...issue,
148838
- message: normalizeManifestIssueMessage(issue)
149075
+ ...issue2,
149076
+ message: normalizeManifestIssueMessage(issue2)
148839
149077
  };
148840
149078
  }
148841
149079
  function validateBlockManifestIssues(manifest, values, mode) {
@@ -148847,31 +149085,31 @@ function validateBlockManifestIssues(manifest, values, mode) {
148847
149085
  return result.error.issues.map(withNormalizedManifestMessage);
148848
149086
  }
148849
149087
  function validateBlockManifest(manifest, values, mode) {
148850
- return validateBlockManifestIssues(manifest, values, mode).map((issue) => {
148851
- const path = normalizeIssuePath(issue.path);
149088
+ return validateBlockManifestIssues(manifest, values, mode).map((issue2) => {
149089
+ const path = normalizeIssuePath(issue2.path);
148852
149090
  return {
148853
- code: issue.code,
149091
+ code: issue2.code,
148854
149092
  path,
148855
149093
  fieldPath: normalizePathString(path),
148856
- message: issue.message
149094
+ message: issue2.message
148857
149095
  };
148858
149096
  });
148859
149097
  }
148860
- function normalizeManifestIssueMessage(issue) {
148861
- switch (issue.code) {
149098
+ function normalizeManifestIssueMessage(issue2) {
149099
+ switch (issue2.code) {
148862
149100
  case "invalid_type":
148863
- return issue.message;
149101
+ return issue2.message;
148864
149102
  case "too_big":
148865
- return issue.origin === "string" ? `Use ${issue.maximum} characters or fewer` : issue.message;
149103
+ return issue2.origin === "string" ? `Use ${issue2.maximum} characters or fewer` : issue2.message;
148866
149104
  case "too_small":
148867
- if (issue.origin !== "string") return issue.message;
148868
- return issue.minimum === 1 ? "This field is required" : `Use at least ${issue.minimum} characters`;
149105
+ if (issue2.origin !== "string") return issue2.message;
149106
+ return issue2.minimum === 1 ? "This field is required" : `Use at least ${issue2.minimum} characters`;
148869
149107
  case "invalid_format":
148870
- if (issue.format === "email") return "Enter a valid email address";
148871
- if (issue.format === "url") return "Enter a valid web address";
149108
+ if (issue2.format === "email") return "Enter a valid email address";
149109
+ if (issue2.format === "url") return "Enter a valid web address";
148872
149110
  return "Check the format and try again";
148873
149111
  default:
148874
- return issue.message;
149112
+ return issue2.message;
148875
149113
  }
148876
149114
  }
148877
149115
  function getManifestValidation(manifest, mode) {
@@ -149026,16 +149264,16 @@ function validateAllBlocks(uiStore) {
149026
149264
  }
149027
149265
  const issues = validateBlockManifest(definition.manifest, content, "strict");
149028
149266
  if (issues.length > 0) {
149029
- for (const issue of issues) {
149267
+ for (const issue2 of issues) {
149030
149268
  errors.push({
149031
149269
  blockId: snapshot2.id,
149032
149270
  blockKind: snapshot2.meta.kind,
149033
- fieldPath: issue.fieldPath,
149271
+ fieldPath: issue2.fieldPath,
149034
149272
  fieldLabel: getFieldLabelFromManifest(
149035
149273
  definition.manifest,
149036
- issue.path
149274
+ issue2.path
149037
149275
  ),
149038
- message: issue.message
149276
+ message: issue2.message
149039
149277
  });
149040
149278
  }
149041
149279
  }
@@ -149799,7 +150037,7 @@ var init_extractBlockData = __esm({
149799
150037
  });
149800
150038
 
149801
150039
  // ../content-editor/src/utils/assertNever.ts
149802
- function assertNever8(value, message2) {
150040
+ function assertNever9(value, message2) {
149803
150041
  throw new Error(`Unexpected value: ${String(value)}`);
149804
150042
  }
149805
150043
  var init_assertNever2 = __esm({
@@ -150397,7 +150635,7 @@ function applyEditorCommand(snapshot2, command2) {
150397
150635
  return nextSnapshot;
150398
150636
  }
150399
150637
  default:
150400
- return assertNever8(command2);
150638
+ return assertNever9(command2);
150401
150639
  }
150402
150640
  }
150403
150641
  function applyUserOperation(snapshot2, operation) {
@@ -150469,7 +150707,7 @@ function applySystemOperation(snapshot2, operation) {
150469
150707
  case "replace-block-list":
150470
150708
  return replaceEditorBlockList(snapshot2, operation.next);
150471
150709
  default:
150472
- return assertNever8(operation);
150710
+ return assertNever9(operation);
150473
150711
  }
150474
150712
  }
150475
150713
  function hydrateMetadataSnapshot(snapshot2, baseline, current, published) {
@@ -152239,7 +152477,7 @@ function toDrainFailure(effect, error) {
152239
152477
  case "persist-remove":
152240
152478
  return { kind: effect.type, message: message2 };
152241
152479
  default:
152242
- return assertNever8(effect);
152480
+ return assertNever9(effect);
152243
152481
  }
152244
152482
  }
152245
152483
  async function drainEditorEffect(effect, context) {
@@ -152251,7 +152489,7 @@ async function drainEditorEffect(effect, context) {
152251
152489
  case "persist-remove":
152252
152490
  return drainPersistRemoveEffect(effect, context);
152253
152491
  default:
152254
- return assertNever8(effect);
152492
+ return assertNever9(effect);
152255
152493
  }
152256
152494
  }
152257
152495
  async function drainEditorEffects(effects, context) {
@@ -153311,40 +153549,151 @@ var init_TextField = __esm({
153311
153549
  init_FieldFrame();
153312
153550
  }
153313
153551
  });
153314
- function withTextFieldSharedRules(schema, field) {
153315
- const maxLengthMessage = typeof field.maxLength === "number" ? `${field.label} must be ${field.maxLength} characters or less` : void 0;
153316
- let withRules = schema;
153317
- if (typeof field.maxLength === "number") {
153318
- withRules = withRules.max(field.maxLength, { message: maxLengthMessage });
153552
+
153553
+ // ../block-form/src/widgets/utils/readNumericUiConfig.ts
153554
+ function readNumericInputUiConfig(ui) {
153555
+ if (!ui || typeof ui !== "object") return {};
153556
+ const rec = ui;
153557
+ return {
153558
+ min: typeof rec.min === "number" ? rec.min : void 0,
153559
+ max: typeof rec.max === "number" ? rec.max : void 0,
153560
+ step: typeof rec.step === "number" ? rec.step : void 0
153561
+ };
153562
+ }
153563
+ function readNumberFieldUiConfig(ui) {
153564
+ return readNumericInputUiConfig(ui);
153565
+ }
153566
+ function readSliderFieldUiConfig(ui) {
153567
+ const base2 = readNumericInputUiConfig(ui);
153568
+ if (!ui || typeof ui !== "object") return base2;
153569
+ const rec = ui;
153570
+ return {
153571
+ ...base2,
153572
+ showValue: typeof rec.showValue === "boolean" ? rec.showValue : void 0
153573
+ };
153574
+ }
153575
+ var init_readNumericUiConfig = __esm({
153576
+ "../block-form/src/widgets/utils/readNumericUiConfig.ts"() {
153319
153577
  }
153320
- if (field.required) {
153321
- return withRules.min(1, "This field is required");
153578
+ });
153579
+
153580
+ // ../block-form/src/manifest/canonicalValidation.ts
153581
+ function buildCanonicalFieldSchema(field) {
153582
+ const manifestField = normalizeFieldForCanonicalValidation(field);
153583
+ return fieldPlanToZod(deriveFieldValidationPlan(manifestField), {
153584
+ allowNull: !Boolean(field.required)
153585
+ });
153586
+ }
153587
+ function normalizeFieldForCanonicalValidation(field) {
153588
+ return parseFieldDefinition(toManifestFieldInput(field));
153589
+ }
153590
+ function toManifestFieldInput(field) {
153591
+ switch (field.type) {
153592
+ case "number":
153593
+ return numberFieldToManifestInput(field);
153594
+ case "group":
153595
+ return groupFieldToManifestInput(field);
153596
+ case "modal":
153597
+ return modalFieldToManifestInput(field);
153598
+ case "repeater":
153599
+ return repeaterFieldToManifestInput(field);
153600
+ case "tabGroup":
153601
+ return {
153602
+ ...field,
153603
+ tabs: field.tabs.map((tab) => ({
153604
+ ...tab,
153605
+ fields: tab.fields.map(toManifestFieldInput)
153606
+ }))
153607
+ };
153608
+ case "button":
153609
+ throw new Error("Button fields do not have canonical content validation");
153610
+ case "text":
153611
+ case "richText":
153612
+ case "media":
153613
+ case "boolean":
153614
+ case "date":
153615
+ case "time":
153616
+ case "datetime":
153617
+ case "slug":
153618
+ case "url":
153619
+ case "link":
153620
+ case "select":
153621
+ case "reference":
153622
+ case "presetOrCustom":
153623
+ case "contentTypeSelect":
153624
+ case "entryPicker":
153625
+ return field;
153322
153626
  }
153323
- return withRules.optional().nullable().or(z.literal(""));
153627
+ return assertNever10(field);
153324
153628
  }
153325
- function buildTextFieldSchema(field) {
153326
- const inputType = field.ui?.inputType;
153327
- if (inputType === "email") {
153328
- return withTextFieldSharedRules(z.string().email("Enter a valid email"), field);
153329
- }
153330
- if (inputType === "tel") {
153331
- return withTextFieldSharedRules(
153332
- z.string().regex(/^[+()0-9\s\-]{3,}$/, "Enter a valid phone number"),
153333
- field
153334
- );
153629
+ function numberFieldToManifestInput(field) {
153630
+ const ui = readNumberFieldUiConfig(field.ui);
153631
+ return {
153632
+ ...field,
153633
+ min: field.min ?? ui.min,
153634
+ max: field.max ?? ui.max,
153635
+ step: field.step ?? ui.step
153636
+ };
153637
+ }
153638
+ function groupFieldToManifestInput(field) {
153639
+ return {
153640
+ ...field,
153641
+ schema: {
153642
+ ...field.schema,
153643
+ fields: (field.schema?.fields ?? field.fields).map(toManifestFieldInput)
153644
+ }
153645
+ };
153646
+ }
153647
+ function modalFieldToManifestInput(field) {
153648
+ return {
153649
+ ...field,
153650
+ schema: {
153651
+ ...field.schema,
153652
+ fields: field.schema.fields.map(toManifestFieldInput)
153653
+ }
153654
+ };
153655
+ }
153656
+ function repeaterFieldToManifestInput(field) {
153657
+ if (field.polymorphic) {
153658
+ return {
153659
+ ...field,
153660
+ itemTypes: Object.fromEntries(
153661
+ Object.entries(field.itemTypes).map(([typeId, itemType]) => [
153662
+ typeId,
153663
+ {
153664
+ ...itemType,
153665
+ fields: itemType.fields.map(toManifestFieldInput)
153666
+ }
153667
+ ])
153668
+ )
153669
+ };
153335
153670
  }
153336
- let s2 = z.string();
153337
- if (field.ui?.pattern) {
153338
- try {
153339
- const re2 = new RegExp(field.ui.pattern);
153340
- s2 = s2.regex(re2, { message: `${field.label} is not in the right format` });
153341
- } catch {
153671
+ return {
153672
+ ...field,
153673
+ schema: {
153674
+ ...field.schema,
153675
+ fields: (field.schema?.fields ?? field.fields).map(toManifestFieldInput)
153342
153676
  }
153677
+ };
153678
+ }
153679
+ function assertNever10(value) {
153680
+ throw new Error(`Unhandled field config variant: ${JSON.stringify(value)}`);
153681
+ }
153682
+ var init_canonicalValidation = __esm({
153683
+ "../block-form/src/manifest/canonicalValidation.ts"() {
153684
+ init_fieldValidation();
153685
+ init_schema3();
153686
+ init_readNumericUiConfig();
153343
153687
  }
153344
- return withTextFieldSharedRules(s2, field);
153688
+ });
153689
+
153690
+ // ../block-form/src/widgets/TextField/textFieldSchema.ts
153691
+ function buildTextFieldSchema(field) {
153692
+ return buildCanonicalFieldSchema(field);
153345
153693
  }
153346
153694
  var init_textFieldSchema = __esm({
153347
153695
  "../block-form/src/widgets/TextField/textFieldSchema.ts"() {
153696
+ init_canonicalValidation();
153348
153697
  }
153349
153698
  });
153350
153699
 
@@ -153369,33 +153718,6 @@ var init_TextField2 = __esm({
153369
153718
  init_TextField();
153370
153719
  }
153371
153720
  });
153372
-
153373
- // ../block-form/src/widgets/utils/readNumericUiConfig.ts
153374
- function readNumericInputUiConfig(ui) {
153375
- if (!ui || typeof ui !== "object") return {};
153376
- const rec = ui;
153377
- return {
153378
- min: typeof rec.min === "number" ? rec.min : void 0,
153379
- max: typeof rec.max === "number" ? rec.max : void 0,
153380
- step: typeof rec.step === "number" ? rec.step : void 0
153381
- };
153382
- }
153383
- function readNumberFieldUiConfig(ui) {
153384
- return readNumericInputUiConfig(ui);
153385
- }
153386
- function readSliderFieldUiConfig(ui) {
153387
- const base2 = readNumericInputUiConfig(ui);
153388
- if (!ui || typeof ui !== "object") return base2;
153389
- const rec = ui;
153390
- return {
153391
- ...base2,
153392
- showValue: typeof rec.showValue === "boolean" ? rec.showValue : void 0
153393
- };
153394
- }
153395
- var init_readNumericUiConfig = __esm({
153396
- "../block-form/src/widgets/utils/readNumericUiConfig.ts"() {
153397
- }
153398
- });
153399
153721
  function NumberField({ path, backend, config }) {
153400
153722
  const { value, error, setValue } = useField(path, backend);
153401
153723
  const ui = readNumberFieldUiConfig(config.ui);
@@ -153435,44 +153757,14 @@ var init_NumberField = __esm({
153435
153757
  init_readNumericUiConfig();
153436
153758
  }
153437
153759
  });
153760
+
153761
+ // ../block-form/src/widgets/NumberField/numberFieldSchema.ts
153438
153762
  function buildNumberFieldSchema(field) {
153439
- const requiredMessage = "This field is required";
153440
- const numberMessage = `${field.label} needs a number`;
153441
- let numberSchema = z.coerce.number({
153442
- error: (issue) => issue.input === void 0 ? requiredMessage : numberMessage
153443
- });
153444
- if (typeof field.ui?.min === "number") {
153445
- numberSchema = numberSchema.min(field.ui.min, {
153446
- message: `${field.label} must be ${field.ui.min} or more`
153447
- });
153448
- }
153449
- if (typeof field.ui?.max === "number") {
153450
- numberSchema = numberSchema.max(field.ui.max, {
153451
- message: `${field.label} must be ${field.ui.max} or less`
153452
- });
153453
- }
153454
- const emptyToUndefined = (value) => value === "" || value === null ? void 0 : value;
153455
- if (!field.required) {
153456
- return z.preprocess(emptyToUndefined, numberSchema.optional().nullable());
153457
- }
153458
- return z.preprocess(
153459
- emptyToUndefined,
153460
- z.unknown().superRefine((value, ctx) => {
153461
- if (value === void 0) {
153462
- ctx.addIssue({ code: "custom", message: requiredMessage });
153463
- return;
153464
- }
153465
- const parsed = numberSchema.safeParse(value);
153466
- if (!parsed.success) {
153467
- for (const issue of parsed.error.issues) {
153468
- ctx.addIssue({ code: "custom", message: issue.message });
153469
- }
153470
- }
153471
- }).transform((value) => Number(value))
153472
- );
153763
+ return buildCanonicalFieldSchema(field);
153473
153764
  }
153474
153765
  var init_numberFieldSchema = __esm({
153475
153766
  "../block-form/src/widgets/NumberField/numberFieldSchema.ts"() {
153767
+ init_canonicalValidation();
153476
153768
  }
153477
153769
  });
153478
153770
 
@@ -153609,29 +153901,14 @@ var init_SelectField = __esm({
153609
153901
  init_selectValueMapping();
153610
153902
  }
153611
153903
  });
153904
+
153905
+ // ../block-form/src/widgets/SelectField/selectFieldSchema.ts
153612
153906
  function buildSelectFieldSchema(field) {
153613
- const validValues = field.options?.map((opt) => opt.value) ?? [];
153614
- const requiredMessage = "This field is required";
153615
- const invalidOptionMessage = `Choose one of the available options for ${field.label}`;
153616
- if (validValues.length === 0) {
153617
- if (field.multiple) {
153618
- const arr = z.array(z.string());
153619
- return field.required ? arr.min(1, { message: requiredMessage }) : arr.nullable();
153620
- }
153621
- const single = z.string();
153622
- return field.required ? single.min(1, { message: requiredMessage }) : single.nullable();
153623
- }
153624
- const base2 = z.enum(validValues, {
153625
- error: invalidOptionMessage
153626
- });
153627
- if (field.multiple) {
153628
- const arr = z.array(base2);
153629
- return field.required ? arr.min(1, { message: requiredMessage }) : arr.nullable();
153630
- }
153631
- return field.required ? base2 : base2.nullable();
153907
+ return buildCanonicalFieldSchema(field);
153632
153908
  }
153633
153909
  var init_selectFieldSchema = __esm({
153634
153910
  "../block-form/src/widgets/SelectField/selectFieldSchema.ts"() {
153911
+ init_canonicalValidation();
153635
153912
  }
153636
153913
  });
153637
153914
 
@@ -154733,7 +155010,7 @@ function createStoreBackend(options) {
154733
155010
  return issues;
154734
155011
  }
154735
155012
  return issues.filter(
154736
- (issue) => blockValidation.isPathEdited(currentBlockId, issue.path.join("."))
155013
+ (issue2) => blockValidation.isPathEdited(currentBlockId, issue2.path.join("."))
154737
155014
  );
154738
155015
  };
154739
155016
  return {
@@ -154775,7 +155052,7 @@ function createStoreBackend(options) {
154775
155052
  let fieldError;
154776
155053
  if (validateFn) {
154777
155054
  const issues = getVisibleValidationIssues();
154778
- const fieldIssue = issues.find((issue) => issue.path.join(".") === path);
155055
+ const fieldIssue = issues.find((issue2) => issue2.path.join(".") === path);
154779
155056
  if (fieldIssue) {
154780
155057
  fieldError = { message: fieldIssue.message };
154781
155058
  }
@@ -154800,9 +155077,9 @@ function createStoreBackend(options) {
154800
155077
  getErrors: () => {
154801
155078
  const issues = getVisibleValidationIssues();
154802
155079
  const errors = {};
154803
- issues.forEach((issue) => {
154804
- const path = issue.path.join(".");
154805
- errors[path] = { message: issue.message };
155080
+ issues.forEach((issue2) => {
155081
+ const path = issue2.path.join(".");
155082
+ errors[path] = { message: issue2.message };
154806
155083
  });
154807
155084
  return errors;
154808
155085
  },
@@ -154886,9 +155163,9 @@ function createStoreBackend(options) {
154886
155163
  const issues = getValidationIssues();
154887
155164
  const visibleIssues = getVisibleValidationIssues();
154888
155165
  const errors = {};
154889
- visibleIssues.forEach((issue) => {
154890
- const path = issue.path.join(".");
154891
- errors[path] = { message: issue.message };
155166
+ visibleIssues.forEach((issue2) => {
155167
+ const path = issue2.path.join(".");
155168
+ errors[path] = { message: issue2.message };
154892
155169
  });
154893
155170
  return {
154894
155171
  isDirty: isSnapshotDirty(snapshot2),
@@ -154928,12 +155205,6 @@ var init_types22 = __esm({
154928
155205
  }
154929
155206
  });
154930
155207
 
154931
- // ../block-form/src/backend/validation.ts
154932
- var init_validation3 = __esm({
154933
- "../block-form/src/backend/validation.ts"() {
154934
- }
154935
- });
154936
-
154937
155208
  // ../block-form/src/backend/adapter.ts
154938
155209
  var init_adapter = __esm({
154939
155210
  "../block-form/src/backend/adapter.ts"() {
@@ -155018,7 +155289,6 @@ var init_backend = __esm({
155018
155289
  "../block-form/src/backend/index.ts"() {
155019
155290
  init_types22();
155020
155291
  init_hooks();
155021
- init_validation3();
155022
155292
  init_adapter();
155023
155293
  init_useRepeaterBackend();
155024
155294
  }
@@ -156395,7 +156665,7 @@ function ze() {
156395
156665
  /* @__PURE__ */ Te(P)
156396
156666
  );
156397
156667
  }
156398
- function z71(e3) {
156668
+ function z69(e3) {
156399
156669
  if (L2) {
156400
156670
  if (/* @__PURE__ */ Te(P) !== null)
156401
156671
  throw Tt(), Je;
@@ -158424,12 +158694,12 @@ function ha(e3, t3) {
158424
158694
  var mt = we(Dr, 2);
158425
158695
  let Pr;
158426
158696
  var We = X3(mt);
158427
- en(We), We.__change = ui, z71(mt);
158697
+ en(We), We.__change = ui, z69(mt);
158428
158698
  var Ut = we(mt, 2), wi = X3(Ut);
158429
158699
  {
158430
158700
  var pi = (n3) => {
158431
158701
  var u3 = na(), _2 = Gr(u3), y2 = X3(_2);
158432
- Ge(y2, () => c3(re2).verified), z71(_2);
158702
+ Ge(y2, () => c3(re2).verified), z69(_2);
158433
158703
  var T2 = we(_2, 2);
158434
158704
  en(T2), Pe(() => {
158435
158705
  se(T2, "name", V2()), jo(T2, c3(Le));
@@ -158438,10 +158708,10 @@ function ha(e3, t3) {
158438
158708
  {
158439
158709
  var _2 = (T2) => {
158440
158710
  var E = ia(), p2 = X3(E);
158441
- Ge(p2, () => c3(re2).verifying), z71(E), ne(T2, E);
158711
+ Ge(p2, () => c3(re2).verifying), z69(E), ne(T2, E);
158442
158712
  }, y2 = (T2) => {
158443
158713
  var E = oa(), p2 = X3(E);
158444
- Ge(p2, () => c3(re2).label), z71(E), Pe(() => se(E, "for", c3(cr))), ne(T2, E);
158714
+ Ge(p2, () => c3(re2).label), z69(E), Pe(() => se(E, "for", c3(cr))), ne(T2, E);
158445
158715
  };
158446
158716
  $e(
158447
158717
  n3,
@@ -158456,18 +158726,18 @@ function ha(e3, t3) {
158456
158726
  c3(C2) === b2.VERIFIED ? n3(pi) : n3(bi, false);
158457
158727
  });
158458
158728
  }
158459
- z71(Ut);
158729
+ z69(Ut);
158460
158730
  var yi = we(Ut, 2);
158461
158731
  {
158462
158732
  var Ei = (n3) => {
158463
158733
  var u3 = aa(), _2 = X3(u3);
158464
- se(_2, "href", sr), z71(u3), Pe(() => se(_2, "aria-label", c3(re2).ariaLinkLabel)), ne(n3, u3);
158734
+ se(_2, "href", sr), z69(u3), Pe(() => se(_2, "aria-label", c3(re2).ariaLinkLabel)), ne(n3, u3);
158465
158735
  };
158466
158736
  $e(yi, (n3) => {
158467
158737
  (N() !== true || c3(Dt)) && n3(Ei);
158468
158738
  });
158469
158739
  }
158470
- z71(Mt);
158740
+ z69(Mt);
158471
158741
  var Or = we(Mt, 2);
158472
158742
  {
158473
158743
  var xi = (n3) => {
@@ -158475,16 +158745,16 @@ function ha(e3, t3) {
158475
158745
  {
158476
158746
  var y2 = (E) => {
158477
158747
  var p2 = la(), x2 = X3(p2);
158478
- Ge(x2, () => c3(re2).expired), z71(p2), Pe(() => se(p2, "title", c3(He))), ne(E, p2);
158748
+ Ge(x2, () => c3(re2).expired), z69(p2), Pe(() => se(p2, "title", c3(He))), ne(E, p2);
158479
158749
  }, T2 = (E) => {
158480
158750
  var p2 = sa(), x2 = X3(p2);
158481
- Ge(x2, () => c3(re2).error), z71(p2), Pe(() => se(p2, "title", c3(He))), ne(E, p2);
158751
+ Ge(x2, () => c3(re2).error), z69(p2), Pe(() => se(p2, "title", c3(He))), ne(E, p2);
158482
158752
  };
158483
158753
  $e(_2, (E) => {
158484
158754
  c3(C2) === b2.EXPIRED ? E(y2) : E(T2, false);
158485
158755
  });
158486
158756
  }
158487
- z71(u3), ne(n3, u3);
158757
+ z69(u3), ne(n3, u3);
158488
158758
  };
158489
158759
  $e(Or, (n3) => {
158490
158760
  (c3(He) || c3(C2) === b2.EXPIRED) && n3(xi);
@@ -158494,7 +158764,7 @@ function ha(e3, t3) {
158494
158764
  {
158495
158765
  var $i = (n3) => {
158496
158766
  var u3 = ua(), _2 = X3(u3), y2 = X3(_2);
158497
- Ge(y2, () => c3(re2).footer), z71(_2), z71(u3), ne(n3, u3);
158767
+ Ge(y2, () => c3(re2).footer), z69(_2), z69(u3), ne(n3, u3);
158498
158768
  };
158499
158769
  $e(Fr, (n3) => {
158500
158770
  c3(re2).footer && (k() !== true || c3(Dt)) && n3($i);
@@ -158510,7 +158780,7 @@ function ha(e3, t3) {
158510
158780
  v2() && n3(Ci);
158511
158781
  });
158512
158782
  }
158513
- return z71(ot), nn(ot, (n3) => D2(B, n3), () => c3(B)), Pe(
158783
+ return z69(ot), nn(ot, (n3) => D2(B, n3), () => c3(B)), Pe(
158514
158784
  (n3) => {
158515
158785
  se(ot, "data-state", c3(C2)), se(ot, "data-floating", v2()), Pr = Fo(mt, 1, "altcha-checkbox", null, Pr, n3), se(We, "id", c3(cr)), We.required = r4() !== "onsubmit" && (!v2() || r4() !== "off");
158516
158786
  },
@@ -159257,7 +159527,7 @@ function multiStepReducer(state, action) {
159257
159527
  case "reset":
159258
159528
  return createInitialMultiStepState(action.initialData);
159259
159529
  default:
159260
- return assertNever7(action);
159530
+ return assertNever8(action);
159261
159531
  }
159262
159532
  }
159263
159533
  function getVisibleSteps(steps2, data) {
@@ -160116,7 +160386,7 @@ var init_DatePicker = __esm({
160116
160386
  dateOptions,
160117
160387
  required = true,
160118
160388
  isLoading = false,
160119
- isEmpty: isEmpty2 = false,
160389
+ isEmpty = false,
160120
160390
  hasMore = false,
160121
160391
  onLoadMore
160122
160392
  }) => {
@@ -160130,7 +160400,7 @@ var init_DatePicker = __esm({
160130
160400
  /* @__PURE__ */ jsx("p", { className: "ab-text ab-text--muted ab-text--sm", children: "Loading available dates..." })
160131
160401
  ] });
160132
160402
  }
160133
- if (isEmpty2) {
160403
+ if (isEmpty) {
160134
160404
  return /* @__PURE__ */ jsxs("div", { className: "ab-stack--sm", children: [
160135
160405
  /* @__PURE__ */ jsxs("label", { className: "ab-label", children: [
160136
160406
  "Select Date",
@@ -160681,7 +160951,7 @@ function buildBookingPaymentOptionViewModel(input) {
160681
160951
  };
160682
160952
  }
160683
160953
  default:
160684
- return assertNever7(input.option);
160954
+ return assertNever8(input.option);
160685
160955
  }
160686
160956
  }
160687
160957
  function buildInstalmentSchedulePreview(input) {
@@ -160738,7 +161008,7 @@ function buildInstalmentSchedulePreview(input) {
160738
161008
  })));
160739
161009
  }
160740
161010
  default:
160741
- return assertNever7(input.option.plan);
161011
+ return assertNever8(input.option.plan);
160742
161012
  }
160743
161013
  }
160744
161014
  function getPaymentCadenceLabel(plan) {
@@ -161491,7 +161761,7 @@ function pollingReducer(state, action) {
161491
161761
  case "timeout":
161492
161762
  return state;
161493
161763
  default:
161494
- return assertNever7(state);
161764
+ return assertNever8(state);
161495
161765
  }
161496
161766
  case "polling-timed-out":
161497
161767
  return {
@@ -161500,7 +161770,7 @@ function pollingReducer(state, action) {
161500
161770
  error: new Error("Polling timed out")
161501
161771
  };
161502
161772
  default:
161503
- return assertNever7(action);
161773
+ return assertNever8(action);
161504
161774
  }
161505
161775
  }
161506
161776
  var init_usePolling_state = __esm({
@@ -161681,7 +161951,7 @@ function bookingSubmissionReducer(state, action) {
161681
161951
  feedback: { tag: "idle" }
161682
161952
  };
161683
161953
  default:
161684
- return assertNever7(action);
161954
+ return assertNever8(action);
161685
161955
  }
161686
161956
  }
161687
161957
  function selectIsSubmitting2(state) {
@@ -162013,7 +162283,7 @@ function validateFormData(data) {
162013
162283
  return errors;
162014
162284
  }
162015
162285
  var EMAIL_REGEX;
162016
- var init_validation4 = __esm({
162286
+ var init_validation3 = __esm({
162017
162287
  "../blocks/src/system/runtime/shared/utils/validation.ts"() {
162018
162288
  EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
162019
162289
  }
@@ -162037,7 +162307,7 @@ var init_utils11 = __esm({
162037
162307
  init_scrollToBlock();
162038
162308
  init_themePortalRoot();
162039
162309
  init_urlParams();
162040
- init_validation4();
162310
+ init_validation3();
162041
162311
  init_wizardSteps();
162042
162312
  }
162043
162313
  });
@@ -163082,7 +163352,7 @@ function eligibilityLookupReducer(state, action) {
163082
163352
  error: action.message
163083
163353
  };
163084
163354
  default:
163085
- return assertNever7(action);
163355
+ return assertNever8(action);
163086
163356
  }
163087
163357
  }
163088
163358
  function existingRegistrationLookupReducer(state, action) {
@@ -163100,7 +163370,7 @@ function existingRegistrationLookupReducer(state, action) {
163100
163370
  registration: action.registration
163101
163371
  };
163102
163372
  default:
163103
- return assertNever7(action);
163373
+ return assertNever8(action);
163104
163374
  }
163105
163375
  }
163106
163376
  var initialEligibilityLookupState, initialExistingRegistrationLookupState;
@@ -164749,7 +165019,7 @@ function validateFormData2(formData) {
164749
165019
  }
164750
165020
  return errors;
164751
165021
  }
164752
- var init_validation5 = __esm({
165022
+ var init_validation4 = __esm({
164753
165023
  "../blocks/src/system/runtime/nodes/event-registration/validation.ts"() {
164754
165024
  "use client";
164755
165025
  }
@@ -165689,7 +165959,7 @@ var init_useEventRegistrationWizard = __esm({
165689
165959
  "use client";
165690
165960
  init_api();
165691
165961
  init_events2();
165692
- init_validation5();
165962
+ init_validation4();
165693
165963
  init_hooks3();
165694
165964
  init_portalLogout();
165695
165965
  init_useWaitlistClaim();
@@ -168329,7 +168599,7 @@ function shopPassesMembershipsReducer(state, action) {
168329
168599
  returnNotice: null
168330
168600
  };
168331
168601
  default:
168332
- return assertNever7(action);
168602
+ return assertNever8(action);
168333
168603
  }
168334
168604
  }
168335
168605
  function getOpenCheckout(state) {
@@ -169175,7 +169445,7 @@ function shopCheckoutReducer(state, action) {
169175
169445
  notice: action.notice
169176
169446
  };
169177
169447
  default:
169178
- return assertNever7(action);
169448
+ return assertNever8(action);
169179
169449
  }
169180
169450
  }
169181
169451
  var initialShopCheckoutState;
@@ -169593,7 +169863,7 @@ function giftingClientReducer(state, action) {
169593
169863
  purchaseNotice: action.notice
169594
169864
  };
169595
169865
  default:
169596
- return assertNever7(action);
169866
+ return assertNever8(action);
169597
169867
  }
169598
169868
  }
169599
169869
  function resolveGiftingPurchaseNotice(search, defaultSuccessMessage) {
@@ -173298,7 +173568,7 @@ function formSubmissionReducer(_state, action) {
173298
173568
  case "submission-failed":
173299
173569
  return { tag: "failed", message: action.message };
173300
173570
  default:
173301
- return assertNever7(action);
173571
+ return assertNever8(action);
173302
173572
  }
173303
173573
  }
173304
173574
  var initialFormSubmissionState;
@@ -174032,32 +174302,14 @@ var init_repeaterFieldDefaults = __esm({
174032
174302
  "../block-form/src/widgets/RepeaterField/repeaterFieldDefaults.ts"() {
174033
174303
  }
174034
174304
  });
174305
+
174306
+ // ../block-form/src/widgets/UrlField/urlFieldSchema.ts
174035
174307
  function buildUrlFieldSchema(field) {
174036
- const message2 = "Enter a valid web address";
174037
- const validator = (value) => {
174038
- if (!value) {
174039
- return !field.required;
174040
- }
174041
- if (field.allowRelative && value.startsWith("/")) {
174042
- return true;
174043
- }
174044
- try {
174045
- const parsed = new URL(value);
174046
- return ALLOWED_PROTOCOLS.includes(parsed.protocol);
174047
- } catch {
174048
- return false;
174049
- }
174050
- };
174051
- const base2 = z.string().trim().refine(validator, message2);
174052
- if (field.required) {
174053
- return base2.min(1, { message: "This field is required" });
174054
- }
174055
- return z.union([base2, z.literal("")]).optional().nullable();
174308
+ return buildCanonicalFieldSchema(field);
174056
174309
  }
174057
- var ALLOWED_PROTOCOLS;
174058
174310
  var init_urlFieldSchema = __esm({
174059
174311
  "../block-form/src/widgets/UrlField/urlFieldSchema.ts"() {
174060
- ALLOWED_PROTOCOLS = ["http:", "https:"];
174312
+ init_canonicalValidation();
174061
174313
  }
174062
174314
  });
174063
174315
 
@@ -174136,18 +174388,14 @@ var init_dateTimeFieldDefaults = __esm({
174136
174388
  "../block-form/src/widgets/DateTimeField/dateTimeFieldDefaults.ts"() {
174137
174389
  }
174138
174390
  });
174391
+
174392
+ // ../block-form/src/widgets/SlugField/slugFieldSchema.ts
174139
174393
  function buildSlugFieldSchema(field) {
174140
- const base2 = z.string().regex(SLUG_PATTERN2, `${field.label} must use lowercase letters, numbers, and dashes`);
174141
- const withLength = field.maxLength ? base2.max(field.maxLength, { message: `${field.label} must be at most ${field.maxLength} characters` }) : base2;
174142
- if (field.required) {
174143
- return withLength.min(1, { message: `${field.label} is required` });
174144
- }
174145
- return z.union([withLength, z.literal("")]).optional().nullable();
174394
+ return buildCanonicalFieldSchema(field);
174146
174395
  }
174147
- var SLUG_PATTERN2;
174148
174396
  var init_slugFieldSchema = __esm({
174149
174397
  "../block-form/src/widgets/SlugField/slugFieldSchema.ts"() {
174150
- SLUG_PATTERN2 = /^(?:[a-z0-9]+(?:-[a-z0-9]+)*)(?:\/(?:[a-z0-9]+(?:-[a-z0-9]+)*))*$/;
174398
+ init_canonicalValidation();
174151
174399
  }
174152
174400
  });
174153
174401
 
@@ -174159,51 +174407,14 @@ var init_slugFieldDefaults = __esm({
174159
174407
  "../block-form/src/widgets/SlugField/slugFieldDefaults.ts"() {
174160
174408
  }
174161
174409
  });
174410
+
174411
+ // ../block-form/src/widgets/LinkField/linkFieldSchema.ts
174162
174412
  function buildLinkFieldSchema(field) {
174163
- if (field.required) {
174164
- return linkSchema2;
174165
- }
174166
- return z.union([linkSchema2, z.null()]).optional();
174413
+ return buildCanonicalFieldSchema(field);
174167
174414
  }
174168
- var internalLinkSchema2, externalLinkSchema2, customLinkSchema2, pageLinkSchema2, entryLinkSchema2, linkSchema2;
174169
174415
  var init_linkFieldSchema = __esm({
174170
174416
  "../block-form/src/widgets/LinkField/linkFieldSchema.ts"() {
174171
- internalLinkSchema2 = z.object({
174172
- kind: z.literal("internal"),
174173
- routeId: z.string().min(1),
174174
- entityId: z.string().min(1),
174175
- entityType: z.enum(["page", "content"]),
174176
- href: z.string().min(1),
174177
- title: z.string().min(1),
174178
- typeLabel: z.string().min(1),
174179
- contentTypeKey: z.string().nullable().optional(),
174180
- contentTypeName: z.string().nullable().optional(),
174181
- updatedAt: z.string().nullable().optional()
174182
- }).passthrough();
174183
- externalLinkSchema2 = z.object({
174184
- kind: z.literal("external"),
174185
- href: z.string().min(1)
174186
- }).passthrough();
174187
- customLinkSchema2 = z.object({
174188
- kind: z.literal("url"),
174189
- href: z.string().min(1)
174190
- }).passthrough();
174191
- pageLinkSchema2 = z.object({
174192
- kind: z.literal("page"),
174193
- identifier: z.string().min(1)
174194
- }).passthrough();
174195
- entryLinkSchema2 = z.object({
174196
- kind: z.literal("entry"),
174197
- contentType: z.string().min(1),
174198
- identifier: z.string().min(1)
174199
- }).passthrough();
174200
- linkSchema2 = z.union([
174201
- internalLinkSchema2,
174202
- externalLinkSchema2,
174203
- customLinkSchema2,
174204
- pageLinkSchema2,
174205
- entryLinkSchema2
174206
- ]);
174417
+ init_canonicalValidation();
174207
174418
  }
174208
174419
  });
174209
174420
 
@@ -174221,6 +174432,55 @@ var init_linkFieldDefaults = __esm({
174221
174432
  "../block-form/src/widgets/LinkField/linkFieldDefaults.ts"() {
174222
174433
  }
174223
174434
  });
174435
+ function buildRichTextSchema(options) {
174436
+ let schema = RichTextValueSchema;
174437
+ if (options?.required) {
174438
+ const label = options.label ?? "This field";
174439
+ schema = schema.refine(
174440
+ (val) => {
174441
+ const doc3 = isRecord5(val) && "doc" in val ? val.doc : val;
174442
+ const content = isRecord5(doc3) ? doc3.content : void 0;
174443
+ if (!Array.isArray(content) || content.length === 0) return false;
174444
+ const first2 = content[0];
174445
+ if (content.length === 1 && isRecord5(first2) && first2.type === "paragraph" && (!("content" in first2) || first2.content == null)) {
174446
+ return false;
174447
+ }
174448
+ return true;
174449
+ },
174450
+ {
174451
+ message: `${label} is required`
174452
+ }
174453
+ );
174454
+ }
174455
+ return schema;
174456
+ }
174457
+ var TipTapMarkSchema, TipTapNodeSchema, RichTextValueSchema;
174458
+ var init_richTextSchema = __esm({
174459
+ "../blocks/src/system/manifest/richTextSchema.ts"() {
174460
+ init_typeGuards2();
174461
+ TipTapMarkSchema = z.object({
174462
+ type: z.string(),
174463
+ attrs: z.record(z.string(), z.unknown()).optional()
174464
+ });
174465
+ TipTapNodeSchema = z.lazy(
174466
+ () => z.object({
174467
+ type: z.string(),
174468
+ content: z.array(TipTapNodeSchema).optional(),
174469
+ text: z.string().optional(),
174470
+ attrs: z.record(z.string(), z.unknown()).optional(),
174471
+ marks: z.array(TipTapMarkSchema).optional()
174472
+ })
174473
+ );
174474
+ RichTextValueSchema = z.union([
174475
+ // New format: TipTap document directly
174476
+ TipTapNodeSchema,
174477
+ // Legacy format: wrapped in { doc: {...} }
174478
+ z.object({
174479
+ doc: TipTapNodeSchema
174480
+ })
174481
+ ]);
174482
+ }
174483
+ });
174224
174484
  function buildRichTextFieldSchema(config) {
174225
174485
  const schema = buildRichTextSchema({
174226
174486
  required: config.required,
@@ -174251,30 +174511,14 @@ var init_richTextFieldDefaults = __esm({
174251
174511
  };
174252
174512
  }
174253
174513
  });
174514
+
174515
+ // ../block-form/src/widgets/MediaField/mediaFieldSchema.ts
174254
174516
  function buildMediaFieldSchema(config) {
174255
- let schema = MediaValueSchema.nullable();
174256
- if (config.required) {
174257
- schema = schema.refine((val) => val !== null, {
174258
- message: `${config.label} is required`
174259
- });
174260
- }
174261
- return schema;
174517
+ return buildCanonicalFieldSchema(config);
174262
174518
  }
174263
- var MediaValueSchema;
174264
174519
  var init_mediaFieldSchema = __esm({
174265
174520
  "../block-form/src/widgets/MediaField/mediaFieldSchema.ts"() {
174266
- MediaValueSchema = z.object({
174267
- kind: z.enum(["image", "video", "audio", "document", "spreadsheet", "archive"]),
174268
- url: z.string().url(),
174269
- title: z.string().optional(),
174270
- alt: z.string().optional(),
174271
- caption: z.string().optional(),
174272
- credit: z.string().optional(),
174273
- width: z.number().optional(),
174274
- height: z.number().optional(),
174275
- size: z.number().optional(),
174276
- mimeType: z.string().optional()
174277
- });
174521
+ init_canonicalValidation();
174278
174522
  }
174279
174523
  });
174280
174524
 
@@ -174286,15 +174530,14 @@ var init_mediaFieldDefaults = __esm({
174286
174530
  "../block-form/src/widgets/MediaField/mediaFieldDefaults.ts"() {
174287
174531
  }
174288
174532
  });
174533
+
174534
+ // ../block-form/src/widgets/ReferenceField/referenceFieldSchema.ts
174289
174535
  function buildReferenceFieldSchema(field, _ctx) {
174290
- const schema = z.string();
174291
- if (field.required) {
174292
- return schema.refine((value) => value.trim().length > 0, "This field is required");
174293
- }
174294
- return schema.optional().nullable().or(z.literal(""));
174536
+ return buildCanonicalFieldSchema(field);
174295
174537
  }
174296
174538
  var init_referenceFieldSchema = __esm({
174297
174539
  "../block-form/src/widgets/ReferenceField/referenceFieldSchema.ts"() {
174540
+ init_canonicalValidation();
174298
174541
  }
174299
174542
  });
174300
174543
 
@@ -193053,7 +193296,7 @@ var init_PreviewRichTextEditor = __esm({
193053
193296
  const isEditingRef = useRef(false);
193054
193297
  const initialDoc = normaliseDoc(value ?? doc3);
193055
193298
  const chosenVariant = variant ?? "full";
193056
- const { editor, isEmpty: isEmpty2, config } = useRichTextEditor({
193299
+ const { editor, isEmpty, config } = useRichTextEditor({
193057
193300
  content: initialDoc,
193058
193301
  editable: true,
193059
193302
  variant: chosenVariant
@@ -193130,7 +193373,7 @@ var init_PreviewRichTextEditor = __esm({
193130
193373
  {
193131
193374
  editor,
193132
193375
  config,
193133
- isEmpty: isEmpty2,
193376
+ isEmpty,
193134
193377
  className: `relative w-full min-h-[30px] rounded border border-dashed ${showAffordance ? "border-slate-400/75 bg-white/5" : "border-transparent bg-transparent"}`,
193135
193378
  contentClassName: "cursor-text",
193136
193379
  placeholderClassName: "text-gray-400",
@@ -193985,7 +194228,9 @@ function isSameLinkValue(a2, b3) {
193985
194228
  if (!a2 || !b3 || a2.kind !== b3.kind) return false;
193986
194229
  switch (a2.kind) {
193987
194230
  case "internal":
193988
- return b3.kind === "internal" && a2.routeId === b3.routeId && a2.entityId === b3.entityId && a2.entityType === b3.entityType && a2.href === b3.href && a2.title === b3.title && a2.typeLabel === b3.typeLabel && a2.contentTypeKey === b3.contentTypeKey && a2.contentTypeName === b3.contentTypeName && a2.updatedAt === b3.updatedAt;
194231
+ if (b3.kind !== "internal" || a2.routeId !== b3.routeId) return false;
194232
+ if (!isInternalResolvedLinkValue(a2) || !isInternalResolvedLinkValue(b3)) return true;
194233
+ return a2.entityId === b3.entityId && a2.entityType === b3.entityType && a2.href === b3.href && a2.title === b3.title && a2.typeLabel === b3.typeLabel && a2.contentTypeKey === b3.contentTypeKey && a2.contentTypeName === b3.contentTypeName && a2.updatedAt === b3.updatedAt;
193989
194234
  case "page":
193990
194235
  return b3.kind === "page" && a2.identifier === b3.identifier;
193991
194236
  case "entry":
@@ -194004,6 +194249,7 @@ function getDisplayTitle2(item) {
194004
194249
  var init_utils22 = __esm({
194005
194250
  "../editor-blocks/src/widgets/link/utils.ts"() {
194006
194251
  init_navigation2();
194252
+ init_src6();
194007
194253
  }
194008
194254
  });
194009
194255
  function getActiveTab(value) {
@@ -194312,6 +194558,12 @@ function LinkTriggerContent({ value }) {
194312
194558
  return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Select a link..." });
194313
194559
  }
194314
194560
  if (value.kind === "internal") {
194561
+ if (!isInternalResolvedLinkValue(value)) {
194562
+ return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
194563
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium", title: value.routeId, children: "Internal route" }),
194564
+ /* @__PURE__ */ jsx(Badge2, { variant: "secondary", className: "shrink-0", children: "Internal" })
194565
+ ] });
194566
+ }
194315
194567
  return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
194316
194568
  /* @__PURE__ */ jsx("span", { className: "truncate font-medium", title: value.title || void 0, children: value.title || "Untitled" }),
194317
194569
  /* @__PURE__ */ jsx(Badge2, { variant: "secondary", className: "shrink-0", children: value.typeLabel })
@@ -194408,6 +194660,7 @@ function LinkWidget({
194408
194660
  var init_LinkWidget = __esm({
194409
194661
  "../editor-blocks/src/widgets/link/LinkWidget.tsx"() {
194410
194662
  "use client";
194663
+ init_src6();
194411
194664
  init_src();
194412
194665
  init_lucide_react();
194413
194666
  init_client4();
@@ -194836,8 +195089,8 @@ function unwrapValue(value) {
194836
195089
  if (typeof value === "string") {
194837
195090
  return value;
194838
195091
  }
194839
- if (isObjectRecord(value)) {
194840
- if (isObjectRecord(value.doc)) {
195092
+ if (isObjectRecord2(value)) {
195093
+ if (isObjectRecord2(value.doc)) {
194841
195094
  return value.doc;
194842
195095
  }
194843
195096
  if (typeof value.type === "string") {
@@ -197699,9 +197952,9 @@ function blockSaveabilityEqual(left, right) {
197699
197952
  if (left.issues.length !== right.issues.length) {
197700
197953
  return false;
197701
197954
  }
197702
- return left.issues.every((issue, index2) => {
197955
+ return left.issues.every((issue2, index2) => {
197703
197956
  const nextIssue = right.issues[index2];
197704
- return nextIssue?.fieldPath === issue.fieldPath && nextIssue.message === issue.message;
197957
+ return nextIssue?.fieldPath === issue2.fieldPath && nextIssue.message === issue2.message;
197705
197958
  });
197706
197959
  }
197707
197960
  var init_BlockForm = __esm({
@@ -200817,38 +201070,38 @@ var internalLinkPayloadSchema = z.object({
200817
201070
  contentTypeName: z.string().nullable().optional(),
200818
201071
  updatedAt: z.string().nullable().optional()
200819
201072
  }).passthrough();
200820
- var externalLinkSchema3 = z.object({
201073
+ var externalLinkSchema2 = z.object({
200821
201074
  kind: z.literal("external"),
200822
201075
  // Navigation external links are expected to be absolute URLs.
200823
201076
  href: z.string().url()
200824
201077
  });
200825
- var customLinkSchema3 = z.object({
201078
+ var customLinkSchema2 = z.object({
200826
201079
  kind: z.literal("url"),
200827
201080
  href: z.string().min(1)
200828
201081
  });
200829
- var pageLinkSchema3 = z.object({
201082
+ var pageLinkSchema2 = z.object({
200830
201083
  kind: z.literal("page"),
200831
201084
  identifier: z.string().min(1)
200832
201085
  });
200833
- var entryLinkSchema3 = z.object({
201086
+ var entryLinkSchema2 = z.object({
200834
201087
  kind: z.literal("entry"),
200835
201088
  contentType: z.string().min(1),
200836
201089
  identifier: z.string().min(1)
200837
201090
  });
200838
201091
  var linkPayloadSchema = z.discriminatedUnion("kind", [
200839
201092
  internalLinkPayloadSchema,
200840
- pageLinkSchema3,
200841
- entryLinkSchema3,
200842
- externalLinkSchema3,
200843
- customLinkSchema3,
201093
+ pageLinkSchema2,
201094
+ entryLinkSchema2,
201095
+ externalLinkSchema2,
201096
+ customLinkSchema2,
200844
201097
  portalLinkPayloadSchema,
200845
201098
  cartLinkPayloadSchema
200846
201099
  ]);
200847
201100
  var navigationLinkInputSchemaOptions = [
200848
- pageLinkSchema3,
200849
- entryLinkSchema3,
200850
- externalLinkSchema3,
200851
- customLinkSchema3,
201101
+ pageLinkSchema2,
201102
+ entryLinkSchema2,
201103
+ externalLinkSchema2,
201104
+ customLinkSchema2,
200852
201105
  portalLinkPayloadSchema,
200853
201106
  cartLinkPayloadSchema
200854
201107
  ];
@@ -201612,11 +201865,11 @@ siteBannerSettingsSchema.superRefine((value, ctx) => {
201612
201865
  return;
201613
201866
  }
201614
201867
  const analysis = analyzeSiteBannerBody(value.body);
201615
- for (const issue of analysis.issues) {
201868
+ for (const issue2 of analysis.issues) {
201616
201869
  ctx.addIssue({
201617
201870
  code: z.ZodIssueCode.custom,
201618
201871
  path: ["body"],
201619
- message: siteBannerBodyIssueMessage(issue)
201872
+ message: siteBannerBodyIssueMessage(issue2)
201620
201873
  });
201621
201874
  }
201622
201875
  });
@@ -201650,8 +201903,8 @@ function analyzeSiteBannerBody(body) {
201650
201903
  issues
201651
201904
  };
201652
201905
  }
201653
- function siteBannerBodyIssueMessage(issue) {
201654
- switch (issue) {
201906
+ function siteBannerBodyIssueMessage(issue2) {
201907
+ switch (issue2) {
201655
201908
  case "empty":
201656
201909
  return "Banner message is required when the banner is enabled.";
201657
201910
  case "too-many-paragraphs":
@@ -202056,7 +202309,7 @@ function previewCustomizeHistoryEntryFromAction(editorModel, action) {
202056
202309
  };
202057
202310
  }
202058
202311
  default:
202059
- return assertNever5(action, "Unhandled preview customize action");
202312
+ return assertNever6(action, "Unhandled preview customize action");
202060
202313
  }
202061
202314
  }
202062
202315
  function previewCustomizeUndoActionForEntry(entry) {
@@ -202097,7 +202350,7 @@ function previewCustomizeActionForEntryValue(entry, valueKey) {
202097
202350
  };
202098
202351
  }
202099
202352
  default:
202100
- return assertNever5(entry, "Unhandled preview customize history entry");
202353
+ return assertNever6(entry, "Unhandled preview customize history entry");
202101
202354
  }
202102
202355
  }
202103
202356
  function supportedPinnedChoiceValue(choice) {
@@ -202119,7 +202372,7 @@ function previewCustomizeHistoryEntryStillApplies(entry, editorModel) {
202119
202372
  (boundary) => boundary.boundaryId === entry.boundaryId && boundary.previousBlockId === entry.previousBlockId && boundary.nextBlockId === entry.nextBlockId
202120
202373
  );
202121
202374
  default:
202122
- return assertNever5(entry, "Unhandled preview customize history entry");
202375
+ return assertNever6(entry, "Unhandled preview customize history entry");
202123
202376
  }
202124
202377
  }
202125
202378
  function previewCustomizeHistoryEntryEquals(left, right) {
@@ -202133,7 +202386,7 @@ function previewCustomizeHistoryEntryEquals(left, right) {
202133
202386
  case "boundary":
202134
202387
  return right.kind === "boundary" && left.boundaryId === right.boundaryId && left.previousBlockId === right.previousBlockId && left.nextBlockId === right.nextBlockId && left.fromBoundaryOptionId === right.fromBoundaryOptionId && left.toBoundaryOptionId === right.toBoundaryOptionId;
202135
202388
  default:
202136
- return assertNever5(left, "Unhandled preview customize history entry");
202389
+ return assertNever6(left, "Unhandled preview customize history entry");
202137
202390
  }
202138
202391
  }
202139
202392
 
@@ -202174,7 +202427,7 @@ function previewCustomizeWorkflowPageState(workflow) {
202174
202427
  case "loaded":
202175
202428
  return workflow.pageState;
202176
202429
  default:
202177
- return assertNever5(workflow, "Unhandled preview customize workflow state");
202430
+ return assertNever6(workflow, "Unhandled preview customize workflow state");
202178
202431
  }
202179
202432
  }
202180
202433
  function beginPreviewCustomizeApply(workflow, action) {
@@ -202269,7 +202522,7 @@ function confirmPreviewCustomizeMutation(workflow, response) {
202269
202522
  case "stale":
202270
202523
  return workflow;
202271
202524
  default:
202272
- return assertNever5(workflow.mutation, "Unhandled preview customize mutation");
202525
+ return assertNever6(workflow.mutation, "Unhandled preview customize mutation");
202273
202526
  }
202274
202527
  }
202275
202528
  function rejectPreviewCustomizeMutation(previousWorkflow, outcome) {
@@ -202303,7 +202556,7 @@ function previewCustomizeFailureMessage(workflow) {
202303
202556
  case "redoing":
202304
202557
  return null;
202305
202558
  default:
202306
- return assertNever5(workflow.mutation, "Unhandled preview customize mutation");
202559
+ return assertNever6(workflow.mutation, "Unhandled preview customize mutation");
202307
202560
  }
202308
202561
  }
202309
202562
  function skippedPreviewCustomizeOutcome(reason) {
@@ -202335,7 +202588,7 @@ function skippedPreviewCustomizeMessage(reason) {
202335
202588
  case "cannot-redo":
202336
202589
  return "No design choice is available to redo.";
202337
202590
  default:
202338
- return assertNever5(reason, "Unhandled preview customize skip reason");
202591
+ return assertNever6(reason, "Unhandled preview customize skip reason");
202339
202592
  }
202340
202593
  }
202341
202594
  function skipReasonForNewMutation(workflow) {
@@ -202358,7 +202611,7 @@ function isPendingMutation(mutation) {
202358
202611
  case "stale":
202359
202612
  return false;
202360
202613
  default:
202361
- return assertNever5(mutation, "Unhandled preview customize mutation");
202614
+ return assertNever6(mutation, "Unhandled preview customize mutation");
202362
202615
  }
202363
202616
  }
202364
202617
  function confirmedLoadedState(current, response) {
@@ -202433,7 +202686,7 @@ function applyPreviewCustomizeActionToLoadedState(state, action) {
202433
202686
  }
202434
202687
  };
202435
202688
  default:
202436
- return assertNever5(action, "Unhandled preview customize action");
202689
+ return assertNever6(action, "Unhandled preview customize action");
202437
202690
  }
202438
202691
  }
202439
202692
  function optimisticBoundaryBreakChoice(editorModel, boundary, action) {
@@ -202451,7 +202704,7 @@ function optimisticBoundaryBreakChoice(editorModel, boundary, action) {
202451
202704
  effectiveValue: autoBoundaryEffectiveValue(editorModel, boundary)
202452
202705
  };
202453
202706
  default:
202454
- return assertNever5(action, "Unhandled optimistic boundary action");
202707
+ return assertNever6(action, "Unhandled optimistic boundary action");
202455
202708
  }
202456
202709
  }
202457
202710
  function autoBoundaryEffectiveValue(editorModel, boundary) {
@@ -202711,7 +202964,7 @@ function pageDesignEditorActionForPersistence(action) {
202711
202964
  case "set-boundary":
202712
202965
  return action;
202713
202966
  default:
202714
- return assertNever5(action, "Unhandled page design editor action");
202967
+ return assertNever6(action, "Unhandled page design editor action");
202715
202968
  }
202716
202969
  }
202717
202970
  function classifyApplyActionError(error) {
@@ -202754,7 +203007,7 @@ function blockIdForRuntimePatch(action) {
202754
203007
  case "reset-boundary":
202755
203008
  return action.previousBlockId;
202756
203009
  default:
202757
- return assertNever5(action, "Unhandled runtime patch action");
203010
+ return assertNever6(action, "Unhandled runtime patch action");
202758
203011
  }
202759
203012
  }
202760
203013
  function currentLocalBlockContent(uiStore, targetBlockId) {
@@ -205409,7 +205662,7 @@ function boundaryBreakDisplay(boundary) {
205409
205662
  resetLabel: "Use default break"
205410
205663
  };
205411
205664
  default:
205412
- return assertNever5(boundary.breakChoice, "Unhandled boundary break choice");
205665
+ return assertNever6(boundary.breakChoice, "Unhandled boundary break choice");
205413
205666
  }
205414
205667
  }
205415
205668
  function formatBlockKindLabel2(blockKind) {