@riverbankcms/sdk 0.60.7 → 0.60.11

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 (44) hide show
  1. package/dist/_dts/api/src/index.d.ts +2 -1
  2. package/dist/_dts/api/src/navigation/linkValue.d.ts +15 -2
  3. package/dist/_dts/api/src/navigation.d.ts +2 -0
  4. package/dist/_dts/blocks/src/index.d.ts +2 -1
  5. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +185 -0
  6. package/dist/_dts/blocks/src/system/manifest/index.d.ts +1 -0
  7. package/dist/_dts/blocks/src/system/manifest/validation.d.ts +2 -84
  8. package/dist/_dts/blocks/src/system/node/fragments/ctaButton.d.ts +2 -2
  9. package/dist/_dts/blocks/src/system/runtime/nodes/basic.d.ts +2 -1
  10. package/dist/_dts/blocks/src/system/types/link.d.ts +100 -2
  11. package/dist/_dts/db/src/schemas/forms.d.ts +24 -3
  12. package/dist/_dts/editor-blocks/src/widgets/link/LinkSummary.d.ts +1 -1
  13. package/dist/_dts/editor-blocks/src/widgets/link/LinkWidget.d.ts +1 -1
  14. package/dist/_dts/editor-blocks/src/widgets/link/utils.d.ts +1 -1
  15. package/dist/_dts/sdk/src/config/typed-entries.d.ts +36 -1
  16. package/dist/_dts/sdk/src/contracts/content.d.ts +13 -2
  17. package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
  18. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +1 -0
  19. package/dist/_dts/sdk/src/version.d.ts +1 -1
  20. package/dist/_dts/theme-core/src/buttons/classNames.d.ts +21 -0
  21. package/dist/_dts/theme-core/src/buttons/index.d.ts +1 -0
  22. package/dist/_dts/theme-core/src/buttons/types.d.ts +1 -0
  23. package/dist/cli/index.mjs +736 -427
  24. package/dist/client/bookings.mjs +746 -149
  25. package/dist/client/client.mjs +40389 -39847
  26. package/dist/client/hooks.mjs +1737 -1735
  27. package/dist/client/rendering/client.mjs +351 -113
  28. package/dist/client/rendering/islands.mjs +4549 -4366
  29. package/dist/client/rendering.mjs +1915 -1373
  30. package/dist/preview-next/client/runtime.mjs +1509 -945
  31. package/dist/server/components.mjs +3148 -2781
  32. package/dist/server/config-validation.mjs +1727 -1725
  33. package/dist/server/config.mjs +1727 -1725
  34. package/dist/server/data.mjs +1737 -1735
  35. package/dist/server/index.mjs +1 -1
  36. package/dist/server/next.mjs +3193 -2826
  37. package/dist/server/page-converter.mjs +10 -10
  38. package/dist/server/prebuild.mjs +1 -1
  39. package/dist/server/rendering/server.mjs +3161 -2794
  40. package/dist/server/rendering.mjs +3161 -2794
  41. package/dist/server/routing.mjs +297 -314
  42. package/dist/server/server.mjs +1738 -1736
  43. package/package.json +1 -1
  44. package/dist/_dts/blocks/src/system/runtime/shared/themedButtonClass.d.ts +0 -11
@@ -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,109 +100637,605 @@ 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;
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 formatFieldPath(path) {
100651
+ return path.map((segment) => String(segment)).join(".");
100652
+ }
100653
+ function fieldIssueToMessage(issue2) {
100654
+ switch (issue2.kind) {
100655
+ case "required":
100656
+ return "This field is required";
100657
+ case "wrongType":
100658
+ return `${issue2.label} needs ${issue2.expected}`;
100659
+ case "tooLong":
100660
+ return `Use ${issue2.maximum} characters or fewer`;
100661
+ case "invalidEmail":
100662
+ return "Enter a valid email address";
100663
+ case "invalidPhone":
100664
+ return "Enter a valid phone number";
100665
+ case "invalidPattern":
100666
+ return "Check the format and try again";
100667
+ case "invalidUrl":
100668
+ return "Enter a valid web address";
100669
+ case "invalidNumber":
100670
+ return `${issue2.label} needs a number`;
100671
+ case "tooSmall":
100672
+ return `${issue2.label} must be ${issue2.minimum} or more`;
100673
+ case "tooLarge":
100674
+ return `${issue2.label} must be ${issue2.maximum} or less`;
100675
+ case "invalidSlug":
100676
+ return `${issue2.label} can only use lowercase letters, numbers, and dashes`;
100677
+ case "invalidOption":
100678
+ return `Choose one of the available options for ${issue2.label}`;
100679
+ case "tooFewItems":
100680
+ return `${issue2.label} must have at least ${issue2.minimum} ${pluralize(issue2.itemLabel, issue2.minimum)}`;
100681
+ case "tooManyItems":
100682
+ return `${issue2.label} must have at most ${issue2.maximum} ${pluralize(issue2.itemLabel, issue2.maximum)}`;
100683
+ case "invalidRichText":
100684
+ return `${issue2.label} must be valid rich text`;
100685
+ case "invalidMedia":
100686
+ return `${issue2.label} must be a valid media item`;
100687
+ case "invalidLink":
100688
+ return `${issue2.label} must be a valid link`;
100689
+ case "invalidReference":
100690
+ return `${issue2.label} must reference a valid item`;
100691
+ default:
100692
+ return assertNever5(issue2);
100693
+ }
100601
100694
  }
100602
- var init_typeGuards2 = __esm({
100603
- "../blocks/src/lib/typeGuards.ts"() {
100695
+ function pluralize(label, count3) {
100696
+ if (count3 === 1) return label;
100697
+ return label.endsWith("s") ? label : `${label}s`;
100698
+ }
100699
+ function deriveFieldValidationPlan(field, path = [field.id]) {
100700
+ const required = Boolean(field.required);
100701
+ switch (field.type) {
100702
+ case "text": {
100703
+ const inputType = field.ui?.inputType;
100704
+ if (inputType === "number") {
100705
+ const constraints2 = commonConstraints(required, { kind: "numberType" });
100706
+ if (typeof field.ui?.min === "number") constraints2.push({ kind: "numberMin", minimum: field.ui.min });
100707
+ if (typeof field.ui?.max === "number") constraints2.push({ kind: "numberMax", maximum: field.ui.max });
100708
+ return makePlan("number", "number", field, path, required, constraints2);
100709
+ }
100710
+ const constraints = commonConstraints(required, { kind: "textType" });
100711
+ if (inputType === "email") constraints.push({ kind: "emailFormat" });
100712
+ if (inputType === "tel") constraints.push({ kind: "phoneFormat" });
100713
+ if (field.ui?.pattern) constraints.push({ kind: "patternFormat", pattern: field.ui.pattern });
100714
+ if (typeof field.maxLength === "number") constraints.push({ kind: "maxLength", maximum: field.maxLength });
100715
+ return makePlan("string", "string", field, path, required, constraints);
100716
+ }
100717
+ case "number": {
100718
+ const constraints = commonConstraints(required, { kind: "numberType" });
100719
+ if (typeof field.min === "number") constraints.push({ kind: "numberMin", minimum: field.min });
100720
+ if (typeof field.max === "number") constraints.push({ kind: "numberMax", maximum: field.max });
100721
+ return makePlan("number", "number", field, path, required, constraints);
100722
+ }
100723
+ case "slug": {
100724
+ const constraints = commonConstraints(required, { kind: "textType" }, { kind: "slugFormat" });
100725
+ if (typeof field.maxLength === "number") constraints.push({ kind: "maxLength", maximum: field.maxLength });
100726
+ return makePlan("string", "string", field, path, required, constraints);
100727
+ }
100728
+ case "url":
100729
+ return makePlan("string", "string", field, path, required, commonConstraints(
100730
+ required,
100731
+ { kind: "textType" },
100732
+ { kind: "urlFormat", allowRelative: Boolean(field.allowRelative) }
100733
+ ));
100734
+ case "reference":
100735
+ return makePlan("string", "string", field, path, required, commonConstraints(required, { kind: "referenceText" }));
100736
+ case "date":
100737
+ case "time":
100738
+ case "datetime":
100739
+ return makePlan("string", "string", field, path, required, commonConstraints(required, { kind: "textType" }));
100740
+ case "select":
100741
+ return makePlan("select", "select", field, path, required, commonConstraints(required, {
100742
+ kind: "selectOption",
100743
+ source: resolveSelectConstraintSource(field),
100744
+ multiple: Boolean(field.multiple)
100745
+ }));
100746
+ case "richText":
100747
+ return makePlan("richText", "object", field, path, required, commonConstraints(required, { kind: "richTextDoc" }));
100748
+ case "media":
100749
+ return makePlan("media", "object", field, path, required, commonConstraints(required, { kind: "mediaObject" }));
100750
+ case "link":
100751
+ return makePlan("link", "object", field, path, required, commonConstraints(required, { kind: "linkObject" }));
100752
+ case "boolean":
100753
+ return makePlan("boolean", "boolean", field, path, required, requiredConstraints(required));
100754
+ case "repeater":
100755
+ return {
100756
+ ...makePlan("repeater", "array", field, path, required, commonConstraints(required, { kind: "arrayType" })),
100757
+ ...field.polymorphic && field.itemTypes ? { repeatedItemVariants: deriveRepeatedItemVariants(field, [...path, 0]) } : { repeatedItemPlan: deriveNestedFieldPlans(getRepeaterFields(field), [...path, 0]) },
100758
+ constraints: withRepeaterItemConstraints(field, commonConstraints(required, { kind: "arrayType" }))
100759
+ };
100760
+ case "group":
100761
+ case "modal":
100762
+ return {
100763
+ ...makePlan("group", "object", field, path, required, requiredConstraints(required)),
100764
+ children: deriveNestedFieldPlans(field.schema?.fields ?? [], path),
100765
+ allowNullChildren: field.type === "group" && field.ui?.widget === "locationPicker"
100766
+ };
100767
+ case "tabGroup":
100768
+ return {
100769
+ ...makePlan("group", "object", field, path, required, requiredConstraints(required)),
100770
+ children: field.tabs.flatMap((tab) => deriveNestedFieldPlans(tab.fields, path))
100771
+ };
100772
+ case "presetOrCustom":
100773
+ case "contentTypeSelect":
100774
+ case "entryPicker":
100775
+ return makePlan("passthrough", "unknown", field, path, false, []);
100776
+ default:
100777
+ return assertNever5(field);
100604
100778
  }
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
- );
100779
+ }
100780
+ function commonConstraints(required, ...specific) {
100781
+ return required ? [{ kind: "required" }, ...specific] : [...specific];
100782
+ }
100783
+ function requiredConstraints(required) {
100784
+ return required ? [{ kind: "required" }] : [];
100785
+ }
100786
+ function makePlan(kind, valueKind, field, path, required, constraints) {
100787
+ return {
100788
+ kind,
100789
+ valueKind,
100790
+ fieldId: field.id,
100791
+ label: field.label,
100792
+ fieldType: field.type,
100793
+ path,
100794
+ required,
100795
+ constraints
100796
+ };
100797
+ }
100798
+ function withRepeaterItemConstraints(field, constraints) {
100799
+ const next = [...constraints];
100800
+ if (typeof field.minItems === "number") next.push({ kind: "minItems", minimum: field.minItems });
100801
+ if (typeof field.maxItems === "number") next.push({ kind: "maxItems", maximum: field.maxItems });
100802
+ return next;
100803
+ }
100804
+ function deriveRepeatedItemVariants(field, parentPath) {
100805
+ return Object.entries(field.itemTypes ?? {}).map(([typeId, itemType]) => ({
100806
+ typeId,
100807
+ fields: deriveNestedFieldPlans(getFlattenedRepeaterFields(itemType.fields), parentPath)
100808
+ }));
100809
+ }
100810
+ function deriveNestedFieldPlans(fields3, parentPath) {
100811
+ return fields3.map((field) => deriveFieldValidationPlan(field, [...parentPath, field.id]));
100812
+ }
100813
+ function getRepeaterFields(field) {
100814
+ const fields3 = field.polymorphic && field.itemTypes ? Object.values(field.itemTypes).flatMap((itemType) => itemType.fields) : field.schema?.fields ?? [];
100815
+ return getFlattenedRepeaterFields(fields3);
100816
+ }
100817
+ function getFlattenedRepeaterFields(fields3) {
100818
+ return fields3.flatMap((child) => {
100819
+ if (child.type === "group" && child.ui?.flattenInRepeater) {
100820
+ return child.schema?.fields ?? [];
100821
+ }
100822
+ return child;
100823
+ });
100824
+ }
100825
+ function resolveSelectConstraintSource(field) {
100826
+ const source = normalizeSelectSource(field);
100827
+ switch (source.kind) {
100828
+ case "static":
100829
+ return { kind: "static", values: field.options.map((option) => option.value) };
100830
+ case "site":
100831
+ case "sdk":
100832
+ return { kind: "runtime", source: source.kind };
100833
+ default:
100834
+ return assertNever5(source);
100625
100835
  }
100626
- return schema;
100627
100836
  }
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
- ]);
100837
+ function normalizeFieldValue(plan, value, ctx) {
100838
+ switch (plan.kind) {
100839
+ case "number":
100840
+ return normalizeNumberInput(value, ctx.allowNull);
100841
+ case "string":
100842
+ return acceptsOptionalBlankAsMissing(plan, value) ? void 0 : value;
100843
+ case "group":
100844
+ return normalizeObjectChildren(plan.children, value, childValidationContext(plan, ctx));
100845
+ case "repeater":
100846
+ return normalizeRepeaterItems(plan, value, ctx);
100847
+ case "boolean":
100848
+ case "richText":
100849
+ case "media":
100850
+ case "link":
100851
+ case "select":
100852
+ case "passthrough":
100853
+ return value;
100854
+ default:
100855
+ return assertNever5(plan);
100653
100856
  }
100654
- });
100655
- function isEmpty(value) {
100857
+ }
100858
+ function normalizeObjectChildren(children, value, ctx) {
100859
+ if (!value || typeof value !== "object" || Array.isArray(value)) return value;
100860
+ const normalized = { ...value };
100861
+ for (const child of children) {
100862
+ normalized[child.fieldId] = normalizeFieldValue(child, normalized[child.fieldId], ctx);
100863
+ }
100864
+ return normalized;
100865
+ }
100866
+ function normalizeRepeaterItems(plan, value, ctx) {
100867
+ if (!Array.isArray(value)) return value;
100868
+ return value.map((item) => {
100869
+ if (!item || typeof item !== "object" || Array.isArray(item)) return item;
100870
+ const itemRecord = item;
100871
+ const fields3 = plan.repeatedItemVariants ? plan.repeatedItemVariants.find((variant) => variant.typeId === itemRecord._type)?.fields : plan.repeatedItemPlan;
100872
+ if (!fields3) return item;
100873
+ return normalizeObjectChildren(fields3, itemRecord, ctx);
100874
+ });
100875
+ }
100876
+ function normalizeNumberInput(value, _allowNull) {
100877
+ if (value === "") return void 0;
100878
+ if (typeof value === "string" && value.trim() !== "") return Number(value);
100879
+ return value;
100880
+ }
100881
+ function acceptsOptionalBlankAsMissing(plan, value) {
100882
+ if (plan.required || typeof value !== "string" || value.trim() !== "") return false;
100883
+ return plan.constraints.some(
100884
+ (constraint) => constraint.kind === "urlFormat" || constraint.kind === "slugFormat" || constraint.kind === "emailFormat" || constraint.kind === "phoneFormat" || constraint.kind === "patternFormat"
100885
+ );
100886
+ }
100887
+ function validateNormalizedFieldValue(plan, value, ctx) {
100888
+ if (value === null && (ctx.allowNull || acceptsOptionalNullValue(plan))) return [];
100889
+ if (isMissingForPlan(plan, value)) {
100890
+ return shouldRequireValue(plan, value, ctx) ? [requiredIssue(plan, value)] : [];
100891
+ }
100892
+ switch (plan.kind) {
100893
+ case "string":
100894
+ return validateStringPlan(plan, value);
100895
+ case "number":
100896
+ return validateNumberPlan(plan, value);
100897
+ case "boolean":
100898
+ return typeof value === "boolean" ? [] : [issue(plan, "wrongType", { expected: "a true/false value" })];
100899
+ case "select":
100900
+ return validateSelectPlan(plan, value);
100901
+ case "richText":
100902
+ return isValidRichTextDoc(value) ? [] : [issue(plan, "invalidRichText")];
100903
+ case "media":
100904
+ return isPlainObject3(value) ? [] : [issue(plan, "invalidMedia")];
100905
+ case "link":
100906
+ return linkSchema.safeParse(value).success ? [] : [issue(plan, "invalidLink")];
100907
+ case "repeater":
100908
+ return validateRepeaterPlan(plan, value, ctx);
100909
+ case "group":
100910
+ return validateGroupPlan(plan, value, ctx);
100911
+ case "passthrough":
100912
+ return [];
100913
+ default:
100914
+ return assertNever5(plan);
100915
+ }
100916
+ }
100917
+ function shouldRequireValue(plan, value, ctx) {
100918
+ if (!plan.required || ctx.allowIncomplete) return false;
100919
+ if (value === null && ctx.allowNull) return false;
100920
+ return true;
100921
+ }
100922
+ function acceptsOptionalNullValue(plan) {
100923
+ return !plan.required && (plan.kind === "media" || plan.kind === "number");
100924
+ }
100925
+ function isMissingForPlan(plan, value) {
100926
+ if (value === void 0) return true;
100927
+ if (value === null) return plan.required;
100656
100928
  if (typeof value === "string" && value.trim() === "") return true;
100929
+ if (Array.isArray(value) && value.length === 0) return true;
100930
+ return false;
100931
+ }
100932
+ function validateStringPlan(plan, value) {
100933
+ if (typeof value !== "string") return [issue(plan, "wrongType", { expected: "text" })];
100934
+ return plan.constraints.flatMap((constraint) => validateStringConstraint(plan, constraint, value));
100935
+ }
100936
+ function validateStringConstraint(plan, constraint, value) {
100937
+ switch (constraint.kind) {
100938
+ case "required":
100939
+ case "textType":
100940
+ case "referenceText":
100941
+ return [];
100942
+ case "maxLength":
100943
+ return value.length > constraint.maximum ? [issue(plan, "tooLong", { maximum: constraint.maximum })] : [];
100944
+ case "emailFormat":
100945
+ return z.email().safeParse(value).success ? [] : [issue(plan, "invalidEmail")];
100946
+ case "phoneFormat":
100947
+ return TEL_RE.test(value) ? [] : [issue(plan, "invalidPhone")];
100948
+ case "patternFormat": {
100949
+ const re2 = compilePattern(constraint.pattern);
100950
+ return re2 && !re2.test(value) ? [issue(plan, "invalidPattern")] : [];
100951
+ }
100952
+ case "urlFormat":
100953
+ return isValidUrl(value, constraint.allowRelative) ? [] : [issue(plan, "invalidUrl")];
100954
+ case "slugFormat":
100955
+ return SLUG_PATTERN.test(value) ? [] : [issue(plan, "invalidSlug")];
100956
+ default:
100957
+ return assertNever5(constraint);
100958
+ }
100959
+ }
100960
+ function validateNumberPlan(plan, value) {
100961
+ if (!isValidNumber(value)) return [issue(plan, "invalidNumber")];
100962
+ return plan.constraints.flatMap((constraint) => validateNumberConstraint(plan, constraint, Number(value)));
100963
+ }
100964
+ function validateNumberConstraint(plan, constraint, value) {
100965
+ switch (constraint.kind) {
100966
+ case "required":
100967
+ case "numberType":
100968
+ return [];
100969
+ case "numberMin":
100970
+ return value < constraint.minimum ? [issue(plan, "tooSmall", { minimum: constraint.minimum })] : [];
100971
+ case "numberMax":
100972
+ return value > constraint.maximum ? [issue(plan, "tooLarge", { maximum: constraint.maximum })] : [];
100973
+ default:
100974
+ return assertNever5(constraint);
100975
+ }
100976
+ }
100977
+ function validateSelectPlan(plan, value) {
100978
+ const constraint = plan.constraints.find((candidate) => candidate.kind === "selectOption");
100979
+ if (!constraint || constraint.source.kind === "runtime") return [];
100980
+ return isValidSelectValue(value, constraint.source.values, constraint.multiple) ? [] : [issue(plan, "invalidOption")];
100981
+ }
100982
+ function validateRepeaterPlan(plan, value, ctx) {
100983
+ if (!Array.isArray(value)) return [issue(plan, "wrongType", { expected: "a list" })];
100984
+ const constraintIssues = plan.constraints.flatMap((constraint) => {
100985
+ switch (constraint.kind) {
100986
+ case "required":
100987
+ case "arrayType":
100988
+ return [];
100989
+ case "minItems":
100990
+ return value.length < constraint.minimum ? [issue(plan, "tooFewItems", { minimum: constraint.minimum, itemLabel: "item" })] : [];
100991
+ case "maxItems":
100992
+ return value.length > constraint.maximum ? [issue(plan, "tooManyItems", { maximum: constraint.maximum, itemLabel: "item" })] : [];
100993
+ default:
100994
+ return assertNever5(constraint);
100995
+ }
100996
+ });
100997
+ return [
100998
+ ...constraintIssues,
100999
+ ...value.flatMap((item, index2) => validateRepeaterItem(plan, item, index2, ctx))
101000
+ ];
101001
+ }
101002
+ function validateRepeaterItem(plan, item, index2, ctx) {
101003
+ if (!isPlainObject3(item)) return [];
101004
+ const itemType = item._type;
101005
+ const fields3 = plan.repeatedItemVariants ? plan.repeatedItemVariants.find((variant) => variant.typeId === itemType)?.fields : plan.repeatedItemPlan;
101006
+ if (!fields3) return [];
101007
+ return fields3.flatMap((childPlan) => {
101008
+ const indexedPlan = materializeRepeaterItemPlan(childPlan, plan.path, index2);
101009
+ return validateNormalizedFieldValue(indexedPlan, item[childPlan.fieldId], ctx);
101010
+ });
101011
+ }
101012
+ function validateGroupPlan(plan, value, ctx) {
101013
+ if (!isPlainObject3(value)) return [issue(plan, "wrongType", { expected: "an object" })];
101014
+ const childCtx = childValidationContext(plan, ctx);
101015
+ return plan.children.flatMap((childPlan) => validateNormalizedFieldValue(childPlan, value[childPlan.fieldId], childCtx));
101016
+ }
101017
+ function childValidationContext(plan, ctx) {
101018
+ return plan.allowNullChildren ? { ...ctx, allowNull: true } : ctx;
101019
+ }
101020
+ function materializeRepeaterItemPlan(plan, parentPath, index2) {
101021
+ return rebaseFieldPlanPath(plan, [...parentPath, 0], [...parentPath, index2]);
101022
+ }
101023
+ function rebaseFieldPlanPath(plan, fromPrefix, toPrefix) {
101024
+ const path = rebaseFieldPath(plan.path, fromPrefix, toPrefix);
101025
+ switch (plan.kind) {
101026
+ case "group":
101027
+ return {
101028
+ ...plan,
101029
+ path,
101030
+ children: plan.children.map((childPlan) => rebaseFieldPlanPath(childPlan, fromPrefix, toPrefix))
101031
+ };
101032
+ case "repeater":
101033
+ return {
101034
+ ...plan,
101035
+ path,
101036
+ ...plan.repeatedItemVariants ? {
101037
+ repeatedItemVariants: plan.repeatedItemVariants.map((variant) => ({
101038
+ ...variant,
101039
+ fields: variant.fields.map((fieldPlan) => rebaseFieldPlanPath(fieldPlan, fromPrefix, toPrefix))
101040
+ }))
101041
+ } : {},
101042
+ ...plan.repeatedItemPlan ? {
101043
+ repeatedItemPlan: plan.repeatedItemPlan.map(
101044
+ (fieldPlan) => rebaseFieldPlanPath(fieldPlan, fromPrefix, toPrefix)
101045
+ )
101046
+ } : {}
101047
+ };
101048
+ case "string":
101049
+ case "number":
101050
+ case "boolean":
101051
+ case "richText":
101052
+ case "media":
101053
+ case "link":
101054
+ case "select":
101055
+ case "passthrough":
101056
+ return {
101057
+ ...plan,
101058
+ path
101059
+ };
101060
+ default:
101061
+ return assertNever5(plan);
101062
+ }
101063
+ }
101064
+ function rebaseFieldPath(path, fromPrefix, toPrefix) {
101065
+ if (!startsWithFieldPath(path, fromPrefix)) {
101066
+ throw new Error(`Cannot rebase field path ${formatFieldPath(path)} from ${formatFieldPath(fromPrefix)}`);
101067
+ }
101068
+ return [...toPrefix, ...path.slice(fromPrefix.length)];
101069
+ }
101070
+ function startsWithFieldPath(path, prefix) {
101071
+ return prefix.every((segment, index2) => path[index2] === segment);
101072
+ }
101073
+ function issue(plan, kind, extra) {
101074
+ return {
101075
+ kind,
101076
+ path: plan.path,
101077
+ fieldId: plan.fieldId,
101078
+ label: plan.label,
101079
+ ...extra ?? {}
101080
+ };
101081
+ }
101082
+ function requiredIssue(plan, value) {
101083
+ if (typeof value === "string") return issue(plan, "required", { emptyOrigin: "string" });
101084
+ if (Array.isArray(value)) return issue(plan, "required", { emptyOrigin: "array" });
101085
+ return issue(plan, "required");
101086
+ }
101087
+ function fieldPlanToZod(plan, options = {}) {
101088
+ const ctx = validationContext(options);
101089
+ return z.any().transform((value) => normalizeFieldValue(plan, value, ctx)).superRefine((value, zodCtx) => {
101090
+ for (const validationIssue of validateNormalizedFieldValue(plan, value, ctx)) {
101091
+ addFieldIssueToZodContext(zodCtx, validationIssue);
101092
+ }
101093
+ });
101094
+ }
101095
+ function addFieldIssueToZodContext(zodCtx, validationIssue) {
101096
+ const message2 = fieldIssueToMessage(validationIssue);
101097
+ switch (validationIssue.kind) {
101098
+ case "required":
101099
+ if (validationIssue.emptyOrigin) {
101100
+ zodCtx.addIssue({
101101
+ code: "too_small",
101102
+ origin: validationIssue.emptyOrigin,
101103
+ minimum: 1,
101104
+ inclusive: true,
101105
+ message: message2
101106
+ });
101107
+ return;
101108
+ }
101109
+ zodCtx.addIssue({ code: "invalid_type", expected: "nonoptional", message: message2 });
101110
+ return;
101111
+ case "tooLong":
101112
+ zodCtx.addIssue({
101113
+ code: "too_big",
101114
+ origin: "string",
101115
+ maximum: validationIssue.maximum,
101116
+ inclusive: true,
101117
+ message: message2
101118
+ });
101119
+ return;
101120
+ case "invalidOption":
101121
+ zodCtx.addIssue({ code: "invalid_value", values: [], message: message2 });
101122
+ return;
101123
+ case "wrongType":
101124
+ case "invalidEmail":
101125
+ case "invalidPhone":
101126
+ case "invalidPattern":
101127
+ case "invalidUrl":
101128
+ case "invalidNumber":
101129
+ case "tooSmall":
101130
+ case "tooLarge":
101131
+ case "invalidSlug":
101132
+ case "tooFewItems":
101133
+ case "tooManyItems":
101134
+ case "invalidRichText":
101135
+ case "invalidMedia":
101136
+ case "invalidLink":
101137
+ case "invalidReference":
101138
+ zodCtx.addIssue({ code: "custom", message: message2 });
101139
+ return;
101140
+ default:
101141
+ assertNever5(validationIssue);
101142
+ }
101143
+ }
101144
+ function compilePattern(pattern) {
101145
+ try {
101146
+ return new RegExp(pattern);
101147
+ } catch {
101148
+ return null;
101149
+ }
101150
+ }
101151
+ function isValidNumber(value) {
101152
+ return typeof value === "number" && Number.isFinite(value);
101153
+ }
101154
+ function isValidUrl(value, allowRelative) {
101155
+ if (!value) return false;
101156
+ if (allowRelative && value.startsWith("/")) return true;
101157
+ try {
101158
+ const parsed = new URL(value);
101159
+ return ALLOWED_URL_PROTOCOLS.includes(parsed.protocol);
101160
+ } catch {
101161
+ return false;
101162
+ }
101163
+ }
101164
+ function isValidSelectValue(value, values, multiple) {
101165
+ if (multiple) {
101166
+ return Array.isArray(value) && value.every((item) => typeof item === "string" && values.includes(item));
101167
+ }
101168
+ return typeof value === "string" && values.includes(value);
101169
+ }
101170
+ function isEmptyValue(value) {
100657
101171
  if (value === null || value === void 0) return true;
101172
+ if (typeof value === "string" && value.trim() === "") return true;
100658
101173
  if (Array.isArray(value) && value.length === 0) return true;
100659
101174
  if (isEmptyRichTextDoc(value)) return true;
100660
101175
  return false;
100661
101176
  }
101177
+ function isPlainObject3(value) {
101178
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
101179
+ }
101180
+ function isValidRichTextDoc(value) {
101181
+ const doc3 = richTextDoc(value);
101182
+ return Boolean(isPlainObject3(doc3) && doc3.type === "doc");
101183
+ }
100662
101184
  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;
101185
+ const doc3 = richTextDoc(value);
101186
+ if (!isPlainObject3(doc3)) return false;
101187
+ if (doc3.type !== "doc") return false;
101188
+ const content = doc3.content;
100670
101189
  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;
100675
- }
101190
+ if (content.length !== 1) return false;
101191
+ const first2 = content[0];
101192
+ return first2?.type === "paragraph" && (!Array.isArray(first2.content) || first2.content.length === 0);
101193
+ }
101194
+ function richTextDoc(value) {
101195
+ if (!isPlainObject3(value)) return value;
101196
+ return isPlainObject3(value.doc) ? value.doc : value;
101197
+ }
101198
+ var TEL_RE, SLUG_PATTERN, ALLOWED_URL_PROTOCOLS;
101199
+ var init_fieldValidation = __esm({
101200
+ "../blocks/src/system/manifest/fieldValidation/index.ts"() {
101201
+ init_link2();
101202
+ init_schema3();
101203
+ TEL_RE = /^[+()0-9\s-]{3,}$/;
101204
+ SLUG_PATTERN = /^(?:[a-z0-9]+(?:-[a-z0-9]+)*)(?:\/(?:[a-z0-9]+(?:-[a-z0-9]+)*))*$/;
101205
+ ALLOWED_URL_PROTOCOLS = ["http:", "https:"];
100676
101206
  }
100677
- return false;
101207
+ });
101208
+
101209
+ // ../blocks/src/system/manifest/registry.ts
101210
+ function registerManifest(manifest) {
101211
+ manifestStore.set(manifest.name, manifest);
101212
+ return manifest;
100678
101213
  }
101214
+ var REGISTRY_SYMBOL, isVitest, globalScope, manifestStore;
101215
+ var init_registry2 = __esm({
101216
+ "../blocks/src/system/manifest/registry.ts"() {
101217
+ REGISTRY_SYMBOL = /* @__PURE__ */ Symbol.for("@riverbankcms/blocks/manifest-registry");
101218
+ isVitest = typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.VITEST === "true";
101219
+ globalScope = globalThis;
101220
+ manifestStore = isVitest ? /* @__PURE__ */ new Map() : globalScope[REGISTRY_SYMBOL] ?? (globalScope[REGISTRY_SYMBOL] = /* @__PURE__ */ new Map());
101221
+ }
101222
+ });
100679
101223
  function preprocessEmptyValues(content) {
100680
101224
  if (!content || typeof content !== "object" || Array.isArray(content)) {
100681
101225
  return {};
100682
101226
  }
100683
101227
  const result = {};
100684
101228
  for (const [key, value] of Object.entries(content)) {
100685
- result[key] = isEmpty(value) ? void 0 : value;
101229
+ result[key] = isEmptyValue(value) ? void 0 : value;
100686
101230
  }
100687
101231
  return result;
100688
101232
  }
100689
101233
  function createManifestValidator(manifestOrFields, options = {}) {
100690
- const allowNull = options.allowNull ?? true;
100691
101234
  const isDraft = options.mode === "draft";
100692
- const allowIncomplete = isDraft || (options.allowIncomplete ?? false);
100693
101235
  const shape = {};
100694
101236
  const fields3 = Array.isArray(manifestOrFields) ? manifestOrFields : manifestOrFields.fields ?? [];
100695
101237
  for (const field of fields3) {
100696
- shape[field.id] = buildFieldSchema(field, allowNull, allowIncomplete);
101238
+ shape[field.id] = buildFieldSchema(field, options);
100697
101239
  }
100698
101240
  const baseSchema = z.object(shape).catchall(z.unknown()).passthrough();
100699
101241
  if (isDraft) {
@@ -100701,275 +101243,12 @@ function createManifestValidator(manifestOrFields, options = {}) {
100701
101243
  }
100702
101244
  return baseSchema;
100703
101245
  }
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
- }
100720
- 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;
100732
- case "select":
100733
- schema = buildSelectSchema(field);
100734
- break;
100735
- case "reference":
100736
- schema = buildReferenceSchema(field);
100737
- break;
100738
- case "repeater":
100739
- schema = buildRepeaterSchema(field, allowNull, allowIncomplete);
100740
- break;
100741
- case "group":
100742
- schema = buildGroupSchema(field, allowNull, allowIncomplete);
100743
- break;
100744
- default:
100745
- schema = z.unknown();
100746
- break;
100747
- }
100748
- return finalizeSchema(schema, required, allowNull, allowIncomplete);
100749
- }
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
- });
100754
- }
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;
100808
- }
100809
- function buildRichTextSchema2() {
100810
- return buildRichTextSchema();
100811
- }
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
- );
100820
- }
100821
- if (field.required) {
100822
- schema = schema.min(1, { message: `${field.label} is required` });
100823
- }
100824
- return schema;
100825
- }
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;
100842
- }
100843
- };
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
- }
100850
- function buildLinkSchema() {
100851
- return linkSchema;
100852
- }
100853
- function assertNeverSelectSource2(value) {
100854
- throw new Error(`Unhandled select source: ${JSON.stringify(value)}`);
100855
- }
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);
100872
- }
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();
100877
- }
100878
- return field.required ? singleValueSchema : singleValueSchema.nullable();
100879
- }
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` });
100886
- }
100887
- return schema;
101246
+ function buildFieldSchema(field, options) {
101247
+ return fieldPlanToZod(deriveFieldValidationPlan(field), options);
100888
101248
  }
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
- }
100901
- }
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);
100906
- }
100907
- if (typeof field.maxItems === "number") {
100908
- arraySchema = arraySchema.max(field.maxItems);
100909
- }
100910
- return arraySchema;
100911
- }
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);
100917
- }
100918
- return z.object(childShape).catchall(z.unknown()).passthrough();
100919
- }
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;
100926
- }
100927
- return allowNull ? schema.optional().nullable() : schema.optional();
100928
- }
100929
- var SLUG_PATTERN, ALLOWED_URL_PROTOCOLS, nullableString, internalLinkSchema, externalLinkSchema, customLinkSchema, pageLinkSchema, entryLinkSchema, linkSchema;
100930
101249
  var init_validation = __esm({
100931
101250
  "../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
- ]);
101251
+ init_fieldValidation();
100973
101252
  }
100974
101253
  });
100975
101254
 
@@ -101006,6 +101285,7 @@ var init_manifest = __esm({
101006
101285
  "../blocks/src/system/manifest/index.ts"() {
101007
101286
  init_augmentManifest();
101008
101287
  init_fieldPath();
101288
+ init_fieldValidation();
101009
101289
  init_registry2();
101010
101290
  init_schema3();
101011
101291
  init_validation();
@@ -101072,7 +101352,7 @@ function makeBoundaryId(previousBlockId, nextBlockId) {
101072
101352
  const next = encodeURIComponent(nextBlockId);
101073
101353
  return asDesignBoundaryId(`boundary:${previous}:${next}`);
101074
101354
  }
101075
- function assertNever5(value, message2 = "Unhandled Theme V2 variant") {
101355
+ function assertNever6(value, message2 = "Unhandled Theme V2 variant") {
101076
101356
  throw new Error(`${message2}: ${String(value)}`);
101077
101357
  }
101078
101358
  function brandNonEmptyString(value, label) {
@@ -101397,6 +101677,15 @@ var init_curatedChoices = __esm({
101397
101677
  "../theme-core/src/site-styles/curatedChoices.ts"() {
101398
101678
  }
101399
101679
  });
101680
+ function isVariantRole(value) {
101681
+ return VARIANT_ROLES.includes(value);
101682
+ }
101683
+ function asSpecialVariantId(value) {
101684
+ if (value.length === 0) {
101685
+ throw new Error("SpecialVariantId must be a non-empty string");
101686
+ }
101687
+ return value;
101688
+ }
101400
101689
  var VARIANT_ROLES, DEFAULT_VARIANT_ALIAS_ID, cornerStyleSchema, shadowSizeSchema, textTransformSchema, fontWeightSchema, buttonTypographySchema, letterSpacingSchema, hoverTransformSchema, hoverColorSchema, buttonPaddingPresetSchema, gradientStyleSchema, gradientSharpnessSchema, prioritySchema, buttonSizeNameSchema, PADDING_TOKEN_PATTERN, paddingShorthandSchema, buttonSizeConfigSchema, buttonSizesSchema, buttonGlobalSettingsSchema, gradientDirectionSchema, buttonBackgroundSchema, effectApplicationSchema, buttonBorderSchema, variantShadowSchema, variantEffectsSchema, variantSizeOverridesSchema, buttonVariantSchema, buttonSystemSchema;
101401
101690
  var init_types6 = __esm({
101402
101691
  "../theme-core/src/buttons/types.ts"() {
@@ -102177,49 +102466,90 @@ var init_personalities = __esm({
102177
102466
  var hotspotSchema, rotationSchema, rectSchema, aspectCropSchema, transformSchema, mediaSchema;
102178
102467
  var init_media = __esm({
102179
102468
  "../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) => {
102469
+ hotspotSchema = z38.object({
102470
+ x: z38.number().min(0).max(1),
102471
+ y: z38.number().min(0).max(1),
102472
+ radius: z38.number().optional()
102473
+ });
102474
+ rotationSchema = z38.union([z38.literal(0), z38.literal(90), z38.literal(180), z38.literal(270)]);
102475
+ rectSchema = z38.tuple([z38.number(), z38.number(), z38.number(), z38.number()]);
102476
+ aspectCropSchema = z38.object({
102477
+ aspect: z38.preprocess((value) => value == null ? void 0 : value, z38.string().optional()),
102478
+ rect: z38.preprocess((value) => value == null ? void 0 : value, rectSchema.optional()),
102479
+ hotspot: z38.preprocess((value) => value == null ? void 0 : value, hotspotSchema.optional()),
102480
+ rotation: z38.preprocess((value) => value == null ? void 0 : value, rotationSchema.optional())
102481
+ });
102482
+ transformSchema = z38.object({
102483
+ aspectCrops: z38.preprocess((value) => {
102195
102484
  if (!value || typeof value !== "object" || Array.isArray(value)) {
102196
102485
  return void 0;
102197
102486
  }
102198
102487
  return value;
102199
- }, z37.record(z37.string(), aspectCropSchema.catch({}))).optional(),
102488
+ }, z38.record(z38.string(), aspectCropSchema.catch({}))).optional(),
102200
102489
  rect: rectSchema.optional(),
102201
102490
  hotspot: hotspotSchema.optional(),
102202
102491
  rotation: rotationSchema.optional()
102203
102492
  });
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(),
102493
+ mediaSchema = z38.object({
102494
+ type: z38.enum(["image", "video", "audio", "document", "spreadsheet", "archive"]),
102495
+ purpose: z38.string().optional(),
102496
+ placeholder: z38.boolean().default(true).optional(),
102497
+ assetId: z38.string().optional(),
102498
+ identifier: z38.string().optional(),
102499
+ src: z38.string().optional(),
102500
+ alt: z38.string().optional(),
102501
+ filename: z38.string().optional(),
102502
+ mimeType: z38.string().optional(),
102503
+ width: z38.number().optional(),
102504
+ height: z38.number().optional(),
102505
+ storageBucket: z38.string().optional(),
102506
+ storagePath: z38.string().optional(),
102218
102507
  transform: transformSchema.optional()
102219
102508
  });
102220
102509
  }
102221
102510
  });
102222
102511
 
102512
+ // ../theme-core/src/buttons/classNames.ts
102513
+ function parseThemeButtonVariantId(value) {
102514
+ const normalized = value?.trim() ?? "";
102515
+ if (normalized.length === 0) {
102516
+ return null;
102517
+ }
102518
+ if (normalized === DEFAULT_VARIANT_ALIAS_ID) {
102519
+ return DEFAULT_VARIANT_ALIAS_ID;
102520
+ }
102521
+ return isVariantRole(normalized) ? normalized : asSpecialVariantId(normalized);
102522
+ }
102523
+ function themeButtonVariantClassNames(variant) {
102524
+ if (variant === DEFAULT_VARIANT_ALIAS_ID) {
102525
+ return [variant];
102526
+ }
102527
+ return [variant, `button-${variant}`];
102528
+ }
102529
+ function themeButtonSizeClassName(size4) {
102530
+ return `btn-${size4}`;
102531
+ }
102532
+ function themeButtonSelector(variant, size4) {
102533
+ const baseSelector = `.${variant}`;
102534
+ if (!size4) {
102535
+ return baseSelector;
102536
+ }
102537
+ return `${baseSelector}.${themeButtonSizeClassName(size4)}`;
102538
+ }
102539
+ function themeButtonClassName(spec) {
102540
+ const classes = [
102541
+ ...themeButtonVariantClassNames(spec.variant),
102542
+ themeButtonSizeClassName(spec.size),
102543
+ spec.extraClassName
102544
+ ];
102545
+ return classes.filter(Boolean).join(" ");
102546
+ }
102547
+ var init_classNames = __esm({
102548
+ "../theme-core/src/buttons/classNames.ts"() {
102549
+ init_types6();
102550
+ }
102551
+ });
102552
+
102223
102553
  // ../theme-core/src/tokens/resolver.ts
102224
102554
  var TokenResolver;
102225
102555
  var init_resolver = __esm({
@@ -103872,17 +104202,25 @@ function resolveAliasSource(enabled) {
103872
104202
  }
103873
104203
  function variantChunks(variant, global2, themeSizes, themeId, tokens, theme) {
103874
104204
  const out = [];
103875
- out.push(variantBaseRule(variant, global2, themeId, tokens, theme));
103876
- const hoverBg = variantHoverBackgroundRule(variant, global2, themeId, tokens);
104205
+ const variantId = parseButtonVariantIdForCss(variant.id);
104206
+ out.push(variantBaseRule(variant, variantId, global2, themeId, tokens, theme));
104207
+ const hoverBg = variantHoverBackgroundRule(variant, variantId, global2, themeId, tokens);
103877
104208
  if (hoverBg) out.push(hoverBg);
103878
104209
  const effects = variantEffectsCss(variant, themeId, tokens, theme);
103879
104210
  if (effects) out.push({ raw: effects });
103880
- out.push(...variantDisabledRules(variant, themeId));
103881
- out.push(...variantSizeRules(variant, themeSizes, themeId));
104211
+ out.push(...variantDisabledRules(variantId, themeId));
104212
+ out.push(...variantSizeRules(variant, variantId, themeSizes, themeId));
103882
104213
  return out;
103883
104214
  }
103884
- function variantBaseRule(variant, global2, themeId, tokens, theme) {
103885
- const selector = `:where([data-theme-scope="${themeId}"]) .${variant.id}`;
104215
+ function parseButtonVariantIdForCss(value) {
104216
+ const variantId = parseThemeButtonVariantId(value);
104217
+ if (!variantId) {
104218
+ throw new Error("Button variant id must be a non-empty string");
104219
+ }
104220
+ return variantId;
104221
+ }
104222
+ function variantBaseRule(variant, variantId, global2, themeId, tokens, theme) {
104223
+ const selector = `:where([data-theme-scope="${themeId}"]) ${themeButtonSelector(variantId)}`;
103886
104224
  const decls = [];
103887
104225
  decls.push(["font-weight", String(global2.fontWeight)]);
103888
104226
  decls.push(["font-family", resolveFontFamily(global2)]);
@@ -103915,13 +104253,13 @@ function variantBaseRule(variant, global2, themeId, tokens, theme) {
103915
104253
  }
103916
104254
  return rule(selector, decls);
103917
104255
  }
103918
- function variantHoverBackgroundRule(variant, global2, themeId, tokens) {
104256
+ function variantHoverBackgroundRule(variant, variantId, global2, themeId, tokens) {
103919
104257
  let hoverToken = variant.hoverBackgroundToken;
103920
104258
  if (!hoverToken && global2.hoverColor === "token" && global2.hoverColorToken) {
103921
104259
  hoverToken = global2.hoverColorToken;
103922
104260
  }
103923
104261
  if (!hoverToken) return null;
103924
- return rule(`:where([data-theme-scope="${themeId}"]) .${variant.id}:hover`, [
104262
+ return rule(`:where([data-theme-scope="${themeId}"]) ${themeButtonSelector(variantId)}:hover`, [
103925
104263
  ["background-color", tokens.getColor(hoverToken)]
103926
104264
  ]);
103927
104265
  }
@@ -103941,8 +104279,8 @@ function variantEffectsCss(variant, themeId, tokens, theme) {
103941
104279
  theme
103942
104280
  });
103943
104281
  }
103944
- function variantDisabledRules(variant, themeId) {
103945
- const base2 = `:where([data-theme-scope="${themeId}"]) .${variant.id}:disabled`;
104282
+ function variantDisabledRules(variantId, themeId) {
104283
+ const base2 = `:where([data-theme-scope="${themeId}"]) ${themeButtonSelector(variantId)}:disabled`;
103946
104284
  const disabledSelectors = [base2, `${base2}:hover`, `${base2}:active`, `${base2}:focus`];
103947
104285
  const pseudoSelectors = [`${base2}::before`, `${base2}::after`];
103948
104286
  return [
@@ -103960,12 +104298,12 @@ function variantDisabledRules(variant, themeId) {
103960
104298
  ])
103961
104299
  ];
103962
104300
  }
103963
- function variantSizeRules(variant, themeSizes, themeId) {
104301
+ function variantSizeRules(variant, variantId, themeSizes, themeId) {
103964
104302
  const borderWidth = variant.border ? BORDER_WIDTH_MAP[variant.border.widthClass] || "1px" : "0px";
103965
104303
  const rules = [];
103966
104304
  for (const sizeName of BUTTON_SIZE_NAMES) {
103967
104305
  const config = resolveSizeConfig(variant, sizeName, themeSizes);
103968
- const selector = `:where([data-theme-scope="${themeId}"]) .${variant.id}.btn-${sizeName}`;
104306
+ const selector = `:where([data-theme-scope="${themeId}"]) ${themeButtonSelector(variantId, sizeName)}`;
103969
104307
  const decls = [];
103970
104308
  for (const decl of paddingDeclarations(config.padding, borderWidth)) decls.push(decl);
103971
104309
  if (config.fontSize) {
@@ -104027,6 +104365,7 @@ var BUTTON_SIZE_NAMES, LETTER_SPACING_MAP, STRUCTURAL_DECLARATIONS;
104027
104365
  var init_generateButtonCss = __esm({
104028
104366
  "../theme-core/src/buttons/generateButtonCss.ts"() {
104029
104367
  init_types6();
104368
+ init_classNames();
104030
104369
  init_resolver();
104031
104370
  init_generateEffectsCSS();
104032
104371
  init_constants4();
@@ -104069,6 +104408,7 @@ var init_core = __esm({
104069
104408
  var init_buttons = __esm({
104070
104409
  "../theme-core/src/buttons/index.ts"() {
104071
104410
  init_types6();
104411
+ init_classNames();
104072
104412
  init_generateButtonCss();
104073
104413
  init_generateDefaultButtonSystem();
104074
104414
  init_constants4();
@@ -106800,7 +107140,7 @@ function compileContainerStyles(contentFrame, rules) {
106800
107140
  })
106801
107141
  };
106802
107142
  default:
106803
- return assertNever5(contentFrame);
107143
+ return assertNever6(contentFrame);
106804
107144
  }
106805
107145
  }
106806
107146
  function compileBlockRuntimeFields(input) {
@@ -107184,8 +107524,8 @@ var init_generatedDesignPipeline = __esm({
107184
107524
  }
107185
107525
  });
107186
107526
  function validateBlockSequence(snapshots, ctx) {
107187
- for (const issue of collectBlockSequenceIssues(snapshots)) {
107188
- ctx.addIssue(issue);
107527
+ for (const issue2 of collectBlockSequenceIssues(snapshots)) {
107528
+ ctx.addIssue(issue2);
107189
107529
  }
107190
107530
  }
107191
107531
  function collectBlockSequenceIssues(snapshots) {
@@ -113741,9 +114081,9 @@ function createZodCodec(schema) {
113741
114081
  return decodeSuccess(parsed.data);
113742
114082
  }
113743
114083
  return decodeFailure(
113744
- parsed.error.issues.map((issue) => ({
113745
- path: zodIssuePath(issue.path),
113746
- message: issue.message
114084
+ parsed.error.issues.map((issue2) => ({
114085
+ path: zodIssuePath(issue2.path),
114086
+ message: issue2.message
113747
114087
  }))
113748
114088
  );
113749
114089
  }
@@ -114151,7 +114491,7 @@ function getNavStyleClasses(navStyle) {
114151
114491
  return baseClasses;
114152
114492
  }
114153
114493
  }
114154
- function isPlainObject3(value) {
114494
+ function isPlainObject4(value) {
114155
114495
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
114156
114496
  }
114157
114497
  function readString(obj, key) {
@@ -114279,7 +114619,7 @@ var init_ui = __esm({
114279
114619
  summary: "Resolve hero content wrapper className from alignment + max width controls",
114280
114620
  schema: heroContentWrapperClassSchema,
114281
114621
  run: (value, options, context) => {
114282
- const content = isPlainObject3(value) ? value : isPlainObject3(context.data) ? context.data : {};
114622
+ const content = isPlainObject4(value) ? value : isPlainObject4(context.data) ? context.data : {};
114283
114623
  const alignment = resolveHeroContentAlignment(content);
114284
114624
  const maxWidth = resolveHeroContentMaxWidth(content);
114285
114625
  const textAlignClass = alignment === "center" ? "rb-text-center" : alignment === "right" ? "rb-text-right" : "rb-text-left";
@@ -114298,7 +114638,7 @@ var init_ui = __esm({
114298
114638
  kind: "string",
114299
114639
  summary: "Map hero contentAlignment to CTA row justify value",
114300
114640
  run: (value, _options, context) => {
114301
- const content = isPlainObject3(value) ? value : isPlainObject3(context.data) ? context.data : {};
114641
+ const content = isPlainObject4(value) ? value : isPlainObject4(context.data) ? context.data : {};
114302
114642
  const alignment = resolveHeroContentAlignment(content);
114303
114643
  return alignment === "left" ? "start" : alignment === "right" ? "end" : "center";
114304
114644
  }
@@ -114308,7 +114648,7 @@ var init_ui = __esm({
114308
114648
  kind: "string",
114309
114649
  summary: "Map hero verticalAlignment to stack justify value",
114310
114650
  run: (value, _options, context) => {
114311
- const content = isPlainObject3(value) ? value : isPlainObject3(context.data) ? context.data : {};
114651
+ const content = isPlainObject4(value) ? value : isPlainObject4(context.data) ? context.data : {};
114312
114652
  const vertical = resolveHeroVerticalAlignment(content);
114313
114653
  return vertical === "top" ? "start" : vertical === "bottom" ? "end" : "center";
114314
114654
  }
@@ -114322,7 +114662,7 @@ var init_ui = __esm({
114322
114662
  summary: "Append align-items class for hero split layouts based on verticalAlignment",
114323
114663
  schema: heroGridClassFromVerticalAlignmentSchema,
114324
114664
  run: (value, options, context) => {
114325
- const content = isPlainObject3(value) ? value : isPlainObject3(context.data) ? context.data : {};
114665
+ const content = isPlainObject4(value) ? value : isPlainObject4(context.data) ? context.data : {};
114326
114666
  const vertical = resolveHeroVerticalAlignment(content);
114327
114667
  const itemsClass = vertical === "top" ? "rb-items-start" : vertical === "bottom" ? "rb-items-end" : "rb-items-center";
114328
114668
  return joinClasses3([options.base, itemsClass]);
@@ -115202,6 +115542,18 @@ var init_media2 = __esm({
115202
115542
  mediaTransforms = [mediaFromUrl];
115203
115543
  }
115204
115544
  });
115545
+
115546
+ // ../blocks/src/lib/typeGuards.ts
115547
+ function isRecord5(value) {
115548
+ return typeof value === "object" && value !== null && !Array.isArray(value);
115549
+ }
115550
+ function isObjectRecord2(value) {
115551
+ return typeof value === "object" && value !== null;
115552
+ }
115553
+ var init_typeGuards2 = __esm({
115554
+ "../blocks/src/lib/typeGuards.ts"() {
115555
+ }
115556
+ });
115205
115557
  function getSiteName(context) {
115206
115558
  const viewModel = context.viewModel;
115207
115559
  if (!isRecord5(viewModel)) return null;
@@ -117286,52 +117638,52 @@ var init_media3 = __esm({
117286
117638
  "audio",
117287
117639
  "video"
117288
117640
  ];
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) => {
117641
+ hotspotSchema2 = z38.object({
117642
+ x: z38.number().min(0).max(1),
117643
+ y: z38.number().min(0).max(1),
117644
+ radius: z38.number().optional()
117645
+ });
117646
+ rotationSchema2 = z38.union([z38.literal(0), z38.literal(90), z38.literal(180), z38.literal(270)]);
117647
+ rectSchema2 = z38.tuple([z38.number(), z38.number(), z38.number(), z38.number()]);
117648
+ aspectCropSchema2 = z38.object({
117649
+ aspect: z38.preprocess((value) => value == null ? void 0 : value, z38.string().optional()),
117650
+ rect: z38.preprocess((value) => value == null ? void 0 : value, rectSchema2.optional()),
117651
+ hotspot: z38.preprocess((value) => value == null ? void 0 : value, hotspotSchema2.optional()),
117652
+ rotation: z38.preprocess((value) => value == null ? void 0 : value, rotationSchema2.optional())
117653
+ });
117654
+ transformSchema2 = z38.object({
117655
+ aspectCrops: z38.preprocess((value) => {
117304
117656
  if (!value || typeof value !== "object" || Array.isArray(value)) {
117305
117657
  return void 0;
117306
117658
  }
117307
117659
  return value;
117308
- }, z37.record(z37.string(), aspectCropSchema2.catch({}))).optional(),
117660
+ }, z38.record(z38.string(), aspectCropSchema2.catch({}))).optional(),
117309
117661
  rect: rectSchema2.optional(),
117310
117662
  hotspot: hotspotSchema2.optional(),
117311
117663
  rotation: rotationSchema2.optional()
117312
117664
  });
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(),
117665
+ mediaBaseSchema = z38.object({
117666
+ purpose: z38.string().optional(),
117667
+ placeholder: z38.boolean().default(true).optional(),
117668
+ assetId: z38.string().optional(),
117669
+ identifier: z38.string().optional(),
117670
+ src: z38.string().optional(),
117671
+ alt: z38.string().optional(),
117672
+ filename: z38.string().optional(),
117673
+ mimeType: z38.string().optional(),
117674
+ width: z38.number().optional(),
117675
+ height: z38.number().optional(),
117676
+ storageBucket: z38.string().optional(),
117677
+ storagePath: z38.string().optional(),
117326
117678
  transform: transformSchema2.optional()
117327
117679
  });
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", [
117680
+ imageMediaSchema = mediaBaseSchema.extend({ type: z38.literal("image") });
117681
+ videoMediaSchema = mediaBaseSchema.extend({ type: z38.literal("video") });
117682
+ audioMediaSchema = mediaBaseSchema.extend({ type: z38.literal("audio") });
117683
+ documentMediaSchema = mediaBaseSchema.extend({ type: z38.literal("document") });
117684
+ spreadsheetMediaSchema = mediaBaseSchema.extend({ type: z38.literal("spreadsheet") });
117685
+ archiveMediaSchema = mediaBaseSchema.extend({ type: z38.literal("archive") });
117686
+ mediaSchema2 = z38.discriminatedUnion("type", [
117335
117687
  imageMediaSchema,
117336
117688
  videoMediaSchema,
117337
117689
  audioMediaSchema,
@@ -120815,18 +121167,6 @@ var init_EventCardIcons = __esm({
120815
121167
  "../blocks/src/system/runtime/nodes/events/shared/EventCardIcons.tsx"() {
120816
121168
  }
120817
121169
  });
120818
-
120819
- // ../blocks/src/system/runtime/shared/themedButtonClass.ts
120820
- function themedButtonClass(spec) {
120821
- const { variant, size: size4, extraClassName } = spec;
120822
- const normalizedVariant = variant.trim();
120823
- const variantClasses = normalizedVariant ? [normalizedVariant, `button-${normalizedVariant}`] : [];
120824
- return [...variantClasses, `btn-${size4}`, extraClassName].filter(Boolean).join(" ");
120825
- }
120826
- var init_themedButtonClass = __esm({
120827
- "../blocks/src/system/runtime/shared/themedButtonClass.ts"() {
120828
- }
120829
- });
120830
121170
  function formatCapacityText(event, options) {
120831
121171
  if (event.capacity == null) return null;
120832
121172
  if (options.isSoldOut) return "Sold out";
@@ -120871,7 +121211,7 @@ var init_EventCard = __esm({
120871
121211
  init_EventCardIcons();
120872
121212
  init_eventCapacity();
120873
121213
  init_utils7();
120874
- init_themedButtonClass();
121214
+ init_buttons();
120875
121215
  EventCard = ({
120876
121216
  event,
120877
121217
  cardVariant = "default",
@@ -120897,7 +121237,7 @@ var init_EventCard = __esm({
120897
121237
  const isSoldOut = cta.hidden;
120898
121238
  const { available: spotsLeft } = getEventAvailability(event);
120899
121239
  const cardClass = `card-${cardVariant}`;
120900
- const buttonClass = themedButtonClass({ variant: buttonVariant, size: "md" });
121240
+ const buttonClass = themeButtonClassName({ variant: buttonVariant, size: "md" });
120901
121241
  const title = event.title;
120902
121242
  const summary = event.presentation?.summary ?? event.description;
120903
121243
  const image = event.presentation?.image ?? null;
@@ -120975,7 +121315,7 @@ var init_EventCompactRow = __esm({
120975
121315
  "../blocks/src/system/runtime/nodes/events/shared/EventCompactRow.tsx"() {
120976
121316
  init_utils7();
120977
121317
  init_EventCardIcons();
120978
- init_themedButtonClass();
121318
+ init_buttons();
120979
121319
  EventCompactRow = ({
120980
121320
  event,
120981
121321
  buttonVariant = "primary",
@@ -120987,7 +121327,7 @@ var init_EventCompactRow = __esm({
120987
121327
  const price = formatEventPrice(event);
120988
121328
  const teacherLine = formatEventTeacherLine(event);
120989
121329
  const cta = resolveEventCta(event, buttonText);
120990
- const buttonClass = themedButtonClass({ variant: buttonVariant, size: "sm" });
121330
+ const buttonClass = themeButtonClassName({ variant: buttonVariant, size: "sm" });
120991
121331
  return /* @__PURE__ */ jsxs("div", { className: "event-compact-row", children: [
120992
121332
  /* @__PURE__ */ jsxs("div", { className: "event-compact-row-content", children: [
120993
121333
  /* @__PURE__ */ jsxs("div", { className: "event-compact-row-top", children: [
@@ -123749,7 +124089,7 @@ var init_shared8 = __esm({
123749
124089
  });
123750
124090
 
123751
124091
  // ../blocks/src/system/runtime/api/creditProducts.ts
123752
- function assertNever6(value) {
124092
+ function assertNever7(value) {
123753
124093
  throw new Error(`Unhandled credit product case: ${String(value)}`);
123754
124094
  }
123755
124095
  function useCasesFromModules(modules) {
@@ -123782,7 +124122,7 @@ function getCreditProductCreditUnit(useCase) {
123782
124122
  perCreditSuffix: "credit"
123783
124123
  };
123784
124124
  default:
123785
- return assertNever6(useCase);
124125
+ return assertNever7(useCase);
123786
124126
  }
123787
124127
  }
123788
124128
  function deriveCreditProductLabels(products, options = {}) {
@@ -128197,11 +128537,12 @@ var init_basic = __esm({
128197
128537
  }
128198
128538
  return null;
128199
128539
  }
128200
- const resolvedVariantId = typeof variantId === "string" ? variantId.trim() : "";
128201
- const normalizedVariantId = resolvedVariantId === DEFAULT_VARIANT_ALIAS_ID ? "" : resolvedVariantId;
128202
- const variantClasses = normalizedVariantId ? [normalizedVariantId, `button-${normalizedVariantId}`] : [];
128203
- const sizeClass = `btn-${size4}`;
128204
- const combinedClassName = [...variantClasses, sizeClass, className].filter(Boolean).join(" ");
128540
+ const resolvedVariantId = parseThemeButtonVariantId(variantId);
128541
+ const combinedClassName = resolvedVariantId ? themeButtonClassName({
128542
+ variant: resolvedVariantId,
128543
+ size: size4,
128544
+ extraClassName: className
128545
+ }) : className;
128205
128546
  if (resolvedHref) {
128206
128547
  return /* @__PURE__ */ jsx(
128207
128548
  "a",
@@ -128421,7 +128762,7 @@ function FileDownloadNode({
128421
128762
  {
128422
128763
  href,
128423
128764
  download: filename,
128424
- className: themedButtonClass({
128765
+ className: themeButtonClassName({
128425
128766
  variant,
128426
128767
  size: "md",
128427
128768
  extraClassName: "rb-inline-flex rb-shrink-0 rb-items-center rb-justify-center rb-gap-2"
@@ -128440,7 +128781,7 @@ var init_file_download2 = __esm({
128440
128781
  init_lucide_react();
128441
128782
  init_colorStyles();
128442
128783
  init_media3();
128443
- init_themedButtonClass();
128784
+ init_buttons();
128444
128785
  init_media4();
128445
128786
  FILE_DOWNLOAD_BUTTON_VARIANTS = ["primary", "secondary", "outline", "link"];
128446
128787
  }
@@ -129075,7 +129416,7 @@ function okWith(data) {
129075
129416
  function err2(error) {
129076
129417
  return { ok: false, error };
129077
129418
  }
129078
- function assertNever7(value, message2) {
129419
+ function assertNever8(value, message2) {
129079
129420
  throw new Error(`Unexpected value: ${String(value)}`);
129080
129421
  }
129081
129422
  var init_dist88 = __esm({
@@ -129220,7 +129561,7 @@ function deriveBookingFormViewState(input) {
129220
129561
  resourceName: input.verificationState.resourceName
129221
129562
  };
129222
129563
  default:
129223
- return assertNever7(input.verificationState);
129564
+ return assertNever8(input.verificationState);
129224
129565
  }
129225
129566
  }
129226
129567
  function resolveBookingSiteId(siteId, form2) {
@@ -129303,7 +129644,7 @@ function getBookingServicePaymentSelectionMode(service) {
129303
129644
  case "flexible_balance":
129304
129645
  return "implicit_flexible_balance";
129305
129646
  default:
129306
- return assertNever7(onlyKind);
129647
+ return assertNever8(onlyKind);
129307
129648
  }
129308
129649
  }
129309
129650
  if (allowedKinds.length === 2 && allowedKinds.includes("upfront") && (allowedKinds.includes("deferred_manual") || allowedKinds.includes("instalment_plan") || allowedKinds.includes("flexible_balance"))) {
@@ -129505,7 +129846,7 @@ function formatBookingSubmissionPreparationError(error) {
129505
129846
  case "service-missing-duration":
129506
129847
  return `Service "${error.serviceTitle}" is missing duration. Please update the service in the dashboard to include a duration (e.g., 30 minutes).`;
129507
129848
  default:
129508
- return assertNever7(error);
129849
+ return assertNever8(error);
129509
129850
  }
129510
129851
  }
129511
129852
  function getBookingSuccessMessage(successMessage) {
@@ -130584,7 +130925,7 @@ var EventSpotlight;
130584
130925
  var init_EventSpotlight = __esm({
130585
130926
  "../blocks/src/system/runtime/nodes/events/EventSpotlight.tsx"() {
130586
130927
  init_shared7();
130587
- init_themedButtonClass();
130928
+ init_buttons();
130588
130929
  EventSpotlight = ({
130589
130930
  events: events2,
130590
130931
  layout = "grid",
@@ -130606,7 +130947,7 @@ var init_EventSpotlight = __esm({
130606
130947
  }
130607
130948
  const containerClass = getContainerClass(layout, columns);
130608
130949
  const cardOrientation = getCardOrientation(layout);
130609
- const buttonClass = themedButtonClass({ variant: buttonVariant, size: "md" });
130950
+ const buttonClass = themeButtonClassName({ variant: buttonVariant, size: "md" });
130610
130951
  return /* @__PURE__ */ jsxs("div", { className: `event-spotlight-section ${className || ""}`, "data-block": "event-spotlight", children: [
130611
130952
  /* @__PURE__ */ jsx("div", { className: `event-spotlight ${containerClass}`, children: normalizedEvents.map((event) => /* @__PURE__ */ jsx(
130612
130953
  EventCard,
@@ -131100,7 +131441,16 @@ var init_view4 = __esm({
131100
131441
  });
131101
131442
  function renderServerPendingAction(label, soldOut) {
131102
131443
  return /* @__PURE__ */ jsxs(Fragment, { children: [
131103
- /* @__PURE__ */ jsx("button", { type: "button", className: "default", disabled: true, "aria-disabled": "true", children: soldOut ? "Sold out" : label }),
131444
+ /* @__PURE__ */ jsx(
131445
+ "button",
131446
+ {
131447
+ type: "button",
131448
+ className: themeButtonClassName({ variant: "default", size: "md" }),
131449
+ disabled: true,
131450
+ "aria-disabled": "true",
131451
+ children: soldOut ? "Sold out" : label
131452
+ }
131453
+ ),
131104
131454
  !soldOut ? /* @__PURE__ */ jsx("p", { className: "rb-caption status-muted", children: "Cart actions become interactive after page load." }) : null
131105
131455
  ] });
131106
131456
  }
@@ -131120,7 +131470,14 @@ function ProductListServerContent(props2) {
131120
131470
  ),
131121
131471
  actions: /* @__PURE__ */ jsxs(Fragment, { children: [
131122
131472
  renderServerPendingAction(card.actionLabel, card.soldOut),
131123
- card.path ? /* @__PURE__ */ jsx("a", { href: card.path, className: "secondary btn-sm", children: "View details" }) : null
131473
+ card.path ? /* @__PURE__ */ jsx(
131474
+ "a",
131475
+ {
131476
+ href: card.path,
131477
+ className: themeButtonClassName({ variant: "secondary", size: "sm" }),
131478
+ children: "View details"
131479
+ }
131480
+ ) : null
131124
131481
  ] })
131125
131482
  },
131126
131483
  card.productId
@@ -131162,6 +131519,7 @@ function CheckoutServerContent(props2) {
131162
131519
  }
131163
131520
  var init_shop_commerce_server = __esm({
131164
131521
  "../blocks/src/system/runtime/nodes/shop-commerce.server.tsx"() {
131522
+ init_buttons();
131165
131523
  init_RichText();
131166
131524
  init_carousel_server();
131167
131525
  init_richText_coerce();
@@ -131686,7 +132044,7 @@ function renderCalendarGrid(display) {
131686
132044
  "button",
131687
132045
  {
131688
132046
  type: "button",
131689
- className: themedButtonClass({
132047
+ className: themeButtonClassName({
131690
132048
  variant: display.buttonVariant,
131691
132049
  size: "sm"
131692
132050
  }),
@@ -131772,7 +132130,7 @@ function renderTimetableSsr(display) {
131772
132130
  "button",
131773
132131
  {
131774
132132
  type: "button",
131775
- className: themedButtonClass({
132133
+ className: themeButtonClassName({
131776
132134
  variant: display.buttonVariant,
131777
132135
  size: "sm"
131778
132136
  }),
@@ -131899,7 +132257,7 @@ var init_EventCalendar_server = __esm({
131899
132257
  init_renderEventListItem();
131900
132258
  init_utils7();
131901
132259
  init_timetableModel();
131902
- init_themedButtonClass();
132260
+ init_buttons();
131903
132261
  EventCalendarSSR = (props2) => {
131904
132262
  const islandProps = buildEventCalendarInteractiveIslandProps(props2);
131905
132263
  const display = islandProps.render.display;
@@ -132018,7 +132376,7 @@ var init_form_server = __esm({
132018
132376
  "../blocks/src/system/runtime/nodes/form.server.tsx"() {
132019
132377
  init_clsx();
132020
132378
  init_ssr();
132021
- init_themedButtonClass();
132379
+ init_buttons();
132022
132380
  init_form_interactive();
132023
132381
  FormNodeSSR = ({
132024
132382
  blockId,
@@ -132156,7 +132514,7 @@ var init_form_server = __esm({
132156
132514
  "button",
132157
132515
  {
132158
132516
  type: "submit",
132159
- className: themedButtonClass({
132517
+ className: themeButtonClassName({
132160
132518
  variant: "primary",
132161
132519
  size: "md",
132162
132520
  extraClassName: "rb-w-full rb-sm-w-auto"
@@ -132246,7 +132604,7 @@ function NewsletterFormSSR({
132246
132604
  "button",
132247
132605
  {
132248
132606
  type: "submit",
132249
- className: themedButtonClass({ variant: "primary", size: "md" }),
132607
+ className: themeButtonClassName({ variant: "primary", size: "md" }),
132250
132608
  children: display.buttonLabel
132251
132609
  }
132252
132610
  ) })
@@ -132262,7 +132620,7 @@ var init_newsletter_form_server = __esm({
132262
132620
  "../blocks/src/system/runtime/nodes/newsletter-form.server.tsx"() {
132263
132621
  init_clsx();
132264
132622
  init_ssr();
132265
- init_themedButtonClass();
132623
+ init_buttons();
132266
132624
  init_newsletter_form_interactive();
132267
132625
  newsletter_form_server_default = NewsletterFormSSR;
132268
132626
  }
@@ -132382,7 +132740,16 @@ function ShopSSR({
132382
132740
  PassCardView,
132383
132741
  {
132384
132742
  display: pass,
132385
- action: /* @__PURE__ */ jsx("button", { type: "button", className: "default", disabled: true, "aria-disabled": "true", children: pass.actionLabel })
132743
+ action: /* @__PURE__ */ jsx(
132744
+ "button",
132745
+ {
132746
+ type: "button",
132747
+ className: themeButtonClassName({ variant: "default", size: "md" }),
132748
+ disabled: true,
132749
+ "aria-disabled": "true",
132750
+ children: pass.actionLabel
132751
+ }
132752
+ )
132386
132753
  },
132387
132754
  pass.id
132388
132755
  )),
@@ -132390,7 +132757,16 @@ function ShopSSR({
132390
132757
  MembershipCardView,
132391
132758
  {
132392
132759
  display: membership,
132393
- action: /* @__PURE__ */ jsx("button", { type: "button", className: "default", disabled: true, "aria-disabled": "true", children: membership.actionLabel })
132760
+ action: /* @__PURE__ */ jsx(
132761
+ "button",
132762
+ {
132763
+ type: "button",
132764
+ className: themeButtonClassName({ variant: "default", size: "md" }),
132765
+ disabled: true,
132766
+ "aria-disabled": "true",
132767
+ children: membership.actionLabel
132768
+ }
132769
+ )
132394
132770
  },
132395
132771
  membership.id
132396
132772
  ))
@@ -132404,6 +132780,7 @@ function ShopSSR({
132404
132780
  var shop_server_default;
132405
132781
  var init_shop_server = __esm({
132406
132782
  "../blocks/src/system/runtime/nodes/shop.server.tsx"() {
132783
+ init_buttons();
132407
132784
  init_ssr();
132408
132785
  init_view4();
132409
132786
  init_shop_interactive();
@@ -132637,7 +133014,7 @@ function readFromSource(source, segments) {
132637
133014
  return void 0;
132638
133015
  }, source);
132639
133016
  }
132640
- function isPlainObject4(value) {
133017
+ function isPlainObject5(value) {
132641
133018
  return typeof value === "object" && value !== null && !Array.isArray(value);
132642
133019
  }
132643
133020
  function parseRouteEntry(routeId, value) {
@@ -132647,35 +133024,35 @@ function parseRouteEntry(routeId, value) {
132647
133024
  if (typeof value === "string") {
132648
133025
  return [routeId, value];
132649
133026
  }
132650
- if (isPlainObject4(value)) {
133027
+ if (isPlainObject5(value)) {
132651
133028
  return [routeId, value];
132652
133029
  }
132653
133030
  return null;
132654
133031
  }
132655
133032
  function extractRouteMapFromViewModel(viewModel) {
132656
- if (!isPlainObject4(viewModel)) return void 0;
133033
+ if (!isPlainObject5(viewModel)) return void 0;
132657
133034
  const root = viewModel.$root;
132658
- if (!isPlainObject4(root)) return void 0;
133035
+ if (!isPlainObject5(root)) return void 0;
132659
133036
  const routes = root.routes;
132660
- if (!isPlainObject4(routes)) return void 0;
133037
+ if (!isPlainObject5(routes)) return void 0;
132661
133038
  const entries = Object.entries(routes).map(([routeId, value]) => parseRouteEntry(routeId, value)).filter((entry) => entry !== null);
132662
133039
  if (entries.length === 0) return void 0;
132663
133040
  return Object.fromEntries(entries);
132664
133041
  }
132665
133042
  function extractPagesByIdentifierFromViewModel(viewModel) {
132666
- if (!isPlainObject4(viewModel)) return void 0;
133043
+ if (!isPlainObject5(viewModel)) return void 0;
132667
133044
  const root = viewModel.$root;
132668
- if (!isPlainObject4(root)) return void 0;
133045
+ if (!isPlainObject5(root)) return void 0;
132669
133046
  const pagesByIdentifier = root.pagesByIdentifier;
132670
- if (!isPlainObject4(pagesByIdentifier)) return void 0;
133047
+ if (!isPlainObject5(pagesByIdentifier)) return void 0;
132671
133048
  return pagesByIdentifier;
132672
133049
  }
132673
133050
  function extractEntriesByIdentifierFromViewModel(viewModel) {
132674
- if (!isPlainObject4(viewModel)) return void 0;
133051
+ if (!isPlainObject5(viewModel)) return void 0;
132675
133052
  const root = viewModel.$root;
132676
- if (!isPlainObject4(root)) return void 0;
133053
+ if (!isPlainObject5(root)) return void 0;
132677
133054
  const entriesByIdentifier = root.entriesByIdentifier;
132678
- if (!isPlainObject4(entriesByIdentifier)) return void 0;
133055
+ if (!isPlainObject5(entriesByIdentifier)) return void 0;
132679
133056
  return entriesByIdentifier;
132680
133057
  }
132681
133058
  function parseBinding(raw, origin) {
@@ -132691,7 +133068,7 @@ function applyTransformsAndFallback(value, binding, context) {
132691
133068
  const routeMap = context.routes ?? extractRouteMapFromViewModel(context.viewModel);
132692
133069
  const pagesByIdentifier = context.pagesByIdentifier ?? extractPagesByIdentifierFromViewModel(context.viewModel);
132693
133070
  const entriesByIdentifier = context.entriesByIdentifier ?? extractEntriesByIdentifierFromViewModel(context.viewModel);
132694
- const root = isPlainObject4(context.viewModel.$root) ? context.viewModel.$root : null;
133071
+ const root = isPlainObject5(context.viewModel.$root) ? context.viewModel.$root : null;
132695
133072
  const stage = root?.previewStage === "preview" ? "preview" : "published";
132696
133073
  const transformed = runTransforms(
132697
133074
  value,
@@ -132728,21 +133105,21 @@ function resolveTransformData(context, bindingPath) {
132728
133105
  const [first2] = segments;
132729
133106
  if (typeof first2 === "string" && first2 !== "$root") {
132730
133107
  const namedScope = context.scopes.find((entry) => entry.name === first2);
132731
- if (namedScope && isPlainObject4(namedScope.value)) {
133108
+ if (namedScope && isPlainObject5(namedScope.value)) {
132732
133109
  return namedScope.value;
132733
133110
  }
132734
133111
  }
132735
133112
  for (let i2 = context.scopes.length - 1; i2 >= 0; i2 -= 1) {
132736
133113
  const scope = context.scopes[i2];
132737
- if (scope && isPlainObject4(scope.value)) {
133114
+ if (scope && isPlainObject5(scope.value)) {
132738
133115
  return scope.value;
132739
133116
  }
132740
133117
  }
132741
133118
  const content = context.viewModel.content;
132742
- if (isPlainObject4(content)) {
133119
+ if (isPlainObject5(content)) {
132743
133120
  return content;
132744
133121
  }
132745
- if (isPlainObject4(context.viewModel)) {
133122
+ if (isPlainObject5(context.viewModel)) {
132746
133123
  return context.viewModel;
132747
133124
  }
132748
133125
  return void 0;
@@ -132877,7 +133254,7 @@ function getNestedBinding(bindings, path) {
132877
133254
  const segments = path.split(".");
132878
133255
  let current = bindings;
132879
133256
  for (const segment of segments) {
132880
- if (!isPlainObject4(current)) return void 0;
133257
+ if (!isPlainObject5(current)) return void 0;
132881
133258
  current = current[segment];
132882
133259
  }
132883
133260
  return current;
@@ -132891,7 +133268,7 @@ function resolveBindingToEditorPath(fieldName, bindings, editableRouteMetadataFi
132891
133268
  };
132892
133269
  const binding = bindings[fieldName] ?? getNestedBinding(bindings, fieldName);
132893
133270
  if (!binding) return null;
132894
- if (isPlainObject4(binding) && "source" in binding) {
133271
+ if (isPlainObject5(binding) && "source" in binding) {
132895
133272
  const source = binding.source;
132896
133273
  if (source === "field" && "path" in binding) {
132897
133274
  const path = binding.path;
@@ -132910,7 +133287,7 @@ function resolveBindingToEditorPath(fieldName, bindings, editableRouteMetadataFi
132910
133287
  if (typeof option === "string") {
132911
133288
  return `content.${option}`;
132912
133289
  }
132913
- if (isPlainObject4(option) && "source" in option) {
133290
+ if (isPlainObject5(option) && "source" in option) {
132914
133291
  const optSource = option.source;
132915
133292
  if (optSource === "field" && "path" in option) {
132916
133293
  const path = option.path;
@@ -132955,7 +133332,7 @@ function injectEditorPath(props2, node, parsedBinding, context) {
132955
133332
  }
132956
133333
  }
132957
133334
  const root = context.viewModel?.$root;
132958
- const isEntryTemplatePage = isPlainObject4(root) && root.contentEntry != null;
133335
+ const isEntryTemplatePage = isPlainObject5(root) && root.contentEntry != null;
132959
133336
  if (isEntryTemplatePage && context.pathBase) return props2;
132960
133337
  const prefix = context.pathBase ?? "";
132961
133338
  const injectedPath = `${prefix}${fieldPath}`;
@@ -132984,7 +133361,7 @@ function injectMediaSlotPath(props2, node, parsedBinding, context) {
132984
133361
  if (entryPath) return props2;
132985
133362
  }
132986
133363
  const root = context.viewModel?.$root;
132987
- const isEntryTemplatePage = isPlainObject4(root) && root.contentEntry != null;
133364
+ const isEntryTemplatePage = isPlainObject5(root) && root.contentEntry != null;
132988
133365
  if (isEntryTemplatePage && context.pathBase) return props2;
132989
133366
  return {
132990
133367
  ...props2,
@@ -133088,7 +133465,7 @@ function getNodeProps(node) {
133088
133465
  if (key.startsWith("$")) continue;
133089
133466
  legacy[key] = value;
133090
133467
  }
133091
- const props2 = isPlainObject4(node.props) ? node.props : {};
133468
+ const props2 = isPlainObject5(node.props) ? node.props : {};
133092
133469
  return { ...legacy, ...props2 };
133093
133470
  }
133094
133471
  function resolveTree(node, options) {
@@ -133155,14 +133532,14 @@ var init_runtime2 = __esm({
133155
133532
  });
133156
133533
 
133157
133534
  // ../theme-core/src/blockOverrides.ts
133158
- function isPlainObject5(value) {
133535
+ function isPlainObject6(value) {
133159
133536
  return typeof value === "object" && value !== null && !Array.isArray(value);
133160
133537
  }
133161
133538
  function cloneValue(value) {
133162
133539
  if (Array.isArray(value)) {
133163
133540
  return value.map((item) => cloneValue(item));
133164
133541
  }
133165
- if (isPlainObject5(value)) {
133542
+ if (isPlainObject6(value)) {
133166
133543
  const cloned = {};
133167
133544
  for (const [key, child] of Object.entries(value)) {
133168
133545
  cloned[key] = cloneValue(child);
@@ -133178,7 +133555,7 @@ function mergeDeep2(defaultValue2, overrideValue) {
133178
133555
  if (overrideValue === null) {
133179
133556
  return null;
133180
133557
  }
133181
- if (isPlainObject5(defaultValue2) && isPlainObject5(overrideValue)) {
133558
+ if (isPlainObject6(defaultValue2) && isPlainObject6(overrideValue)) {
133182
133559
  const merged = {};
133183
133560
  const keys2 = /* @__PURE__ */ new Set([...Object.keys(defaultValue2), ...Object.keys(overrideValue)]);
133184
133561
  for (const key of keys2) {
@@ -133370,12 +133747,6 @@ var init_ai = __esm({
133370
133747
  }
133371
133748
  });
133372
133749
 
133373
- // ../blocks/src/system/types/link.ts
133374
- var init_link2 = __esm({
133375
- "../blocks/src/system/types/link.ts"() {
133376
- }
133377
- });
133378
-
133379
133750
  // ../blocks/src/system/index.ts
133380
133751
  var init_system = __esm({
133381
133752
  "../blocks/src/system/index.ts"() {
@@ -137473,7 +137844,7 @@ function resolveBlockData({
137473
137844
  }
137474
137845
  function getRenderableContent(block) {
137475
137846
  const source = block.draftContent ?? block.content ?? {};
137476
- if (!isObjectRecord(source)) {
137847
+ if (!isObjectRecord2(source)) {
137477
137848
  return {};
137478
137849
  }
137479
137850
  return source;
@@ -137492,8 +137863,8 @@ function summarizeValue(value) {
137492
137863
  for (const k of keys2.slice(0, 8)) {
137493
137864
  const v2 = rec[k];
137494
137865
  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");
137866
+ const isDocWrapper = !!(v2 && typeof v2 === "object" && isObjectRecord2(v2) && "doc" in v2);
137867
+ const isDoc = !!(v2 && typeof v2 === "object" && isObjectRecord2(v2) && v2.type === "doc");
137497
137868
  preview[k] = isDocWrapper ? "{doc}" : isDoc ? "{type:doc}" : summarizeValue(v2);
137498
137869
  } else {
137499
137870
  preview[k] = summarizeValue(v2);
@@ -139372,25 +139743,25 @@ var init_Button2 = __esm({
139372
139743
  var BlockKind, blockSchema, pagePath;
139373
139744
  var init_schema5 = __esm({
139374
139745
  "../blocks/src/structure/schema.ts"() {
139375
- BlockKind = z37.string();
139376
- blockSchema = z37.object({
139377
- id: z37.string().nullable(),
139746
+ BlockKind = z38.string();
139747
+ blockSchema = z38.object({
139748
+ id: z38.string().nullable(),
139378
139749
  // optional ID for reference in toggle ops
139379
139750
  kind: BlockKind,
139380
- purpose: z37.string().min(1),
139751
+ purpose: z38.string().min(1),
139381
139752
  // Optional content fields used by PageRenderer / block runtime.
139382
- content: z37.record(z37.string(), z37.unknown()).optional(),
139753
+ content: z38.record(z38.string(), z38.unknown()).optional(),
139383
139754
  // Nullable because some persisted sources store "no draft" as null.
139384
- draftContent: z37.record(z37.string(), z37.unknown()).nullable().optional(),
139755
+ draftContent: z38.record(z38.string(), z38.unknown()).nullable().optional(),
139385
139756
  // Optional template bindings for reverse field mapping (entry editing)
139386
- bindings: z37.record(z37.string(), z37.unknown()).optional()
139757
+ bindings: z38.record(z38.string(), z38.unknown()).optional()
139387
139758
  }).passthrough();
139388
- pagePath = z37.string().regex(/^\/[\S]*$/, 'path must start with "/" and contain no spaces');
139389
- z37.object({
139390
- name: z37.string().min(1),
139759
+ pagePath = z38.string().regex(/^\/[\S]*$/, 'path must start with "/" and contain no spaces');
139760
+ z38.object({
139761
+ name: z38.string().min(1),
139391
139762
  path: pagePath,
139392
- purpose: z37.string().min(1),
139393
- blocks: z37.array(blockSchema).min(1)
139763
+ purpose: z38.string().min(1),
139764
+ blocks: z38.array(blockSchema).min(1)
139394
139765
  });
139395
139766
  }
139396
139767
  });
@@ -148782,6 +149153,7 @@ var init_src6 = __esm({
148782
149153
  init_buildThemeRuntimeFromBridge();
148783
149154
  init_blocks4();
148784
149155
  init_system();
149156
+ init_link2();
148785
149157
  init_validation();
148786
149158
  init_primitives();
148787
149159
  init_media4();
@@ -148832,10 +149204,10 @@ function deriveBlockDraftSaveability(input) {
148832
149204
  issues
148833
149205
  };
148834
149206
  }
148835
- function withNormalizedManifestMessage(issue) {
149207
+ function withNormalizedManifestMessage(issue2) {
148836
149208
  return {
148837
- ...issue,
148838
- message: normalizeManifestIssueMessage(issue)
149209
+ ...issue2,
149210
+ message: normalizeManifestIssueMessage(issue2)
148839
149211
  };
148840
149212
  }
148841
149213
  function validateBlockManifestIssues(manifest, values, mode) {
@@ -148847,31 +149219,31 @@ function validateBlockManifestIssues(manifest, values, mode) {
148847
149219
  return result.error.issues.map(withNormalizedManifestMessage);
148848
149220
  }
148849
149221
  function validateBlockManifest(manifest, values, mode) {
148850
- return validateBlockManifestIssues(manifest, values, mode).map((issue) => {
148851
- const path = normalizeIssuePath(issue.path);
149222
+ return validateBlockManifestIssues(manifest, values, mode).map((issue2) => {
149223
+ const path = normalizeIssuePath(issue2.path);
148852
149224
  return {
148853
- code: issue.code,
149225
+ code: issue2.code,
148854
149226
  path,
148855
149227
  fieldPath: normalizePathString(path),
148856
- message: issue.message
149228
+ message: issue2.message
148857
149229
  };
148858
149230
  });
148859
149231
  }
148860
- function normalizeManifestIssueMessage(issue) {
148861
- switch (issue.code) {
149232
+ function normalizeManifestIssueMessage(issue2) {
149233
+ switch (issue2.code) {
148862
149234
  case "invalid_type":
148863
- return issue.message;
149235
+ return issue2.message;
148864
149236
  case "too_big":
148865
- return issue.origin === "string" ? `Use ${issue.maximum} characters or fewer` : issue.message;
149237
+ return issue2.origin === "string" ? `Use ${issue2.maximum} characters or fewer` : issue2.message;
148866
149238
  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`;
149239
+ if (issue2.origin !== "string") return issue2.message;
149240
+ return issue2.minimum === 1 ? "This field is required" : `Use at least ${issue2.minimum} characters`;
148869
149241
  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";
149242
+ if (issue2.format === "email") return "Enter a valid email address";
149243
+ if (issue2.format === "url") return "Enter a valid web address";
148872
149244
  return "Check the format and try again";
148873
149245
  default:
148874
- return issue.message;
149246
+ return issue2.message;
148875
149247
  }
148876
149248
  }
148877
149249
  function getManifestValidation(manifest, mode) {
@@ -149026,16 +149398,16 @@ function validateAllBlocks(uiStore) {
149026
149398
  }
149027
149399
  const issues = validateBlockManifest(definition.manifest, content, "strict");
149028
149400
  if (issues.length > 0) {
149029
- for (const issue of issues) {
149401
+ for (const issue2 of issues) {
149030
149402
  errors.push({
149031
149403
  blockId: snapshot2.id,
149032
149404
  blockKind: snapshot2.meta.kind,
149033
- fieldPath: issue.fieldPath,
149405
+ fieldPath: issue2.fieldPath,
149034
149406
  fieldLabel: getFieldLabelFromManifest(
149035
149407
  definition.manifest,
149036
- issue.path
149408
+ issue2.path
149037
149409
  ),
149038
- message: issue.message
149410
+ message: issue2.message
149039
149411
  });
149040
149412
  }
149041
149413
  }
@@ -149799,7 +150171,7 @@ var init_extractBlockData = __esm({
149799
150171
  });
149800
150172
 
149801
150173
  // ../content-editor/src/utils/assertNever.ts
149802
- function assertNever8(value, message2) {
150174
+ function assertNever9(value, message2) {
149803
150175
  throw new Error(`Unexpected value: ${String(value)}`);
149804
150176
  }
149805
150177
  var init_assertNever2 = __esm({
@@ -150397,7 +150769,7 @@ function applyEditorCommand(snapshot2, command2) {
150397
150769
  return nextSnapshot;
150398
150770
  }
150399
150771
  default:
150400
- return assertNever8(command2);
150772
+ return assertNever9(command2);
150401
150773
  }
150402
150774
  }
150403
150775
  function applyUserOperation(snapshot2, operation) {
@@ -150469,7 +150841,7 @@ function applySystemOperation(snapshot2, operation) {
150469
150841
  case "replace-block-list":
150470
150842
  return replaceEditorBlockList(snapshot2, operation.next);
150471
150843
  default:
150472
- return assertNever8(operation);
150844
+ return assertNever9(operation);
150473
150845
  }
150474
150846
  }
150475
150847
  function hydrateMetadataSnapshot(snapshot2, baseline, current, published) {
@@ -152239,7 +152611,7 @@ function toDrainFailure(effect, error) {
152239
152611
  case "persist-remove":
152240
152612
  return { kind: effect.type, message: message2 };
152241
152613
  default:
152242
- return assertNever8(effect);
152614
+ return assertNever9(effect);
152243
152615
  }
152244
152616
  }
152245
152617
  async function drainEditorEffect(effect, context) {
@@ -152251,7 +152623,7 @@ async function drainEditorEffect(effect, context) {
152251
152623
  case "persist-remove":
152252
152624
  return drainPersistRemoveEffect(effect, context);
152253
152625
  default:
152254
- return assertNever8(effect);
152626
+ return assertNever9(effect);
152255
152627
  }
152256
152628
  }
152257
152629
  async function drainEditorEffects(effects, context) {
@@ -153311,40 +153683,151 @@ var init_TextField = __esm({
153311
153683
  init_FieldFrame();
153312
153684
  }
153313
153685
  });
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 });
153686
+
153687
+ // ../block-form/src/widgets/utils/readNumericUiConfig.ts
153688
+ function readNumericInputUiConfig(ui) {
153689
+ if (!ui || typeof ui !== "object") return {};
153690
+ const rec = ui;
153691
+ return {
153692
+ min: typeof rec.min === "number" ? rec.min : void 0,
153693
+ max: typeof rec.max === "number" ? rec.max : void 0,
153694
+ step: typeof rec.step === "number" ? rec.step : void 0
153695
+ };
153696
+ }
153697
+ function readNumberFieldUiConfig(ui) {
153698
+ return readNumericInputUiConfig(ui);
153699
+ }
153700
+ function readSliderFieldUiConfig(ui) {
153701
+ const base2 = readNumericInputUiConfig(ui);
153702
+ if (!ui || typeof ui !== "object") return base2;
153703
+ const rec = ui;
153704
+ return {
153705
+ ...base2,
153706
+ showValue: typeof rec.showValue === "boolean" ? rec.showValue : void 0
153707
+ };
153708
+ }
153709
+ var init_readNumericUiConfig = __esm({
153710
+ "../block-form/src/widgets/utils/readNumericUiConfig.ts"() {
153319
153711
  }
153320
- if (field.required) {
153321
- return withRules.min(1, "This field is required");
153712
+ });
153713
+
153714
+ // ../block-form/src/manifest/canonicalValidation.ts
153715
+ function buildCanonicalFieldSchema(field) {
153716
+ const manifestField = normalizeFieldForCanonicalValidation(field);
153717
+ return fieldPlanToZod(deriveFieldValidationPlan(manifestField), {
153718
+ allowNull: !Boolean(field.required)
153719
+ });
153720
+ }
153721
+ function normalizeFieldForCanonicalValidation(field) {
153722
+ return parseFieldDefinition(toManifestFieldInput(field));
153723
+ }
153724
+ function toManifestFieldInput(field) {
153725
+ switch (field.type) {
153726
+ case "number":
153727
+ return numberFieldToManifestInput(field);
153728
+ case "group":
153729
+ return groupFieldToManifestInput(field);
153730
+ case "modal":
153731
+ return modalFieldToManifestInput(field);
153732
+ case "repeater":
153733
+ return repeaterFieldToManifestInput(field);
153734
+ case "tabGroup":
153735
+ return {
153736
+ ...field,
153737
+ tabs: field.tabs.map((tab) => ({
153738
+ ...tab,
153739
+ fields: tab.fields.map(toManifestFieldInput)
153740
+ }))
153741
+ };
153742
+ case "button":
153743
+ throw new Error("Button fields do not have canonical content validation");
153744
+ case "text":
153745
+ case "richText":
153746
+ case "media":
153747
+ case "boolean":
153748
+ case "date":
153749
+ case "time":
153750
+ case "datetime":
153751
+ case "slug":
153752
+ case "url":
153753
+ case "link":
153754
+ case "select":
153755
+ case "reference":
153756
+ case "presetOrCustom":
153757
+ case "contentTypeSelect":
153758
+ case "entryPicker":
153759
+ return field;
153322
153760
  }
153323
- return withRules.optional().nullable().or(z.literal(""));
153761
+ return assertNever10(field);
153324
153762
  }
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
- );
153763
+ function numberFieldToManifestInput(field) {
153764
+ const ui = readNumberFieldUiConfig(field.ui);
153765
+ return {
153766
+ ...field,
153767
+ min: field.min ?? ui.min,
153768
+ max: field.max ?? ui.max,
153769
+ step: field.step ?? ui.step
153770
+ };
153771
+ }
153772
+ function groupFieldToManifestInput(field) {
153773
+ return {
153774
+ ...field,
153775
+ schema: {
153776
+ ...field.schema,
153777
+ fields: (field.schema?.fields ?? field.fields).map(toManifestFieldInput)
153778
+ }
153779
+ };
153780
+ }
153781
+ function modalFieldToManifestInput(field) {
153782
+ return {
153783
+ ...field,
153784
+ schema: {
153785
+ ...field.schema,
153786
+ fields: field.schema.fields.map(toManifestFieldInput)
153787
+ }
153788
+ };
153789
+ }
153790
+ function repeaterFieldToManifestInput(field) {
153791
+ if (field.polymorphic) {
153792
+ return {
153793
+ ...field,
153794
+ itemTypes: Object.fromEntries(
153795
+ Object.entries(field.itemTypes).map(([typeId, itemType]) => [
153796
+ typeId,
153797
+ {
153798
+ ...itemType,
153799
+ fields: itemType.fields.map(toManifestFieldInput)
153800
+ }
153801
+ ])
153802
+ )
153803
+ };
153335
153804
  }
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 {
153805
+ return {
153806
+ ...field,
153807
+ schema: {
153808
+ ...field.schema,
153809
+ fields: (field.schema?.fields ?? field.fields).map(toManifestFieldInput)
153342
153810
  }
153811
+ };
153812
+ }
153813
+ function assertNever10(value) {
153814
+ throw new Error(`Unhandled field config variant: ${JSON.stringify(value)}`);
153815
+ }
153816
+ var init_canonicalValidation = __esm({
153817
+ "../block-form/src/manifest/canonicalValidation.ts"() {
153818
+ init_fieldValidation();
153819
+ init_schema3();
153820
+ init_readNumericUiConfig();
153343
153821
  }
153344
- return withTextFieldSharedRules(s2, field);
153822
+ });
153823
+
153824
+ // ../block-form/src/widgets/TextField/textFieldSchema.ts
153825
+ function buildTextFieldSchema(field) {
153826
+ return buildCanonicalFieldSchema(field);
153345
153827
  }
153346
153828
  var init_textFieldSchema = __esm({
153347
153829
  "../block-form/src/widgets/TextField/textFieldSchema.ts"() {
153830
+ init_canonicalValidation();
153348
153831
  }
153349
153832
  });
153350
153833
 
@@ -153369,33 +153852,6 @@ var init_TextField2 = __esm({
153369
153852
  init_TextField();
153370
153853
  }
153371
153854
  });
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
153855
  function NumberField({ path, backend, config }) {
153400
153856
  const { value, error, setValue } = useField(path, backend);
153401
153857
  const ui = readNumberFieldUiConfig(config.ui);
@@ -153435,44 +153891,14 @@ var init_NumberField = __esm({
153435
153891
  init_readNumericUiConfig();
153436
153892
  }
153437
153893
  });
153894
+
153895
+ // ../block-form/src/widgets/NumberField/numberFieldSchema.ts
153438
153896
  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
- );
153897
+ return buildCanonicalFieldSchema(field);
153473
153898
  }
153474
153899
  var init_numberFieldSchema = __esm({
153475
153900
  "../block-form/src/widgets/NumberField/numberFieldSchema.ts"() {
153901
+ init_canonicalValidation();
153476
153902
  }
153477
153903
  });
153478
153904
 
@@ -153609,29 +154035,14 @@ var init_SelectField = __esm({
153609
154035
  init_selectValueMapping();
153610
154036
  }
153611
154037
  });
154038
+
154039
+ // ../block-form/src/widgets/SelectField/selectFieldSchema.ts
153612
154040
  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();
154041
+ return buildCanonicalFieldSchema(field);
153632
154042
  }
153633
154043
  var init_selectFieldSchema = __esm({
153634
154044
  "../block-form/src/widgets/SelectField/selectFieldSchema.ts"() {
154045
+ init_canonicalValidation();
153635
154046
  }
153636
154047
  });
153637
154048
 
@@ -154733,7 +155144,7 @@ function createStoreBackend(options) {
154733
155144
  return issues;
154734
155145
  }
154735
155146
  return issues.filter(
154736
- (issue) => blockValidation.isPathEdited(currentBlockId, issue.path.join("."))
155147
+ (issue2) => blockValidation.isPathEdited(currentBlockId, issue2.path.join("."))
154737
155148
  );
154738
155149
  };
154739
155150
  return {
@@ -154775,7 +155186,7 @@ function createStoreBackend(options) {
154775
155186
  let fieldError;
154776
155187
  if (validateFn) {
154777
155188
  const issues = getVisibleValidationIssues();
154778
- const fieldIssue = issues.find((issue) => issue.path.join(".") === path);
155189
+ const fieldIssue = issues.find((issue2) => issue2.path.join(".") === path);
154779
155190
  if (fieldIssue) {
154780
155191
  fieldError = { message: fieldIssue.message };
154781
155192
  }
@@ -154800,9 +155211,9 @@ function createStoreBackend(options) {
154800
155211
  getErrors: () => {
154801
155212
  const issues = getVisibleValidationIssues();
154802
155213
  const errors = {};
154803
- issues.forEach((issue) => {
154804
- const path = issue.path.join(".");
154805
- errors[path] = { message: issue.message };
155214
+ issues.forEach((issue2) => {
155215
+ const path = issue2.path.join(".");
155216
+ errors[path] = { message: issue2.message };
154806
155217
  });
154807
155218
  return errors;
154808
155219
  },
@@ -154886,9 +155297,9 @@ function createStoreBackend(options) {
154886
155297
  const issues = getValidationIssues();
154887
155298
  const visibleIssues = getVisibleValidationIssues();
154888
155299
  const errors = {};
154889
- visibleIssues.forEach((issue) => {
154890
- const path = issue.path.join(".");
154891
- errors[path] = { message: issue.message };
155300
+ visibleIssues.forEach((issue2) => {
155301
+ const path = issue2.path.join(".");
155302
+ errors[path] = { message: issue2.message };
154892
155303
  });
154893
155304
  return {
154894
155305
  isDirty: isSnapshotDirty(snapshot2),
@@ -154928,12 +155339,6 @@ var init_types22 = __esm({
154928
155339
  }
154929
155340
  });
154930
155341
 
154931
- // ../block-form/src/backend/validation.ts
154932
- var init_validation3 = __esm({
154933
- "../block-form/src/backend/validation.ts"() {
154934
- }
154935
- });
154936
-
154937
155342
  // ../block-form/src/backend/adapter.ts
154938
155343
  var init_adapter = __esm({
154939
155344
  "../block-form/src/backend/adapter.ts"() {
@@ -155018,7 +155423,6 @@ var init_backend = __esm({
155018
155423
  "../block-form/src/backend/index.ts"() {
155019
155424
  init_types22();
155020
155425
  init_hooks();
155021
- init_validation3();
155022
155426
  init_adapter();
155023
155427
  init_useRepeaterBackend();
155024
155428
  }
@@ -155643,6 +156047,92 @@ function encodePublicProductCategorySelector(selector) {
155643
156047
  };
155644
156048
  }
155645
156049
  }
156050
+ function isRecord8(value) {
156051
+ return typeof value === "object" && value !== null;
156052
+ }
156053
+ function isJsonResponseContentType(contentType) {
156054
+ if (!contentType) return false;
156055
+ const mimeType = contentType.split(";", 1)[0]?.trim().toLowerCase() ?? "";
156056
+ return mimeType === "application/json" || mimeType.endsWith("+json");
156057
+ }
156058
+ function getResponseContentType(response) {
156059
+ return response.headers.get("content-type");
156060
+ }
156061
+ async function parseJsonBody(response) {
156062
+ const rawText = await response.text();
156063
+ if (rawText.trim().length === 0) {
156064
+ return { kind: "empty-body" };
156065
+ }
156066
+ try {
156067
+ return { kind: "success", value: JSON.parse(rawText) };
156068
+ } catch {
156069
+ return { kind: "invalid-json" };
156070
+ }
156071
+ }
156072
+ function getBlockApiErrorDetails(data) {
156073
+ if (!isRecord8(data)) {
156074
+ return {};
156075
+ }
156076
+ const nestedError = isRecord8(data.error) ? data.error : void 0;
156077
+ const message2 = typeof nestedError?.message === "string" ? nestedError.message : typeof data.message === "string" ? data.message : void 0;
156078
+ const code = typeof nestedError?.code === "string" ? nestedError.code : typeof data.code === "string" ? data.code : void 0;
156079
+ return { message: message2, code };
156080
+ }
156081
+ function buildUnexpectedJsonResponseMessage(parseResult) {
156082
+ switch (parseResult.kind) {
156083
+ case "empty-body":
156084
+ return "Expected JSON response body but received an empty response";
156085
+ case "invalid-json":
156086
+ return "Expected JSON response but received invalid JSON";
156087
+ }
156088
+ }
156089
+ async function extractErrorDetails(response) {
156090
+ const contentType = getResponseContentType(response);
156091
+ const fallbackMessage = `Request failed: ${response.statusText}`;
156092
+ if (!isJsonResponseContentType(contentType)) {
156093
+ return {
156094
+ message: `${fallbackMessage} (received ${contentType ?? "unknown content type"})`
156095
+ };
156096
+ }
156097
+ const parseResult = await parseJsonBody(response);
156098
+ switch (parseResult.kind) {
156099
+ case "success": {
156100
+ const details = getBlockApiErrorDetails(parseResult.value);
156101
+ return {
156102
+ message: details.message ?? fallbackMessage,
156103
+ code: details.code
156104
+ };
156105
+ }
156106
+ case "invalid-json":
156107
+ return {
156108
+ message: `${fallbackMessage} (received invalid JSON)`
156109
+ };
156110
+ case "empty-body":
156111
+ return {
156112
+ message: `${fallbackMessage} (received an empty response)`
156113
+ };
156114
+ }
156115
+ }
156116
+ async function parseJsonApiResponse(response) {
156117
+ if (response.status === 204 || response.status === 205) {
156118
+ return void 0;
156119
+ }
156120
+ const contentType = getResponseContentType(response);
156121
+ if (!isJsonResponseContentType(contentType)) {
156122
+ throw new BlockApiError(
156123
+ `Expected JSON response but received ${contentType ?? "unknown content type"}`,
156124
+ response.status
156125
+ );
156126
+ }
156127
+ const parseResult = await parseJsonBody(response);
156128
+ if (parseResult.kind !== "success") {
156129
+ throw new BlockApiError(
156130
+ buildUnexpectedJsonResponseMessage(parseResult),
156131
+ response.status
156132
+ );
156133
+ }
156134
+ return parseResult.value;
156135
+ }
155646
156136
  function getAuthHeaders2(auth) {
155647
156137
  switch (auth.type) {
155648
156138
  case "api-key":
@@ -155699,21 +156189,10 @@ function createBlockApi(config) {
155699
156189
  const doFetch = async () => {
155700
156190
  const response = await fetch(url, fetchOptions);
155701
156191
  if (!response.ok) {
155702
- let errorMessage3 = `Request failed: ${response.statusText}`;
155703
- let errorCode;
155704
- try {
155705
- const errorData = await response.json();
155706
- if (typeof errorData.error?.message === "string") {
155707
- errorMessage3 = errorData.error.message;
155708
- } else if (typeof errorData.message === "string") {
155709
- errorMessage3 = errorData.message;
155710
- }
155711
- errorCode = errorData.error?.code || errorData.code;
155712
- } catch {
155713
- }
155714
- throw new BlockApiError(errorMessage3, response.status, errorCode);
156192
+ const details = await extractErrorDetails(response);
156193
+ throw new BlockApiError(details.message, response.status, details.code);
155715
156194
  }
155716
- const json = await response.json();
156195
+ const json = await parseJsonApiResponse(response);
155717
156196
  if (isApiSuccessResponse(json)) {
155718
156197
  return json.data;
155719
156198
  }
@@ -156395,7 +156874,7 @@ function ze() {
156395
156874
  /* @__PURE__ */ Te(P)
156396
156875
  );
156397
156876
  }
156398
- function z71(e3) {
156877
+ function z69(e3) {
156399
156878
  if (L2) {
156400
156879
  if (/* @__PURE__ */ Te(P) !== null)
156401
156880
  throw Tt(), Je;
@@ -158424,12 +158903,12 @@ function ha(e3, t3) {
158424
158903
  var mt = we(Dr, 2);
158425
158904
  let Pr;
158426
158905
  var We = X3(mt);
158427
- en(We), We.__change = ui, z71(mt);
158906
+ en(We), We.__change = ui, z69(mt);
158428
158907
  var Ut = we(mt, 2), wi = X3(Ut);
158429
158908
  {
158430
158909
  var pi = (n3) => {
158431
158910
  var u3 = na(), _2 = Gr(u3), y2 = X3(_2);
158432
- Ge(y2, () => c3(re2).verified), z71(_2);
158911
+ Ge(y2, () => c3(re2).verified), z69(_2);
158433
158912
  var T2 = we(_2, 2);
158434
158913
  en(T2), Pe(() => {
158435
158914
  se(T2, "name", V2()), jo(T2, c3(Le));
@@ -158438,10 +158917,10 @@ function ha(e3, t3) {
158438
158917
  {
158439
158918
  var _2 = (T2) => {
158440
158919
  var E = ia(), p2 = X3(E);
158441
- Ge(p2, () => c3(re2).verifying), z71(E), ne(T2, E);
158920
+ Ge(p2, () => c3(re2).verifying), z69(E), ne(T2, E);
158442
158921
  }, y2 = (T2) => {
158443
158922
  var E = oa(), p2 = X3(E);
158444
- Ge(p2, () => c3(re2).label), z71(E), Pe(() => se(E, "for", c3(cr))), ne(T2, E);
158923
+ Ge(p2, () => c3(re2).label), z69(E), Pe(() => se(E, "for", c3(cr))), ne(T2, E);
158445
158924
  };
158446
158925
  $e(
158447
158926
  n3,
@@ -158456,18 +158935,18 @@ function ha(e3, t3) {
158456
158935
  c3(C2) === b2.VERIFIED ? n3(pi) : n3(bi, false);
158457
158936
  });
158458
158937
  }
158459
- z71(Ut);
158938
+ z69(Ut);
158460
158939
  var yi = we(Ut, 2);
158461
158940
  {
158462
158941
  var Ei = (n3) => {
158463
158942
  var u3 = aa(), _2 = X3(u3);
158464
- se(_2, "href", sr), z71(u3), Pe(() => se(_2, "aria-label", c3(re2).ariaLinkLabel)), ne(n3, u3);
158943
+ se(_2, "href", sr), z69(u3), Pe(() => se(_2, "aria-label", c3(re2).ariaLinkLabel)), ne(n3, u3);
158465
158944
  };
158466
158945
  $e(yi, (n3) => {
158467
158946
  (N() !== true || c3(Dt)) && n3(Ei);
158468
158947
  });
158469
158948
  }
158470
- z71(Mt);
158949
+ z69(Mt);
158471
158950
  var Or = we(Mt, 2);
158472
158951
  {
158473
158952
  var xi = (n3) => {
@@ -158475,16 +158954,16 @@ function ha(e3, t3) {
158475
158954
  {
158476
158955
  var y2 = (E) => {
158477
158956
  var p2 = la(), x2 = X3(p2);
158478
- Ge(x2, () => c3(re2).expired), z71(p2), Pe(() => se(p2, "title", c3(He))), ne(E, p2);
158957
+ Ge(x2, () => c3(re2).expired), z69(p2), Pe(() => se(p2, "title", c3(He))), ne(E, p2);
158479
158958
  }, T2 = (E) => {
158480
158959
  var p2 = sa(), x2 = X3(p2);
158481
- Ge(x2, () => c3(re2).error), z71(p2), Pe(() => se(p2, "title", c3(He))), ne(E, p2);
158960
+ Ge(x2, () => c3(re2).error), z69(p2), Pe(() => se(p2, "title", c3(He))), ne(E, p2);
158482
158961
  };
158483
158962
  $e(_2, (E) => {
158484
158963
  c3(C2) === b2.EXPIRED ? E(y2) : E(T2, false);
158485
158964
  });
158486
158965
  }
158487
- z71(u3), ne(n3, u3);
158966
+ z69(u3), ne(n3, u3);
158488
158967
  };
158489
158968
  $e(Or, (n3) => {
158490
158969
  (c3(He) || c3(C2) === b2.EXPIRED) && n3(xi);
@@ -158494,7 +158973,7 @@ function ha(e3, t3) {
158494
158973
  {
158495
158974
  var $i = (n3) => {
158496
158975
  var u3 = ua(), _2 = X3(u3), y2 = X3(_2);
158497
- Ge(y2, () => c3(re2).footer), z71(_2), z71(u3), ne(n3, u3);
158976
+ Ge(y2, () => c3(re2).footer), z69(_2), z69(u3), ne(n3, u3);
158498
158977
  };
158499
158978
  $e(Fr, (n3) => {
158500
158979
  c3(re2).footer && (k() !== true || c3(Dt)) && n3($i);
@@ -158510,7 +158989,7 @@ function ha(e3, t3) {
158510
158989
  v2() && n3(Ci);
158511
158990
  });
158512
158991
  }
158513
- return z71(ot), nn(ot, (n3) => D2(B, n3), () => c3(B)), Pe(
158992
+ return z69(ot), nn(ot, (n3) => D2(B, n3), () => c3(B)), Pe(
158514
158993
  (n3) => {
158515
158994
  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
158995
  },
@@ -159257,7 +159736,7 @@ function multiStepReducer(state, action) {
159257
159736
  case "reset":
159258
159737
  return createInitialMultiStepState(action.initialData);
159259
159738
  default:
159260
- return assertNever7(action);
159739
+ return assertNever8(action);
159261
159740
  }
159262
159741
  }
159263
159742
  function getVisibleSteps(steps2, data) {
@@ -159535,7 +160014,7 @@ function MultiStepForm({
159535
160014
  type: "button",
159536
160015
  onClick: goToPrevious,
159537
160016
  disabled: !canGoBack,
159538
- className: "outline btn-md",
160017
+ className: themeButtonClassName({ variant: "outline", size: "md" }),
159539
160018
  children: backButtonLabel
159540
160019
  }
159541
160020
  ),
@@ -159545,7 +160024,11 @@ function MultiStepForm({
159545
160024
  type: "button",
159546
160025
  onClick: goToNext,
159547
160026
  disabled: !canGoNext,
159548
- className: "primary btn-md rb-flex-1",
160027
+ className: themeButtonClassName({
160028
+ variant: "primary",
160029
+ size: "md",
160030
+ extraClassName: "rb-flex-1"
160031
+ }),
159549
160032
  children: [
159550
160033
  (isValidating || isSubmitting) && /* @__PURE__ */ jsx(
159551
160034
  SpinnerNode,
@@ -159660,6 +160143,7 @@ function ProgressIndicator({
159660
160143
  var init_MultiStepForm = __esm({
159661
160144
  "../blocks/src/system/runtime/components/multi-step/MultiStepForm.tsx"() {
159662
160145
  "use client";
160146
+ init_buttons();
159663
160147
  init_MultiStepContext();
159664
160148
  init_useMultiStep();
159665
160149
  init_spinner2();
@@ -160116,7 +160600,7 @@ var init_DatePicker = __esm({
160116
160600
  dateOptions,
160117
160601
  required = true,
160118
160602
  isLoading = false,
160119
- isEmpty: isEmpty2 = false,
160603
+ isEmpty = false,
160120
160604
  hasMore = false,
160121
160605
  onLoadMore
160122
160606
  }) => {
@@ -160130,7 +160614,7 @@ var init_DatePicker = __esm({
160130
160614
  /* @__PURE__ */ jsx("p", { className: "ab-text ab-text--muted ab-text--sm", children: "Loading available dates..." })
160131
160615
  ] });
160132
160616
  }
160133
- if (isEmpty2) {
160617
+ if (isEmpty) {
160134
160618
  return /* @__PURE__ */ jsxs("div", { className: "ab-stack--sm", children: [
160135
160619
  /* @__PURE__ */ jsxs("label", { className: "ab-label", children: [
160136
160620
  "Select Date",
@@ -160681,7 +161165,7 @@ function buildBookingPaymentOptionViewModel(input) {
160681
161165
  };
160682
161166
  }
160683
161167
  default:
160684
- return assertNever7(input.option);
161168
+ return assertNever8(input.option);
160685
161169
  }
160686
161170
  }
160687
161171
  function buildInstalmentSchedulePreview(input) {
@@ -160738,7 +161222,7 @@ function buildInstalmentSchedulePreview(input) {
160738
161222
  })));
160739
161223
  }
160740
161224
  default:
160741
- return assertNever7(input.option.plan);
161225
+ return assertNever8(input.option.plan);
160742
161226
  }
160743
161227
  }
160744
161228
  function getPaymentCadenceLabel(plan) {
@@ -160873,7 +161357,10 @@ function PaymentOptionSelectionStep({
160873
161357
  "button",
160874
161358
  {
160875
161359
  type: "button",
160876
- className: isSelected ? "primary btn-md" : "outline btn-md",
161360
+ className: themeButtonClassName({
161361
+ variant: isSelected ? "primary" : "outline",
161362
+ size: "md"
161363
+ }),
160877
161364
  style: paymentOptionLayoutStyle,
160878
161365
  onClick: () => updateData({
160879
161366
  selectedAppointmentPackageId: appointmentPackage.customerPassId,
@@ -160922,7 +161409,10 @@ function PaymentOptionSelectionStep({
160922
161409
  "button",
160923
161410
  {
160924
161411
  type: "button",
160925
- className: isSelected ? "primary btn-md" : "outline btn-md",
161412
+ className: themeButtonClassName({
161413
+ variant: isSelected ? "primary" : "outline",
161414
+ size: "md"
161415
+ }),
160926
161416
  style: paymentOptionLayoutStyle,
160927
161417
  onClick: () => updateData({
160928
161418
  selectedAppointmentPackageId: void 0,
@@ -160950,6 +161440,7 @@ var paymentOptionLayoutStyle, summaryStackStyle;
160950
161440
  var init_PaymentOptionSelectionStep = __esm({
160951
161441
  "../blocks/src/system/runtime/components/booking/PaymentOptionSelectionStep.tsx"() {
160952
161442
  "use client";
161443
+ init_buttons();
160953
161444
  init_api();
160954
161445
  init_MultiStepContext();
160955
161446
  init_booking_form_state();
@@ -161491,7 +161982,7 @@ function pollingReducer(state, action) {
161491
161982
  case "timeout":
161492
161983
  return state;
161493
161984
  default:
161494
- return assertNever7(state);
161985
+ return assertNever8(state);
161495
161986
  }
161496
161987
  case "polling-timed-out":
161497
161988
  return {
@@ -161500,7 +161991,7 @@ function pollingReducer(state, action) {
161500
161991
  error: new Error("Polling timed out")
161501
161992
  };
161502
161993
  default:
161503
- return assertNever7(action);
161994
+ return assertNever8(action);
161504
161995
  }
161505
161996
  }
161506
161997
  var init_usePolling_state = __esm({
@@ -161681,7 +162172,7 @@ function bookingSubmissionReducer(state, action) {
161681
162172
  feedback: { tag: "idle" }
161682
162173
  };
161683
162174
  default:
161684
- return assertNever7(action);
162175
+ return assertNever8(action);
161685
162176
  }
161686
162177
  }
161687
162178
  function selectIsSubmitting2(state) {
@@ -162013,7 +162504,7 @@ function validateFormData(data) {
162013
162504
  return errors;
162014
162505
  }
162015
162506
  var EMAIL_REGEX;
162016
- var init_validation4 = __esm({
162507
+ var init_validation3 = __esm({
162017
162508
  "../blocks/src/system/runtime/shared/utils/validation.ts"() {
162018
162509
  EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
162019
162510
  }
@@ -162037,7 +162528,7 @@ var init_utils11 = __esm({
162037
162528
  init_scrollToBlock();
162038
162529
  init_themePortalRoot();
162039
162530
  init_urlParams();
162040
- init_validation4();
162531
+ init_validation3();
162041
162532
  init_wizardSteps();
162042
162533
  }
162043
162534
  });
@@ -162492,6 +162983,7 @@ var init_booking_form_client = __esm({
162492
162983
  init_noop();
162493
162984
  init_client2();
162494
162985
  init_src8();
162986
+ init_buttons();
162495
162987
  init_api();
162496
162988
  init_MultiStepForm();
162497
162989
  init_SuccessMessage();
@@ -162729,7 +163221,7 @@ var init_booking_form_client = __esm({
162729
163221
  "button",
162730
163222
  {
162731
163223
  type: "button",
162732
- className: "secondary btn-sm",
163224
+ className: themeButtonClassName({ variant: "secondary", size: "sm" }),
162733
163225
  onClick: clearFeedback,
162734
163226
  children: "Dismiss"
162735
163227
  }
@@ -163082,7 +163574,7 @@ function eligibilityLookupReducer(state, action) {
163082
163574
  error: action.message
163083
163575
  };
163084
163576
  default:
163085
- return assertNever7(action);
163577
+ return assertNever8(action);
163086
163578
  }
163087
163579
  }
163088
163580
  function existingRegistrationLookupReducer(state, action) {
@@ -163100,7 +163592,7 @@ function existingRegistrationLookupReducer(state, action) {
163100
163592
  registration: action.registration
163101
163593
  };
163102
163594
  default:
163103
- return assertNever7(action);
163595
+ return assertNever8(action);
163104
163596
  }
163105
163597
  }
163106
163598
  var initialEligibilityLookupState, initialExistingRegistrationLookupState;
@@ -164059,7 +164551,7 @@ var init_PaymentSelectionStep = __esm({
164059
164551
  init_lucide_react();
164060
164552
  init_utils12();
164061
164553
  init_spinner2();
164062
- init_themedButtonClass();
164554
+ init_buttons();
164063
164555
  init_CheckIcon2();
164064
164556
  init_SelectableOptionCard();
164065
164557
  PaymentSelectionStep = ({
@@ -164160,7 +164652,7 @@ var init_PaymentSelectionStep = __esm({
164160
164652
  "button",
164161
164653
  {
164162
164654
  type: "button",
164163
- className: themedButtonClass({ variant: "primary", size: "md" }),
164655
+ className: themeButtonClassName({ variant: "primary", size: "md" }),
164164
164656
  disabled: !email.trim(),
164165
164657
  onClick: onRequestLogin,
164166
164658
  children: "Email me a login link"
@@ -164749,7 +165241,7 @@ function validateFormData2(formData) {
164749
165241
  }
164750
165242
  return errors;
164751
165243
  }
164752
- var init_validation5 = __esm({
165244
+ var init_validation4 = __esm({
164753
165245
  "../blocks/src/system/runtime/nodes/event-registration/validation.ts"() {
164754
165246
  "use client";
164755
165247
  }
@@ -165689,7 +166181,7 @@ var init_useEventRegistrationWizard = __esm({
165689
166181
  "use client";
165690
166182
  init_api();
165691
166183
  init_events2();
165692
- init_validation5();
166184
+ init_validation4();
165693
166185
  init_hooks3();
165694
166186
  init_portalLogout();
165695
166187
  init_useWaitlistClaim();
@@ -165750,7 +166242,7 @@ function MagicLinkForm({
165750
166242
  "button",
165751
166243
  {
165752
166244
  type: "button",
165753
- className: classPrefix === "cp" ? "secondary" : `${classPrefix}-modal-btn ${classPrefix}-modal-btn--secondary`,
166245
+ className: classPrefix === "cp" ? themeButtonClassName({ variant: "secondary", size: "md" }) : `${classPrefix}-modal-btn ${classPrefix}-modal-btn--secondary`,
165754
166246
  onClick: handleReset,
165755
166247
  children: "Try a different email"
165756
166248
  }
@@ -165778,7 +166270,7 @@ function MagicLinkForm({
165778
166270
  "button",
165779
166271
  {
165780
166272
  type: "submit",
165781
- className: classPrefix === "cp" ? "primary" : `${classPrefix}-modal-btn`,
166273
+ className: classPrefix === "cp" ? themeButtonClassName({ variant: "primary", size: "md" }) : `${classPrefix}-modal-btn`,
165782
166274
  disabled: !email.trim() || loading,
165783
166275
  children: loading ? "Sending..." : buttonText
165784
166276
  }
@@ -165788,6 +166280,7 @@ function MagicLinkForm({
165788
166280
  var init_MagicLinkForm = __esm({
165789
166281
  "../blocks/src/system/runtime/nodes/shared/MagicLinkForm.tsx"() {
165790
166282
  "use client";
166283
+ init_buttons();
165791
166284
  init_api();
165792
166285
  }
165793
166286
  });
@@ -165809,7 +166302,7 @@ function EventRegistrationWizard(props2) {
165809
166302
  } = props2;
165810
166303
  const maxTicketsNum = parseInt(maxTickets, 10) || 5;
165811
166304
  const showSpamProtection = spamProtectionEnabled ?? isSpamProtectionEnabled();
165812
- const buttonClass = themedButtonClass({ variant: buttonVariant, size: "md" });
166305
+ const buttonClass = themeButtonClassName({ variant: buttonVariant, size: "md" });
165813
166306
  const wizard = useEventRegistrationWizard({
165814
166307
  anchorId: EVENT_REGISTRATION_ANCHOR_ID,
165815
166308
  occurrenceContext: occurrenceContext ?? null,
@@ -165945,7 +166438,7 @@ var init_EventRegistrationWizard = __esm({
165945
166438
  init_useEventRegistrationWizard();
165946
166439
  init_MagicLinkForm();
165947
166440
  init_spinner2();
165948
- init_themedButtonClass();
166441
+ init_buttons();
165949
166442
  init_event_registration3();
165950
166443
  EVENT_REGISTRATION_ANCHOR_ID = "event-registration";
165951
166444
  EVENT_PORTAL_AUTH_COPY = {
@@ -166355,7 +166848,7 @@ function ErrorStep2({
166355
166848
  buttonVariant = "primary",
166356
166849
  onRetry
166357
166850
  }) {
166358
- const buttonClass = themedButtonClass({ variant: buttonVariant, size: "md" });
166851
+ const buttonClass = themeButtonClassName({ variant: buttonVariant, size: "md" });
166359
166852
  return /* @__PURE__ */ jsxs("div", { className: "cr-error", role: "alert", children: [
166360
166853
  /* @__PURE__ */ jsx(StateIcon, { variant: "error", children: /* @__PURE__ */ jsx(CrossIcon, {}) }),
166361
166854
  /* @__PURE__ */ jsx("h3", { className: "cr-error__title", children: "Enrollment Failed" }),
@@ -166366,7 +166859,7 @@ function ErrorStep2({
166366
166859
  var init_ErrorStep2 = __esm({
166367
166860
  "../blocks/src/system/runtime/nodes/course-registration/ErrorStep.tsx"() {
166368
166861
  init_shared9();
166369
- init_themedButtonClass();
166862
+ init_buttons();
166370
166863
  }
166371
166864
  });
166372
166865
  function VerifyingTimeoutStep2({
@@ -166375,7 +166868,7 @@ function VerifyingTimeoutStep2({
166375
166868
  onCheckAgain,
166376
166869
  supportEmail
166377
166870
  }) {
166378
- const buttonClass = themedButtonClass({ variant: buttonVariant, size: "md" });
166871
+ const buttonClass = themeButtonClassName({ variant: buttonVariant, size: "md" });
166379
166872
  return /* @__PURE__ */ jsxs("div", { className: "cr-error", role: "alert", children: [
166380
166873
  /* @__PURE__ */ jsx(StateIcon, { variant: "warning", children: /* @__PURE__ */ jsx(ClockIcon, {}) }),
166381
166874
  /* @__PURE__ */ jsx("h3", { className: "cr-error__title", children: "Payment Verification Taking Longer" }),
@@ -166391,7 +166884,7 @@ function VerifyingTimeoutStep2({
166391
166884
  var init_VerifyingTimeoutStep2 = __esm({
166392
166885
  "../blocks/src/system/runtime/nodes/course-registration/VerifyingTimeoutStep.tsx"() {
166393
166886
  init_shared9();
166394
- init_themedButtonClass();
166887
+ init_buttons();
166395
166888
  }
166396
166889
  });
166397
166890
  function PaymentFailedStep2({
@@ -166400,7 +166893,7 @@ function PaymentFailedStep2({
166400
166893
  buttonVariant = "primary",
166401
166894
  onRetry
166402
166895
  }) {
166403
- const buttonClass = themedButtonClass({ variant: buttonVariant, size: "md" });
166896
+ const buttonClass = themeButtonClassName({ variant: buttonVariant, size: "md" });
166404
166897
  return /* @__PURE__ */ jsxs("div", { className: "cr-payment-failed", role: "alert", children: [
166405
166898
  /* @__PURE__ */ jsx(StateIcon, { variant: "error", children: /* @__PURE__ */ jsx(CrossIcon, {}) }),
166406
166899
  /* @__PURE__ */ jsx("h3", { className: "cr-payment-failed__title", children: "Payment Failed" }),
@@ -166411,7 +166904,7 @@ function PaymentFailedStep2({
166411
166904
  var init_PaymentFailedStep2 = __esm({
166412
166905
  "../blocks/src/system/runtime/nodes/course-registration/PaymentFailedStep.tsx"() {
166413
166906
  init_shared9();
166414
- init_themedButtonClass();
166907
+ init_buttons();
166415
166908
  }
166416
166909
  });
166417
166910
  function WaitlistStep({ message: message2, position }) {
@@ -167387,7 +167880,7 @@ function CourseRegistrationWizard(props2) {
167387
167880
  handleRetry,
167388
167881
  handleBookingModeChange
167389
167882
  } = useCourseRegistrationWizard(props2);
167390
- const buttonClass = themedButtonClass({ variant: buttonVariant, size: "md" });
167883
+ const buttonClass = themeButtonClassName({ variant: buttonVariant, size: "md" });
167391
167884
  if (scopedCourses.length === 0) {
167392
167885
  return /* @__PURE__ */ jsx(
167393
167886
  "div",
@@ -167796,7 +168289,7 @@ var init_CourseRegistrationWizard = __esm({
167796
168289
  init_PaymentFailedStep2();
167797
168290
  init_VerifyingTimeoutStep2();
167798
168291
  init_spinner2();
167799
- init_themedButtonClass();
168292
+ init_buttons();
167800
168293
  }
167801
168294
  });
167802
168295
  function toCourseRegistrationClientProps(props2) {
@@ -168329,7 +168822,7 @@ function shopPassesMembershipsReducer(state, action) {
168329
168822
  returnNotice: null
168330
168823
  };
168331
168824
  default:
168332
- return assertNever7(action);
168825
+ return assertNever8(action);
168333
168826
  }
168334
168827
  }
168335
168828
  function getOpenCheckout(state) {
@@ -168499,7 +168992,11 @@ function PassesMembershipsController({ render }) {
168499
168992
  "button",
168500
168993
  {
168501
168994
  type: "button",
168502
- className: "secondary btn-sm shop__return-dismiss",
168995
+ className: themeButtonClassName({
168996
+ variant: "secondary",
168997
+ size: "sm",
168998
+ extraClassName: "shop__return-dismiss"
168999
+ }),
168503
169000
  onClick: () => dispatch({ type: "clearReturnNotice" }),
168504
169001
  children: "Dismiss"
168505
169002
  }
@@ -168516,7 +169013,11 @@ function PassesMembershipsController({ render }) {
168516
169013
  "button",
168517
169014
  {
168518
169015
  type: "button",
168519
- className: "default shop__cta",
169016
+ className: themeButtonClassName({
169017
+ variant: "default",
169018
+ size: "md",
169019
+ extraClassName: "shop__cta"
169020
+ }),
168520
169021
  onClick: () => handleBuyPass(pass),
168521
169022
  children: passDisplay.actionLabel
168522
169023
  }
@@ -168543,7 +169044,11 @@ function PassesMembershipsController({ render }) {
168543
169044
  "button",
168544
169045
  {
168545
169046
  type: "button",
168546
- className: "default shop__cta",
169047
+ className: themeButtonClassName({
169048
+ variant: "default",
169049
+ size: "md",
169050
+ extraClassName: "shop__cta"
169051
+ }),
168547
169052
  onClick: () => handleSubscribe(membership),
168548
169053
  children: membershipDisplay.actionLabel
168549
169054
  }
@@ -168587,12 +169092,20 @@ function PassesMembershipsController({ render }) {
168587
169092
  ] }) : null
168588
169093
  ] }),
168589
169094
  /* @__PURE__ */ jsxs(ActionRow, { className: "shop__modal-warning-actions", children: [
168590
- /* @__PURE__ */ jsx("button", { type: "button", className: "secondary", onClick: closeCheckout, children: "Cancel" }),
168591
169095
  /* @__PURE__ */ jsx(
168592
169096
  "button",
168593
169097
  {
168594
169098
  type: "button",
168595
- className: "default",
169099
+ className: themeButtonClassName({ variant: "secondary", size: "md" }),
169100
+ onClick: closeCheckout,
169101
+ children: "Cancel"
169102
+ }
169103
+ ),
169104
+ /* @__PURE__ */ jsx(
169105
+ "button",
169106
+ {
169107
+ type: "button",
169108
+ className: themeButtonClassName({ variant: "default", size: "md" }),
168596
169109
  onClick: handleConfirmDuplicate,
168597
169110
  disabled: checkout2.submitting,
168598
169111
  children: checkout2.submitting ? "Processing..." : "Subscribe Anyway"
@@ -168635,8 +169148,25 @@ function PassesMembershipsController({ render }) {
168635
169148
  ] }),
168636
169149
  checkout2.formError ? /* @__PURE__ */ jsx("p", { className: "shop__modal-error", role: "alert", children: checkout2.formError }) : null,
168637
169150
  /* @__PURE__ */ jsxs(ActionRow, { className: "shop__modal-actions", children: [
168638
- /* @__PURE__ */ jsx("button", { type: "button", className: "secondary", onClick: closeCheckout, disabled: checkout2.submitting, children: "Cancel" }),
168639
- /* @__PURE__ */ jsx("button", { type: "submit", className: "default", disabled: checkout2.submitting, children: checkout2.submitting ? "Processing..." : "Continue to Payment" })
169151
+ /* @__PURE__ */ jsx(
169152
+ "button",
169153
+ {
169154
+ type: "button",
169155
+ className: themeButtonClassName({ variant: "secondary", size: "md" }),
169156
+ onClick: closeCheckout,
169157
+ disabled: checkout2.submitting,
169158
+ children: "Cancel"
169159
+ }
169160
+ ),
169161
+ /* @__PURE__ */ jsx(
169162
+ "button",
169163
+ {
169164
+ type: "submit",
169165
+ className: themeButtonClassName({ variant: "default", size: "md" }),
169166
+ disabled: checkout2.submitting,
169167
+ children: checkout2.submitting ? "Processing..." : "Continue to Payment"
169168
+ }
169169
+ )
168640
169170
  ] })
168641
169171
  ] })
168642
169172
  ] })
@@ -168648,6 +169178,7 @@ var SHOP_ANCHOR_ID;
168648
169178
  var init_shop_client = __esm({
168649
169179
  "../blocks/src/system/runtime/nodes/shop.client.tsx"() {
168650
169180
  "use client";
169181
+ init_buttons();
168651
169182
  init_api();
168652
169183
  init_ModalShell();
168653
169184
  init_shared9();
@@ -169175,7 +169706,7 @@ function shopCheckoutReducer(state, action) {
169175
169706
  notice: action.notice
169176
169707
  };
169177
169708
  default:
169178
- return assertNever7(action);
169709
+ return assertNever8(action);
169179
169710
  }
169180
169711
  }
169181
169712
  var initialShopCheckoutState;
@@ -169244,7 +169775,7 @@ function ProductListController(props2) {
169244
169775
  "button",
169245
169776
  {
169246
169777
  type: "button",
169247
- className: "default",
169778
+ className: themeButtonClassName({ variant: "default", size: "md" }),
169248
169779
  onClick: () => {
169249
169780
  const product = props2.render.hydration.products.find((candidate) => candidate.id === card.productId);
169250
169781
  if (!product) return;
@@ -169260,7 +169791,14 @@ function ProductListController(props2) {
169260
169791
  children: card.soldOut ? "Sold out" : card.actionLabel
169261
169792
  }
169262
169793
  ),
169263
- card.path ? /* @__PURE__ */ jsx("a", { href: card.path, className: "secondary btn-sm", children: "View details" }) : null
169794
+ card.path ? /* @__PURE__ */ jsx(
169795
+ "a",
169796
+ {
169797
+ href: card.path,
169798
+ className: themeButtonClassName({ variant: "secondary", size: "sm" }),
169799
+ children: "View details"
169800
+ }
169801
+ ) : null
169264
169802
  ] }),
169265
169803
  feedback: /* @__PURE__ */ jsx(
169266
169804
  ShopAddFeedback,
@@ -169326,7 +169864,7 @@ function ProductDetailController(props2) {
169326
169864
  "button",
169327
169865
  {
169328
169866
  type: "button",
169329
- className: "default",
169867
+ className: themeButtonClassName({ variant: "default", size: "md" }),
169330
169868
  disabled: display.soldOut,
169331
169869
  onClick: () => {
169332
169870
  if (!selectedProduct) return;
@@ -169376,15 +169914,31 @@ function CartController(props2) {
169376
169914
  onChange: item.quantityEditable ? (event) => cart2.updateQuantity(item.key, Number(event.target.value)) : void 0
169377
169915
  }
169378
169916
  ),
169379
- /* @__PURE__ */ jsx("button", { type: "button", className: "secondary btn-sm", onClick: () => cart2.removeItem(item.key), children: "Remove" })
169917
+ /* @__PURE__ */ jsx(
169918
+ "button",
169919
+ {
169920
+ type: "button",
169921
+ className: themeButtonClassName({ variant: "secondary", size: "sm" }),
169922
+ onClick: () => cart2.removeItem(item.key),
169923
+ children: "Remove"
169924
+ }
169925
+ )
169380
169926
  ] }),
169381
169927
  footerActions: /* @__PURE__ */ jsxs(Fragment, { children: [
169382
- /* @__PURE__ */ jsx("button", { type: "button", className: "secondary btn-sm", onClick: () => cart2.clear(), children: display.clearButtonText }),
169383
169928
  /* @__PURE__ */ jsx(
169384
169929
  "button",
169385
169930
  {
169386
169931
  type: "button",
169387
- className: "default",
169932
+ className: themeButtonClassName({ variant: "secondary", size: "sm" }),
169933
+ onClick: () => cart2.clear(),
169934
+ children: display.clearButtonText
169935
+ }
169936
+ ),
169937
+ /* @__PURE__ */ jsx(
169938
+ "button",
169939
+ {
169940
+ type: "button",
169941
+ className: themeButtonClassName({ variant: "default", size: "md" }),
169388
169942
  onClick: () => {
169389
169943
  window.location.href = resolveDedicatedCheckoutPath(window.location.pathname);
169390
169944
  },
@@ -169490,7 +170044,15 @@ function CheckoutController(props2) {
169490
170044
  )
169491
170045
  ] }),
169492
170046
  state.feedback.tag === "error" ? /* @__PURE__ */ jsx("p", { className: "rb-caption status-muted", children: state.feedback.message }) : null,
169493
- /* @__PURE__ */ jsx("button", { type: "submit", className: "default", disabled: state.submission === "submitting", children: state.submission === "submitting" ? "Loading\u2026" : display.submitButtonText })
170047
+ /* @__PURE__ */ jsx(
170048
+ "button",
170049
+ {
170050
+ type: "submit",
170051
+ className: themeButtonClassName({ variant: "default", size: "md" }),
170052
+ disabled: state.submission === "submitting",
170053
+ children: state.submission === "submitting" ? "Loading\u2026" : display.submitButtonText
170054
+ }
170055
+ )
169494
170056
  ] })
169495
170057
  }
169496
170058
  );
@@ -169499,6 +170061,7 @@ var CHECKOUT_ANCHOR_ID;
169499
170061
  var init_shop_commerce = __esm({
169500
170062
  "../blocks/src/system/runtime/nodes/shop-commerce.tsx"() {
169501
170063
  "use client";
170064
+ init_buttons();
169502
170065
  init_api();
169503
170066
  init_RichText();
169504
170067
  init_carousel_client();
@@ -169593,7 +170156,7 @@ function giftingClientReducer(state, action) {
169593
170156
  purchaseNotice: action.notice
169594
170157
  };
169595
170158
  default:
169596
- return assertNever7(action);
170159
+ return assertNever8(action);
169597
170160
  }
169598
170161
  }
169599
170162
  function resolveGiftingPurchaseNotice(search, defaultSuccessMessage) {
@@ -170102,7 +170665,7 @@ function HeaderCartDrawerItems(props2) {
170102
170665
  "button",
170103
170666
  {
170104
170667
  type: "button",
170105
- className: "secondary btn-sm",
170668
+ className: themeButtonClassName({ variant: "secondary", size: "sm" }),
170106
170669
  onClick: () => props2.cart.removeItem(item.key),
170107
170670
  children: "Remove"
170108
170671
  }
@@ -170195,7 +170758,7 @@ function HeaderCartDrawer(props2) {
170195
170758
  "button",
170196
170759
  {
170197
170760
  type: "button",
170198
- className: "secondary",
170761
+ className: themeButtonClassName({ variant: "secondary", size: "md" }),
170199
170762
  onClick: () => props2.cart.clear(),
170200
170763
  disabled: display.state === "empty",
170201
170764
  children: display.clearButtonText
@@ -170204,12 +170767,20 @@ function HeaderCartDrawer(props2) {
170204
170767
  props2.checkoutHref && display.state === "ready" ? /* @__PURE__ */ jsx(
170205
170768
  "a",
170206
170769
  {
170207
- className: "default",
170770
+ className: themeButtonClassName({ variant: "default", size: "md" }),
170208
170771
  href: props2.checkoutHref,
170209
170772
  onClick: props2.onClose,
170210
170773
  children: display.checkoutButtonText
170211
170774
  }
170212
- ) : /* @__PURE__ */ jsx("button", { type: "button", className: "default", disabled: true, children: display.checkoutButtonText })
170775
+ ) : /* @__PURE__ */ jsx(
170776
+ "button",
170777
+ {
170778
+ type: "button",
170779
+ className: themeButtonClassName({ variant: "default", size: "md" }),
170780
+ disabled: true,
170781
+ children: display.checkoutButtonText
170782
+ }
170783
+ )
170213
170784
  ] })
170214
170785
  ]
170215
170786
  }
@@ -170221,6 +170792,7 @@ function HeaderCartDrawer(props2) {
170221
170792
  var init_HeaderCartDrawer = __esm({
170222
170793
  "../blocks/src/system/runtime/header/HeaderCartDrawer.tsx"() {
170223
170794
  "use client";
170795
+ init_buttons();
170224
170796
  init_display();
170225
170797
  init_ModalShell();
170226
170798
  }
@@ -170963,7 +171535,7 @@ var init_EventPaginatedListView_client = __esm({
170963
171535
  init_EventCompactRow();
170964
171536
  init_EmptyState();
170965
171537
  init_EventListing_view();
170966
- init_themedButtonClass();
171538
+ init_buttons();
170967
171539
  EventPaginatedListView = ({
170968
171540
  filters,
170969
171541
  display,
@@ -171006,7 +171578,7 @@ var init_EventPaginatedListView_client = __esm({
171006
171578
  {
171007
171579
  type: "button",
171008
171580
  onClick: loadMore,
171009
- className: themedButtonClass({
171581
+ className: themeButtonClassName({
171010
171582
  variant: display.buttonVariant,
171011
171583
  size: "md"
171012
171584
  }),
@@ -171020,7 +171592,7 @@ var init_EventPaginatedListView_client = __esm({
171020
171592
  type: "button",
171021
171593
  onClick: loadMore,
171022
171594
  disabled: loading,
171023
- className: themedButtonClass({
171595
+ className: themeButtonClassName({
171024
171596
  variant: display.buttonVariant,
171025
171597
  size: "md",
171026
171598
  extraClassName: loading ? "rb-opacity-50 rb-cursor-wait" : null
@@ -171032,7 +171604,7 @@ var init_EventPaginatedListView_client = __esm({
171032
171604
  "a",
171033
171605
  {
171034
171606
  href: seeAllUrl,
171035
- className: themedButtonClass({
171607
+ className: themeButtonClassName({
171036
171608
  variant: display.buttonVariant,
171037
171609
  size: "md"
171038
171610
  }),
@@ -172326,7 +172898,7 @@ var init_EventCombined_client = __esm({
172326
172898
  init_EventModalContext();
172327
172899
  init_EventModals();
172328
172900
  init_utils7();
172329
- init_themedButtonClass();
172901
+ init_buttons();
172330
172902
  EventCombinedClient = ({
172331
172903
  events: initialEvents,
172332
172904
  siteId,
@@ -172652,7 +173224,7 @@ var init_EventCombined_client = __esm({
172652
173224
  {
172653
173225
  type: "button",
172654
173226
  onClick: goToToday,
172655
- className: themedButtonClass({ variant: buttonVariant, size: "sm" }),
173227
+ className: themeButtonClassName({ variant: buttonVariant, size: "sm" }),
172656
173228
  children: "Today"
172657
173229
  }
172658
173230
  )
@@ -172959,7 +173531,7 @@ var init_EventCalendar_client = __esm({
172959
173531
  init_EventModalContext();
172960
173532
  init_EventModals();
172961
173533
  init_WeekTimetableView();
172962
- init_themedButtonClass();
173534
+ init_buttons();
172963
173535
  EventCalendarClient = ({
172964
173536
  render
172965
173537
  }) => {
@@ -173248,7 +173820,7 @@ var init_EventCalendar_client = __esm({
173248
173820
  {
173249
173821
  type: "button",
173250
173822
  onClick: onToday,
173251
- className: themedButtonClass({
173823
+ className: themeButtonClassName({
173252
173824
  variant: display.buttonVariant,
173253
173825
  size: "sm"
173254
173826
  }),
@@ -173264,7 +173836,7 @@ var init_EventCalendar_client = __esm({
173264
173836
  {
173265
173837
  type: "button",
173266
173838
  onClick: onToday,
173267
- className: themedButtonClass({
173839
+ className: themeButtonClassName({
173268
173840
  variant: display.buttonVariant,
173269
173841
  size: "sm"
173270
173842
  }),
@@ -173298,7 +173870,7 @@ function formSubmissionReducer(_state, action) {
173298
173870
  case "submission-failed":
173299
173871
  return { tag: "failed", message: action.message };
173300
173872
  default:
173301
- return assertNever7(action);
173873
+ return assertNever8(action);
173302
173874
  }
173303
173875
  }
173304
173876
  var initialFormSubmissionState;
@@ -173351,7 +173923,7 @@ var init_form_client = __esm({
173351
173923
  init_client2();
173352
173924
  init_src8();
173353
173925
  init_useFormSubmission();
173354
- init_themedButtonClass();
173926
+ init_buttons();
173355
173927
  FormNodeClient = ({
173356
173928
  render
173357
173929
  }) => {
@@ -173493,7 +174065,7 @@ var init_form_client = __esm({
173493
174065
  "button",
173494
174066
  {
173495
174067
  type: "submit",
173496
- className: themedButtonClass({
174068
+ className: themeButtonClassName({
173497
174069
  variant: "primary",
173498
174070
  size: "md",
173499
174071
  extraClassName: "rb-w-full rb-sm-w-auto"
@@ -173713,7 +174285,7 @@ function NewsletterFormClient({
173713
174285
  "button",
173714
174286
  {
173715
174287
  type: "submit",
173716
- className: themedButtonClass({ variant: "primary", size: "md" }),
174288
+ className: themeButtonClassName({ variant: "primary", size: "md" }),
173717
174289
  disabled: isSubmitting,
173718
174290
  children: isSubmitting ? "Subscribing..." : render.display.buttonLabel
173719
174291
  }
@@ -173731,11 +174303,11 @@ var init_newsletter_form_client = __esm({
173731
174303
  init_client2();
173732
174304
  init_src8();
173733
174305
  init_api();
173734
- init_themedButtonClass();
174306
+ init_buttons();
173735
174307
  newsletter_form_client_default = NewsletterFormClient;
173736
174308
  }
173737
174309
  });
173738
- function isRecord8(value) {
174310
+ function isRecord9(value) {
173739
174311
  return typeof value === "object" && value !== null;
173740
174312
  }
173741
174313
  function buildRenderFromLooseProps(runtime, mode, props2) {
@@ -173754,14 +174326,14 @@ function withRuntimeBackedEnvelope(source, runtime, render) {
173754
174326
  function normalizeLegacyInteractiveRenderProps(runtime, mode, props2) {
173755
174327
  const source = props2;
173756
174328
  const render = props2["render"];
173757
- if (!isRecord8(render)) {
174329
+ if (!isRecord9(render)) {
173758
174330
  return withRuntimeBackedEnvelope(
173759
174331
  source,
173760
174332
  runtime,
173761
174333
  buildRenderFromLooseProps(runtime, mode, props2)
173762
174334
  );
173763
174335
  }
173764
- if (isRecord8(render["hydration"])) {
174336
+ if (isRecord9(render["hydration"])) {
173765
174337
  return withRuntimeBackedEnvelope(
173766
174338
  source,
173767
174339
  runtime,
@@ -173771,7 +174343,7 @@ function normalizeLegacyInteractiveRenderProps(runtime, mode, props2) {
173771
174343
  }
173772
174344
  );
173773
174345
  }
173774
- if (!isRecord8(render["display"])) {
174346
+ if (!isRecord9(render["display"])) {
173775
174347
  return withRuntimeBackedEnvelope(
173776
174348
  source,
173777
174349
  runtime,
@@ -174032,32 +174604,14 @@ var init_repeaterFieldDefaults = __esm({
174032
174604
  "../block-form/src/widgets/RepeaterField/repeaterFieldDefaults.ts"() {
174033
174605
  }
174034
174606
  });
174607
+
174608
+ // ../block-form/src/widgets/UrlField/urlFieldSchema.ts
174035
174609
  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();
174610
+ return buildCanonicalFieldSchema(field);
174056
174611
  }
174057
- var ALLOWED_PROTOCOLS;
174058
174612
  var init_urlFieldSchema = __esm({
174059
174613
  "../block-form/src/widgets/UrlField/urlFieldSchema.ts"() {
174060
- ALLOWED_PROTOCOLS = ["http:", "https:"];
174614
+ init_canonicalValidation();
174061
174615
  }
174062
174616
  });
174063
174617
 
@@ -174136,18 +174690,14 @@ var init_dateTimeFieldDefaults = __esm({
174136
174690
  "../block-form/src/widgets/DateTimeField/dateTimeFieldDefaults.ts"() {
174137
174691
  }
174138
174692
  });
174693
+
174694
+ // ../block-form/src/widgets/SlugField/slugFieldSchema.ts
174139
174695
  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();
174696
+ return buildCanonicalFieldSchema(field);
174146
174697
  }
174147
- var SLUG_PATTERN2;
174148
174698
  var init_slugFieldSchema = __esm({
174149
174699
  "../block-form/src/widgets/SlugField/slugFieldSchema.ts"() {
174150
- SLUG_PATTERN2 = /^(?:[a-z0-9]+(?:-[a-z0-9]+)*)(?:\/(?:[a-z0-9]+(?:-[a-z0-9]+)*))*$/;
174700
+ init_canonicalValidation();
174151
174701
  }
174152
174702
  });
174153
174703
 
@@ -174159,51 +174709,14 @@ var init_slugFieldDefaults = __esm({
174159
174709
  "../block-form/src/widgets/SlugField/slugFieldDefaults.ts"() {
174160
174710
  }
174161
174711
  });
174712
+
174713
+ // ../block-form/src/widgets/LinkField/linkFieldSchema.ts
174162
174714
  function buildLinkFieldSchema(field) {
174163
- if (field.required) {
174164
- return linkSchema2;
174165
- }
174166
- return z.union([linkSchema2, z.null()]).optional();
174715
+ return buildCanonicalFieldSchema(field);
174167
174716
  }
174168
- var internalLinkSchema2, externalLinkSchema2, customLinkSchema2, pageLinkSchema2, entryLinkSchema2, linkSchema2;
174169
174717
  var init_linkFieldSchema = __esm({
174170
174718
  "../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
- ]);
174719
+ init_canonicalValidation();
174207
174720
  }
174208
174721
  });
174209
174722
 
@@ -174221,6 +174734,55 @@ var init_linkFieldDefaults = __esm({
174221
174734
  "../block-form/src/widgets/LinkField/linkFieldDefaults.ts"() {
174222
174735
  }
174223
174736
  });
174737
+ function buildRichTextSchema(options) {
174738
+ let schema = RichTextValueSchema;
174739
+ if (options?.required) {
174740
+ const label = options.label ?? "This field";
174741
+ schema = schema.refine(
174742
+ (val) => {
174743
+ const doc3 = isRecord5(val) && "doc" in val ? val.doc : val;
174744
+ const content = isRecord5(doc3) ? doc3.content : void 0;
174745
+ if (!Array.isArray(content) || content.length === 0) return false;
174746
+ const first2 = content[0];
174747
+ if (content.length === 1 && isRecord5(first2) && first2.type === "paragraph" && (!("content" in first2) || first2.content == null)) {
174748
+ return false;
174749
+ }
174750
+ return true;
174751
+ },
174752
+ {
174753
+ message: `${label} is required`
174754
+ }
174755
+ );
174756
+ }
174757
+ return schema;
174758
+ }
174759
+ var TipTapMarkSchema, TipTapNodeSchema, RichTextValueSchema;
174760
+ var init_richTextSchema = __esm({
174761
+ "../blocks/src/system/manifest/richTextSchema.ts"() {
174762
+ init_typeGuards2();
174763
+ TipTapMarkSchema = z.object({
174764
+ type: z.string(),
174765
+ attrs: z.record(z.string(), z.unknown()).optional()
174766
+ });
174767
+ TipTapNodeSchema = z.lazy(
174768
+ () => z.object({
174769
+ type: z.string(),
174770
+ content: z.array(TipTapNodeSchema).optional(),
174771
+ text: z.string().optional(),
174772
+ attrs: z.record(z.string(), z.unknown()).optional(),
174773
+ marks: z.array(TipTapMarkSchema).optional()
174774
+ })
174775
+ );
174776
+ RichTextValueSchema = z.union([
174777
+ // New format: TipTap document directly
174778
+ TipTapNodeSchema,
174779
+ // Legacy format: wrapped in { doc: {...} }
174780
+ z.object({
174781
+ doc: TipTapNodeSchema
174782
+ })
174783
+ ]);
174784
+ }
174785
+ });
174224
174786
  function buildRichTextFieldSchema(config) {
174225
174787
  const schema = buildRichTextSchema({
174226
174788
  required: config.required,
@@ -174251,30 +174813,14 @@ var init_richTextFieldDefaults = __esm({
174251
174813
  };
174252
174814
  }
174253
174815
  });
174816
+
174817
+ // ../block-form/src/widgets/MediaField/mediaFieldSchema.ts
174254
174818
  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;
174819
+ return buildCanonicalFieldSchema(config);
174262
174820
  }
174263
- var MediaValueSchema;
174264
174821
  var init_mediaFieldSchema = __esm({
174265
174822
  "../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
- });
174823
+ init_canonicalValidation();
174278
174824
  }
174279
174825
  });
174280
174826
 
@@ -174286,15 +174832,14 @@ var init_mediaFieldDefaults = __esm({
174286
174832
  "../block-form/src/widgets/MediaField/mediaFieldDefaults.ts"() {
174287
174833
  }
174288
174834
  });
174835
+
174836
+ // ../block-form/src/widgets/ReferenceField/referenceFieldSchema.ts
174289
174837
  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(""));
174838
+ return buildCanonicalFieldSchema(field);
174295
174839
  }
174296
174840
  var init_referenceFieldSchema = __esm({
174297
174841
  "../block-form/src/widgets/ReferenceField/referenceFieldSchema.ts"() {
174842
+ init_canonicalValidation();
174298
174843
  }
174299
174844
  });
174300
174845
 
@@ -188902,7 +189447,7 @@ var init_MediaEditor = __esm({
188902
189447
  });
188903
189448
 
188904
189449
  // ../media-storage-api/dist/index.mjs
188905
- function isRecord9(value) {
189450
+ function isRecord10(value) {
188906
189451
  return typeof value === "object" && value !== null;
188907
189452
  }
188908
189453
  function createCachedMediaRepo(baseRepo, options) {
@@ -189025,7 +189570,7 @@ var init_dist91 = __esm({
189025
189570
  return payload;
189026
189571
  };
189027
189572
  extractErrorMessage = (body) => {
189028
- if (!isRecord9(body)) {
189573
+ if (!isRecord10(body)) {
189029
189574
  return typeof body === "string" && body.trim().length > 0 ? body : null;
189030
189575
  }
189031
189576
  const directKeys = ["error", "message", "detail", "reason"];
@@ -189041,7 +189586,7 @@ var init_dist91 = __esm({
189041
189586
  if (typeof entry === "string" && entry.trim().length > 0) {
189042
189587
  return entry;
189043
189588
  }
189044
- if (isRecord9(entry) && typeof entry.message === "string" && entry.message.trim().length > 0) {
189589
+ if (isRecord10(entry) && typeof entry.message === "string" && entry.message.trim().length > 0) {
189045
189590
  return entry.message;
189046
189591
  }
189047
189592
  }
@@ -189049,7 +189594,7 @@ var init_dist91 = __esm({
189049
189594
  const errors = body.errors;
189050
189595
  if (Array.isArray(errors)) {
189051
189596
  for (const entry of errors) {
189052
- if (isRecord9(entry) && typeof entry.message === "string" && entry.message.trim().length > 0) {
189597
+ if (isRecord10(entry) && typeof entry.message === "string" && entry.message.trim().length > 0) {
189053
189598
  return entry.message;
189054
189599
  }
189055
189600
  }
@@ -193053,7 +193598,7 @@ var init_PreviewRichTextEditor = __esm({
193053
193598
  const isEditingRef = useRef(false);
193054
193599
  const initialDoc = normaliseDoc(value ?? doc3);
193055
193600
  const chosenVariant = variant ?? "full";
193056
- const { editor, isEmpty: isEmpty2, config } = useRichTextEditor({
193601
+ const { editor, isEmpty, config } = useRichTextEditor({
193057
193602
  content: initialDoc,
193058
193603
  editable: true,
193059
193604
  variant: chosenVariant
@@ -193130,7 +193675,7 @@ var init_PreviewRichTextEditor = __esm({
193130
193675
  {
193131
193676
  editor,
193132
193677
  config,
193133
- isEmpty: isEmpty2,
193678
+ isEmpty,
193134
193679
  className: `relative w-full min-h-[30px] rounded border border-dashed ${showAffordance ? "border-slate-400/75 bg-white/5" : "border-transparent bg-transparent"}`,
193135
193680
  contentClassName: "cursor-text",
193136
193681
  placeholderClassName: "text-gray-400",
@@ -193288,6 +193833,14 @@ var init_routableLink = __esm({
193288
193833
  }
193289
193834
  });
193290
193835
 
193836
+ // ../api/src/navigation/linkValue.ts
193837
+ var init_linkValue = __esm({
193838
+ "../api/src/navigation/linkValue.ts"() {
193839
+ init_src3();
193840
+ init_routableLink();
193841
+ }
193842
+ });
193843
+
193291
193844
  // ../api/src/navigation/matcher.ts
193292
193845
  var init_matcher = __esm({
193293
193846
  "../api/src/navigation/matcher.ts"() {
@@ -193302,6 +193855,7 @@ var init_navigation2 = __esm({
193302
193855
  init_navigationMenuValidation();
193303
193856
  init_linkResolver();
193304
193857
  init_routableLink();
193858
+ init_linkValue();
193305
193859
  init_matcher();
193306
193860
  }
193307
193861
  });
@@ -193985,7 +194539,9 @@ function isSameLinkValue(a2, b3) {
193985
194539
  if (!a2 || !b3 || a2.kind !== b3.kind) return false;
193986
194540
  switch (a2.kind) {
193987
194541
  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;
194542
+ if (b3.kind !== "internal" || a2.routeId !== b3.routeId) return false;
194543
+ if (!isInternalResolvedLinkValue(a2) || !isInternalResolvedLinkValue(b3)) return true;
194544
+ 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
194545
  case "page":
193990
194546
  return b3.kind === "page" && a2.identifier === b3.identifier;
193991
194547
  case "entry":
@@ -194004,6 +194560,7 @@ function getDisplayTitle2(item) {
194004
194560
  var init_utils22 = __esm({
194005
194561
  "../editor-blocks/src/widgets/link/utils.ts"() {
194006
194562
  init_navigation2();
194563
+ init_src6();
194007
194564
  }
194008
194565
  });
194009
194566
  function getActiveTab(value) {
@@ -194312,6 +194869,12 @@ function LinkTriggerContent({ value }) {
194312
194869
  return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Select a link..." });
194313
194870
  }
194314
194871
  if (value.kind === "internal") {
194872
+ if (!isInternalResolvedLinkValue(value)) {
194873
+ return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
194874
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium", title: value.routeId, children: "Internal route" }),
194875
+ /* @__PURE__ */ jsx(Badge2, { variant: "secondary", className: "shrink-0", children: "Internal" })
194876
+ ] });
194877
+ }
194315
194878
  return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
194316
194879
  /* @__PURE__ */ jsx("span", { className: "truncate font-medium", title: value.title || void 0, children: value.title || "Untitled" }),
194317
194880
  /* @__PURE__ */ jsx(Badge2, { variant: "secondary", className: "shrink-0", children: value.typeLabel })
@@ -194408,6 +194971,7 @@ function LinkWidget({
194408
194971
  var init_LinkWidget = __esm({
194409
194972
  "../editor-blocks/src/widgets/link/LinkWidget.tsx"() {
194410
194973
  "use client";
194974
+ init_src6();
194411
194975
  init_src();
194412
194976
  init_lucide_react();
194413
194977
  init_client4();
@@ -194836,8 +195400,8 @@ function unwrapValue(value) {
194836
195400
  if (typeof value === "string") {
194837
195401
  return value;
194838
195402
  }
194839
- if (isObjectRecord(value)) {
194840
- if (isObjectRecord(value.doc)) {
195403
+ if (isObjectRecord2(value)) {
195404
+ if (isObjectRecord2(value.doc)) {
194841
195405
  return value.doc;
194842
195406
  }
194843
195407
  if (typeof value.type === "string") {
@@ -197699,9 +198263,9 @@ function blockSaveabilityEqual(left, right) {
197699
198263
  if (left.issues.length !== right.issues.length) {
197700
198264
  return false;
197701
198265
  }
197702
- return left.issues.every((issue, index2) => {
198266
+ return left.issues.every((issue2, index2) => {
197703
198267
  const nextIssue = right.issues[index2];
197704
- return nextIssue?.fieldPath === issue.fieldPath && nextIssue.message === issue.message;
198268
+ return nextIssue?.fieldPath === issue2.fieldPath && nextIssue.message === issue2.message;
197705
198269
  });
197706
198270
  }
197707
198271
  var init_BlockForm = __esm({
@@ -200817,38 +201381,38 @@ var internalLinkPayloadSchema = z.object({
200817
201381
  contentTypeName: z.string().nullable().optional(),
200818
201382
  updatedAt: z.string().nullable().optional()
200819
201383
  }).passthrough();
200820
- var externalLinkSchema3 = z.object({
201384
+ var externalLinkSchema2 = z.object({
200821
201385
  kind: z.literal("external"),
200822
201386
  // Navigation external links are expected to be absolute URLs.
200823
201387
  href: z.string().url()
200824
201388
  });
200825
- var customLinkSchema3 = z.object({
201389
+ var customLinkSchema2 = z.object({
200826
201390
  kind: z.literal("url"),
200827
201391
  href: z.string().min(1)
200828
201392
  });
200829
- var pageLinkSchema3 = z.object({
201393
+ var pageLinkSchema2 = z.object({
200830
201394
  kind: z.literal("page"),
200831
201395
  identifier: z.string().min(1)
200832
201396
  });
200833
- var entryLinkSchema3 = z.object({
201397
+ var entryLinkSchema2 = z.object({
200834
201398
  kind: z.literal("entry"),
200835
201399
  contentType: z.string().min(1),
200836
201400
  identifier: z.string().min(1)
200837
201401
  });
200838
201402
  var linkPayloadSchema = z.discriminatedUnion("kind", [
200839
201403
  internalLinkPayloadSchema,
200840
- pageLinkSchema3,
200841
- entryLinkSchema3,
200842
- externalLinkSchema3,
200843
- customLinkSchema3,
201404
+ pageLinkSchema2,
201405
+ entryLinkSchema2,
201406
+ externalLinkSchema2,
201407
+ customLinkSchema2,
200844
201408
  portalLinkPayloadSchema,
200845
201409
  cartLinkPayloadSchema
200846
201410
  ]);
200847
201411
  var navigationLinkInputSchemaOptions = [
200848
- pageLinkSchema3,
200849
- entryLinkSchema3,
200850
- externalLinkSchema3,
200851
- customLinkSchema3,
201412
+ pageLinkSchema2,
201413
+ entryLinkSchema2,
201414
+ externalLinkSchema2,
201415
+ customLinkSchema2,
200852
201416
  portalLinkPayloadSchema,
200853
201417
  cartLinkPayloadSchema
200854
201418
  ];
@@ -201612,11 +202176,11 @@ siteBannerSettingsSchema.superRefine((value, ctx) => {
201612
202176
  return;
201613
202177
  }
201614
202178
  const analysis = analyzeSiteBannerBody(value.body);
201615
- for (const issue of analysis.issues) {
202179
+ for (const issue2 of analysis.issues) {
201616
202180
  ctx.addIssue({
201617
202181
  code: z.ZodIssueCode.custom,
201618
202182
  path: ["body"],
201619
- message: siteBannerBodyIssueMessage(issue)
202183
+ message: siteBannerBodyIssueMessage(issue2)
201620
202184
  });
201621
202185
  }
201622
202186
  });
@@ -201650,8 +202214,8 @@ function analyzeSiteBannerBody(body) {
201650
202214
  issues
201651
202215
  };
201652
202216
  }
201653
- function siteBannerBodyIssueMessage(issue) {
201654
- switch (issue) {
202217
+ function siteBannerBodyIssueMessage(issue2) {
202218
+ switch (issue2) {
201655
202219
  case "empty":
201656
202220
  return "Banner message is required when the banner is enabled.";
201657
202221
  case "too-many-paragraphs":
@@ -201868,8 +202432,8 @@ init_matcher();
201868
202432
  // ../api/src/navigation/visibility.ts
201869
202433
  init_isRecord();
201870
202434
 
201871
- // ../api/src/navigation/linkValue.ts
201872
- init_routableLink();
202435
+ // ../api/src/index.ts
202436
+ init_linkValue();
201873
202437
 
201874
202438
  // ../api/src/redirects.ts
201875
202439
  init_envelope();
@@ -202056,7 +202620,7 @@ function previewCustomizeHistoryEntryFromAction(editorModel, action) {
202056
202620
  };
202057
202621
  }
202058
202622
  default:
202059
- return assertNever5(action, "Unhandled preview customize action");
202623
+ return assertNever6(action, "Unhandled preview customize action");
202060
202624
  }
202061
202625
  }
202062
202626
  function previewCustomizeUndoActionForEntry(entry) {
@@ -202097,7 +202661,7 @@ function previewCustomizeActionForEntryValue(entry, valueKey) {
202097
202661
  };
202098
202662
  }
202099
202663
  default:
202100
- return assertNever5(entry, "Unhandled preview customize history entry");
202664
+ return assertNever6(entry, "Unhandled preview customize history entry");
202101
202665
  }
202102
202666
  }
202103
202667
  function supportedPinnedChoiceValue(choice) {
@@ -202119,7 +202683,7 @@ function previewCustomizeHistoryEntryStillApplies(entry, editorModel) {
202119
202683
  (boundary) => boundary.boundaryId === entry.boundaryId && boundary.previousBlockId === entry.previousBlockId && boundary.nextBlockId === entry.nextBlockId
202120
202684
  );
202121
202685
  default:
202122
- return assertNever5(entry, "Unhandled preview customize history entry");
202686
+ return assertNever6(entry, "Unhandled preview customize history entry");
202123
202687
  }
202124
202688
  }
202125
202689
  function previewCustomizeHistoryEntryEquals(left, right) {
@@ -202133,7 +202697,7 @@ function previewCustomizeHistoryEntryEquals(left, right) {
202133
202697
  case "boundary":
202134
202698
  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
202699
  default:
202136
- return assertNever5(left, "Unhandled preview customize history entry");
202700
+ return assertNever6(left, "Unhandled preview customize history entry");
202137
202701
  }
202138
202702
  }
202139
202703
 
@@ -202174,7 +202738,7 @@ function previewCustomizeWorkflowPageState(workflow) {
202174
202738
  case "loaded":
202175
202739
  return workflow.pageState;
202176
202740
  default:
202177
- return assertNever5(workflow, "Unhandled preview customize workflow state");
202741
+ return assertNever6(workflow, "Unhandled preview customize workflow state");
202178
202742
  }
202179
202743
  }
202180
202744
  function beginPreviewCustomizeApply(workflow, action) {
@@ -202269,7 +202833,7 @@ function confirmPreviewCustomizeMutation(workflow, response) {
202269
202833
  case "stale":
202270
202834
  return workflow;
202271
202835
  default:
202272
- return assertNever5(workflow.mutation, "Unhandled preview customize mutation");
202836
+ return assertNever6(workflow.mutation, "Unhandled preview customize mutation");
202273
202837
  }
202274
202838
  }
202275
202839
  function rejectPreviewCustomizeMutation(previousWorkflow, outcome) {
@@ -202303,7 +202867,7 @@ function previewCustomizeFailureMessage(workflow) {
202303
202867
  case "redoing":
202304
202868
  return null;
202305
202869
  default:
202306
- return assertNever5(workflow.mutation, "Unhandled preview customize mutation");
202870
+ return assertNever6(workflow.mutation, "Unhandled preview customize mutation");
202307
202871
  }
202308
202872
  }
202309
202873
  function skippedPreviewCustomizeOutcome(reason) {
@@ -202335,7 +202899,7 @@ function skippedPreviewCustomizeMessage(reason) {
202335
202899
  case "cannot-redo":
202336
202900
  return "No design choice is available to redo.";
202337
202901
  default:
202338
- return assertNever5(reason, "Unhandled preview customize skip reason");
202902
+ return assertNever6(reason, "Unhandled preview customize skip reason");
202339
202903
  }
202340
202904
  }
202341
202905
  function skipReasonForNewMutation(workflow) {
@@ -202358,7 +202922,7 @@ function isPendingMutation(mutation) {
202358
202922
  case "stale":
202359
202923
  return false;
202360
202924
  default:
202361
- return assertNever5(mutation, "Unhandled preview customize mutation");
202925
+ return assertNever6(mutation, "Unhandled preview customize mutation");
202362
202926
  }
202363
202927
  }
202364
202928
  function confirmedLoadedState(current, response) {
@@ -202433,7 +202997,7 @@ function applyPreviewCustomizeActionToLoadedState(state, action) {
202433
202997
  }
202434
202998
  };
202435
202999
  default:
202436
- return assertNever5(action, "Unhandled preview customize action");
203000
+ return assertNever6(action, "Unhandled preview customize action");
202437
203001
  }
202438
203002
  }
202439
203003
  function optimisticBoundaryBreakChoice(editorModel, boundary, action) {
@@ -202451,7 +203015,7 @@ function optimisticBoundaryBreakChoice(editorModel, boundary, action) {
202451
203015
  effectiveValue: autoBoundaryEffectiveValue(editorModel, boundary)
202452
203016
  };
202453
203017
  default:
202454
- return assertNever5(action, "Unhandled optimistic boundary action");
203018
+ return assertNever6(action, "Unhandled optimistic boundary action");
202455
203019
  }
202456
203020
  }
202457
203021
  function autoBoundaryEffectiveValue(editorModel, boundary) {
@@ -202711,7 +203275,7 @@ function pageDesignEditorActionForPersistence(action) {
202711
203275
  case "set-boundary":
202712
203276
  return action;
202713
203277
  default:
202714
- return assertNever5(action, "Unhandled page design editor action");
203278
+ return assertNever6(action, "Unhandled page design editor action");
202715
203279
  }
202716
203280
  }
202717
203281
  function classifyApplyActionError(error) {
@@ -202754,12 +203318,12 @@ function blockIdForRuntimePatch(action) {
202754
203318
  case "reset-boundary":
202755
203319
  return action.previousBlockId;
202756
203320
  default:
202757
- return assertNever5(action, "Unhandled runtime patch action");
203321
+ return assertNever6(action, "Unhandled runtime patch action");
202758
203322
  }
202759
203323
  }
202760
203324
  function currentLocalBlockContent(uiStore, targetBlockId) {
202761
203325
  const current = uiStore.getState().drafts.getCurrentValues(asEditorBlockId(targetBlockId));
202762
- return isRecord10(current) ? current : null;
203326
+ return isRecord11(current) ? current : null;
202763
203327
  }
202764
203328
  function replaceLocalBlockContentWithoutHistory(uiStore, targetBlockId, nextContent) {
202765
203329
  const editorBlockId = asEditorBlockId(targetBlockId);
@@ -202778,7 +203342,7 @@ function replaceLocalBlockContentWithoutHistory(uiStore, targetBlockId, nextCont
202778
203342
  }
202779
203343
  });
202780
203344
  }
202781
- function isRecord10(value) {
203345
+ function isRecord11(value) {
202782
203346
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
202783
203347
  }
202784
203348
 
@@ -203352,25 +203916,25 @@ var INITIAL_ONBOARDING_CONFIRMATION_STATE = {
203352
203916
  resendFeedback: null,
203353
203917
  statusLoadFailed: false
203354
203918
  };
203355
- function isRecord11(value) {
203919
+ function isRecord12(value) {
203356
203920
  return value !== null && typeof value === "object";
203357
203921
  }
203358
203922
  function getErrorMessageFromEnvelope(payload, fallback2) {
203359
- const error = isRecord11(payload) ? payload.error : null;
203360
- const message2 = isRecord11(error) ? error.message : null;
203923
+ const error = isRecord12(payload) ? payload.error : null;
203924
+ const message2 = isRecord12(error) ? error.message : null;
203361
203925
  return typeof message2 === "string" && message2.trim().length > 0 ? message2 : fallback2;
203362
203926
  }
203363
203927
  function isLaunchReadiness(value) {
203364
- return isRecord11(value) && Array.isArray(value.requirements) && typeof value.pendingRequiredCount === "number" && typeof value.pendingRecommendedCount === "number" && typeof value.pendingOptionalCount === "number" && isRecord11(value.goLiveDecision) && (value.goLiveDecision.kind === "allowed" || value.goLiveDecision.kind === "blocked");
203928
+ return isRecord12(value) && Array.isArray(value.requirements) && typeof value.pendingRequiredCount === "number" && typeof value.pendingRecommendedCount === "number" && typeof value.pendingOptionalCount === "number" && isRecord12(value.goLiveDecision) && (value.goLiveDecision.kind === "allowed" || value.goLiveDecision.kind === "blocked");
203365
203929
  }
203366
203930
  function isOnboardingPreviewStatusResponse(value) {
203367
- return isRecord11(value) && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
203931
+ return isRecord12(value) && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
203368
203932
  }
203369
203933
  function isResendOnboardingPreviewConfirmationResponse(value) {
203370
- return isRecord11(value) && (value.result === "resent" || value.result === "already_confirmed") && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
203934
+ return isRecord12(value) && (value.result === "resent" || value.result === "already_confirmed") && typeof value.dashboardUnlocked === "boolean" && typeof value.requiresEmailConfirmation === "boolean" && isLaunchReadiness(value.launchReadiness);
203371
203935
  }
203372
203936
  function getSuccessData(payload, isData) {
203373
- if (!isRecord11(payload) || payload.success !== true || !isData(payload.data)) {
203937
+ if (!isRecord12(payload) || payload.success !== true || !isData(payload.data)) {
203374
203938
  return null;
203375
203939
  }
203376
203940
  return payload.data;
@@ -204461,11 +205025,11 @@ init_src3();
204461
205025
  // ../preview-next/src/client/utils/path.ts
204462
205026
  var PATH_SEPARATOR_REGEX3 = /\./g;
204463
205027
  var BRACKET_ACCESS_REGEX3 = /\[([^\]]+)\]/g;
204464
- function isRecord12(value) {
205028
+ function isRecord13(value) {
204465
205029
  return typeof value === "object" && value !== null && !Array.isArray(value);
204466
205030
  }
204467
205031
  function isPathContainer2(value) {
204468
- return Array.isArray(value) || isRecord12(value);
205032
+ return Array.isArray(value) || isRecord13(value);
204469
205033
  }
204470
205034
  function createPathContainer2(nextIsIndex) {
204471
205035
  return nextIsIndex ? [] : {};
@@ -204760,7 +205324,7 @@ init_src11();
204760
205324
  init_lucide_react();
204761
205325
 
204762
205326
  // ../preview-next/src/client/blocks/isRecord.ts
204763
- function isRecord13(value) {
205327
+ function isRecord14(value) {
204764
205328
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
204765
205329
  }
204766
205330
 
@@ -204972,7 +205536,7 @@ function BlockToolbar({
204972
205536
  return;
204973
205537
  }
204974
205538
  if (!outcome.response.content) return;
204975
- const savedContent = isRecord13(outcome.response.content.data) ? outcome.response.content.data : null;
205539
+ const savedContent = isRecord14(outcome.response.content.data) ? outcome.response.content.data : null;
204976
205540
  const editorBlockId = asEditorBlockId(input.action.blockId);
204977
205541
  const currentContent = uiStore.getState().drafts.getCurrentValues(editorBlockId);
204978
205542
  if (jsonValuesEqual(currentContent, savedContent)) {
@@ -205122,8 +205686,8 @@ function jsonValuesEqual(left, right) {
205122
205686
  if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) return false;
205123
205687
  return left.every((value, index2) => jsonValuesEqual(value, right[index2]));
205124
205688
  }
205125
- if (isRecord13(left) || isRecord13(right)) {
205126
- if (!isRecord13(left) || !isRecord13(right)) return false;
205689
+ if (isRecord14(left) || isRecord14(right)) {
205690
+ if (!isRecord14(left) || !isRecord14(right)) return false;
205127
205691
  const leftKeys = Object.keys(left);
205128
205692
  const rightKeys = Object.keys(right);
205129
205693
  if (leftKeys.length !== rightKeys.length) return false;
@@ -205155,13 +205719,13 @@ function findFirstFieldPath(fields3, data, prefix) {
205155
205719
  }
205156
205720
  const nextPrefix = [...prefix, field.id];
205157
205721
  if (field.type === "group") {
205158
- const groupValue = isRecord13(data) ? data[field.id] : void 0;
205722
+ const groupValue = isRecord14(data) ? data[field.id] : void 0;
205159
205723
  const nested = findFirstFieldPath(field.schema.fields, groupValue, nextPrefix);
205160
205724
  if (nested) return nested;
205161
205725
  continue;
205162
205726
  }
205163
205727
  if (field.type === "repeater" && field.schema) {
205164
- const collection = isRecord13(data) ? data[field.id] : void 0;
205728
+ const collection = isRecord14(data) ? data[field.id] : void 0;
205165
205729
  const items = Array.isArray(collection) ? collection : [];
205166
205730
  if (items.length > 0) {
205167
205731
  const firstItem = items[0];
@@ -205409,7 +205973,7 @@ function boundaryBreakDisplay(boundary) {
205409
205973
  resetLabel: "Use default break"
205410
205974
  };
205411
205975
  default:
205412
- return assertNever5(boundary.breakChoice, "Unhandled boundary break choice");
205976
+ return assertNever6(boundary.breakChoice, "Unhandled boundary break choice");
205413
205977
  }
205414
205978
  }
205415
205979
  function formatBlockKindLabel2(blockKind) {
@@ -205431,7 +205995,7 @@ function applyPageDesignRuntimeFieldsToBlockItems(blockItems, source) {
205431
205995
  const fields3 = blockId ? fieldsByBlockId.get(blockId) : void 0;
205432
205996
  return {
205433
205997
  ...block,
205434
- content: applyCompiledRuntimeFieldsToContent(isRecord14(block.content) ? block.content : {}, fields3)
205998
+ content: applyCompiledRuntimeFieldsToContent(isRecord15(block.content) ? block.content : {}, fields3)
205435
205999
  };
205436
206000
  });
205437
206001
  }
@@ -205450,7 +206014,7 @@ function resolveRuntimePreviewSource(pageDesignState) {
205450
206014
  function designBlockIdFromBlockItem(block) {
205451
206015
  return typeof block.id === "string" && block.id.length > 0 ? asDesignBlockId(block.id) : null;
205452
206016
  }
205453
- function isRecord14(value) {
206017
+ function isRecord15(value) {
205454
206018
  return typeof value === "object" && value !== null && !Array.isArray(value);
205455
206019
  }
205456
206020
  function EditablePageRenderer(props2) {