@riverbankcms/sdk 0.136.0 → 0.137.0

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 (160) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/dist/{PreviewEditorSidebar-BU5ZlhQR.mjs → PreviewEditorSidebar-Bn6cONPa.mjs} +8 -8
  3. package/dist/{PreviewEditorUI-9XkHL-bC.mjs → PreviewEditorUI-LAwXZPSx.mjs} +3 -3
  4. package/dist/{PreviewQueryProvider-wbEpXryy.mjs → PreviewQueryProvider-ztQUdsNo.mjs} +1 -1
  5. package/dist/{SdkPreviewModeRuntime-CnWmj-2B.mjs → SdkPreviewModeRuntime-BbbGsI_v.mjs} +596 -164
  6. package/dist/{SiteChromeCustomizeContext-B6d5zkog.mjs → SiteChromeCustomizeContext-BbkNSt5a.mjs} +2888 -1404
  7. package/dist/_dts/ai/src/contracts/proposals.d.ts +12 -298
  8. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +21 -14
  9. package/dist/_dts/ai/src/designer/themePatch.d.ts +5 -10
  10. package/dist/_dts/api/src/accessAdmin.d.ts +1 -9
  11. package/dist/_dts/api/src/accountApi.d.ts +49 -2
  12. package/dist/_dts/api/src/contentRuntime.d.ts +1 -4
  13. package/dist/_dts/api/src/domainConnection.d.ts +41 -0
  14. package/dist/_dts/api/src/endpoints.d.ts +194 -181
  15. package/dist/_dts/api/src/index.d.ts +4 -3
  16. package/dist/_dts/api/src/media.d.ts +19 -2
  17. package/dist/_dts/api/src/sdkContracts.d.ts +2 -15
  18. package/dist/_dts/api/src/sdkMediaContracts.d.ts +40 -0
  19. package/dist/_dts/api/src/sdkMediaEndpointDefinitions.d.ts +61 -0
  20. package/dist/_dts/api/src/sdkThemeWire.d.ts +15 -4
  21. package/dist/_dts/api/src/siteInfrastructure.d.ts +17 -23
  22. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +7 -21
  23. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +27 -3
  24. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +37 -17
  25. package/dist/_dts/api/src/types.d.ts +1 -1
  26. package/dist/_dts/blocks/src/PageRenderer.d.ts +2 -2
  27. package/dist/_dts/blocks/src/index.d.ts +1 -1
  28. package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +9 -0
  29. package/dist/_dts/blocks/src/pageRendererBlockSupport.d.ts +75 -0
  30. package/dist/_dts/blocks/src/pageRendererBoundaries.d.ts +2 -0
  31. package/dist/_dts/blocks/src/server.d.ts +1 -1
  32. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +1 -1
  33. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +2 -1
  34. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.d.ts +3 -3
  35. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +34 -22
  36. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/ErrorStep.d.ts +3 -5
  37. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +2 -0
  38. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.planning.d.ts +1 -1
  39. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.d.ts +2 -0
  40. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationErrorPresentation.d.ts +5 -0
  41. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.d.ts +25 -0
  42. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationWizardContext.d.ts +4 -0
  43. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationStripeReturn.d.ts +7 -3
  44. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +2 -0
  45. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +5 -2
  46. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useWaitlistClaimRestoration.d.ts +2 -0
  47. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/capacity.d.ts +164 -0
  48. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/cta.d.ts +29 -0
  49. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/dates.d.ts +47 -0
  50. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/index.d.ts +14 -0
  51. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/people.d.ts +6 -0
  52. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/pricing.d.ts +31 -0
  53. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/OfferingTitle.d.ts +11 -0
  54. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekAgendaView.d.ts +1 -1
  55. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekBoardView.d.ts +1 -1
  56. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/index.d.ts +3 -1
  57. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/listingLayout.d.ts +23 -0
  58. package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +57 -0
  59. package/dist/_dts/commerce/src/purchase/index.d.ts +1 -0
  60. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +8 -40
  61. package/dist/_dts/db/src/index.d.ts +1 -0
  62. package/dist/_dts/db/src/utils/postgrestFilter.d.ts +2 -0
  63. package/dist/_dts/media-core/src/bulkDeletePlanning.d.ts +4 -0
  64. package/dist/_dts/media-core/src/fileDomain.d.ts +3 -0
  65. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +1 -0
  66. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +1 -0
  67. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +3 -2
  68. package/dist/_dts/preview-next/src/client/preview/siteChromeBrandPreferences.d.ts +1 -1
  69. package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlHistoryState.d.ts +2 -0
  70. package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlSaveRequest.d.ts +51 -0
  71. package/dist/_dts/preview-next/src/client/preview/siteChromeSavePlan.d.ts +24 -2
  72. package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +23 -1
  73. package/dist/_dts/preview-next/src/client/preview/usePersistedHeaderPreferences.d.ts +8 -0
  74. package/dist/_dts/sdk/src/public-api/contracts.d.ts +2 -1
  75. package/dist/_dts/sdk/src/version.d.ts +1 -1
  76. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  77. package/dist/_dts/theme-core/src/gradients/types.d.ts +5 -0
  78. package/dist/_dts/theme-core/src/header/interactionPalette.d.ts +25 -2
  79. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +3 -3
  80. package/dist/_dts/theme-core/src/schema.d.ts +12 -11
  81. package/dist/_dts/theme-core/src/site-styles/compilationPlan.d.ts +43 -3
  82. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +10 -0
  83. package/dist/_dts/theme-core/src/site-styles/headerBrandPresentation.d.ts +63 -0
  84. package/dist/_dts/theme-core/src/site-styles/headerBytesComparison.d.ts +30 -0
  85. package/dist/_dts/theme-core/src/site-styles/headerInteractionPalette.d.ts +50 -1
  86. package/dist/_dts/theme-core/src/site-styles/headerLayoutCatalog.d.ts +48 -9
  87. package/dist/_dts/theme-core/src/site-styles/headerPreferences.d.ts +162 -0
  88. package/dist/_dts/theme-core/src/site-styles/headerPreferencesPersistence.d.ts +73 -0
  89. package/dist/_dts/theme-core/src/site-styles/headerRecompile.d.ts +118 -0
  90. package/dist/_dts/theme-core/src/site-styles/headerStyleCompiler.d.ts +10 -1
  91. package/dist/_dts/theme-core/src/site-styles/headerStyleDefaults.d.ts +1 -1
  92. package/dist/_dts/theme-core/src/site-styles/headerStyleRecipe.d.ts +7 -0
  93. package/dist/_dts/theme-core/src/site-styles/index.d.ts +5 -0
  94. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +1 -1
  95. package/dist/_dts/theme-core/src/site-styles/siteChromeBackgrounds.d.ts +20 -1
  96. package/dist/_dts/theme-core/src/site-styles/siteChromeNavPreferences.d.ts +43 -2
  97. package/dist/client/{BookingConsentAgreement-DCch21a6.mjs → BookingConsentAgreement--_fUCZe-.mjs} +2 -2
  98. package/dist/client/{DiscountCodeDisclosure-DIj1T59K.mjs → DiscountCodeDisclosure-BMipSoDJ.mjs} +1 -1
  99. package/dist/client/{EventCombined.client-BWVNlXTx.mjs → EventCombined.client-CwJOxn7A.mjs} +154 -178
  100. package/dist/client/{EventListing.client-DVFCDe3i.mjs → EventListing.client-eVwiylPW.mjs} +2 -2
  101. package/dist/client/{LeafletStaticMap-BY5mIHw9.mjs → LeafletStaticMap-IKenna5u.mjs} +1 -1
  102. package/dist/client/{accordion-CK29E8rG.mjs → accordion-MGAO3PuE.mjs} +1 -1
  103. package/dist/client/{bookingForm-DFvnet-N.mjs → bookingForm-CudlQPUu.mjs} +5 -5
  104. package/dist/client/bookings.mjs +418 -79
  105. package/dist/client/capacity-BW00PO7s.mjs +271 -0
  106. package/dist/client/{carousel-BVU5NQlb.mjs → carousel-BrbGJ2Jl.mjs} +1 -1
  107. package/dist/client/{cart-BNItcZVa.mjs → cart-Bq5eU0xZ.mjs} +3 -3
  108. package/dist/client/{checkout-Bu6iCdkP.mjs → checkout-BAFVRdrK.mjs} +3 -3
  109. package/dist/client/client.mjs +2919 -1918
  110. package/dist/client/{context-BImarOAq.mjs → context-DCkiHVdD.mjs} +8 -5
  111. package/dist/client/dates-2RPXHQy4.mjs +264 -0
  112. package/dist/client/{eventCalendar-DS2h-UXD.mjs → eventCalendar-B0O-hPF7.mjs} +10 -17
  113. package/dist/client/{eventCombined-Drt4Oq9p.mjs → eventCombined-DCkDaoDI.mjs} +3 -3
  114. package/dist/client/{eventDetails-Bl2vWgTX.mjs → eventDetails-D8GG2dnD.mjs} +5 -3
  115. package/dist/client/{eventListing-CS7PHY7v.mjs → eventListing-3ssV_bxz.mjs} +3 -3
  116. package/dist/client/{eventRegistration-D-j8eNy2.mjs → eventRegistration-bPQo3kVw.mjs} +562 -309
  117. package/dist/client/{form-RMpoLTyr.mjs → form-qMv8RDkk.mjs} +2 -2
  118. package/dist/client/{headerSection-BYE3Lb3k.mjs → headerSection-CH0Sc5hX.mjs} +2 -2
  119. package/dist/client/hooks.mjs +289 -32
  120. package/dist/client/{locationMap-BxSr7Kkh.mjs → locationMap-0_xlBnNI.mjs} +2 -2
  121. package/dist/client/{newsletterForm-DerbXwFC.mjs → newsletterForm-NUW7m9RI.mjs} +2 -2
  122. package/dist/client/{productDetail-4SZCLhAf.mjs → productDetail-FBEOM7jW.mjs} +3 -3
  123. package/dist/client/{productList-D7AP4GNq.mjs → productList-R0OSGhnn.mjs} +3 -3
  124. package/dist/client/{propsDecoder-pzBeCh14.mjs → propsDecoder-pYvx_Srl.mjs} +88 -380
  125. package/dist/client/rendering/client.mjs +2616 -1637
  126. package/dist/client/rendering/islands.mjs +17 -17
  127. package/dist/client/rendering.mjs +2710 -1702
  128. package/dist/client/{scrollToBlock-CduAKf8T.mjs → scrollToBlock-ByQv96M2.mjs} +1 -1
  129. package/dist/client/{shop-Cp5p_kGe.mjs → shop-RUG9DmRE.mjs} +6 -6
  130. package/dist/client/{shop-commerce-DicXYaYX.mjs → shop-commerce-B76Jz23B.mjs} +5 -5
  131. package/dist/client/{shop-commerce-store-CGWnpY4K.mjs → shop-commerce-store-QuQNdDsD.mjs} +1 -1
  132. package/dist/client/{shopShared-BDf9ljkm.mjs → shopShared-vXU1omwJ.mjs} +3 -3
  133. package/dist/client/{useEventFilters-DeeyGYuk.mjs → useEventFilters-ByuU6HLA.mjs} +33 -18
  134. package/dist/preview-next/before-render.mjs +79 -51
  135. package/dist/preview-next/client/runtime.mjs +4 -4
  136. package/dist/preview-next/keepAlive.mjs +79 -51
  137. package/dist/preview-next/middleware.mjs +79 -51
  138. package/dist/{previewAuthStore-DbqBol0V.mjs → previewAuthStore-L_cKW8Sb.mjs} +79 -51
  139. package/dist/{sdk-runtime-19MO27F0.mjs → sdk-runtime-sUMr5d70.mjs} +2 -2
  140. package/dist/{separator-DaPLtJ1f.mjs → separator-BIHkie5i.mjs} +1 -1
  141. package/dist/server/components.mjs +2077 -1274
  142. package/dist/server/config-validation.mjs +289 -32
  143. package/dist/server/config.mjs +289 -32
  144. package/dist/server/data.mjs +289 -32
  145. package/dist/server/index.mjs +80 -52
  146. package/dist/server/next.mjs +1822 -1111
  147. package/dist/server/page-converter.mjs +167 -31
  148. package/dist/server/prebuild.mjs +1 -1
  149. package/dist/server/rendering/server.mjs +1988 -1286
  150. package/dist/server/rendering.mjs +1943 -1182
  151. package/dist/server/routing.mjs +351 -86
  152. package/dist/server/server.mjs +293 -128
  153. package/dist/server/theme-bridge.mjs +52 -8
  154. package/dist/server/theme.mjs +27 -8
  155. package/dist/styles/index.css +15 -0
  156. package/package.json +1 -1
  157. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCapacity.d.ts +0 -48
  158. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/pricing.d.ts +0 -17
  159. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/utils.d.ts +0 -100
  160. /package/dist/_dts/blocks/src/system/runtime/nodes/events/{shared → domain}/destination.d.ts +0 -0
@@ -1,7 +1,7 @@
1
1
  "use client";
2
- import { $i as SelectItem, $n as ImageResolveContextProvider, $r as runTransforms, $t as createSnapshotFromPageRecord, Aa as Button, Ai as asDesignBlockId, An as getResponsiveScopeSpec, At as useEditor, Ba as X, Bi as SdkConfigProvider, Bn as resolveEntryRouteTarget, Br as sectionTransitionVariantForBoundaryOptionId, Bt as useEditorUiStoreInstance, Cn as useMediaEditorOptional, Cr as componentRuntimeRulesForTheme, Ct as MediaField, Di as parseThemeForPersistence, Dn as containerResponsiveThemeCss, Dr as surfaceResolutionContextFromTheme, Dt as RichTextField, En as ThemeScope, Et as useRichTextImagePicker, Fa as unsafeAsEditorBlockValues, Fn as getDefaultComponentRegistry, Fr as parseGradientPresetId, Ft as prepareBlockEditorManifest, G as beginAutosaveBatch, Gi as unmapValueFromSelect, Gn as SITE_CHROME_VISIBLE_HEADER_SELECTOR, Gr as ctaButton, Gt as pushHistoryEntry, Hi as hasEmptyOption, Hn as resolveRouteTarget, Hr as backgroundAppearanceQuickColorTokenNames, Ht as canRedoHistory, Ia as assertNever$2, Ii as ORDINARY_TEXT_MIN_CONTRAST_RATIO, In as LINKED_CONTENT_ENTRY_META_KEY, It as stripTopLevelRoutingUi, J as enqueueTransaction, Ja as RotateCcw, Jn as visibleHeaderClearancePx, Jr as eventCalendarListLayoutOptions, Jt as unsafeAsLinkedContentEntryId, K as confirmAutosaveBatch, Ki as FieldFrame, Kn as SITE_OVERLAY_HEADER_CLEARANCE_CSS_VAR, Kr as bindingSchema, Kt as redoHistory, La as expectParsedBrandedId, Li as BlockApiProvider, Ln as coerceLinkedContentEntriesPayload, Lr as defaultSectionTransitionVariantForFamily, Lt as getBlockManifestFromSdkConfig, Ma as cn, Mn as createCustomBlockRegistry, Mr as GRADIENT_PRESETS, Mt as LinkWidgetProvider, Na as parseFooterModuleId, Ni as textColorStyle, Nn as makeDefaultBlockComponent, Nr as GRADIENT_PRESET_IDS, Oi as isThemeV2NormalEditorRawStyleFieldName, On as buildThemeRuntime, Ot as RichTextWidgetProvider, Pa as unsafeAsEditorBlockId, Pn as readBlockComposition, Pr as getGradientPreset, Pt as hideThemeV2RawStyleFields, Q as resolvePreviewSidebarTab, Qi as SelectContent, Qn as clientComponentRegistry, Qr as parseBackgroundContent, Qt as createRoutingHelpers, Ra as parseMediaAssetId, Ri as getFieldIntent, Rn as getLinkedContentEntryMeta, Rr as sectionTransitionFamilies, Sn as MediaEditorContextProvider, Sr as planPageDesignLayoutLookCompatibility, St as FileField, Tn as isSupportedLoaderEndpoint, Tr as designRuntimeRulesForTheme, Tt as ReferenceWidgetProvider, Ui as mapCurrentValueForSelect, Un as getBlockDefinition, Ur as parseBackgroundAppearanceColorToken, Ut as canUndoHistory, Va as Upload, Vi as useSdkConfig, Vn as resolvePageRouteTarget, Vr as backgroundAppearanceColorTokenNames, Vt as useOptionalEditorUiStoreInstance, Wi as mapOptionValueForSelect, Wn as projectRecurringSchedule, Wr as defaultThemeTokens, Wt as createHistoryState, X as rejectAutosaveBatch, Xn as compileManifestContentContract, Y as idleEditorTransactionQueueState, Yn as resolveVariantKey, Yr as bookingConsentCarrierSchema, Yt as recordsEqual, Zi as Select, Zn as validateManifestDraft, Zr as planSiteChromePlacement, Zt as useDebouncedLatestSave, _ as PREVIEW_DESIGN_SAVE_ERROR_MESSAGE, _a as DialogHeader, _i as getAtPath, _r as formatSiteChromeBackgroundTokenLabel, _t as IconPickerField, ai as isRecord$13, ar as blogFeaturedPostFragment, at as useUISelector, bn as deriveLaunchReadiness, br as retargetCompiledBoundaryRuntimeForContentAdjacency, bt as ButtonVariantField, ci as isInlineTextEmpty, cr as formCopyFragment, da as TabsList, di as buildResolveImageUrlContext, dn as FormRenderer, dr as ctaCopyFragment, dt as createSiteOptionWidgetAdapters, ea as SelectTrigger, ei as parseBlockIconValue, en as BUILT_IN_REFERENCE_KINDS, er as richTextFragment, et as renderSiteChromeBlock, f as PreviewDesignCoordinatorProvider, fa as TabsTrigger, fi as getCurrentResolveImageUrlContext, fn as evaluateVisibility, fr as heroCtaRowFragment, ft as SiteOptionPickerField, g as PREVIEW_DESIGN_LOAD_ERROR_MESSAGE, ga as DialogFooter, gi as attachRenderableMediaAssetFields, gn as getPageDesignEditorState, gr as defineFragment, gt as InlineTextField, h as usePreviewThemeOverlay, ha as DialogDescription, hi as SECTION_BACKGROUND_MIN_SOURCE_WIDTH, hn as applyPageDesignEditorAction, hr as bodyCopyFragment, ht as OfferingsPreviewWidgetProvider, i as usePreviewDesignHistoryOrder, ii as isObjectRecord, ir as faqHeadingFragment, ji as assertNever$1, jn as escapeStyleContent, jr as gradientToCss, jt as LinkField, ki as pageDesignEditorBackgroundOverrideOwner, kn as DEFAULT_THEME_RESPONSIVE_MODE, kt as EditorProvider, la as Tabs, li as Text$1, ln as createManifestFormAdapter, lr as testimonialsCarouselFragment, lt as useEntryEditorController, m as PreviewThemeOverlayProvider, ma as DialogContent, mi as setContextResolveImageUrlContext, mn as MediaEditor, mr as heroCopyFragment, mt as OfferingsPreviewGroupOrderField, n as useSiteChromeCustomizeOptional, ni as parseGeneratedIconSetId, nn as parseReferenceKind, no as Image, nr as cardFragment, nt as PreviewInlineTextEditor, oi as coerceInlineTextWithFallback, on as PaletteProvider, oo as ChevronRight, or as singleButtonFragment, ot as EditableBlockProvider, pa as Dialog, pi as resolveImageUrlWithContext, pn as createStoreBackend, pr as ctaRowFragment, pt as SiteOptionWidgetProvider, q as deriveTransactionCapabilities, qi as useField, qn as planSiteOverlayHeaderClearance, qr as eventCalendarListLayoutCompatibleDisplayModeValues, qt as undoHistory, r as PreviewDesignHistoryOrderProvider, ri as renderInlineText, ro as GripVertical, rr as faqAccordionFragment, rt as PreviewTextEditor, si as inlineTextToPlainText, sn as usePalette, so as ChevronLeft, sr as formEmbedFragment, st as EntryControllerProvider, t as SiteChromeCustomizeProvider, ta as SelectValue, ti as parseGeneratedIconAssetId, tr as headingFragment, tt as PreviewRichTextEditor, ua as TabsContent, ui as RichText$1, uo as __exportAll, ur as testimonialsHeadingFragment, ut as createSiteOptionApiLoader, v as reportPreviewDesignError, va as DialogTitle, vi as siblingPath, vn as decodePublicProductCategorySelectorQuery, vr as applyCompiledRuntimeFieldsToContent, vt as EntryPickerField, wn as useApiMediaUploader, wt as ReferenceField, xn as AMBIENT_BACKGROUND_ROLES, xr as retargetCompiledRuntimeFieldsForContentAdjacency, xt as ButtonWidgetProvider, yn as DEFAULT_LAUNCH_READINESS_INPUT, yr as compileEditorModelRuntime, yt as EntryPickerWidgetProvider, za as parseSiteId, zi as isHeaderField, zn as defaultTransforms, zr as sectionTransitionFamilyForBoundaryOptionId, zt as useEditorUiStore } from "./SiteChromeCustomizeContext-B6d5zkog.mjs";
3
- import { i as useOptionalPreviewLayout, t as PreviewQueryProvider } from "./PreviewQueryProvider-wbEpXryy.mjs";
4
- import { _ as API_ENDPOINTS, a as usePreviewToken, c as createBearerAPIClient, d as unwrapResponse, g as resolveSurfaceDocumentAttributes, h as SURFACE_IDS, i as usePreviewAuthFetch, m as SURFACE_DOCUMENT_DATA_ATTRIBUTE, n as markPreviewAuthExpired, o as isPreviewRuntimeSessionEditable, r as usePreviewAuth, s as ApiRequestError, t as initPreviewAuth } from "./previewAuthStore-DbqBol0V.mjs";
2
+ import { $i as SelectItem, $n as ImageResolveContextProvider, $r as runTransforms, $t as createSnapshotFromPageRecord, Aa as Button, Ai as asDesignBlockId, An as getResponsiveScopeSpec, At as useEditor, Ba as X, Bi as SdkConfigProvider, Bn as resolveEntryRouteTarget, Br as sectionTransitionVariantForBoundaryOptionId, Bt as useEditorUiStoreInstance, Cn as useMediaEditorOptional, Cr as componentRuntimeRulesForTheme, Ct as MediaField, Di as parseThemeForPersistence, Dn as containerResponsiveThemeCss, Dr as surfaceResolutionContextFromTheme, Dt as RichTextField, En as ThemeScope, Et as useRichTextImagePicker, Fa as unsafeAsEditorBlockValues, Fn as getDefaultComponentRegistry, Fr as parseGradientPresetId, Ft as prepareBlockEditorManifest, G as confirmAutosaveBatch, Gi as unmapValueFromSelect, Gn as SITE_CHROME_VISIBLE_HEADER_SELECTOR, Gr as ctaButton, Gt as pushHistoryEntry, Hi as hasEmptyOption, Hn as resolveRouteTarget, Hr as backgroundAppearanceQuickColorTokenNames, Ht as canRedoHistory, Ia as assertNever$2, Ii as ORDINARY_TEXT_MIN_CONTRAST_RATIO, In as LINKED_CONTENT_ENTRY_META_KEY, It as stripTopLevelRoutingUi, J as idleEditorTransactionQueueState, Ja as RotateCcw, Jn as visibleHeaderClearancePx, Jr as eventCalendarListLayoutOptions, Jt as unsafeAsLinkedContentEntryId, K as deriveTransactionCapabilities, Ki as FieldFrame, Kn as SITE_OVERLAY_HEADER_CLEARANCE_CSS_VAR, Kr as bindingSchema, Kt as redoHistory, La as expectParsedBrandedId, Li as BlockApiProvider, Ln as coerceLinkedContentEntriesPayload, Lr as defaultSectionTransitionVariantForFamily, Lt as getBlockManifestFromSdkConfig, Ma as cn, Mn as createCustomBlockRegistry, Mr as GRADIENT_PRESETS, Mt as LinkWidgetProvider, Na as parseFooterModuleId, Ni as textColorStyle, Nn as makeDefaultBlockComponent, Nr as GRADIENT_PRESET_IDS, Oi as isThemeV2NormalEditorRawStyleFieldName, On as buildThemeRuntime, Ot as RichTextWidgetProvider, Pa as unsafeAsEditorBlockId, Pn as readBlockComposition, Pr as getGradientPreset, Pt as hideThemeV2RawStyleFields, Q as resolvePreviewSidebarTab, Qi as SelectContent, Qn as clientComponentRegistry, Qr as parseBackgroundContent, Qt as createRoutingHelpers, Ra as parseMediaAssetId, Ri as getFieldIntent, Rn as getLinkedContentEntryMeta, Rr as sectionTransitionFamilies, Sn as MediaEditorContextProvider, Sr as planPageDesignLayoutLookCompatibility, St as FileField, Tn as isSupportedLoaderEndpoint, Tr as designRuntimeRulesForTheme, Tt as ReferenceWidgetProvider, Ui as mapCurrentValueForSelect, Un as getBlockDefinition, Ur as parseBackgroundAppearanceColorToken, Ut as canUndoHistory, Va as Upload, Vi as useSdkConfig, Vn as resolvePageRouteTarget, Vr as backgroundAppearanceColorTokenNames, Vt as useOptionalEditorUiStoreInstance, W as beginAutosaveBatch, Wi as mapOptionValueForSelect, Wn as projectRecurringSchedule, Wr as defaultThemeTokens, Wt as createHistoryState, Xn as compileManifestContentContract, Y as rejectAutosaveBatch, Yn as resolveVariantKey, Yr as bookingConsentCarrierSchema, Yt as recordsEqual, Zi as Select, Zn as validateManifestDraft, Zr as planSiteChromePlacement, Zt as useDebouncedLatestSave, _ as reportPreviewDesignError, _a as DialogHeader, _i as getAtPath, _r as applyCompiledRuntimeFieldsToContent, _t as IconPickerField, ai as isRecord$13, ar as blogFeaturedPostFragment, at as useUISelector, bn as deriveLaunchReadiness, br as retargetCompiledRuntimeFieldsForContentAdjacency, bt as ButtonVariantField, ci as isInlineTextEmpty, cr as formCopyFragment, d as PreviewDesignCoordinatorProvider, da as TabsList, di as buildResolveImageUrlContext, dn as FormRenderer, dr as ctaCopyFragment, dt as createSiteOptionWidgetAdapters, ea as SelectTrigger, ei as parseBlockIconValue, en as BUILT_IN_REFERENCE_KINDS, er as richTextFragment, et as renderSiteChromeBlock, fa as TabsTrigger, fi as getCurrentResolveImageUrlContext, fn as evaluateVisibility, fr as heroCtaRowFragment, ft as SiteOptionPickerField, g as PREVIEW_DESIGN_SAVE_ERROR_MESSAGE, ga as DialogFooter, gi as attachRenderableMediaAssetFields, gn as getPageDesignEditorState, gr as defineFragment, gt as InlineTextField, h as PREVIEW_DESIGN_LOAD_ERROR_MESSAGE, ha as DialogDescription, hi as SECTION_BACKGROUND_MIN_SOURCE_WIDTH, hn as applyPageDesignEditorAction, hr as bodyCopyFragment, ht as OfferingsPreviewWidgetProvider, i as usePreviewDesignHistoryOrder, ii as isObjectRecord, ir as faqHeadingFragment, ji as assertNever$1, jn as escapeStyleContent, jr as gradientToCss, jt as LinkField, ki as pageDesignEditorBackgroundOverrideOwner, kn as DEFAULT_THEME_RESPONSIVE_MODE, kt as EditorProvider, la as Tabs, li as Text$1, ln as createManifestFormAdapter, lr as testimonialsCarouselFragment, lt as useEntryEditorController, m as usePreviewThemeOverlay, ma as DialogContent, mi as setContextResolveImageUrlContext, mn as MediaEditor, mr as heroCopyFragment, mt as OfferingsPreviewGroupOrderField, n as useSiteChromeCustomizeOptional, ni as parseGeneratedIconSetId, nn as parseReferenceKind, no as Image, nr as cardFragment, nt as PreviewInlineTextEditor, oi as coerceInlineTextWithFallback, on as PaletteProvider, oo as ChevronRight, or as singleButtonFragment, ot as EditableBlockProvider, p as PreviewThemeOverlayProvider, pa as Dialog, pi as resolveImageUrlWithContext, pn as createStoreBackend, pr as ctaRowFragment, pt as SiteOptionWidgetProvider, q as enqueueTransaction, qi as useField, qn as planSiteOverlayHeaderClearance, qr as eventCalendarListLayoutCompatibleDisplayModeValues, qt as undoHistory, r as PreviewDesignHistoryOrderProvider, ri as renderInlineText, ro as GripVertical, rr as faqAccordionFragment, rt as PreviewTextEditor, si as inlineTextToPlainText, sn as usePalette, so as ChevronLeft, sr as formEmbedFragment, st as EntryControllerProvider, t as SiteChromeCustomizeProvider, ta as SelectValue, ti as parseGeneratedIconAssetId, tr as headingFragment, tt as PreviewRichTextEditor, ua as TabsContent, ui as RichText$1, uo as __exportAll, ur as testimonialsHeadingFragment, ut as createSiteOptionApiLoader, va as DialogTitle, vi as siblingPath, vn as decodePublicProductCategorySelectorQuery, vr as compileEditorModelRuntime, vt as EntryPickerField, wn as useApiMediaUploader, wt as ReferenceField, xn as AMBIENT_BACKGROUND_ROLES, xr as formatSiteChromeBackgroundTokenLabel, xt as ButtonWidgetProvider, yn as DEFAULT_LAUNCH_READINESS_INPUT, yr as retargetCompiledBoundaryRuntimeForContentAdjacency, yt as EntryPickerWidgetProvider, za as parseSiteId, zi as isHeaderField, zn as defaultTransforms, zr as sectionTransitionFamilyForBoundaryOptionId, zt as useEditorUiStore } from "./SiteChromeCustomizeContext-BbkNSt5a.mjs";
3
+ import { i as useOptionalPreviewLayout, t as PreviewQueryProvider } from "./PreviewQueryProvider-ztQUdsNo.mjs";
4
+ import { _ as API_ENDPOINTS, a as usePreviewToken, c as createBearerAPIClient, d as unwrapResponse, g as resolveSurfaceDocumentAttributes, h as SURFACE_IDS, i as usePreviewAuthFetch, m as SURFACE_DOCUMENT_DATA_ATTRIBUTE, n as markPreviewAuthExpired, o as isPreviewRuntimeSessionEditable, r as usePreviewAuth, s as ApiRequestError, t as initPreviewAuth } from "./previewAuthStore-L_cKW8Sb.mjs";
5
5
  import * as React$1 from "react";
6
6
  import React, { Children, Fragment, cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useReducer, useRef, useState } from "react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -509,6 +509,32 @@ function isSiteStyleTransitionStyleGroup(value) {
509
509
  function boundaryMapForAdjacentBlockIds(boundaries) {
510
510
  return new Map(boundaries.map((boundary) => [boundaryKey(boundary.previousBlockId, boundary.nextBlockId), boundary]));
511
511
  }
512
+ /** Keep a surviving block's outgoing treatment when omitted blocks change its neighbor. */
513
+ function boundariesForSurvivingBlocks(boundaries, blocks) {
514
+ const outgoing = new Map(boundaries.map((boundary) => [boundary.previousBlockId, boundary]));
515
+ const incoming = new Map(boundaries.map((boundary) => [boundary.nextBlockId, boundary]));
516
+ return blocks.flatMap((block, index) => {
517
+ const next = blocks[index + 1];
518
+ if (!block.id || !next?.id) return [];
519
+ const boundary = outgoing.get(block.id);
520
+ if (!boundary) return [];
521
+ if (boundary.nextBlockId === next.id) return [boundary];
522
+ const destination = incoming.get(next.id);
523
+ return [retargetCompiledBoundaryRuntimeForContentAdjacency({
524
+ ...boundary,
525
+ boundaryId: `boundary:${block.id}:${next.id}`,
526
+ nextBlockId: next.id,
527
+ to: destination?.to ?? boundary.to,
528
+ cssVars: {
529
+ ...boundary.cssVars,
530
+ to: destination?.cssVars.to ?? boundary.cssVars.to
531
+ }
532
+ }, {
533
+ currentContent: block.content,
534
+ nextContent: next.content
535
+ })];
536
+ });
537
+ }
512
538
  function boundaryBetweenBlocks(previousBlock, nextBlock, boundaries) {
513
539
  const previousBlockId = previousBlock?.id ?? null;
514
540
  const nextBlockId = nextBlock?.id ?? null;
@@ -585,41 +611,173 @@ function toEditorPresentationPage(page) {
585
611
  };
586
612
  }
587
613
  //#endregion
614
+ //#region ../blocks/src/pageRendererBlockSupport.tsx
615
+ function fallback(message) {
616
+ return /* @__PURE__ */ jsx("div", {
617
+ className: "rb-p-6 rb-caption",
618
+ style: textColorStyle("mutedText"),
619
+ children: message
620
+ });
621
+ }
622
+ /**
623
+ * A page with nothing to show. Authoring surfaces get the diagnostic; a public
624
+ * page renders nothing at all rather than telling a visitor about the outline.
625
+ */
626
+ function emptyPageNotice(audience) {
627
+ if (audience === "public") return null;
628
+ return /* @__PURE__ */ jsx("div", {
629
+ className: "rb-p-6 rb-caption",
630
+ style: textColorStyle("mutedText"),
631
+ children: "No blocks found."
632
+ });
633
+ }
634
+ /**
635
+ * A public page dropped a block, so nothing in the rendered HTML says the
636
+ * content is missing. Say it in the logs instead.
637
+ */
638
+ function warnOmittedFromPublicPage(input) {
639
+ try {
640
+ console.warn("[blocks:PageRenderer] omitted a non-renderable block from a public page", {
641
+ blockId: input.block.id ?? null,
642
+ blockKind: input.block.kind,
643
+ outcome: input.outcome,
644
+ ...input.admissionError ? { error: input.admissionError } : {}
645
+ });
646
+ } catch {}
647
+ }
648
+ function shouldDebugCustomBlocks() {
649
+ try {
650
+ return globalThis.process?.env?.DEBUG_CUSTOM_BLOCKS === "1";
651
+ } catch {
652
+ return false;
653
+ }
654
+ }
655
+ /**
656
+ * Look up a block override component by block kind.
657
+ * Supports both full ("block.hero") and short ("hero") keys.
658
+ */
659
+ function getBlockOverride(blockKind, overrides) {
660
+ if (!overrides) return void 0;
661
+ if (overrides[blockKind]) return overrides[blockKind];
662
+ const shortKind = blockKind.replace(/^block\./, "");
663
+ if (overrides[shortKind]) return overrides[shortKind];
664
+ }
665
+ /**
666
+ * Resolves block content based on stage priority.
667
+ * For draft/preview: draftContent takes priority over content.
668
+ * For published: content is the source of truth.
669
+ * Returns empty object if no content exists (validator will handle placeholders if needed).
670
+ */
671
+ function getRenderableContent(block, previewStage = "published") {
672
+ const source = previewStage === "preview" && block.draftContent ? block.draftContent : block.content ?? {};
673
+ if (!isObjectRecord(source)) return {};
674
+ return source;
675
+ }
676
+ function resolvePageRendererImageResolveContext(dataContext) {
677
+ const input = dataContext?.imageResolveContext;
678
+ return buildResolveImageUrlContext({
679
+ siteId: input?.siteId ?? dataContext?.siteId,
680
+ supabaseUrl: input?.supabaseUrl ?? dataContext?.supabaseUrl,
681
+ mediaAssetIndex: input?.mediaAssetIndex,
682
+ mediaAssets: input?.mediaAssets ?? dataContext?.mediaAssets
683
+ });
684
+ }
685
+ /**
686
+ * The RSC-safe props every override component receives, whether the block
687
+ * resolved a manifest or is being rendered from an override alone.
688
+ */
689
+ function buildBlockOverrideProps(input) {
690
+ return {
691
+ content: input.content,
692
+ ...overrideThemeProps(input.themeResources),
693
+ ...blockOverrideContextProps(input.dataContext),
694
+ data: input.data,
695
+ imageResolveContext: input.imageResolveContext,
696
+ blockId: input.block.id ?? null,
697
+ blockKind: input.block.kind
698
+ };
699
+ }
700
+ /** The render-context half of the override props, absent context included. */
701
+ function blockOverrideContextProps(dataContext) {
702
+ const context = dataContext ?? {};
703
+ return {
704
+ siteId: context.siteId,
705
+ apiBaseUrl: context.apiBaseUrl,
706
+ bookingTimeZone: context.bookingTimeZone,
707
+ portalToken: context.portalToken ?? null,
708
+ previewToken: context.previewToken ?? null,
709
+ stage: context.previewStage,
710
+ occurrenceContext: context.occurrenceContext ?? null,
711
+ entrySubrouteContext: context.entrySubrouteContext ?? null,
712
+ contentEntry: context.contentEntry ?? null,
713
+ pageSurface: context.pageSurface ?? null,
714
+ subject: context.subject ?? null,
715
+ supabaseUrl: context.supabaseUrl
716
+ };
717
+ }
718
+ const blockComponentCache = /* @__PURE__ */ new WeakMap();
719
+ const DEFAULT_PERF_SLOW_BLOCK_RENDER_THRESHOLD_MS = 25;
720
+ let cachedPerfSlowBlockRenderThresholdMs = null;
721
+ function getPerfSlowBlockRenderThresholdMs() {
722
+ if (cachedPerfSlowBlockRenderThresholdMs !== null) return cachedPerfSlowBlockRenderThresholdMs;
723
+ const raw = globalThis.process?.env?.DEBUG_PERF_BLOCK_MS;
724
+ const parsed = raw ? Number.parseInt(raw, 10) : NaN;
725
+ cachedPerfSlowBlockRenderThresholdMs = Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_PERF_SLOW_BLOCK_RENDER_THRESHOLD_MS;
726
+ return cachedPerfSlowBlockRenderThresholdMs;
727
+ }
728
+ function getCachedBlockComponent(manifest) {
729
+ const cached = blockComponentCache.get(manifest);
730
+ if (cached) return cached;
731
+ const created = makeDefaultBlockComponent({ manifest });
732
+ blockComponentCache.set(manifest, created);
733
+ return created;
734
+ }
735
+ //#endregion
588
736
  //#region ../blocks/src/PageRenderer.tsx
589
737
  function EditorPageRenderer(props) {
590
738
  const page = React$1.useMemo(() => toEditorPresentationPage(props.page), [props.page]);
591
739
  return /* @__PURE__ */ jsx(PageRendererCore, {
592
740
  ...props,
593
- page
741
+ page,
742
+ audience: "authoring"
594
743
  });
595
744
  }
596
745
  function PageRendererCore(props) {
597
- const { page, runtimeBoundaries, dataContext, wrapBlock, wrapBoundary, registry } = props;
746
+ const { page, audience, runtimeBoundaries, dataContext, wrapBlock, wrapBoundary, registry } = props;
598
747
  const imageResolveContext = React$1.useMemo(() => resolvePageRendererImageResolveContext(dataContext), [
599
748
  dataContext?.imageResolveContext,
600
749
  dataContext?.mediaAssets,
601
750
  dataContext?.siteId,
602
751
  dataContext?.supabaseUrl
603
752
  ]);
604
- const boundaryByAdjacentBlockIds = React$1.useMemo(() => boundaryMapForAdjacentBlockIds(runtimeBoundaries ?? []), [runtimeBoundaries]);
605
753
  const usesRuntimeBoundaries = runtimeBoundaries !== void 0;
606
754
  const themeResources = React$1.useMemo(() => resolvePageThemeResources(props), [
607
755
  props.rendering,
608
756
  props.theme,
609
757
  props.themeTokens
610
758
  ]);
611
- if (!page || page.blocks.length === 0) return /* @__PURE__ */ jsx("div", {
612
- className: "rb-p-6 rb-caption",
613
- style: textColorStyle("mutedText"),
614
- children: "No blocks found."
615
- });
616
759
  const resolvedRegistry = registry ?? getDefaultComponentRegistry();
617
760
  setContextResolveImageUrlContext(imageResolveContext);
618
- return /* @__PURE__ */ jsx("div", { children: page.blocks.map((block, index) => {
619
- const blockPosition = pageBlockPosition(index, page.blocks.length);
620
- const blockKey = block.id ?? `${block.kind}-${index}`;
621
- const previousBlock = page.blocks[index - 1] ?? null;
622
- const nextBlock = page.blocks[index + 1] ?? null;
761
+ const sections = usePageSections(props, {
762
+ page,
763
+ themeResources,
764
+ imageResolveContext,
765
+ registry: resolvedRegistry
766
+ });
767
+ const boundaryByAdjacentBlockIds = React$1.useMemo(() => boundaryMapForAdjacentBlockIds(boundariesForSurvivingBlocks(runtimeBoundaries ?? [], sections.map(({ block }) => ({
768
+ ...block,
769
+ content: getRenderableContent(block, dataContext?.previewStage)
770
+ })))), [
771
+ runtimeBoundaries,
772
+ sections,
773
+ dataContext?.previewStage
774
+ ]);
775
+ if (sections.length === 0) return emptyPageNotice(audience);
776
+ return /* @__PURE__ */ jsx("div", { children: sections.map((section, index) => {
777
+ const { block, blockKey, node } = section;
778
+ const blockPosition = pageBlockPosition(index, sections.length);
779
+ const previousBlock = sections[index - 1]?.block ?? null;
780
+ const nextBlock = sections[index + 1]?.block ?? null;
623
781
  const boundaryBefore = boundaryBetweenBlocks(previousBlock, block, boundaryByAdjacentBlockIds);
624
782
  const boundaryAfter = boundaryBetweenBlocks(block, nextBlock, boundaryByAdjacentBlockIds);
625
783
  const boundaryElement = renderBoundaryAfterBlock({
@@ -634,19 +792,7 @@ function PageRendererCore(props) {
634
792
  const managesOwnWrapper = definition?.manifest.behaviours?.managesOwnWrapper;
635
793
  const renderableContent = getRenderableContent(block, dataContext?.previewStage);
636
794
  const variantKey = definition?.manifest ? resolveVariantKey(definition.manifest, renderableContent) : null;
637
- const shouldUseWrapper = !managesOwnWrapper || Boolean(wrapBlock);
638
- const blockSectionProps = buildBlockSectionProps({
639
- props,
640
- themeResources,
641
- block,
642
- blockKey,
643
- imageResolveContext,
644
- registry: resolvedRegistry
645
- });
646
- if (!shouldUseWrapper) {
647
- const rendered = /* @__PURE__ */ jsx(MemoBlockSection, { ...blockSectionProps }, `${blockKey}:block`);
648
- return boundaryElement ? /* @__PURE__ */ jsxs(React$1.Fragment, { children: [rendered, boundaryElement] }, blockKey) : rendered;
649
- }
795
+ if (!(!managesOwnWrapper || Boolean(wrapBlock))) return /* @__PURE__ */ jsxs(React$1.Fragment, { children: [node, boundaryElement] }, blockKey);
650
796
  const wrapperClassName = [`block-${cleanKind}`, wrapBlock ? "group relative" : null].filter(Boolean).join(" ");
651
797
  const styleGroup = typeof renderableContent.styleGroup === "string" ? renderableContent.styleGroup : void 0;
652
798
  const blockLook = typeof renderableContent.blockLook === "string" ? renderableContent.blockLook : void 0;
@@ -671,7 +817,7 @@ function PageRendererCore(props) {
671
817
  "data-site-style-boundary-after": boundaryAfter?.metrics.size,
672
818
  "data-style-group": styleGroup,
673
819
  style: blockStyle,
674
- children: /* @__PURE__ */ jsx(MemoBlockSection, { ...blockSectionProps })
820
+ children: node
675
821
  }, blockKey);
676
822
  if (boundaryElement) return /* @__PURE__ */ jsxs(React$1.Fragment, { children: [blockElement, boundaryElement] }, blockKey);
677
823
  if (usesRuntimeBoundaries || !isSiteStyleTransitionStyleGroup(styleGroup)) return blockElement;
@@ -684,18 +830,69 @@ function PageRendererCore(props) {
684
830
  })] }, blockKey);
685
831
  }) });
686
832
  }
687
- function resolvePageRendererImageResolveContext(dataContext) {
688
- const input = dataContext?.imageResolveContext;
689
- return buildResolveImageUrlContext({
690
- siteId: input?.siteId ?? dataContext?.siteId,
691
- supabaseUrl: input?.supabaseUrl ?? dataContext?.supabaseUrl,
692
- mediaAssetIndex: input?.mediaAssetIndex,
693
- mediaAssets: input?.mediaAssets ?? dataContext?.mediaAssets
833
+ /**
834
+ * Memoised so that a re-render with unchanged inputs reuses the same section
835
+ * elements and React can skip the block subtrees, exactly as the per-block memo
836
+ * did before public pages started resolving their bodies up front.
837
+ */
838
+ function usePageSections(props, input) {
839
+ const { page, themeResources, imageResolveContext, registry } = input;
840
+ return React$1.useMemo(() => admitPageSections({
841
+ props,
842
+ blocks: page?.blocks ?? [],
843
+ audience: props.audience,
844
+ themeResources,
845
+ imageResolveContext,
846
+ registry
847
+ }), [
848
+ page,
849
+ props.audience,
850
+ themeResources,
851
+ imageResolveContext,
852
+ registry,
853
+ props.dataContext,
854
+ props.routeMap,
855
+ props.wrapBlock,
856
+ props.blockOverrides,
857
+ props.sdkConfig,
858
+ props.customBlocks,
859
+ props.previewAuthoring
860
+ ]);
861
+ }
862
+ /**
863
+ * Resolves each block's rendered body before the page decides what to wrap.
864
+ *
865
+ * On a public page the body is resolved eagerly so a block that cannot render
866
+ * is dropped along with its wrapper, its data attributes, its boundary reserve
867
+ * space and its style-group sibling — the section body is the single source of
868
+ * truth for whether the block is on the page (issue 1378). Authoring surfaces
869
+ * keep the memoised component so the editor's render-loop guards still hold.
870
+ */
871
+ function admitPageSections(input) {
872
+ const sections = [];
873
+ input.blocks.forEach((block, index) => {
874
+ const blockKey = block.id ?? `${block.kind}-${index}`;
875
+ const blockSectionProps = buildBlockSectionProps({
876
+ props: input.props,
877
+ themeResources: input.themeResources,
878
+ block,
879
+ blockKey,
880
+ imageResolveContext: input.imageResolveContext,
881
+ registry: input.registry
882
+ });
883
+ const node = input.audience === "public" ? renderBlockSection(blockSectionProps) : /* @__PURE__ */ jsx(MemoBlockSection, { ...blockSectionProps }, `${blockKey}:block`);
884
+ if (node === null || node === void 0) return;
885
+ sections.push({
886
+ block,
887
+ blockKey,
888
+ node
889
+ });
694
890
  });
891
+ return sections;
695
892
  }
696
- const resolveBookingTimeZone = (dataContext) => dataContext?.bookingTimeZone;
697
893
  function buildBlockSectionProps(input) {
698
894
  return {
895
+ audience: input.props.audience,
699
896
  themeResources: input.themeResources,
700
897
  block: input.block,
701
898
  dataContext: input.props.dataContext,
@@ -711,40 +908,24 @@ function buildBlockSectionProps(input) {
711
908
  };
712
909
  }
713
910
  /**
714
- * Look up a block override component by block kind.
715
- * Supports both full ("block.hero") and short ("hero") keys.
716
- */
717
- function getBlockOverride(blockKind, overrides) {
718
- if (!overrides) return void 0;
719
- if (overrides[blockKind]) return overrides[blockKind];
720
- const shortKind = blockKind.replace(/^block\./, "");
721
- if (overrides[shortKind]) return overrides[shortKind];
722
- }
723
- const blockComponentCache = /* @__PURE__ */ new WeakMap();
724
- const DEFAULT_PERF_SLOW_BLOCK_RENDER_THRESHOLD_MS = 25;
725
- let cachedPerfSlowBlockRenderThresholdMs = null;
726
- function getPerfSlowBlockRenderThresholdMs() {
727
- if (cachedPerfSlowBlockRenderThresholdMs !== null) return cachedPerfSlowBlockRenderThresholdMs;
728
- const raw = globalThis.process?.env?.DEBUG_PERF_BLOCK_MS;
729
- const parsed = raw ? Number.parseInt(raw, 10) : NaN;
730
- cachedPerfSlowBlockRenderThresholdMs = Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_PERF_SLOW_BLOCK_RENDER_THRESHOLD_MS;
731
- return cachedPerfSlowBlockRenderThresholdMs;
732
- }
733
- function getCachedBlockComponent(manifest) {
734
- const cached = blockComponentCache.get(manifest);
735
- if (cached) return cached;
736
- const created = makeDefaultBlockComponent({ manifest });
737
- blockComponentCache.set(manifest, created);
738
- return created;
739
- }
740
- /**
741
911
  * Memoized block section component.
742
912
  *
743
913
  * Custom memoization prevents render loops during editing by explicitly checking
744
914
  * referential equality of all props that affect rendering. Standard React.memo
745
915
  * wouldn't catch all the render triggers from the editor store.
746
916
  */
747
- const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeResources, block, dataContext, registry, routeMap, wrapBlock, blockOverrides, sdkConfig, customBlocks, imageResolveContext, previewAuthoring }) {
917
+ const MemoBlockSection = React$1.memo(function MemoBlockSection(props) {
918
+ return renderBlockSection(props);
919
+ }, (prev, next) => {
920
+ return prev.audience === next.audience && prev.block === next.block && prev.registry === next.registry && prev.dataContext === next.dataContext && prev.themeResources === next.themeResources && prev.routeMap === next.routeMap && prev.block.presentationAdmission === next.block.presentationAdmission && prev.wrapBlock === next.wrapBlock && prev.blockOverrides === next.blockOverrides && prev.sdkConfig === next.sdkConfig && prev.customBlocks === next.customBlocks && prev.imageResolveContext === next.imageResolveContext && prev.previewAuthoring === next.previewAuthoring;
921
+ });
922
+ /**
923
+ * Renders a single block body.
924
+ *
925
+ * Returns `null` when the block cannot render and the audience is `public`;
926
+ * the caller treats that as "this block is not on the page".
927
+ */
928
+ function renderBlockSection({ audience, themeResources, block, dataContext, registry, routeMap, wrapBlock, blockOverrides, sdkConfig, customBlocks, imageResolveContext, previewAuthoring }) {
748
929
  const perfStart = globalThis.process?.env?.DEBUG_PERF === "1" && typeof window === "undefined" ? Date.now() : 0;
749
930
  const fallbackImageResolveContext = getCurrentResolveImageUrlContext();
750
931
  const resolvedImageResolveContext = imageResolveContext ?? fallbackImageResolveContext;
@@ -764,19 +945,30 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeResources
764
945
  } catch {}
765
946
  return node;
766
947
  }
767
- if (block.presentationAdmission.kind === "invalid") {
768
- try {
769
- if (globalThis.process?.env?.NODE_ENV !== "production") console.warn("[blocks:PageRenderer] block admission failed", {
770
- blockId: block.id ?? null,
771
- blockKind: block.kind,
772
- error: block.presentationAdmission.error
773
- });
774
- } catch {}
775
- return finish(fallback(`Invalid content for block kind "${block.kind}".`), {
776
- outcome: "invalidContent",
777
- override: false
948
+ /**
949
+ * The one place that decides what a block that cannot render leaves behind.
950
+ * A public page gets nothing (and a log line, since dropping content on a
951
+ * 200 is otherwise invisible); authoring surfaces get the diagnostic.
952
+ */
953
+ function diagnostic(message, detail) {
954
+ if (audience !== "public") return fallback(message);
955
+ warnOmittedFromPublicPage({
956
+ block,
957
+ ...detail
778
958
  });
959
+ return null;
779
960
  }
961
+ function withBlockWrapper(node) {
962
+ if (node === null) return null;
963
+ return wrapBlock && block.id ? /* @__PURE__ */ jsx(Fragment$1, { children: wrapBlock(block.id, node) }) : /* @__PURE__ */ jsx(Fragment$1, { children: node });
964
+ }
965
+ if (block.presentationAdmission.kind === "invalid") return finish(diagnostic(`Invalid content for block kind "${block.kind}".`, {
966
+ outcome: "invalidContent",
967
+ admissionError: block.presentationAdmission.error
968
+ }), {
969
+ outcome: "invalidContent",
970
+ override: false
971
+ });
780
972
  const OverrideComponent = getBlockOverride(block.kind, blockOverrides);
781
973
  requireBlockOverride(themeResources, OverrideComponent, block.kind);
782
974
  let definition = getBlockDefinition(block.kind);
@@ -789,25 +981,14 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeResources
789
981
  }).findManifest(block.kind)?.descriptor.definition;
790
982
  if (!definition) {
791
983
  if (OverrideComponent) {
792
- const rendered = /* @__PURE__ */ jsx(OverrideComponent, {
984
+ const rendered = /* @__PURE__ */ jsx(OverrideComponent, { ...buildBlockOverrideProps({
985
+ block,
793
986
  content: getRenderableContent(block, dataContext?.previewStage),
794
- ...overrideThemeProps(themeResources),
795
987
  data: void 0,
796
- siteId: dataContext?.siteId,
797
- apiBaseUrl: dataContext?.apiBaseUrl,
798
- portalToken: dataContext?.portalToken ?? null,
799
- previewToken: dataContext?.previewToken ?? null,
800
- stage: dataContext?.previewStage,
801
- occurrenceContext: dataContext?.occurrenceContext ?? null,
802
- entrySubrouteContext: dataContext?.entrySubrouteContext ?? null,
803
- contentEntry: dataContext?.contentEntry ?? null,
804
- pageSurface: dataContext?.pageSurface ?? null,
805
- subject: dataContext?.subject ?? null,
806
- supabaseUrl: dataContext?.supabaseUrl,
807
- imageResolveContext: resolvedImageResolveContext,
808
- blockId: block.id ?? null,
809
- blockKind: block.kind
810
- });
988
+ themeResources,
989
+ dataContext,
990
+ imageResolveContext: resolvedImageResolveContext
991
+ }) });
811
992
  return finish(wrapBlock && block.id ? /* @__PURE__ */ jsx(Fragment$1, { children: wrapBlock(block.id, rendered) }) : /* @__PURE__ */ jsx(Fragment$1, { children: rendered }), {
812
993
  outcome: "overrideWithoutDefinition",
813
994
  override: true,
@@ -823,8 +1004,7 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeResources
823
1004
  dbCustomBlocksCount: customBlocks?.length ?? 0
824
1005
  });
825
1006
  } catch {}
826
- const rendered = fallback(block.kind.startsWith("custom.") ? `No renderer available for block kind "${block.kind}". The custom block definition was not found (missing manifest).` : `No renderer available for block kind "${block.kind}".`);
827
- return finish(wrapBlock && block.id ? /* @__PURE__ */ jsx(Fragment$1, { children: wrapBlock(block.id, rendered) }) : /* @__PURE__ */ jsx(Fragment$1, { children: rendered }), {
1007
+ return finish(withBlockWrapper(diagnostic(block.kind.startsWith("custom.") ? `No renderer available for block kind "${block.kind}". The custom block definition was not found (missing manifest).` : `No renderer available for block kind "${block.kind}".`, { outcome: "missingDefinition" })), {
828
1008
  outcome: "missingDefinition",
829
1009
  override: false
830
1010
  });
@@ -839,8 +1019,7 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeResources
839
1019
  manifestKeys: Object.keys(definition.manifest ?? {}).sort()
840
1020
  });
841
1021
  } catch {}
842
- const rendered = fallback(block.kind.startsWith("custom.") ? `No renderer available for block kind "${block.kind}". This custom block has no layout/variants, so it must be rendered via blockOverrides["${block.kind}"].` : `No renderer available for block kind "${block.kind}".`);
843
- return finish(wrapBlock && block.id ? /* @__PURE__ */ jsx(Fragment$1, { children: wrapBlock(block.id, rendered) }) : /* @__PURE__ */ jsx(Fragment$1, { children: rendered }), {
1022
+ return finish(withBlockWrapper(diagnostic(block.kind.startsWith("custom.") ? `No renderer available for block kind "${block.kind}". This custom block has no layout/variants, so it must be rendered via blockOverrides["${block.kind}"].` : `No renderer available for block kind "${block.kind}".`, { outcome: "missingLayout" })), {
844
1023
  outcome: "missingLayout",
845
1024
  override: false
846
1025
  });
@@ -850,39 +1029,24 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeResources
850
1029
  if (block.presentationAdmission.kind === "editor") {
851
1030
  const draft = validateManifestDraft(compileManifestContentContract(definition.manifest), content);
852
1031
  if (draft.kind === "previewable") data = draft.data;
853
- else {
854
- const rendered = fallback(`Unable to render block kind "${block.kind}".`);
855
- return finish(wrapBlock && block.id ? /* @__PURE__ */ jsx(Fragment$1, { children: wrapBlock(block.id, rendered) }) : /* @__PURE__ */ jsx(Fragment$1, { children: rendered }), {
856
- outcome: "invalidPlaceholder",
857
- override: false
858
- });
859
- }
1032
+ else return finish(withBlockWrapper(diagnostic(`Unable to render block kind "${block.kind}".`, { outcome: "invalidPlaceholder" })), {
1033
+ outcome: "invalidPlaceholder",
1034
+ override: false
1035
+ });
860
1036
  }
861
1037
  try {
862
1038
  const routes = routeMap ?? dataContext?.routes;
863
1039
  const hydratedContent = routes ? hydrateManifestLinks(definition.manifest, data, routes, dataContext?.pagesByIdentifier, dataContext?.entriesByIdentifier) : data;
864
1040
  const resolved = resolveBlockData(block.id, definition.dataLoaders, dataContext, routes);
865
1041
  const hasResolvedData = !!resolved && typeof resolved === "object" && Object.keys(resolved).length > 0;
866
- const baseProps = {
1042
+ const baseProps = buildBlockOverrideProps({
1043
+ block,
867
1044
  content: hydratedContent,
868
- ...overrideThemeProps(themeResources),
869
1045
  data: resolved,
870
- siteId: dataContext?.siteId,
871
- apiBaseUrl: dataContext?.apiBaseUrl,
872
- portalToken: dataContext?.portalToken ?? null,
873
- previewToken: dataContext?.previewToken ?? null,
874
- stage: dataContext?.previewStage,
875
- occurrenceContext: dataContext?.occurrenceContext ?? null,
876
- entrySubrouteContext: dataContext?.entrySubrouteContext ?? null,
877
- contentEntry: dataContext?.contentEntry ?? null,
878
- pageSurface: dataContext?.pageSurface ?? null,
879
- subject: dataContext?.subject ?? null,
880
- supabaseUrl: dataContext?.supabaseUrl,
881
- imageResolveContext: resolvedImageResolveContext,
882
- blockId: block.id ?? null,
883
- blockKind: block.kind
884
- };
885
- baseProps.bookingTimeZone = resolveBookingTimeZone(dataContext);
1046
+ themeResources,
1047
+ dataContext,
1048
+ imageResolveContext: resolvedImageResolveContext
1049
+ });
886
1050
  let rendered;
887
1051
  if (OverrideComponent) rendered = /* @__PURE__ */ jsx(OverrideComponent, { ...baseProps });
888
1052
  else {
@@ -929,39 +1093,11 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeResources
929
1093
  hasResolvedData
930
1094
  });
931
1095
  } catch {
932
- const rendered = block.presentationAdmission.kind === "editor" ? fallback(`Unable to render block kind "${block.kind}".`) : fallback(`Invalid content for block kind "${block.kind}".`);
933
- return finish(wrapBlock && block.id ? /* @__PURE__ */ jsx(Fragment$1, { children: wrapBlock(block.id, rendered) }) : /* @__PURE__ */ jsx(Fragment$1, { children: rendered }), {
1096
+ return finish(withBlockWrapper(diagnostic(block.presentationAdmission.kind === "editor" ? `Unable to render block kind "${block.kind}".` : `Invalid content for block kind "${block.kind}".`, { outcome: "exception" })), {
934
1097
  outcome: "exception",
935
1098
  override: false
936
1099
  });
937
1100
  }
938
- }, (prev, next) => {
939
- return prev.block === next.block && prev.registry === next.registry && prev.dataContext === next.dataContext && prev.themeResources === next.themeResources && prev.routeMap === next.routeMap && prev.block.presentationAdmission === next.block.presentationAdmission && prev.wrapBlock === next.wrapBlock && prev.blockOverrides === next.blockOverrides && prev.sdkConfig === next.sdkConfig && prev.customBlocks === next.customBlocks && prev.imageResolveContext === next.imageResolveContext && prev.previewAuthoring === next.previewAuthoring;
940
- });
941
- function fallback(message) {
942
- return /* @__PURE__ */ jsx("div", {
943
- className: "rb-p-6 rb-caption",
944
- style: textColorStyle("mutedText"),
945
- children: message
946
- });
947
- }
948
- function shouldDebugCustomBlocks() {
949
- try {
950
- return globalThis.process?.env?.DEBUG_CUSTOM_BLOCKS === "1";
951
- } catch {
952
- return false;
953
- }
954
- }
955
- /**
956
- * Resolves block content based on stage priority.
957
- * For draft/preview: draftContent takes priority over content.
958
- * For published: content is the source of truth.
959
- * Returns empty object if no content exists (validator will handle placeholders if needed).
960
- */
961
- function getRenderableContent(block, previewStage = "published") {
962
- const source = previewStage === "preview" && block.draftContent ? block.draftContent : block.content ?? {};
963
- if (!isObjectRecord(source)) return {};
964
- return source;
965
1101
  }
966
1102
  //#endregion
967
1103
  //#region ../theme-core/src/fonts/types.ts
@@ -1756,6 +1892,297 @@ function normalizePublicApiLoaderParams(endpoint, params, context) {
1756
1892
  const Text = Text$1;
1757
1893
  const RichText = RichText$1;
1758
1894
  //#endregion
1895
+ //#region ../db/src/schemas/forms.ts
1896
+ /**
1897
+ * Form Settings Schemas
1898
+ *
1899
+ * Zod schemas for validating form settings JSON stored in the database.
1900
+ * These schemas are the single source of truth for form settings validation
1901
+ * across API routes, type guards, and client-side form submission.
1902
+ */
1903
+ const sensitiveCollectionModeSchema = z.enum(["standard", "sensitive"]).default("standard");
1904
+ const sensitiveCollectionConfirmationVersionSchema = z.union([z.literal(1), z.null()]);
1905
+ const formPresentationSettingsShape = {
1906
+ submitLabel: z.string().min(1).max(40).nullable().optional(),
1907
+ templateKey: z.string().min(1).nullable().optional()
1908
+ };
1909
+ const formPresentationSettingsSchema = z.object(formPresentationSettingsShape).strict();
1910
+ const sensitiveCollectionConfigSchema = z.object({
1911
+ enabledAt: z.string().datetime().nullable(),
1912
+ enabledByUserId: z.string().uuid().nullable(),
1913
+ confirmationVersion: sensitiveCollectionConfirmationVersionSchema
1914
+ }).strict();
1915
+ /**
1916
+ * Email notification settings for contact forms
1917
+ */
1918
+ const emailNotificationSchema = z.object({
1919
+ enabled: z.boolean(),
1920
+ recipients: z.array(z.string().email()).optional()
1921
+ }).strict();
1922
+ /**
1923
+ * Submitter auto-reply settings for contact forms.
1924
+ *
1925
+ * Intentionally does not include form field values; overrides are purely template strings.
1926
+ */
1927
+ const submitterAutoReplySchema = z.object({
1928
+ enabled: z.boolean(),
1929
+ override: z.object({
1930
+ subjectTemplate: z.string().max(200),
1931
+ bodyTemplate: z.string().max(1e4)
1932
+ }).strict().optional()
1933
+ }).strict();
1934
+ /**
1935
+ * Webhook notification settings for forms
1936
+ */
1937
+ const webhookNotificationSchema = z.object({
1938
+ enabled: z.boolean(),
1939
+ url: z.string().url().optional(),
1940
+ headers: z.record(z.string(), z.string()).optional()
1941
+ }).strict();
1942
+ /**
1943
+ * Notification settings structure
1944
+ */
1945
+ const notificationSettingsSchema = z.object({
1946
+ email: emailNotificationSchema.optional(),
1947
+ autoReply: submitterAutoReplySchema.optional(),
1948
+ webhook: webhookNotificationSchema.optional(),
1949
+ emails: z.array(z.string().email()).optional()
1950
+ }).strict().optional();
1951
+ const standardContactOptionalFieldSettingsSchema = z.object({ visible: z.boolean() }).strict();
1952
+ const contactFormDefinitionSettingsSchema = z.discriminatedUnion("kind", [z.object({ kind: z.literal("custom-contact") }).strict(), z.object({
1953
+ kind: z.literal("standard-contact"),
1954
+ optionalFields: z.object({
1955
+ name: standardContactOptionalFieldSettingsSchema,
1956
+ phone: standardContactOptionalFieldSettingsSchema
1957
+ }).strict()
1958
+ }).strict()]);
1959
+ /**
1960
+ * Contact form settings
1961
+ * Used for general inquiry forms that send notifications to site owners
1962
+ */
1963
+ const contactFormSettingsSchema = z.object({
1964
+ type: z.literal("contact"),
1965
+ successMessage: z.string().optional(),
1966
+ sensitiveCollectionMode: sensitiveCollectionModeSchema.optional(),
1967
+ sensitiveCollection: sensitiveCollectionConfigSchema.optional(),
1968
+ notifications: notificationSettingsSchema,
1969
+ definition: contactFormDefinitionSettingsSchema.default({ kind: "custom-contact" })
1970
+ }).strict();
1971
+ /**
1972
+ * Booking form settings
1973
+ * Used for appointment booking forms that create appointments in the system
1974
+ *
1975
+ * Service configuration:
1976
+ * - serviceId: Single service (backward compatible)
1977
+ * - serviceIds: Multiple services (user selects at booking time)
1978
+ * - If neither provided: Shows all available services for the site
1979
+ *
1980
+ * Note: Form can have either serviceId OR serviceIds, not both.
1981
+ * XOR validation enforces this constraint.
1982
+ */
1983
+ const bookingFormSettingsSchema = z.object({
1984
+ type: z.literal("booking"),
1985
+ serviceId: z.string().optional(),
1986
+ serviceIds: z.array(z.string()).optional(),
1987
+ resourceId: z.string().nullable().optional(),
1988
+ requiresApproval: z.boolean().default(false),
1989
+ successMessage: z.string().optional(),
1990
+ sensitiveCollectionMode: sensitiveCollectionModeSchema.optional(),
1991
+ sensitiveCollection: sensitiveCollectionConfigSchema.optional()
1992
+ }).strict().refine((data) => {
1993
+ const hasSingle = data.serviceId !== void 0 && data.serviceId.length > 0;
1994
+ const hasMultiple = data.serviceIds !== void 0 && data.serviceIds.length > 0;
1995
+ return !(hasSingle && hasMultiple);
1996
+ }, { message: "Form cannot have both serviceId and serviceIds. Use one or the other." });
1997
+ /**
1998
+ * Event registration form settings
1999
+ * Used for event registration forms that create event attendees
2000
+ *
2001
+ * Series configuration:
2002
+ * - seriesId: Single event series (form is for specific event)
2003
+ * - If not provided: Block must specify series or get from context
2004
+ */
2005
+ const eventRegistrationFormSettingsSchema = z.object({
2006
+ type: z.literal("event-registration"),
2007
+ seriesId: z.string().uuid().optional(),
2008
+ maxTickets: z.number().int().positive().max(10).default(10),
2009
+ requiresApproval: z.boolean().default(false),
2010
+ successMessage: z.string().optional(),
2011
+ sensitiveCollectionMode: sensitiveCollectionModeSchema.optional(),
2012
+ sensitiveCollection: sensitiveCollectionConfigSchema.optional()
2013
+ }).strict();
2014
+ /**
2015
+ * Booking Questions form settings
2016
+ * Used for reusable short forms / detailed questionnaires attached through booking requirements.
2017
+ */
2018
+ const bookingQuestionsFormSettingsSchema = z.object({
2019
+ type: z.literal("booking-questions"),
2020
+ schemaVersion: z.literal(2).default(2),
2021
+ shape: z.enum(["short-form", "detailed-questionnaire"]).default("short-form"),
2022
+ sensitiveCollectionMode: sensitiveCollectionModeSchema.optional(),
2023
+ sensitiveCollection: sensitiveCollectionConfigSchema.optional(),
2024
+ audienceHint: z.enum([
2025
+ "appointments",
2026
+ "events",
2027
+ "courses",
2028
+ "mixed"
2029
+ ]).optional(),
2030
+ customerTitle: z.string().min(1).max(120).optional(),
2031
+ introTitle: z.string().min(1).max(120).nullable().optional(),
2032
+ introBody: z.string().min(1).max(4e3).nullable().optional(),
2033
+ reviewLayout: z.enum(["flat", "sectioned"]).default("flat")
2034
+ }).strict();
2035
+ z.discriminatedUnion("type", [
2036
+ contactFormSettingsSchema,
2037
+ bookingFormSettingsSchema,
2038
+ eventRegistrationFormSettingsSchema,
2039
+ bookingQuestionsFormSettingsSchema
2040
+ ]);
2041
+ const contactFormSettingsInputSchema = contactFormSettingsSchema.extend(formPresentationSettingsShape).strict();
2042
+ const bookingFormSettingsInputSchema = bookingFormSettingsSchema.safeExtend(formPresentationSettingsShape).strict();
2043
+ const eventRegistrationFormSettingsInputSchema = eventRegistrationFormSettingsSchema.extend(formPresentationSettingsShape).strict();
2044
+ const bookingQuestionsFormSettingsInputSchema = bookingQuestionsFormSettingsSchema.extend(formPresentationSettingsShape).strict();
2045
+ /**
2046
+ * Transitional input schema for API/SDK callers that may still send form-level
2047
+ * presentation metadata inside settings. Storage code must split these keys out
2048
+ * before persisting canonical behavior settings.
2049
+ */
2050
+ const formSettingsInputSchema = z.discriminatedUnion("type", [
2051
+ contactFormSettingsInputSchema,
2052
+ bookingFormSettingsInputSchema,
2053
+ eventRegistrationFormSettingsInputSchema,
2054
+ bookingQuestionsFormSettingsInputSchema
2055
+ ]);
2056
+ /**
2057
+ * Form field option schema
2058
+ */
2059
+ const formFieldOptionSchema = z.object({
2060
+ value: z.string().min(1),
2061
+ label: z.string()
2062
+ }).strict();
2063
+ /**
2064
+ * Form field layout schema
2065
+ * Controls presentation on the public site renderer (e.g. 2-column rows).
2066
+ */
2067
+ const formFieldLayoutSchema = z.object({ width: z.enum(["full", "half"]).default("full") }).strict();
2068
+ const formFieldSchema = z.object({
2069
+ id: z.string().min(1, "Field ID is required"),
2070
+ label: z.string().min(1, "Field label is required"),
2071
+ type: z.enum([
2072
+ "text",
2073
+ "email",
2074
+ "textarea",
2075
+ "select",
2076
+ "radio",
2077
+ "checkbox",
2078
+ "consent",
2079
+ "tel",
2080
+ "url",
2081
+ "number",
2082
+ "date",
2083
+ "time"
2084
+ ]),
2085
+ required: z.boolean().default(false),
2086
+ placeholder: z.string().optional(),
2087
+ helpText: z.string().optional(),
2088
+ options: z.array(formFieldOptionSchema).optional(),
2089
+ multiple: z.boolean().optional(),
2090
+ minLength: z.number().int().positive().optional(),
2091
+ maxLength: z.number().int().positive().optional(),
2092
+ pattern: z.string().optional(),
2093
+ min: z.number().optional(),
2094
+ max: z.number().optional(),
2095
+ layout: formFieldLayoutSchema.optional()
2096
+ }).strict();
2097
+ const bookingQuestionFieldTypeSchema = z.enum([
2098
+ "text",
2099
+ "email",
2100
+ "textarea",
2101
+ "select",
2102
+ "radio",
2103
+ "checkbox",
2104
+ "tel",
2105
+ "url",
2106
+ "number",
2107
+ "date",
2108
+ "time"
2109
+ ]);
2110
+ const bookingQuestionDocumentFileTypeSchema = z.enum([
2111
+ "pdf",
2112
+ "image",
2113
+ "docx"
2114
+ ]);
2115
+ const bookingQuestionScalarFieldSchema = formFieldSchema.extend({ type: bookingQuestionFieldTypeSchema }).strict();
2116
+ const bookingQuestionDocumentUploadFieldSchema = z.object({
2117
+ id: z.string().min(1, "Field ID is required"),
2118
+ label: z.string().min(1, "Field label is required"),
2119
+ type: z.literal("document_upload"),
2120
+ required: z.boolean().default(false),
2121
+ placeholder: z.string().optional(),
2122
+ helpText: z.string().optional(),
2123
+ layout: formFieldLayoutSchema.optional(),
2124
+ allowedFileTypes: z.array(bookingQuestionDocumentFileTypeSchema).min(1, "Choose at least one allowed file type").default([
2125
+ "pdf",
2126
+ "image",
2127
+ "docx"
2128
+ ]),
2129
+ maxBytes: z.number().int().positive().max(25 * 1024 * 1024).default(25 * 1024 * 1024)
2130
+ }).strict();
2131
+ const bookingQuestionFieldSchema = z.discriminatedUnion("type", [bookingQuestionScalarFieldSchema, bookingQuestionDocumentUploadFieldSchema]);
2132
+ const bookingQuestionsSectionSchema = z.object({
2133
+ id: z.string().min(1, "Section ID is required"),
2134
+ title: z.string().min(1, "Section title is required"),
2135
+ description: z.string().optional(),
2136
+ items: z.array(bookingQuestionFieldSchema).min(1, "Section must contain at least one question")
2137
+ }).strict();
2138
+ const bookingQuestionsDetailedSchemaSchema = z.object({
2139
+ schemaVersion: z.literal(2),
2140
+ sections: z.array(bookingQuestionsSectionSchema).min(1, "Questionnaire must have at least one section")
2141
+ }).strict();
2142
+ /**
2143
+ * Form schema structure
2144
+ * Validates the complete form schema stored in schema_json column
2145
+ */
2146
+ const formSchemaSchema = z.object({
2147
+ version: z.string().default("1.0"),
2148
+ fields: z.array(formFieldSchema).min(1, "Form must have at least one field")
2149
+ }).strict();
2150
+ const bookingQuestionsFlatSchemaSchema = z.object({
2151
+ version: z.string().default("1.0"),
2152
+ fields: z.array(bookingQuestionFieldSchema).min(1, "Form must have at least one question")
2153
+ }).strict();
2154
+ z.union([bookingQuestionsFlatSchemaSchema, bookingQuestionsDetailedSchemaSchema]);
2155
+ const formSlugSchema = z.string().min(1, "Form slug is required").regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Use lowercase letters, numbers, and hyphens only").transform((value) => value);
2156
+ z.object({
2157
+ name: z.string().min(1, "Form name is required"),
2158
+ slug: formSlugSchema,
2159
+ schema: formSchemaSchema,
2160
+ settings: formSettingsInputSchema.optional(),
2161
+ presentation: formPresentationSettingsSchema.optional()
2162
+ }).strict();
2163
+ //#endregion
2164
+ //#region ../db/src/schemas/standard-contact.ts
2165
+ const standardContactLabelSchema = z.string().trim().min(1).max(80);
2166
+ const standardContactPlaceholderSchema = z.string().trim().max(160).optional();
2167
+ function standardContactFieldSchema(id, type, required) {
2168
+ return z.object({
2169
+ id: z.literal(id),
2170
+ label: standardContactLabelSchema,
2171
+ type: z.literal(type),
2172
+ required: z.literal(required),
2173
+ placeholder: standardContactPlaceholderSchema
2174
+ }).strict();
2175
+ }
2176
+ z.object({
2177
+ version: z.literal("1.0"),
2178
+ fields: z.tuple([
2179
+ standardContactFieldSchema("name", "text", false),
2180
+ standardContactFieldSchema("email", "email", true),
2181
+ standardContactFieldSchema("phone", "tel", false),
2182
+ standardContactFieldSchema("message", "textarea", true)
2183
+ ])
2184
+ }).strict();
2185
+ //#endregion
1759
2186
  //#region ../media-storage-supabase/dist/index.mjs
1760
2187
  function ok(value) {
1761
2188
  return {
@@ -2527,15 +2954,17 @@ const createApiMediaRepo = ({ client }) => ({
2527
2954
  }, (error) => toMediaStorageError(error, DEFAULT_MESSAGES.update));
2528
2955
  },
2529
2956
  async deleteAsset(assetId, options) {
2530
- try {
2531
- await client({
2532
- endpoint: "mediaDelete",
2533
- params: { assetId },
2534
- body: { deleteObject: options?.deleteObject }
2535
- });
2536
- } catch (error) {
2537
- throw toMediaStorageError(error, DEFAULT_MESSAGES.delete);
2538
- }
2957
+ const response = await callClient(client, {
2958
+ endpoint: "mediaDelete",
2959
+ params: { assetId },
2960
+ body: { deleteObject: options?.deleteObject }
2961
+ }, (error) => toMediaStorageError(error, DEFAULT_MESSAGES.delete));
2962
+ if (response.kind === "deleted") return response;
2963
+ const orphanWarning = response.warnings.find((warning) => warning.kind === "ORPHAN_CLEANUP_FAILED");
2964
+ return orphanWarning === void 0 ? { kind: "deleted" } : {
2965
+ kind: "deleted_with_orphan_warning",
2966
+ warning: orphanWarning
2967
+ };
2539
2968
  },
2540
2969
  generateStoragePath
2541
2970
  });
@@ -2626,8 +3055,9 @@ function createCachedMediaRepo(baseRepo, options) {
2626
3055
  return result;
2627
3056
  },
2628
3057
  async deleteAsset(assetId, options) {
2629
- await baseRepo.deleteAsset(assetId, options);
3058
+ const outcome = await baseRepo.deleteAsset(assetId, options);
2630
3059
  invalidateCache();
3060
+ return outcome;
2631
3061
  },
2632
3062
  generateStoragePath: baseRepo.generateStoragePath
2633
3063
  };
@@ -8302,10 +8732,10 @@ function resolveShellThemeRoles(props) {
8302
8732
  }
8303
8733
  const previewContainerResponsiveEnabled = process.env.NEXT_PUBLIC_ENABLE_PREVIEW_CONTAINER_RESPONSIVE !== "false";
8304
8734
  const PreviewEditorSidebar = React.lazy(async () => {
8305
- return { default: (await import("./PreviewEditorSidebar-BU5ZlhQR.mjs")).PreviewEditorSidebar };
8735
+ return { default: (await import("./PreviewEditorSidebar-Bn6cONPa.mjs")).PreviewEditorSidebar };
8306
8736
  });
8307
8737
  const PreviewEditorUI = React.lazy(async () => {
8308
- return { default: (await import("./PreviewEditorUI-9XkHL-bC.mjs")).PreviewEditorUI };
8738
+ return { default: (await import("./PreviewEditorUI-LAwXZPSx.mjs")).PreviewEditorUI };
8309
8739
  });
8310
8740
  const previewPaneContainmentStyle = {
8311
8741
  contain: "layout paint",
@@ -8321,6 +8751,7 @@ function renderShellProviders(input) {
8321
8751
  siteId: props.siteId,
8322
8752
  apiClient: input.apiClient,
8323
8753
  theme: themeRoles.persistenceTheme,
8754
+ headerPreferences: props.themeSelectionHeaderPreferences ?? null,
8324
8755
  themeId: props.themeId ?? null,
8325
8756
  selectionId: props.themeSelectionId ?? null,
8326
8757
  selectionVersion: props.themeSelectionVersion ?? null,
@@ -8636,6 +9067,7 @@ function resolveShellLayoutProps(input) {
8636
9067
  themeSelectionUpdatedAt: props.themeSelectionUpdatedAt ?? null,
8637
9068
  themeSelectionButtonStyleSelection: props.themeSelectionButtonStyleSelection ?? null,
8638
9069
  themeSelectionButtonStyleRepairs: props.themeSelectionButtonStyleRepairs ?? [],
9070
+ themeSelectionHeaderPreferences: props.themeSelectionHeaderPreferences ?? null,
8639
9071
  themeSelectionHeaderSelection: props.themeSelectionHeaderSelection ?? null,
8640
9072
  themeSelectionFooterLookId: props.themeSelectionFooterLookId ?? null,
8641
9073
  themeSelectionHeaderLogo: props.themeSelectionHeaderLogo,