@riverbankcms/sdk 0.147.0 → 0.149.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 (442) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +1 -1
  3. package/dist/{PreviewEditorSidebar-DtpB3_sS.mjs → PreviewEditorSidebar-DBKln68M.mjs} +301 -205
  4. package/dist/{PreviewEditorUI-DxTLgaHo.mjs → PreviewEditorUI-DpRX4Mum.mjs} +68 -63
  5. package/dist/{PreviewQueryProvider-Dd4dxOiU.mjs → PreviewQueryProvider-C0mndwHB.mjs} +3 -3
  6. package/dist/{SdkPreviewModeRuntime-DMMNCngt.mjs → SdkPreviewModeRuntime-DJPmPY-r.mjs} +1247 -541
  7. package/dist/{SiteChromeCustomizeContext-DQXZXiqS.mjs → SiteChromeCustomizeContext-JYA0cJ_Z.mjs} +209720 -204978
  8. package/dist/_dts/ai/src/contracts/proposals.d.ts +0 -33
  9. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +0 -3
  10. package/dist/_dts/api/src/accessAdmin.d.ts +0 -4
  11. package/dist/_dts/api/src/accountApi.d.ts +1 -1
  12. package/dist/_dts/api/src/admin.d.ts +22 -22
  13. package/dist/_dts/api/src/aiPatch.d.ts +2 -2
  14. package/dist/_dts/api/src/aiPlayground.d.ts +1 -0
  15. package/dist/_dts/api/src/analytics.d.ts +2 -2
  16. package/dist/_dts/api/src/apiEndpointTypes.d.ts +2 -0
  17. package/dist/_dts/api/src/appointmentSetup.d.ts +2 -2
  18. package/dist/_dts/api/src/auth.d.ts +10 -10
  19. package/dist/_dts/api/src/availability.d.ts +6 -6
  20. package/dist/_dts/api/src/billing.d.ts +42 -15
  21. package/dist/_dts/api/src/billingEndpointDefinitions.d.ts +8 -0
  22. package/dist/_dts/api/src/billingEndpointTypes.d.ts +15 -6
  23. package/dist/_dts/api/src/blocks.d.ts +15 -14
  24. package/dist/_dts/api/src/blocksKeys.d.ts +2 -0
  25. package/dist/_dts/api/src/bookingConfig.d.ts +33 -50
  26. package/dist/_dts/api/src/bookingManagementEndpoints.d.ts +2 -6
  27. package/dist/_dts/api/src/bookingOperations.d.ts +9 -11
  28. package/dist/_dts/api/src/bookingRecords.d.ts +16 -11
  29. package/dist/_dts/api/src/bookingRefundOutcomes.d.ts +5 -5
  30. package/dist/_dts/api/src/bookings.d.ts +7 -7
  31. package/dist/_dts/api/src/calendar.d.ts +9 -9
  32. package/dist/_dts/api/src/clientErrorReporting.d.ts +11 -0
  33. package/dist/_dts/api/src/commercePortalEndpoints.d.ts +7 -8
  34. package/dist/_dts/api/src/common/cancellation.d.ts +23 -0
  35. package/dist/_dts/api/src/common/envelope.d.ts +2 -2
  36. package/dist/_dts/api/src/content-editor.d.ts +2 -2
  37. package/dist/_dts/api/src/contentEntries.d.ts +17 -48
  38. package/dist/_dts/api/src/contentRuntime.d.ts +51 -37
  39. package/dist/_dts/api/src/contentTypes.d.ts +11 -11
  40. package/dist/_dts/api/src/contentVersionHistoryClient.d.ts +6 -6
  41. package/dist/_dts/api/src/customerMembershipOutcomes.d.ts +1 -1
  42. package/dist/_dts/api/src/documentLifecycle.d.ts +67 -0
  43. package/dist/_dts/api/src/domains.d.ts +16 -16
  44. package/dist/_dts/api/src/editLeaseEndpoints.d.ts +72 -0
  45. package/dist/_dts/api/src/emailSettings.d.ts +4 -4
  46. package/dist/_dts/api/src/endpoints.d.ts +135 -51
  47. package/dist/_dts/api/src/eventEmailTemplates.d.ts +2 -2
  48. package/dist/_dts/api/src/eventManagementContracts.d.ts +29 -7
  49. package/dist/_dts/api/src/eventManagementEndpointDefinitions.d.ts +0 -8
  50. package/dist/_dts/api/src/eventPageWords.d.ts +7 -12
  51. package/dist/_dts/api/src/footerSettings.d.ts +6 -6
  52. package/dist/_dts/api/src/index.d.ts +8 -7
  53. package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -0
  54. package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -1
  55. package/dist/_dts/api/src/navigation.d.ts +5 -5
  56. package/dist/_dts/api/src/pageSurfaceEditorEndpoints.d.ts +55 -0
  57. package/dist/_dts/api/src/pageSurfaceEndpoints.d.ts +28 -7
  58. package/dist/_dts/api/src/pages.d.ts +7 -7
  59. package/dist/_dts/api/src/performance.d.ts +1 -1
  60. package/dist/_dts/api/src/public/index.d.ts +1 -1
  61. package/dist/_dts/api/src/publicAppointmentBookingContracts.d.ts +4 -2
  62. package/dist/_dts/api/src/publicExperience/commerceEndpoints.d.ts +6 -29
  63. package/dist/_dts/api/src/redirects.d.ts +3 -3
  64. package/dist/_dts/api/src/request.d.ts +11 -2
  65. package/dist/_dts/api/src/resources.d.ts +4 -4
  66. package/dist/_dts/api/src/routes.d.ts +8 -3
  67. package/dist/_dts/api/src/sdk-event-upsert.d.ts +1 -2
  68. package/dist/_dts/api/src/sdkBlockUpsertContracts.d.ts +21 -0
  69. package/dist/_dts/api/src/sdkContracts.d.ts +5 -28
  70. package/dist/_dts/api/src/sdkEventEndpointDefinitions.d.ts +1 -1
  71. package/dist/_dts/api/src/sdkEventOccurrenceRequestContracts.d.ts +43 -0
  72. package/dist/_dts/api/src/sdkManagedEventContracts.d.ts +4 -2
  73. package/dist/_dts/api/src/sdkPullEventContracts.d.ts +9 -2
  74. package/dist/_dts/api/src/seo.d.ts +4 -4
  75. package/dist/_dts/api/src/services.d.ts +4 -4
  76. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +15 -8
  77. package/dist/_dts/api/src/siteMembers.d.ts +10 -10
  78. package/dist/_dts/api/src/siteOnboarding.d.ts +14 -0
  79. package/dist/_dts/api/src/siteOperations.d.ts +6 -2
  80. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +7 -3
  81. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +5 -12
  82. package/dist/_dts/api/src/siteRuntimeEntry.d.ts +31 -0
  83. package/dist/_dts/billing/src/checkout/platform.d.ts +77 -0
  84. package/dist/_dts/billing/src/components/index.d.ts +25 -40
  85. package/dist/_dts/billing/src/membership/index.d.ts +1 -3
  86. package/dist/_dts/billing/src/plans/entitlements.d.ts +80 -0
  87. package/dist/_dts/billing/src/plans/registry.d.ts +16 -16
  88. package/dist/_dts/billing/src/plans/standing.d.ts +9 -2
  89. package/dist/_dts/billing/src/plans/types.d.ts +5 -15
  90. package/dist/_dts/billing/src/site-arrangements.d.ts +2 -2
  91. package/dist/_dts/billing/src/subscriptions/standingEvidence.d.ts +2 -4
  92. package/dist/_dts/billing/src/subscriptions/store.d.ts +17 -11
  93. package/dist/_dts/block-form/src/backend/store-backend.d.ts +6 -7
  94. package/dist/_dts/block-form/src/backend/types.d.ts +7 -0
  95. package/dist/_dts/block-form/src/widgets/FieldFrame.d.ts +3 -1
  96. package/dist/_dts/blocks/src/client/events.d.ts +3 -0
  97. package/dist/_dts/blocks/src/contracts/index.d.ts +1 -1
  98. package/dist/_dts/blocks/src/contracts/non-block-islands.d.ts +2 -2
  99. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +54 -14
  100. package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +4 -13
  101. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +2 -0
  102. package/dist/_dts/blocks/src/portal/types.d.ts +9 -8
  103. package/dist/_dts/blocks/src/system/blocks/contact-newsletter.d.ts +2 -1
  104. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +3 -1
  105. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +28 -28
  106. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +7 -2
  107. package/dist/_dts/blocks/src/system/blocks/shared/bookingPaymentTerms.d.ts +84 -160
  108. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +2 -2
  109. package/dist/_dts/blocks/src/system/blocks/shop.shared.d.ts +31 -4
  110. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +2 -2
  111. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
  112. package/dist/_dts/blocks/src/system/runtime/api/types/appointments.d.ts +4 -2
  113. package/dist/_dts/blocks/src/system/runtime/api/types/core.d.ts +3 -1
  114. package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +6 -0
  115. package/dist/_dts/blocks/src/system/runtime/api/types/portal.d.ts +6 -0
  116. package/dist/_dts/blocks/src/system/runtime/api/types/shop.d.ts +4 -0
  117. package/dist/_dts/blocks/src/system/runtime/components/booking/SuccessMessage.d.ts +4 -1
  118. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +72 -12
  119. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +36 -6
  120. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingNowIso.d.ts +8 -0
  121. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.d.ts +3 -0
  122. package/dist/_dts/blocks/src/system/runtime/hooks/usePaymentVerification.d.ts +2 -1
  123. package/dist/_dts/blocks/src/system/runtime/hooks/usePolling.d.ts +7 -48
  124. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.checkout-return-context.d.ts +7 -0
  125. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.completion.d.ts +3 -1
  126. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +4 -0
  127. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.interactive.d.ts +9 -0
  128. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.payment-confirmation.d.ts +13 -0
  129. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.state.d.ts +17 -2
  130. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.submit-actions.d.ts +8 -0
  131. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.submit-handler.d.ts +1 -0
  132. package/dist/_dts/blocks/src/system/runtime/nodes/booking-runtime-sources.d.ts +1 -0
  133. package/dist/_dts/blocks/src/system/runtime/nodes/checkout.server.d.ts +2 -1
  134. package/dist/_dts/blocks/src/system/runtime/nodes/commerce/shared/display.d.ts +9 -2
  135. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/presentation.d.ts +14 -2
  136. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +2 -1
  137. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationWizard.d.ts +5 -0
  138. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/PaymentSelectionStep.d.ts +2 -0
  139. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/SuccessStep.d.ts +4 -1
  140. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventPaymentOptions.d.ts +3 -3
  141. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +2 -0
  142. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +2 -5
  143. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +4 -0
  144. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +9 -5
  145. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.interactive.d.ts +6 -0
  146. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/dates.d.ts +37 -3
  147. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventCard.client.d.ts +1 -1
  148. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventCard.d.ts +16 -1
  149. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCardPresentations.d.ts +13 -0
  150. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +29 -29
  151. package/dist/_dts/blocks/src/system/runtime/nodes/shared/MagicLinkForm.d.ts +1 -14
  152. package/dist/_dts/blocks/src/system/runtime/nodes/shared/MagicLinkForm.state.d.ts +12 -0
  153. package/dist/_dts/blocks/src/system/runtime/nodes/shop.interactive.d.ts +54 -6
  154. package/dist/_dts/blocks/src/system/runtime/shared/bookingPaymentOptions.d.ts +7 -2
  155. package/dist/_dts/blocks/src/system/runtime/shared/components/DemoBookingPortalAccess.d.ts +22 -0
  156. package/dist/_dts/blocks/src/system/runtime/shared/components/DemoPortalSignInLink.d.ts +4 -0
  157. package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +1 -0
  158. package/dist/_dts/blocks/src/system/runtime/shared/utils/demoBookingPassStorage.d.ts +10 -0
  159. package/dist/_dts/blocks/src/system/runtime/shared/utils/demoPortalMagicLink.d.ts +29 -0
  160. package/dist/_dts/commerce/src/purchase/bookingPaymentSelection.d.ts +54 -0
  161. package/dist/_dts/commerce/src/purchase/checkoutCommitPlan.d.ts +58 -13
  162. package/dist/_dts/commerce/src/purchase/checkoutErrorCodes.d.ts +1 -1
  163. package/dist/_dts/commerce/src/purchase/checkoutPaymentPlanPlanning.d.ts +16 -21
  164. package/dist/_dts/commerce/src/purchase/checkoutPaymentTerms.d.ts +23 -40
  165. package/dist/_dts/commerce/src/purchase/checkoutSessionMetadata.d.ts +2 -2
  166. package/dist/_dts/commerce/src/purchase/checkoutStripeSessionPlanning.d.ts +5 -4
  167. package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +4 -0
  168. package/dist/_dts/commerce/src/purchase/index.d.ts +1 -3
  169. package/dist/_dts/commerce/src/purchase/membershipOrderItemMetadata.d.ts +4 -0
  170. package/dist/_dts/commerce/src/purchase/oneTimeCheckoutPlanning.d.ts +9 -4
  171. package/dist/_dts/commerce/src/purchase/orderInstalmentClosure.d.ts +13 -1
  172. package/dist/_dts/commerce/src/purchase/orderInstalmentLifecycle.d.ts +5 -0
  173. package/dist/_dts/commerce/src/purchase/orderItemMetadata.d.ts +3 -1
  174. package/dist/_dts/commerce/src/purchase/orderTypes.d.ts +7 -1
  175. package/dist/_dts/commerce/src/purchase/refundRailSplit.d.ts +1 -1
  176. package/dist/_dts/commerce/src/purchase/stateTransitions.d.ts +2 -2
  177. package/dist/_dts/commerce/src/purchase/stripeMinimumCharge.d.ts +6 -0
  178. package/dist/_dts/commerce/src/purchase/types.d.ts +2 -1
  179. package/dist/_dts/content-editor/src/components/ContentFieldsForm.d.ts +2 -7
  180. package/dist/_dts/content-editor/src/controller/EditLeaseController.d.ts +39 -0
  181. package/dist/_dts/content-editor/src/controller/EditorWriteGate.d.ts +38 -0
  182. package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +25 -61
  183. package/dist/_dts/content-editor/src/controller/LinkedEntryLeaseBanner.d.ts +7 -0
  184. package/dist/_dts/content-editor/src/controller/LinkedEntryLeaseControllers.d.ts +14 -0
  185. package/dist/_dts/content-editor/src/controller/deriveEditorUnpublishedState.d.ts +6 -0
  186. package/dist/_dts/content-editor/src/controller/documentValueBaseline.d.ts +25 -0
  187. package/dist/_dts/content-editor/src/controller/editLeaseHandover.d.ts +30 -0
  188. package/dist/_dts/content-editor/src/controller/editLeaseLossSignal.d.ts +6 -0
  189. package/dist/_dts/content-editor/src/controller/editLeaseNotice.d.ts +28 -0
  190. package/dist/_dts/content-editor/src/controller/editorClientId.d.ts +2 -0
  191. package/dist/_dts/content-editor/src/controller/editorEditability.d.ts +38 -0
  192. package/dist/_dts/content-editor/src/controller/editorLeaseParticipation.d.ts +34 -0
  193. package/dist/_dts/content-editor/src/controller/normalizedMetadataBaseline.d.ts +29 -0
  194. package/dist/_dts/content-editor/src/controller/pageSurfaceDocumentBaselines.d.ts +14 -0
  195. package/dist/_dts/content-editor/src/controller/pageSurfaceLifecycle.d.ts +11 -0
  196. package/dist/_dts/content-editor/src/controller/planDocumentBaselineRefresh.d.ts +19 -0
  197. package/dist/_dts/content-editor/src/controller/readDocumentLeaseBaselines.d.ts +19 -0
  198. package/dist/_dts/content-editor/src/controller/refreshDocumentLeaseBaseline.d.ts +12 -0
  199. package/dist/_dts/content-editor/src/controller/refreshLinkedEntry.d.ts +17 -0
  200. package/dist/_dts/content-editor/src/controller/replayRestoredEditorEffects.d.ts +2 -3
  201. package/dist/_dts/content-editor/src/controller/routeWrites.d.ts +26 -0
  202. package/dist/_dts/content-editor/src/controller/useAutosaveTriggers.d.ts +16 -17
  203. package/dist/_dts/content-editor/src/controller/useBlockedPublishPlan.d.ts +6 -2
  204. package/dist/_dts/content-editor/src/controller/useBlocksList.d.ts +3 -3
  205. package/dist/_dts/content-editor/src/controller/useEntryValueAutosaves.d.ts +21 -0
  206. package/dist/_dts/content-editor/src/controller/useInitialEditorUiStore.d.ts +24 -0
  207. package/dist/_dts/content-editor/src/controller/useServerBaselineReconciliation.d.ts +17 -0
  208. package/dist/_dts/content-editor/src/footerComposerPanelTypes.d.ts +1 -1
  209. package/dist/_dts/content-editor/src/hooks/applyBlockedPublishPlan.d.ts +5 -1
  210. package/dist/_dts/content-editor/src/hooks/blockDraftLifecycle.d.ts +8 -47
  211. package/dist/_dts/content-editor/src/hooks/editLeaseMachine.d.ts +120 -0
  212. package/dist/_dts/content-editor/src/hooks/publishability.d.ts +6 -10
  213. package/dist/_dts/content-editor/src/hooks/useAutosaveStatus.d.ts +3 -0
  214. package/dist/_dts/content-editor/src/hooks/useBlockAutosave.d.ts +5 -15
  215. package/dist/_dts/content-editor/src/hooks/useDebouncedLatestSave.d.ts +7 -5
  216. package/dist/_dts/content-editor/src/hooks/useEditLease.d.ts +28 -0
  217. package/dist/_dts/content-editor/src/hooks/useEntryActions.d.ts +25 -39
  218. package/dist/_dts/content-editor/src/hooks/useEntryMutations.d.ts +17 -19
  219. package/dist/_dts/content-editor/src/hooks/useLinkedEntryAutosave.d.ts +5 -8
  220. package/dist/_dts/content-editor/src/hooks/useValueAutosave.d.ts +64 -0
  221. package/dist/_dts/content-editor/src/hooks/validateBlocksForPublish.d.ts +0 -7
  222. package/dist/_dts/content-editor/src/index.d.ts +26 -7
  223. package/dist/_dts/content-editor/src/lib/browserStorage.d.ts +5 -0
  224. package/dist/_dts/content-editor/src/linkedEntries/domain.d.ts +12 -0
  225. package/dist/_dts/content-editor/src/linkedEntries/owner.d.ts +9 -0
  226. package/dist/_dts/content-editor/src/liveDrafts/draftProjection.d.ts +66 -0
  227. package/dist/_dts/content-editor/src/liveDrafts/linkedSaveHandovers.d.ts +37 -0
  228. package/dist/_dts/content-editor/src/liveDrafts/remoteDraftOverlay.d.ts +113 -0
  229. package/dist/_dts/content-editor/src/liveDrafts/useLiveDrafts.d.ts +32 -0
  230. package/dist/_dts/content-editor/src/liveDrafts/useRetentionTicks.d.ts +7 -0
  231. package/dist/_dts/content-editor/src/primitives/shared/activePreviewField.d.ts +6 -0
  232. package/dist/_dts/content-editor/src/primitives/shared/storeBinding.d.ts +1 -0
  233. package/dist/_dts/content-editor/src/services/contentEntryServices.d.ts +96 -19
  234. package/dist/_dts/content-editor/src/services/editorApiClient.d.ts +13 -0
  235. package/dist/_dts/content-editor/src/services/index.d.ts +2 -0
  236. package/dist/_dts/content-editor/src/services/pageSurfaceEditorServices.d.ts +23 -0
  237. package/dist/_dts/content-editor/src/sync/flushValues.d.ts +13 -0
  238. package/dist/_dts/content-editor/src/sync/lifecycleFailure.d.ts +51 -0
  239. package/dist/_dts/content-editor/src/sync/runLifecycle.d.ts +64 -0
  240. package/dist/_dts/content-editor/src/sync/schedulerValues.d.ts +27 -0
  241. package/dist/_dts/content-editor/src/sync/sendPlanning.d.ts +104 -0
  242. package/dist/_dts/content-editor/src/sync/valueSync.d.ts +114 -0
  243. package/dist/_dts/content-editor/src/ui/blockCollection.d.ts +8 -0
  244. package/dist/_dts/content-editor/src/ui/documentLifecycle.d.ts +18 -0
  245. package/dist/_dts/content-editor/src/ui/editorLeaseUiState.d.ts +7 -0
  246. package/dist/_dts/content-editor/src/ui/editorRefresh.d.ts +82 -0
  247. package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +102 -127
  248. package/dist/_dts/content-editor/src/ui/editorTransactionState.d.ts +1 -1
  249. package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +126 -72
  250. package/dist/_dts/content-editor/src/ui/editorValueSnapshot.d.ts +18 -0
  251. package/dist/_dts/content-editor/src/ui/serverBlockAdmission.d.ts +26 -0
  252. package/dist/_dts/content-editor/src/ui/stores/autosaveStore.d.ts +16 -27
  253. package/dist/_dts/content-editor/src/ui/stores/blockVersionsStore.d.ts +24 -0
  254. package/dist/_dts/content-editor/src/ui/stores/linkedEntryLeaseStore.d.ts +54 -0
  255. package/dist/_dts/content-editor/src/ui/stores/linkedSaveHandoversStore.d.ts +11 -0
  256. package/dist/_dts/content-editor/src/ui/stores/remoteDraftsStore.d.ts +10 -0
  257. package/dist/_dts/content-editor/src/ui/stores/types.d.ts +63 -3
  258. package/dist/_dts/content-editor/src/useFooterComposerState.d.ts +2 -2
  259. package/dist/_dts/content-editor/src/useFooterNavigationLayout.d.ts +1 -1
  260. package/dist/_dts/content-model/src/content-types/builtin-schemas.d.ts +4 -4
  261. package/dist/_dts/content-model/src/content-types/builtins.d.ts +4 -4
  262. package/dist/_dts/content-model/src/definitions/shared.d.ts +11 -2
  263. package/dist/_dts/content-model/src/entry-slots/index.d.ts +1 -0
  264. package/dist/_dts/content-model/src/entry-slots/serializeAllowedBlocks.d.ts +2 -0
  265. package/dist/_dts/content-model/src/metadataConfig.d.ts +10 -38
  266. package/dist/_dts/content-model/src/templates/defaults.d.ts +0 -1
  267. package/dist/_dts/content-model/src/types.d.ts +0 -1
  268. package/dist/_dts/core/src/block-content-identity.d.ts +49 -1
  269. package/dist/_dts/core/src/booking-flexible-balance.d.ts +2 -2
  270. package/dist/_dts/core/src/booking-instalment-deposit.d.ts +20 -0
  271. package/dist/_dts/core/src/booking-live-payment-terms.d.ts +72 -0
  272. package/dist/_dts/core/src/booking-payment-options.d.ts +24 -0
  273. package/dist/_dts/core/src/booking-payment-schemas.d.ts +522 -0
  274. package/dist/_dts/core/src/branded.d.ts +15 -0
  275. package/dist/_dts/core/src/currency-format.d.ts +8 -2
  276. package/dist/_dts/core/src/demo-lifecycle-status.d.ts +2 -2
  277. package/dist/_dts/core/src/demo-warm-pool-target.d.ts +8 -0
  278. package/dist/_dts/core/src/edit-lease.d.ts +60 -0
  279. package/dist/_dts/core/src/editor-state.d.ts +38 -13
  280. package/dist/_dts/core/src/editor-value-sync.d.ts +79 -0
  281. package/dist/_dts/core/src/html-entities.d.ts +6 -0
  282. package/dist/_dts/core/src/index.d.ts +7 -0
  283. package/dist/_dts/core/src/uuid.d.ts +7 -5
  284. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +456 -189
  285. package/dist/_dts/editor/src/EditorProvider.d.ts +5 -0
  286. package/dist/_dts/editor/src/chrome/EditorChrome.d.ts +14 -0
  287. package/dist/_dts/editor/src/chrome/EditorStatusBar.d.ts +1 -0
  288. package/dist/_dts/editor/src/chrome/statusBarPresentation.d.ts +0 -1
  289. package/dist/_dts/editor/src/index.d.ts +1 -1
  290. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +10 -9
  291. package/dist/_dts/editor-blocks/src/BlockForm.d.ts +1 -1
  292. package/dist/_dts/editor-blocks/src/block-editor/BlockCard.d.ts +1 -1
  293. package/dist/_dts/editor-blocks/src/block-editor/BlockCardFrame.d.ts +1 -1
  294. package/dist/_dts/editor-blocks/src/block-editor/BlockSettingsModal.d.ts +1 -1
  295. package/dist/_dts/editor-blocks/src/block-editor/applyExtendedFieldDefaults.d.ts +3 -4
  296. package/dist/_dts/editor-blocks/src/block-editor/blockDraftBaselineSeed.d.ts +4 -8
  297. package/dist/_dts/editor-blocks/src/block-editor/editorBlockItem.d.ts +23 -0
  298. package/dist/_dts/editor-blocks/src/block-editor/generatedIconApplyCoordination.d.ts +2 -7
  299. package/dist/_dts/editor-blocks/src/block-editor/hooks/applyBlockStructureChange.d.ts +4 -0
  300. package/dist/_dts/editor-blocks/src/block-editor/hooks/buildInsertBlockHistoryCommand.d.ts +14 -5
  301. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockBaselineSync.d.ts +21 -19
  302. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockCreation.d.ts +2 -10
  303. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockDuplication.d.ts +8 -16
  304. package/dist/_dts/editor-blocks/src/block-editor/owner.d.ts +6 -16
  305. package/dist/_dts/editor-blocks/src/block-editor/types.d.ts +37 -9
  306. package/dist/_dts/editor-blocks/src/index.d.ts +2 -1
  307. package/dist/_dts/editor-blocks/src/widgets/entry-picker/loaders.d.ts +1 -1
  308. package/dist/_dts/editor-blocks/src/widgets/link/loaders.d.ts +1 -1
  309. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/loaders.d.ts +1 -1
  310. package/dist/_dts/editor-blocks/src/widgets/reference/loaders.d.ts +1 -1
  311. package/dist/_dts/editor-blocks/src/widgets/site-option-picker/loaders.d.ts +3 -2
  312. package/dist/_dts/media-core/src/fileStorage.d.ts +4 -0
  313. package/dist/_dts/media-editor/src/MediaPickerDialog.d.ts +3 -1
  314. package/dist/_dts/media-editor/src/MediaPickerMiniDialog.d.ts +10 -0
  315. package/dist/_dts/media-editor/src/context.d.ts +1 -1
  316. package/dist/_dts/media-editor/src/createMediaEditorProvider.d.ts +1 -2
  317. package/dist/_dts/media-editor/src/index.d.ts +2 -0
  318. package/dist/_dts/media-editor/src/provider.d.ts +3 -2
  319. package/dist/_dts/media-react/src/hooks/internal/classification.d.ts +1 -1
  320. package/dist/_dts/media-react/src/hooks/useApiMediaUploader.d.ts +3 -1
  321. package/dist/_dts/preview-next/src/client/blocks/composer/mergeDrafts.d.ts +8 -3
  322. package/dist/_dts/preview-next/src/client/blocks/composer/types.d.ts +6 -3
  323. package/dist/_dts/preview-next/src/client/blocks/linkedEntryRenderOverlay.d.ts +22 -2
  324. package/dist/_dts/preview-next/src/client/blocks/previewProjection/entryFieldRebinding.d.ts +13 -0
  325. package/dist/_dts/preview-next/src/client/blocks/previewProjection/index.d.ts +2 -1
  326. package/dist/_dts/preview-next/src/client/blocks/previewProjection/types.d.ts +11 -1
  327. package/dist/_dts/preview-next/src/client/blocks/renderPrecedence.d.ts +17 -0
  328. package/dist/_dts/preview-next/src/client/blocks/useLinkedSaveHandoverRetention.d.ts +20 -0
  329. package/dist/_dts/preview-next/src/client/index.d.ts +1 -1
  330. package/dist/_dts/preview-next/src/client/preview/EntryEditorPanel.d.ts +2 -1
  331. package/dist/_dts/preview-next/src/client/preview/EntrySlotBlockEditorPanel.d.ts +2 -1
  332. package/dist/_dts/preview-next/src/client/preview/PreviewAccessBanners.d.ts +7 -0
  333. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +2 -1
  334. package/dist/_dts/preview-next/src/client/preview/PreviewEntryControllerProvider.d.ts +23 -14
  335. package/dist/_dts/preview-next/src/client/preview/PreviewLeaseEditingMode.d.ts +2 -0
  336. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +9 -2
  337. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +1 -0
  338. package/dist/_dts/preview-next/src/client/preview/previewCustomizeAutosave.d.ts +5 -0
  339. package/dist/_dts/preview-next/src/client/preview/previewCustomizeWorkflowState.d.ts +3 -4
  340. package/dist/_dts/preview-next/src/client/preview/sdkConfig.d.ts +1 -0
  341. package/dist/_dts/preview-next/src/client/preview/usePreviewCustomizeWorkflowState.d.ts +4 -0
  342. package/dist/_dts/preview-next/src/client/previewAuthStore.d.ts +7 -0
  343. package/dist/_dts/preview-next/src/constants.d.ts +4 -0
  344. package/dist/_dts/preview-next/src/keepAlive.d.ts +1 -0
  345. package/dist/_dts/realtime/src/client.d.ts +3 -0
  346. package/dist/_dts/realtime/src/draftChannel.d.ts +91 -0
  347. package/dist/_dts/realtime/src/drafts.d.ts +210 -0
  348. package/dist/_dts/realtime/src/index.d.ts +3 -0
  349. package/dist/_dts/realtime/src/leaseChangeSubscriptions.d.ts +8 -0
  350. package/dist/_dts/realtime/src/types.d.ts +113 -0
  351. package/dist/_dts/realtime/src/useDraftChannel.d.ts +34 -0
  352. package/dist/_dts/realtime/src/useSiteRealtimeReload.d.ts +27 -0
  353. package/dist/_dts/sdk/src/public-api/contracts.d.ts +6 -55
  354. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +1 -0
  355. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +1 -0
  356. package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +2 -0
  357. package/dist/_dts/sdk/src/rendering/islands/types.d.ts +2 -12
  358. package/dist/_dts/sdk/src/version.d.ts +1 -1
  359. package/dist/_dts/surfaces/src/index.d.ts +1 -0
  360. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +2 -2
  361. package/dist/_dts/theme-core/src/site-styles/pageDesignIntent.d.ts +0 -5
  362. package/dist/_dts/ui/src/color-picker.d.ts +1 -1
  363. package/dist/_dts/ui/src/palette/useHexDraft.d.ts +7 -0
  364. package/dist/client/{BookingMailingListNote-1n4Ch_u_.mjs → BookingMailingListNote-Cr3EeTP5.mjs} +504 -163
  365. package/dist/client/DemoBookingPortalAccess-BFGB1Fay.mjs +344 -0
  366. package/dist/client/{EventCombined.client-C0pgma9y.mjs → EventCombined.client-DKYV0_ft.mjs} +6 -6
  367. package/dist/client/{EventListing.client-4fhLOvHP.mjs → EventListing.client-B9UIcEYc.mjs} +2 -2
  368. package/dist/client/{LeafletStaticMap-DScC4F3w.mjs → LeafletStaticMap-CFLPkP0K.mjs} +1 -1
  369. package/dist/client/{TerminalPanel-B5ZUsYhe.mjs → TerminalPanel-JjmgxEsR.mjs} +1 -1
  370. package/dist/client/{ThemedButton-DoVIV1Ao.mjs → ThemedButton-CKV1Jh2m.mjs} +1 -1
  371. package/dist/client/{accordion-CoT5g7zo.mjs → accordion-DXWIfT3T.mjs} +1 -1
  372. package/dist/client/{bookingForm-BWxB46xD.mjs → bookingForm-CjZgHNvv.mjs} +216 -63
  373. package/dist/client/bookings.mjs +1187 -692
  374. package/dist/client/{carousel-DtNYWFd3.mjs → carousel-DSLikmvZ.mjs} +1 -1
  375. package/dist/client/{cart-z4qZih1Y.mjs → cart-HDjWReFt.mjs} +3 -3
  376. package/dist/client/{checkout-DpL7euFH.mjs → checkout-CUvRZA3W.mjs} +3 -3
  377. package/dist/client/{checkoutUrls-BEfR7kVu.mjs → checkoutUrls-CXhko2Rv.mjs} +1 -1
  378. package/dist/client/client.mjs +2711 -1684
  379. package/dist/client/{context-C8TinPJc.mjs → context-DFmaZa-Q.mjs} +4 -3
  380. package/dist/client/{dates-vwwxTeB0.mjs → dates-BBep1JnF.mjs} +56 -11
  381. package/dist/client/{eventCalendar-DIbHfJXO.mjs → eventCalendar-zEobhxo4.mjs} +9 -9
  382. package/dist/client/{eventCombined-DoGMJ6cg.mjs → eventCombined-Dp7bz5k-.mjs} +4 -4
  383. package/dist/client/{eventDetails-BjN9v6a1.mjs → eventDetails-FE-zqTt7.mjs} +4 -4
  384. package/dist/client/{eventListing-DajjWgOv.mjs → eventListing-BMt5snal.mjs} +4 -4
  385. package/dist/client/{eventRegistration-DMq9gMA-.mjs → eventRegistration-O6ZxHfOb.mjs} +422 -570
  386. package/dist/client/{form-Qf6qTbos.mjs → form-DFa1D8vt.mjs} +3 -3
  387. package/dist/client/{headerSection-D7qJrqFX.mjs → headerSection-CmjHLR-N.mjs} +3 -3
  388. package/dist/client/hooks.mjs +414 -182
  389. package/dist/client/{locationMap-CCF9-t_0.mjs → locationMap-BXKP_lGh.mjs} +3 -3
  390. package/dist/client/{media-CwBGetqC.mjs → media-Cl38iOMI.mjs} +10 -3
  391. package/dist/client/{newsletterForm-DzCLSP4S.mjs → newsletterForm-CU-HmxGx.mjs} +3 -3
  392. package/dist/client/{pricing-Cgxv2KLC.mjs → pricing-KEAEsibq.mjs} +1 -1
  393. package/dist/client/{productDetail-ru9w5GHx.mjs → productDetail-Ckp7MGnt.mjs} +3 -3
  394. package/dist/client/{productList-zaapKSl-.mjs → productList-D91V0sYa.mjs} +3 -3
  395. package/dist/client/{propsDecoder-CwvvNOHx.mjs → propsDecoder-DZd6RJeA.mjs} +244 -94
  396. package/dist/client/rendering/client.mjs +2656 -1705
  397. package/dist/client/rendering/islands.mjs +18 -18
  398. package/dist/client/rendering.mjs +3430 -2352
  399. package/dist/client/{routeIslandApiConfig-BwVFo0Y4.mjs → routeIslandApiConfig-E1EkhhYY.mjs} +1 -1
  400. package/dist/client/{shop-mktkXvbV.mjs → shop-4F2jLQPI.mjs} +131 -85
  401. package/dist/client/{shop-commerce-De7gEnkA.mjs → shop-commerce-BbfCJjB3.mjs} +25 -13
  402. package/dist/client/{shop-commerce-store-B3MCxIBW.mjs → shop-commerce-store-vicweP2K.mjs} +1 -1
  403. package/dist/client/{shopShared-TqExh235.mjs → shopShared-DlONJt0T.mjs} +4 -4
  404. package/dist/client/{useEventFilters-n_OjkIjX.mjs → useEventFilters-COYyL3m7.mjs} +32 -17
  405. package/dist/preview-next/before-render.mjs +207 -105
  406. package/dist/preview-next/client/runtime.mjs +4 -4
  407. package/dist/preview-next/constants.mjs +5 -1
  408. package/dist/preview-next/index.mjs +5 -1
  409. package/dist/preview-next/keepAlive.mjs +341 -165
  410. package/dist/preview-next/middleware.mjs +207 -105
  411. package/dist/{previewAuthStore-C_EHQ5XA.mjs → previewAuthStore-BBmV7UsW.mjs} +243 -112
  412. package/dist/{sdk-runtime-BIkJg5y1.mjs → sdk-runtime-CwvFFjB-.mjs} +2 -2
  413. package/dist/{separator-C9qDP95Z.mjs → separator-ByL72zUT.mjs} +1 -1
  414. package/dist/server/components.mjs +1839 -1475
  415. package/dist/server/config-validation.mjs +381 -166
  416. package/dist/server/config.mjs +381 -166
  417. package/dist/server/data.mjs +381 -166
  418. package/dist/server/index.mjs +214 -110
  419. package/dist/server/next.mjs +663 -351
  420. package/dist/server/page-converter.mjs +198 -79
  421. package/dist/server/prebuild.mjs +1 -1
  422. package/dist/server/rendering/server.mjs +1536 -1169
  423. package/dist/server/rendering.mjs +2432 -2068
  424. package/dist/server/routing.mjs +456 -173
  425. package/dist/server/server.mjs +447 -267
  426. package/package.json +1 -1
  427. package/dist/_dts/api/src/bookingPaymentTermSchemas.d.ts +0 -123
  428. package/dist/_dts/billing/src/plans/display.d.ts +0 -15
  429. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.mailing-list-note.d.ts +0 -3
  430. package/dist/_dts/commerce/src/purchase/checkoutPaymentTermPlanning.d.ts +0 -10
  431. package/dist/_dts/commerce/src/purchase/checkoutValidatedItemPlanning.d.ts +0 -55
  432. package/dist/_dts/commerce/src/purchase/orderInstalmentPayoff.d.ts +0 -24
  433. package/dist/_dts/content-editor/src/controller/buildBlockPublishedBaselines.d.ts +0 -4
  434. package/dist/_dts/content-editor/src/controller/buildPublishSuccessTransition.d.ts +0 -16
  435. package/dist/_dts/content-editor/src/controller/driver.d.ts +0 -14
  436. package/dist/_dts/content-editor/src/controller/seedDraftBaselinesFromBlocks.d.ts +0 -7
  437. package/dist/_dts/content-editor/src/controller/useEntrySyncHelpers.d.ts +0 -29
  438. package/dist/_dts/content-editor/src/hooks/autosaveScopePlanning.d.ts +0 -26
  439. package/dist/_dts/content-editor/src/hooks/useSimpleAutosave.d.ts +0 -64
  440. package/dist/_dts/content-editor/src/hooks/useStoreAutosave.d.ts +0 -48
  441. package/dist/_dts/content-editor/src/types.d.ts +0 -44
  442. package/dist/client/DiscountCodeDisclosure-CKJtz0mY.mjs +0 -137
@@ -62,6 +62,19 @@ const CURRENCY_LOCALE_BY_CODE = {
62
62
  function resolveCurrencyLocale(currencyCode, override) {
63
63
  return override ?? CURRENCY_LOCALE_BY_CODE[currencyCode] ?? "en";
64
64
  }
65
+ function fractionDigitsFor(decimals, exactFormatter) {
66
+ switch (decimals) {
67
+ case "exact": return {};
68
+ case "auto": return {
69
+ minimumFractionDigits: 0,
70
+ maximumFractionDigits: exactFormatter.resolvedOptions().maximumFractionDigits
71
+ };
72
+ case "whole": return {
73
+ minimumFractionDigits: 0,
74
+ maximumFractionDigits: 0
75
+ };
76
+ }
77
+ }
65
78
  /**
66
79
  * The single currency-amount formatter for the product: minor units in,
67
80
  * localized string out.
@@ -72,6 +85,13 @@ function resolveCurrencyLocale(currencyCode, override) {
72
85
  * own `Intl.NumberFormat`.
73
86
  */
74
87
  function formatCurrencyAmount(amountCents, currency, options) {
88
+ return formatCurrencyMajorUnits(amountCents / 100, currency, options);
89
+ }
90
+ /**
91
+ * `formatCurrencyAmount` for an amount already in MAJOR units (29.99 = £29.99),
92
+ * such as a registrar price. Prefer minor units everywhere else.
93
+ */
94
+ function formatCurrencyMajorUnits(amount, currency, options) {
75
95
  const currencyCode = currency.toUpperCase();
76
96
  const locale = resolveCurrencyLocale(currencyCode, options?.locale);
77
97
  try {
@@ -79,17 +99,13 @@ function formatCurrencyAmount(amountCents, currency, options) {
79
99
  style: "currency",
80
100
  currency: currencyCode
81
101
  });
82
- const fractionDigits = options?.decimals === "auto" ? {
83
- minimumFractionDigits: 0,
84
- maximumFractionDigits: exactFormatter.resolvedOptions().maximumFractionDigits
85
- } : {};
86
102
  return new Intl.NumberFormat(locale, {
87
103
  style: "currency",
88
104
  currency: currencyCode,
89
- ...fractionDigits
90
- }).format(amountCents / 100);
105
+ ...fractionDigitsFor(options?.decimals ?? "exact", exactFormatter)
106
+ }).format(amount);
91
107
  } catch {
92
- return `${(amountCents / 100).toFixed(2)} ${currencyCode}`;
108
+ return `${amount.toFixed(2)} ${currencyCode}`;
93
109
  }
94
110
  }
95
111
  /** Default clock for production callers that do not inject time explicitly. */
@@ -373,6 +389,16 @@ function isRecord$41(value) {
373
389
  return typeof value === "object" && value !== null && !Array.isArray(value);
374
390
  }
375
391
  //#endregion
392
+ //#region ../core/src/booking-payment-options.ts
393
+ /** Automatic instalments and a flexible balance cannot share one booking offer. */
394
+ function validateBookingPaymentOptionKinds(kinds) {
395
+ if (kinds.length === 0) return err$3("no_options");
396
+ const uniqueKinds = new Set(kinds);
397
+ if (uniqueKinds.size !== kinds.length) return err$3("duplicate_kind");
398
+ if (uniqueKinds.has("instalment_plan") && uniqueKinds.has("flexible_balance")) return err$3("incompatible_collection_options");
399
+ return ok$3(void 0);
400
+ }
401
+ //#endregion
376
402
  //#region ../core/src/booking-time-zone.ts
377
403
  const TIME_ZONE_VALIDITY_CACHE_LIMIT = 100;
378
404
  const timeZoneValidityCache = /* @__PURE__ */ new Map();
@@ -680,6 +706,26 @@ function toLocationCoordinates(value) {
680
706
  };
681
707
  }
682
708
  //#endregion
709
+ //#region ../core/src/block-content-identity.ts
710
+ function readContentVersionId(value) {
711
+ const parsed = parseContentVersionId(value);
712
+ return parsed.ok ? parsed.value : null;
713
+ }
714
+ /** The one pairing of a published id with its content. */
715
+ function readPublishedBlockPlacement(id, content) {
716
+ if (id == null && content == null) return null;
717
+ const versionId = readContentVersionId(id);
718
+ return versionId !== null && content != null ? {
719
+ kind: "published",
720
+ id: versionId,
721
+ content
722
+ } : {
723
+ kind: "incomplete",
724
+ id: id ?? null,
725
+ content: content ?? null
726
+ };
727
+ }
728
+ //#endregion
683
729
  //#region ../core/src/rich-text.ts
684
730
  function isRecord$39(value) {
685
731
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -1657,11 +1703,18 @@ function isReservedPathSegment(value) {
1657
1703
  function isUnsafePathSegment$1(segment) {
1658
1704
  return segment.trim().length === 0 || segment !== segment.trim() || isReservedPathSegment(segment) || containsUnsafePathSegmentCharacter(segment);
1659
1705
  }
1660
- ({
1706
+ //#endregion
1707
+ //#region ../media-core/src/fileStorage.ts
1708
+ const FILE_STORAGE_BUCKETS = {
1661
1709
  publicSite: unsafeAsStorageBucketName("media"),
1662
1710
  privateSite: unsafeAsStorageBucketName("site-files-private"),
1663
- temporary: unsafeAsStorageBucketName("temp-uploads")
1664
- }).publicSite;
1711
+ temporary: unsafeAsStorageBucketName("temp-uploads"),
1712
+ siteAssets: unsafeAsStorageBucketName("site-assets"),
1713
+ siteFonts: unsafeAsStorageBucketName("site-fonts"),
1714
+ bookingRequirementDocuments: unsafeAsStorageBucketName("booking-requirement-documents")
1715
+ };
1716
+ FILE_STORAGE_BUCKETS.publicSite, FILE_STORAGE_BUCKETS.siteAssets, FILE_STORAGE_BUCKETS.siteFonts;
1717
+ FILE_STORAGE_BUCKETS.publicSite, FILE_STORAGE_BUCKETS.privateSite, FILE_STORAGE_BUCKETS.temporary, FILE_STORAGE_BUCKETS.siteAssets, FILE_STORAGE_BUCKETS.siteFonts, FILE_STORAGE_BUCKETS.bookingRequirementDocuments;
1665
1718
  function parseStoragePath(value) {
1666
1719
  return joinStoragePathSegments(value.split("/"));
1667
1720
  }
@@ -29471,68 +29524,113 @@ function createRichTextDoc(paragraphs) {
29471
29524
  };
29472
29525
  }
29473
29526
  //#endregion
29474
- //#region ../blocks/src/system/blocks/shared/bookingPaymentTerms.ts
29475
- const bookingDepositRefundPolicySchema$1 = z$1.enum(["refundable", "non_refundable"]);
29476
- const bookingInstalmentPlanSchema$1 = z$1.union([
29477
- z$1.object({
29478
- kind: z$1.literal("deposit_plus_one_remainder"),
29479
- depositAmountCents: z$1.number().int().min(0),
29480
- depositRefundability: bookingDepositRefundPolicySchema$1,
29481
- remainderDueCount: z$1.number().int().positive(),
29482
- intervalUnit: z$1.enum([
29483
- "day",
29484
- "week",
29485
- "month"
29486
- ])
29487
- }),
29488
- z$1.object({
29489
- kind: z$1.literal("deposit_plus_scheduled_instalments"),
29490
- depositAmountCents: z$1.number().int().min(0),
29491
- depositRefundability: bookingDepositRefundPolicySchema$1,
29492
- instalmentCount: z$1.number().int().positive(),
29493
- intervalCount: z$1.number().int().positive(),
29494
- intervalUnit: z$1.enum([
29495
- "day",
29496
- "week",
29497
- "month"
29498
- ])
29499
- }),
29500
- z$1.object({
29501
- kind: z$1.literal("equal_scheduled_instalments"),
29502
- instalmentCount: z$1.number().int().positive(),
29503
- intervalCount: z$1.number().int().positive(),
29504
- intervalUnit: z$1.enum([
29505
- "day",
29506
- "week",
29507
- "month"
29508
- ])
29509
- })
29510
- ]);
29511
- const bookingFlexibleBalanceDueDateRuleSchema$1 = z$1.union([z$1.object({
29512
- kind: z$1.literal("relative_to_start_date"),
29513
- daysBeforeStart: z$1.number().int().positive()
29514
- }), z$1.object({
29515
- kind: z$1.literal("fixed_calendar_date"),
29516
- dueAt: z$1.string().datetime()
29517
- })]);
29518
- const bookingFlexibleBalanceConfigSchema$1 = z$1.object({
29519
- upfrontAmountCents: z$1.number().int().min(0),
29520
- dueDateRule: bookingFlexibleBalanceDueDateRuleSchema$1,
29521
- depositRefundability: bookingDepositRefundPolicySchema$1
29522
- });
29523
- const blockBookingPaymentCollectionOptionSchema = z$1.union([
29524
- z$1.object({ kind: z$1.literal("upfront") }),
29525
- z$1.object({ kind: z$1.literal("deferred_manual") }),
29526
- z$1.object({
29527
- kind: z$1.literal("instalment_plan"),
29528
- plan: bookingInstalmentPlanSchema$1
29529
- }),
29530
- z$1.object({
29531
- kind: z$1.literal("flexible_balance"),
29532
- config: bookingFlexibleBalanceConfigSchema$1
29533
- })
29527
+ //#region ../core/src/booking-payment-schemas.ts
29528
+ const stripObject = (shape) => z$1.object(shape);
29529
+ const strictObject = (shape) => z$1.strictObject(shape);
29530
+ const depositRefundPolicySchema = z$1.enum(["refundable", "non_refundable"]);
29531
+ const intervalUnitSchema = z$1.enum([
29532
+ "day",
29533
+ "week",
29534
+ "month"
29534
29535
  ]);
29535
- const blockBookingPaymentTermsSchema = z$1.object({ allowedOptions: z$1.array(blockBookingPaymentCollectionOptionSchema).min(1) });
29536
+ const nonNegativeIntegerSchema = z$1.number().int().nonnegative();
29537
+ const positiveIntegerSchema = z$1.number().int().positive();
29538
+ function createInstalmentPlanSchema(object) {
29539
+ return z$1.discriminatedUnion("kind", [
29540
+ object({
29541
+ kind: z$1.literal("deposit_plus_one_remainder"),
29542
+ depositAmountCents: nonNegativeIntegerSchema,
29543
+ depositRefundability: depositRefundPolicySchema,
29544
+ remainderDueCount: positiveIntegerSchema,
29545
+ intervalUnit: intervalUnitSchema
29546
+ }),
29547
+ object({
29548
+ kind: z$1.literal("deposit_plus_scheduled_instalments"),
29549
+ depositAmountCents: nonNegativeIntegerSchema,
29550
+ depositRefundability: depositRefundPolicySchema,
29551
+ instalmentCount: positiveIntegerSchema,
29552
+ intervalCount: positiveIntegerSchema,
29553
+ intervalUnit: intervalUnitSchema
29554
+ }),
29555
+ object({
29556
+ kind: z$1.literal("equal_scheduled_instalments"),
29557
+ instalmentCount: positiveIntegerSchema,
29558
+ intervalCount: positiveIntegerSchema,
29559
+ intervalUnit: intervalUnitSchema
29560
+ })
29561
+ ]);
29562
+ }
29563
+ function createFlexibleBalanceSchemas(object) {
29564
+ const dueDateRule = z$1.discriminatedUnion("kind", [object({
29565
+ kind: z$1.literal("relative_to_start_date"),
29566
+ daysBeforeStart: positiveIntegerSchema
29567
+ }), object({
29568
+ kind: z$1.literal("fixed_calendar_date"),
29569
+ dueAt: z$1.string().datetime()
29570
+ })]);
29571
+ return {
29572
+ dueDateRule,
29573
+ config: object({
29574
+ upfrontAmountCents: nonNegativeIntegerSchema,
29575
+ dueDateRule,
29576
+ depositRefundability: depositRefundPolicySchema
29577
+ })
29578
+ };
29579
+ }
29580
+ const paymentOptionKindsMessages = {
29581
+ no_options: "Choose at least one way for customers to pay.",
29582
+ duplicate_kind: "Choose each payment option only once.",
29583
+ incompatible_collection_options: "Offer instalments or a deposit with the rest paid later, but not both."
29584
+ };
29585
+ function buildBookingPaymentOptionSchemas(object) {
29586
+ const instalmentPlan = createInstalmentPlanSchema(object);
29587
+ const flexibleBalance = createFlexibleBalanceSchemas(object);
29588
+ const paymentCollectionOption = z$1.discriminatedUnion("kind", [
29589
+ object({ kind: z$1.literal("upfront") }),
29590
+ object({ kind: z$1.literal("deferred_manual") }),
29591
+ object({
29592
+ kind: z$1.literal("instalment_plan"),
29593
+ plan: instalmentPlan
29594
+ }),
29595
+ object({
29596
+ kind: z$1.literal("flexible_balance"),
29597
+ config: flexibleBalance.config
29598
+ })
29599
+ ]);
29600
+ const paymentTerms = object({ allowedOptions: z$1.array(paymentCollectionOption) }).superRefine(({ allowedOptions }, ctx) => {
29601
+ const result = validateBookingPaymentOptionKinds(allowedOptions.map(({ kind }) => kind));
29602
+ if (!result.ok) ctx.addIssue({
29603
+ code: "custom",
29604
+ path: ["allowedOptions"],
29605
+ message: paymentOptionKindsMessages[result.error]
29606
+ });
29607
+ });
29608
+ const paymentOptionsChoice = z$1.discriminatedUnion("source", [z$1.strictObject({ source: z$1.literal("default") }), z$1.strictObject({
29609
+ source: z$1.literal("custom"),
29610
+ paymentTerms
29611
+ })]);
29612
+ return {
29613
+ depositRefundPolicy: depositRefundPolicySchema,
29614
+ instalmentPlan,
29615
+ flexibleBalanceDueDateRule: flexibleBalance.dueDateRule,
29616
+ flexibleBalanceConfig: flexibleBalance.config,
29617
+ paymentCollectionOption,
29618
+ paymentTerms,
29619
+ paymentOptionsChoice
29620
+ };
29621
+ }
29622
+ function createBookingPaymentOptionSchemas(mode) {
29623
+ return mode === "strict" ? buildBookingPaymentOptionSchemas(strictObject) : buildBookingPaymentOptionSchemas(stripObject);
29624
+ }
29625
+ const bookingPaymentOptionSchemas = createBookingPaymentOptionSchemas("strip");
29626
+ bookingPaymentOptionSchemas.depositRefundPolicy;
29627
+ bookingPaymentOptionSchemas.instalmentPlan;
29628
+ bookingPaymentOptionSchemas.flexibleBalanceDueDateRule;
29629
+ bookingPaymentOptionSchemas.flexibleBalanceConfig;
29630
+ bookingPaymentOptionSchemas.paymentCollectionOption;
29631
+ const bookingPaymentTermsSchema = bookingPaymentOptionSchemas.paymentTerms;
29632
+ bookingPaymentOptionSchemas.paymentOptionsChoice;
29633
+ const blockBookingPaymentTermsSchema = bookingPaymentTermsSchema;
29536
29634
  const blockBookingConsentSchema = z$1.object({
29537
29635
  requirementId: z$1.string(),
29538
29636
  title: z$1.string(),
@@ -29776,7 +29874,6 @@ const publicEventBaseSchema = z$1.object({
29776
29874
  description: z$1.string().nullable(),
29777
29875
  content: z$1.object({ body: RichTextDocSchema.nullable().optional() }).optional(),
29778
29876
  presentation: z$1.object({
29779
- cardTitleOverride: z$1.string().nullable().optional(),
29780
29877
  summary: z$1.string().nullable().optional(),
29781
29878
  image: mediaSchema.nullable().optional()
29782
29879
  }).optional(),
@@ -29809,6 +29906,7 @@ const publicEventBaseSchema = z$1.object({
29809
29906
  "archived"
29810
29907
  ]).optional(),
29811
29908
  timeZone: z$1.string(),
29909
+ siteTimeZone: z$1.string().optional(),
29812
29910
  pricing: publicEventPricingSchema,
29813
29911
  paymentTerms: blockBookingPaymentTermsSchema,
29814
29912
  cancellationPolicy: z$1.object({ refunds: z$1.object({
@@ -30500,6 +30598,13 @@ const STRUCTURED_KEYS = /* @__PURE__ */ new Set([
30500
30598
  "domainOperationProvider",
30501
30599
  "domainOperationError",
30502
30600
  "domainOperationMetadata",
30601
+ "previewDecision",
30602
+ "previewOutcome",
30603
+ "previewTokenTtlBucket",
30604
+ "previewRefreshCookiePresent",
30605
+ "previewDashboardStatus",
30606
+ "previewProviderResult",
30607
+ "previewUpstreamStatus",
30503
30608
  "durationMs",
30504
30609
  "duration",
30505
30610
  "status",
@@ -33795,6 +33900,7 @@ const bookingMailingListContextSchema = z$1.unknown().transform((value) => {
33795
33900
  return parsed.ok ? parsed.value : void 0;
33796
33901
  });
33797
33902
  const bookingSourceSchema = z$1.object({
33903
+ demoEmailSuppressed: z$1.boolean().optional(),
33798
33904
  mailingList: bookingMailingListContextSchema.optional(),
33799
33905
  siteName: z$1.string().optional(),
33800
33906
  siteId: z$1.string().optional(),
@@ -33825,6 +33931,7 @@ const bookingDisplaySchema = z$1.object({
33825
33931
  message: z$1.string().nullable()
33826
33932
  });
33827
33933
  const bookingHydrationSchema = z$1.object({
33934
+ demoEmailSuppressed: z$1.boolean().optional(),
33828
33935
  mailingList: bookingMailingListContextSchema.optional(),
33829
33936
  siteName: z$1.string().optional(),
33830
33937
  formId: z$1.string().nullable(),
@@ -33872,6 +33979,7 @@ const bookingFormBlockRuntime = defineClientOwnedBlockRuntime({
33872
33979
  return {
33873
33980
  display: buildBookingFormDisplay(source, form),
33874
33981
  hydration: {
33982
+ demoEmailSuppressed: source.demoEmailSuppressed,
33875
33983
  mailingList: source.mailingList,
33876
33984
  siteName: source.siteName,
33877
33985
  formId: form?.id ?? source.formId ?? null,
@@ -34708,6 +34816,44 @@ function resolveEventCta(event, buttonText) {
34708
34816
  * timestamps become strings or date buckets. Calendar-grid primitives are
34709
34817
  * re-exported from @riverbankcms/calendar so block code has one import.
34710
34818
  */
34819
+ /**
34820
+ * The English locale a site's public dates are written in, read from the
34821
+ * site's own time zone (Will, 2026-09-26: "date style from site time zone").
34822
+ *
34823
+ * Sites don't store a locale, and every public word around a date is English,
34824
+ * so the only open question is which English conventions to follow: day or
34825
+ * month first, and a 24 or 12-hour clock. The site's time zone is the one
34826
+ * fact every site carries about where it is. It is the site's, never an
34827
+ * event's: a venue left at UTC must not turn a UK site's dates American.
34828
+ * Anywhere this can't place (UTC, the Americas, Asia) keeps US English, which
34829
+ * is what these helpers wrote before sites were placed at all.
34830
+ */
34831
+ function eventDateLocale(siteTimeZone) {
34832
+ if (!siteTimeZone) return "en-US";
34833
+ if (siteTimeZone === "Europe/Dublin") return "en-IE";
34834
+ if (siteTimeZone.startsWith("Europe/")) return "en-GB";
34835
+ if (siteTimeZone.startsWith("Australia/")) return "en-AU";
34836
+ if (siteTimeZone === "Pacific/Auckland" || siteTimeZone === "Pacific/Chatham") return "en-NZ";
34837
+ return "en-US";
34838
+ }
34839
+ /**
34840
+ * Formatting options for an event's dates: the times in the event's own zone,
34841
+ * written in its site's locale. A record from an older server that doesn't
34842
+ * name the site's zone falls back to the event's.
34843
+ */
34844
+ function eventDateOptions(place) {
34845
+ return {
34846
+ timeZone: place.timeZone ?? null,
34847
+ locale: eventDateLocale(place.siteTimeZone ?? place.timeZone)
34848
+ };
34849
+ }
34850
+ /**
34851
+ * Start and end times as cards write them, in the site's locale:
34852
+ * "10:00 to 16:00" in the UK, "10:00 AM to 4:00 PM" in the US.
34853
+ */
34854
+ function formatEventTimeRange$1(times, options) {
34855
+ return `${formatTime(times.startsAt, options)} to ${formatTime(times.endsAt, options)}`;
34856
+ }
34711
34857
  /** Use the event timezone when present, otherwise the calendar/site timezone. */
34712
34858
  function resolveEventTimeZone(event, calendarTimeZone) {
34713
34859
  return event.timeZone || calendarTimeZone;
@@ -34729,18 +34875,25 @@ function formatDate$2(isoTimestamp, options) {
34729
34875
  });
34730
34876
  }
34731
34877
  /**
34732
- * Format time for display.
34733
- * Returns: "10:00 AM"
34878
+ * Whether the locale reads a 24-hour clock, where hours are written with two
34879
+ * digits ("09:00"), as the dashboard writes them.
34880
+ */
34881
+ function usesTwentyFourHourClock(locale) {
34882
+ return new Intl.DateTimeFormat(locale, { hour: "numeric" }).resolvedOptions().hour12 === false;
34883
+ }
34884
+ /**
34885
+ * Format time for display, on the locale's own clock.
34886
+ * Returns: "9:00 AM" (en-US) or "09:00" (en-GB)
34734
34887
  */
34735
34888
  function formatTime(isoTimestamp, options) {
34889
+ const locale = options?.locale ?? "en-US";
34736
34890
  return formatBookingTime(toScheduledBookingDateTime({
34737
34891
  startsAt: isoTimestamp,
34738
34892
  timeZone: toBookingTimeZone(options?.timeZone ?? "UTC"),
34739
- locale: options?.locale ?? "en-US"
34893
+ locale
34740
34894
  }), {
34741
- hour: "numeric",
34742
- minute: "2-digit",
34743
- hour12: true
34895
+ hour: usesTwentyFourHourClock(locale) ? "2-digit" : "numeric",
34896
+ minute: "2-digit"
34744
34897
  });
34745
34898
  }
34746
34899
  function formatEventDateParts(args) {
@@ -34772,7 +34925,7 @@ function formatEventCompactDateRail(isoTimestamp, options) {
34772
34925
  locale: options?.locale ?? "en-US"
34773
34926
  });
34774
34927
  const weekday = formatBookingDate(dateTime, { weekday: "short" }).toLocaleUpperCase(options?.locale ?? "en-US");
34775
- const month = formatBookingDate(dateTime, { month: "short" }).toLocaleUpperCase(options?.locale ?? "en-US");
34928
+ const month = formatBookingDate(dateTime, { month: "short" }).slice(0, 3).toLocaleUpperCase(options?.locale ?? "en-US");
34776
34929
  return {
34777
34930
  weekday,
34778
34931
  day: formatBookingDate(dateTime, { day: "numeric" }),
@@ -34792,7 +34945,7 @@ function formatEventCompactDateRail(isoTimestamp, options) {
34792
34945
  * keep the fact panel on the same date and timezone rules as event rows.
34793
34946
  */
34794
34947
  function formatEventNextDateFact(event) {
34795
- const rail = formatEventCompactDateRail(event.startsAt, { timeZone: event.timeZone });
34948
+ const rail = formatEventCompactDateRail(event.startsAt, eventDateOptions(event));
34796
34949
  return {
34797
34950
  dateTime: event.startsAt,
34798
34951
  value: `${rail.weekday} ${rail.day} ${rail.month}`,
@@ -35639,6 +35792,13 @@ function CalendarIcon({ className, size = 16, strokeWidth = 2 }) {
35639
35792
  }
35640
35793
  //#endregion
35641
35794
  //#region ../blocks/src/system/runtime/nodes/events/shared/EventCard.tsx
35795
+ /** The category's badge, when the event has a category. */
35796
+ function eventCardCategoryBadge(category) {
35797
+ return category ? {
35798
+ label: category.name,
35799
+ style: getCategoryBadgeStyle(category.color ?? null)
35800
+ } : null;
35801
+ }
35642
35802
  /**
35643
35803
  * EventCard Component
35644
35804
  *
@@ -35647,24 +35807,19 @@ function CalendarIcon({ className, size = 16, strokeWidth = 2 }) {
35647
35807
  *
35648
35808
  * This component is server-safe (uses no client APIs like Intl).
35649
35809
  */
35650
- const EventCard = ({ event, cardRole = "default", buttonVariant = "primary", buttonText, showVenue = true, showMap = true, mapSlot, allowMap = true, showCapacity = true, showImage = true, showCategory = true, showSummary = true, orientation = "vertical", presentation, headingLevel }) => {
35810
+ const EventCard = ({ event, cardRole = "default", buttonVariant = "primary", buttonText, showVenue = true, showMap = true, mapSlot, allowMap = true, showCapacity = true, showImage = true, showCategory = true, showSummary = true, orientation = "vertical", presentation, headingLevel, imageResolveContext }) => {
35651
35811
  const { presentation: cardPresentation, presentationClass, headingLevel: cardHeadingLevel } = resolveEventCardOptions({
35652
35812
  presentation,
35653
35813
  headingLevel
35654
35814
  });
35655
- const timeZone = event.timeZone ?? null;
35656
- const formattedDate = formatDate$2(event.startsAt, { timeZone });
35657
- const formattedTime = `${formatTime(event.startsAt, { timeZone })} - ${formatTime(event.endsAt, { timeZone })}`;
35815
+ const { formattedDate, formattedTime } = formatEventCardWhen(event);
35658
35816
  const cta = resolveEventCta(event, buttonText);
35659
35817
  const cardClass = boxStyleClassNames({ role: cardRole }, { baseClass: "event-card" });
35660
35818
  const title = event.title;
35661
35819
  const summary = event.presentation?.summary ?? event.description;
35662
35820
  const image = event.presentation?.image ?? null;
35663
35821
  const category = event.eventCategory;
35664
- const categoryBadge = category && showCategory ? {
35665
- label: category.name,
35666
- style: getCategoryBadgeStyle(category.color ?? null)
35667
- } : null;
35822
+ const categoryBadge = showCategory ? eventCardCategoryBadge(category) : null;
35668
35823
  const hasImage = Boolean(showImage && image);
35669
35824
  const dateFact = resolveEventCardDateFact({
35670
35825
  event,
@@ -35683,7 +35838,8 @@ const EventCard = ({ event, cardRole = "default", buttonVariant = "primary", but
35683
35838
  categoryId: category?.id,
35684
35839
  dateFact,
35685
35840
  hasImage,
35686
- image
35841
+ image,
35842
+ imageResolveContext
35687
35843
  }), /* @__PURE__ */ jsx(EventCardContent, {
35688
35844
  allowMap,
35689
35845
  buttonVariant,
@@ -35731,7 +35887,8 @@ function EventCardMedia(props) {
35731
35887
  /* @__PURE__ */ jsx(MediaNodeServer, {
35732
35888
  value: props.image,
35733
35889
  className: "event-card-image",
35734
- size: ImagePresets$1.card
35890
+ size: ImagePresets$1.card,
35891
+ imageResolveContext: props.imageResolveContext
35735
35892
  }),
35736
35893
  props.categoryBadge && /* @__PURE__ */ jsx("span", {
35737
35894
  className: "event-category-badge event-category-badge--overlay",
@@ -35846,6 +36003,17 @@ function resolveEventCardOptions(props) {
35846
36003
  headingLevel: props.headingLevel ?? 3
35847
36004
  };
35848
36005
  }
36006
+ /**
36007
+ * The card's date and times, written the way the event's place writes them
36008
+ * ("Friday, 16 October 2026" and "10:00 to 16:00" in the UK).
36009
+ */
36010
+ function formatEventCardWhen(event) {
36011
+ const options = eventDateOptions(event);
36012
+ return {
36013
+ formattedDate: formatDate$2(event.startsAt, options),
36014
+ formattedTime: formatEventTimeRange$1(event, options)
36015
+ };
36016
+ }
35849
36017
  function resolveEventCardDateFact(props) {
35850
36018
  if (!props.showImage || props.image || props.presentation !== "catalogue") return null;
35851
36019
  return formatEventNextDateFact(props.event);
@@ -37283,6 +37451,34 @@ function buildEventCombinedInteractiveIslandProps(props) {
37283
37451
  });
37284
37452
  }
37285
37453
  //#endregion
37454
+ //#region ../blocks/src/system/runtime/nodes/events/shared/eventCardPresentations.ts
37455
+ /** A booking page's catalogue card: one per series, "See dates" for dated events. */
37456
+ function catalogueEventCardProps(event, buttonVariant = "primary") {
37457
+ return {
37458
+ presentation: "catalogue",
37459
+ headingLevel: 4,
37460
+ buttonVariant,
37461
+ buttonText: event.bookingScope === "single_occurrence" ? "See dates" : void 0,
37462
+ showMap: false,
37463
+ allowMap: false,
37464
+ showCategory: false,
37465
+ orientation: "vertical"
37466
+ };
37467
+ }
37468
+ /** An events listing's card, from the listing's display settings. */
37469
+ function listingEventCardProps(display) {
37470
+ return {
37471
+ cardRole: display.cardRole,
37472
+ buttonVariant: display.buttonVariant,
37473
+ buttonText: display.buttonText,
37474
+ showVenue: display.showVenue,
37475
+ showMap: display.showMap,
37476
+ allowMap: false,
37477
+ showCapacity: display.showCapacity,
37478
+ orientation: display.orientation
37479
+ };
37480
+ }
37481
+ //#endregion
37286
37482
  //#region ../blocks/src/system/runtime/nodes/events/shared/renderEventListItem.tsx
37287
37483
  /**
37288
37484
  * Shared SSR render function for event list items.
@@ -37299,14 +37495,7 @@ function renderEventListItem(event, display) {
37299
37495
  }, event.occurrenceId || event.id);
37300
37496
  return /* @__PURE__ */ jsx(EventCard, {
37301
37497
  event,
37302
- cardRole: display.cardRole,
37303
- buttonVariant: display.buttonVariant,
37304
- buttonText: display.buttonText,
37305
- showVenue: display.showVenue,
37306
- showMap: display.showMap,
37307
- allowMap: false,
37308
- showCapacity: display.showCapacity,
37309
- orientation: display.orientation
37498
+ ...listingEventCardProps(display)
37310
37499
  }, event.occurrenceId || event.id);
37311
37500
  }
37312
37501
  //#endregion
@@ -37712,14 +37901,7 @@ function OfferingsCatalogue(props) {
37712
37901
  style: { gridTemplateColumns: "repeat(auto-fill, minmax(min(100%, 18rem), 1fr))" },
37713
37902
  children: events.map((event) => /* @__PURE__ */ jsx(EventCard, {
37714
37903
  event,
37715
- presentation: "catalogue",
37716
- headingLevel: 4,
37717
- buttonVariant: props.buttonVariant ?? "primary",
37718
- buttonText: event.bookingScope === "single_occurrence" ? "See dates" : void 0,
37719
- showMap: false,
37720
- allowMap: false,
37721
- showCategory: false,
37722
- orientation: "vertical"
37904
+ ...catalogueEventCardProps(event, props.buttonVariant ?? "primary")
37723
37905
  }, event.seriesId))
37724
37906
  })]
37725
37907
  }, group.sourceKey))
@@ -38007,45 +38189,73 @@ function FeaturedOfferingSummary({ item }) {
38007
38189
  }
38008
38190
  function featuredSummaryDetails(item) {
38009
38191
  switch (item.kind) {
38010
- case "event": return formatFeaturedSummary(deriveEventScheduleSummary(item.event), item.event.venue?.name ?? null);
38192
+ case "event": return formatFeaturedSummary(deriveEventScheduleSummary(item.event), {
38193
+ venue: item.event.venue?.name ?? null,
38194
+ siteTimeZone: item.event.siteTimeZone
38195
+ });
38011
38196
  case "run": {
38012
38197
  const schedule = derivePreviewRunSchedule(item.run.run.sessions);
38013
- return schedule.kind === "scheduled" ? formatFeaturedSummary(schedule.summary, item.run.representative.venue?.name ?? null) : null;
38198
+ return schedule.kind === "scheduled" ? formatFeaturedSummary(schedule.summary, {
38199
+ venue: item.run.representative.venue?.name ?? null,
38200
+ siteTimeZone: item.run.representative.siteTimeZone
38201
+ }) : null;
38014
38202
  }
38015
38203
  default: return assertNever$21(item, "Unhandled offerings preview item");
38016
38204
  }
38017
38205
  }
38018
- function formatFeaturedSummary(summary, venue) {
38206
+ function formatFeaturedSummary(summary, place) {
38019
38207
  switch (summary.kind) {
38020
- case "single-occurrence": return detailsFromOccurrences(summary.occurrence, null, venue, null, null);
38021
- case "multi-day-span": return detailsFromOccurrences(summary.occurrence, summary.occurrence, venue, null, null, true);
38022
- case "fixed-recurring-run": return detailsFromOccurrences(summary.first, summary.last, venue, summary.recurrenceLabel, null);
38023
- case "irregular-multi-session-run": return detailsFromOccurrences(summary.first, summary.last, venue, null, `${summary.sessionCount} dates`);
38208
+ case "single-occurrence": return detailsFromOccurrences({
38209
+ first: summary.occurrence,
38210
+ last: null,
38211
+ place
38212
+ });
38213
+ case "multi-day-span": return detailsFromOccurrences({
38214
+ first: summary.occurrence,
38215
+ last: summary.occurrence,
38216
+ place,
38217
+ spanUsesEndDate: true
38218
+ });
38219
+ case "fixed-recurring-run": return detailsFromOccurrences({
38220
+ first: summary.first,
38221
+ last: summary.last,
38222
+ place,
38223
+ recurrence: summary.recurrenceLabel
38224
+ });
38225
+ case "irregular-multi-session-run": return detailsFromOccurrences({
38226
+ first: summary.first,
38227
+ last: summary.last,
38228
+ place,
38229
+ sessionCount: `${summary.sessionCount} dates`
38230
+ });
38024
38231
  default: return assertNever$21(summary, "Unhandled offerings preview schedule summary");
38025
38232
  }
38026
38233
  }
38027
- function detailsFromOccurrences(first, last, venue, recurrence, sessionCount, spanUsesEndDate = false) {
38028
- const endDateTime = spanUsesEndDate ? first.endsAt : last?.startsAt ?? first.startsAt;
38234
+ function detailsFromOccurrences(input) {
38235
+ const { first, last, place } = input;
38236
+ const endDateTime = input.spanUsesEndDate ? first.endsAt : last?.startsAt ?? first.startsAt;
38237
+ const options = eventDateOptions({
38238
+ timeZone: first.timeZone,
38239
+ siteTimeZone: place.siteTimeZone
38240
+ });
38241
+ const summaryDate = (isoTimestamp, timeZone) => formatSummaryDate(isoTimestamp, {
38242
+ timeZone,
38243
+ locale: options.locale
38244
+ });
38029
38245
  return {
38030
- startDate: formatSummaryDate(first.startsAt, first.timeZone),
38246
+ startDate: summaryDate(first.startsAt, first.timeZone),
38031
38247
  startDateTime: first.startsAt,
38032
- endDate: last ? formatSummaryDate(endDateTime, last.timeZone) : null,
38248
+ endDate: last ? summaryDate(endDateTime, last.timeZone) : null,
38033
38249
  endDateTime,
38034
- timeRange: `${formatTime(first.startsAt, {
38035
- timeZone: first.timeZone,
38036
- locale: "en-GB"
38037
- })} – ${formatTime(first.endsAt, {
38038
- timeZone: first.timeZone,
38039
- locale: "en-GB"
38040
- })}`,
38041
- recurrence,
38042
- sessionCount,
38043
- venue
38044
- };
38045
- }
38046
- function formatSummaryDate(isoTimestamp, timeZone) {
38047
- return new Intl.DateTimeFormat("en-GB", {
38048
- timeZone,
38250
+ timeRange: formatEventTimeRange$1(first, options),
38251
+ recurrence: input.recurrence ?? null,
38252
+ sessionCount: input.sessionCount ?? null,
38253
+ venue: place.venue
38254
+ };
38255
+ }
38256
+ function formatSummaryDate(isoTimestamp, options) {
38257
+ return new Intl.DateTimeFormat(options.locale, {
38258
+ timeZone: options.timeZone,
38049
38259
  weekday: "long",
38050
38260
  day: "numeric",
38051
38261
  month: "long",
@@ -38092,9 +38302,12 @@ function WholeSeriesRunCompactRow({ group, path, now }) {
38092
38302
  path
38093
38303
  });
38094
38304
  const { sessionCount: sessionsCount, firstSession } = schedule;
38095
- const timeZone = firstSession.timeZone;
38096
- const dateRail = formatEventCompactDateRail(firstSession.startsAt, { timeZone });
38097
- const timeRange = `${formatTime(firstSession.startsAt, { timeZone })} - ${formatTime(firstSession.endsAt, { timeZone })}`;
38305
+ const options = eventDateOptions({
38306
+ timeZone: firstSession.timeZone,
38307
+ siteTimeZone: group.representative.siteTimeZone
38308
+ });
38309
+ const dateRail = formatEventCompactDateRail(firstSession.startsAt, options);
38310
+ const timeRange = formatEventTimeRange$1(firstSession, options);
38098
38311
  const price = formatEventPriceDisplay(group.representative.pricing);
38099
38312
  const statusLabel = resolveWholeSeriesBookingPhase(group.run, now).kind === "open" ? null : "Registration closed";
38100
38313
  return /* @__PURE__ */ jsxs("article", {
@@ -38174,9 +38387,12 @@ function WholeSeriesRunFeatureCard({ group, now, path, buttonVariant, buttonText
38174
38387
  path
38175
38388
  });
38176
38389
  const { firstSession } = schedule;
38177
- const timeZone = firstSession.timeZone;
38178
- const formattedDate = formatEventCompactDateRail(firstSession.startsAt, { timeZone }).label;
38179
- const timeRange = `${formatTime(firstSession.startsAt, { timeZone })} - ${formatTime(firstSession.endsAt, { timeZone })}`;
38390
+ const options = eventDateOptions({
38391
+ timeZone: firstSession.timeZone,
38392
+ siteTimeZone: group.representative.siteTimeZone
38393
+ });
38394
+ const formattedDate = formatEventCompactDateRail(firstSession.startsAt, options).label;
38395
+ const timeRange = formatEventTimeRange$1(firstSession, options);
38180
38396
  const price = formatEventPriceDisplay(group.representative.pricing);
38181
38397
  const statusLabel = resolveWholeSeriesBookingPhase(group.run, now).kind === "open" ? null : "Registration closed";
38182
38398
  const description = group.representative.description;
@@ -38680,7 +38896,7 @@ const publicPassProductCollectionSchema = z$1.object({ passes: z$1.array(publicP
38680
38896
  /**
38681
38897
  * Public membership product for shop display
38682
38898
  */
38683
- const publicMembershipProductSchema = z$1.object({
38899
+ const publicMembershipProductFields = {
38684
38900
  id: z$1.string(),
38685
38901
  name: z$1.string(),
38686
38902
  description: z$1.string().nullable(),
@@ -38689,7 +38905,16 @@ const publicMembershipProductSchema = z$1.object({
38689
38905
  billingInterval: z$1.enum(["month", "year"]),
38690
38906
  eligibleCategoryIds: z$1.array(z$1.string()),
38691
38907
  eligibleCategoryNames: z$1.array(z$1.string())
38908
+ };
38909
+ const purchasablePublicMembershipProductSchema = z$1.object({
38910
+ ...publicMembershipProductFields,
38911
+ purchaseAvailability: z$1.literal("purchasable")
38692
38912
  });
38913
+ const publicMembershipProductSchema = z$1.discriminatedUnion("purchaseAvailability", [purchasablePublicMembershipProductSchema, z$1.object({
38914
+ ...publicMembershipProductFields,
38915
+ purchaseAvailability: z$1.literal("display_only"),
38916
+ unavailabilityReason: z$1.literal("online_payments_unavailable")
38917
+ })]);
38693
38918
  const publicMembershipProductCollectionSchema = z$1.object({ memberships: z$1.array(publicMembershipProductSchema) });
38694
38919
  //#endregion
38695
38920
  //#region ../blocks/src/system/blocks/products/shared.ts
@@ -38930,7 +39155,7 @@ function buildPassesMembershipsDisplay(options) {
38930
39155
  product: pass
38931
39156
  } : {
38932
39157
  kind: "unavailable",
38933
- label: "Online purchasing coming soon."
39158
+ label: "Online purchasing is unavailable."
38934
39159
  }
38935
39160
  };
38936
39161
  });
@@ -38940,7 +39165,14 @@ function buildPassesMembershipsDisplay(options) {
38940
39165
  description: options.showDescriptions ? membership.description : null,
38941
39166
  priceLabel: formatCommercePrice(membership.price, membership.currency),
38942
39167
  intervalLabel: formatInterval(membership.billingInterval),
38943
- actionLabel: options.membershipActionLabel
39168
+ action: membership.purchaseAvailability === "purchasable" ? {
39169
+ kind: "purchase",
39170
+ label: options.membershipActionLabel,
39171
+ product: membership
39172
+ } : {
39173
+ kind: "unavailable",
39174
+ label: "Online purchasing is unavailable."
39175
+ }
38944
39176
  }));
38945
39177
  return {
38946
39178
  kind: "passes-memberships",
@@ -39092,6 +39324,7 @@ const shopSourceSchema = z$1.object({
39092
39324
  memberships: z$1.array(publicMembershipProductSchema).nullable().optional(),
39093
39325
  products: z$1.array(publicProductSchema).nullable().optional(),
39094
39326
  siteId: z$1.string().optional(),
39327
+ demoEmailSuppressed: z$1.boolean().optional(),
39095
39328
  apiBaseUrl: z$1.string().optional(),
39096
39329
  readAuthority: browserReadAuthoritySchema.optional(),
39097
39330
  stage: previewStageSchema.optional()
@@ -39159,7 +39392,14 @@ const membershipCardDisplaySchema = z$1.object({
39159
39392
  description: z$1.string().nullable(),
39160
39393
  priceLabel: z$1.string(),
39161
39394
  intervalLabel: z$1.string(),
39162
- actionLabel: z$1.string()
39395
+ action: z$1.discriminatedUnion("kind", [z$1.object({
39396
+ kind: z$1.literal("purchase"),
39397
+ label: z$1.string(),
39398
+ product: purchasablePublicMembershipProductSchema
39399
+ }), z$1.object({
39400
+ kind: z$1.literal("unavailable"),
39401
+ label: z$1.string()
39402
+ })])
39163
39403
  });
39164
39404
  const passesMembershipsDisplaySchema = z$1.object({
39165
39405
  kind: z$1.literal("passes-memberships"),
@@ -39211,7 +39451,8 @@ const checkoutDisplaySchema = z$1.object({
39211
39451
  const passesMembershipsHydrationSchema = z$1.object({
39212
39452
  memberships: z$1.array(publicMembershipProductSchema),
39213
39453
  passPurchaseMode: z$1.enum(["add_to_cart", "buy_now"]),
39214
- buttonVariant: blockButtonRoleSchema
39454
+ buttonVariant: blockButtonRoleSchema,
39455
+ demoEmailSuppressed: z$1.boolean().optional()
39215
39456
  });
39216
39457
  const productListHydrationSchema = z$1.object({
39217
39458
  products: z$1.array(publicProductSchema),
@@ -39233,7 +39474,8 @@ const cartHydrationSchema = z$1.object({
39233
39474
  });
39234
39475
  const checkoutHydrationSchema = z$1.object({
39235
39476
  emptyStateText: z$1.string(),
39236
- submitButtonText: z$1.string()
39477
+ submitButtonText: z$1.string(),
39478
+ demoEmailSuppressed: z$1.boolean().optional()
39237
39479
  });
39238
39480
  const passesMembershipsRenderSchema = z$1.object({
39239
39481
  display: passesMembershipsDisplaySchema,
@@ -39292,7 +39534,8 @@ const shopBlockRuntime = defineProgressiveBlockRuntime({
39292
39534
  hydration: {
39293
39535
  memberships: source.showMemberships === false ? [] : source.memberships ?? [],
39294
39536
  passPurchaseMode,
39295
- buttonVariant: source.buttonVariant ?? "primary"
39537
+ buttonVariant: source.buttonVariant ?? "primary",
39538
+ demoEmailSuppressed: source.demoEmailSuppressed
39296
39539
  }
39297
39540
  };
39298
39541
  }
@@ -39385,7 +39628,8 @@ const checkoutBlockRuntime = defineClientOwnedBlockRuntime({
39385
39628
  }),
39386
39629
  hydration: {
39387
39630
  emptyStateText: source.emptyStateText ?? "Add something to your cart to continue.",
39388
- submitButtonText: source.submitButtonText ?? "Checkout"
39631
+ submitButtonText: source.submitButtonText ?? "Checkout",
39632
+ demoEmailSuppressed: source.demoEmailSuppressed
39389
39633
  }
39390
39634
  })
39391
39635
  });
@@ -39626,6 +39870,10 @@ const checkoutBlockDefinition = {
39626
39870
  baseClass: "",
39627
39871
  spacing: "spacious",
39628
39872
  children: sectionContainer([checkout(withApiBindings({
39873
+ demoEmailSuppressed: { $bind: {
39874
+ from: "$root.demoEmailSuppressed",
39875
+ fallback: false
39876
+ } },
39629
39877
  readAuthority: { $bind: { from: "$root.readAuthority" } },
39630
39878
  mode: "checkout",
39631
39879
  heading: { $bind: {
@@ -40034,6 +40282,7 @@ const EVENT_REGISTRATION_SHELL_STEP_LABELS = [
40034
40282
  ];
40035
40283
  const eventRegistrationPublicEventSchema = z$1.preprocess(normalizeEventRegistrationEventInput, publicEventSchema);
40036
40284
  const eventRegistrationHydrationSchemaShape = {
40285
+ demoEmailSuppressed: z$1.boolean().optional(),
40037
40286
  occurrenceContext: occurrenceContextSchema.optional(),
40038
40287
  subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
40039
40288
  maxTickets: z$1.string().optional(),
@@ -40214,6 +40463,7 @@ const eventRegistrationBlockRuntime = defineClientOwnedBlockRuntime({
40214
40463
  ...eventSource,
40215
40464
  events: [...scopedSourceEvents]
40216
40465
  } : eventSource,
40466
+ demoEmailSuppressed: source.demoEmailSuppressed,
40217
40467
  maxTickets: source.maxTickets ?? void 0,
40218
40468
  showVenue: source.showVenue,
40219
40469
  showCapacity: source.showCapacity,
@@ -40357,8 +40607,8 @@ const eventRegistrationBlockDefinition = {
40357
40607
  description: "Message shown after successful registration",
40358
40608
  required: false,
40359
40609
  multiline: true,
40360
- defaultValue: "Thank you for registering! Check your email for confirmation details.",
40361
- maxLength: 500
40610
+ maxLength: 500,
40611
+ ui: { placeholder: "Thank you for registering! Check your email for confirmation details." }
40362
40612
  },
40363
40613
  {
40364
40614
  id: "buttonText",
@@ -40379,6 +40629,10 @@ const eventRegistrationBlockDefinition = {
40379
40629
  text({ as: "h2" }, bind("content.heading"), when("content.heading")),
40380
40630
  richText({ className: "rb-prose rb-max-w-none" }, bind("content.description"), when("content.description")),
40381
40631
  eventRegistration(withApiBindings({
40632
+ demoEmailSuppressed: { $bind: {
40633
+ from: "$root.demoEmailSuppressed",
40634
+ fallback: false
40635
+ } },
40382
40636
  readAuthority: { $bind: { from: "$root.readAuthority" } },
40383
40637
  occurrenceContext: { $bind: { from: "$root.occurrenceContext" } },
40384
40638
  subject: { $bind: { from: "$root.subject" } },
@@ -43419,6 +43673,10 @@ const shopBlockDefinition = {
43419
43673
  spacing: "spacious",
43420
43674
  children: sectionContainer([shop(withApiBindings({
43421
43675
  readAuthority: { $bind: { from: "$root.readAuthority" } },
43676
+ demoEmailSuppressed: { $bind: {
43677
+ from: "$root.demoEmailSuppressed",
43678
+ fallback: false
43679
+ } },
43422
43680
  mode: "passes-memberships",
43423
43681
  showPasses: { $bind: {
43424
43682
  from: "content.showPasses",
@@ -43909,11 +44167,12 @@ function CartSSR({ blockId, siteId, apiBaseUrl, stage, children, ...rest }) {
43909
44167
  }
43910
44168
  //#endregion
43911
44169
  //#region ../blocks/src/system/runtime/nodes/checkout.server.tsx
43912
- function CheckoutSSR({ blockId, siteId, apiBaseUrl, stage, children, ...rest }) {
44170
+ function CheckoutSSR({ blockId, siteId, apiBaseUrl, stage, demoEmailSuppressed, children, ...rest }) {
43913
44171
  const islandProps = buildCheckoutInteractiveIslandProps({
43914
44172
  siteId,
43915
44173
  apiBaseUrl,
43916
44174
  stage,
44175
+ demoEmailSuppressed,
43917
44176
  ...rest
43918
44177
  });
43919
44178
  return /* @__PURE__ */ jsxs("div", {
@@ -45720,11 +45979,11 @@ function ShopSSR({ blockId, siteId, apiBaseUrl, stage, children, checkoutEndpoin
45720
45979
  }, pass.id)),
45721
45980
  membershipCards: render.display.memberships.map((membership) => /* @__PURE__ */ jsx(MembershipCardView, {
45722
45981
  display: membership,
45723
- action: /* @__PURE__ */ jsx(ThemedButton, {
45982
+ action: membership.action.kind === "unavailable" ? /* @__PURE__ */ jsx(PassPurchaseUnavailable, { label: membership.action.label }) : /* @__PURE__ */ jsx(ThemedButton, {
45724
45983
  type: "button",
45725
45984
  variant: render.hydration.buttonVariant,
45726
45985
  size: "md",
45727
- label: membership.actionLabel,
45986
+ label: membership.action.label,
45728
45987
  disabled: true,
45729
45988
  "aria-disabled": "true"
45730
45989
  })
@@ -50109,6 +50368,7 @@ function buildPageRendererRootRuntime(dataContext) {
50109
50368
  const { siteId = null, siteName, pageId = null, pathname = null, bookingTimeZone, previewStage = "published", apiBaseUrl = null, portalToken = null, readAuthority, bookingOfferingPresets = [], appointmentServicePathPrefix = null, mailingList = { tag: "not_configured" }, eventRegistrationOverlayEnabled = false, loaderFailures = {} } = dataContext ?? {};
50110
50369
  return {
50111
50370
  siteId,
50371
+ demoEmailSuppressed: resolveDemoEmailSuppression(dataContext),
50112
50372
  siteName,
50113
50373
  pageId,
50114
50374
  pathname,
@@ -50124,6 +50384,9 @@ function buildPageRendererRootRuntime(dataContext) {
50124
50384
  loaderFailures
50125
50385
  };
50126
50386
  }
50387
+ function resolveDemoEmailSuppression(dataContext) {
50388
+ return dataContext?.demoEmailSuppressed === true;
50389
+ }
50127
50390
  //#endregion
50128
50391
  //#region ../blocks/src/pageRenderAudience.tsx
50129
50392
  /**
@@ -54671,6 +54934,10 @@ const bookingDescription = richText({}, bind("content.description"), when("conte
54671
54934
  * that hydration never rewrites.
54672
54935
  */
54673
54936
  const bookingWizard = bookingForm(withApiBindings({
54937
+ demoEmailSuppressed: { $bind: {
54938
+ from: "$root.demoEmailSuppressed",
54939
+ fallback: false
54940
+ } },
54674
54941
  portalToken: { $bind: {
54675
54942
  from: "$root.portalToken",
54676
54943
  fallback: null
@@ -59847,15 +60114,17 @@ function planNewsletterBlockSubmission(placement) {
59847
60114
  sourceRef
59848
60115
  } : { tag: "unavailable" };
59849
60116
  }
59850
- if (placement.publishedPlacement && "kind" in placement.publishedPlacement) return { tag: "unpublished-settings" };
59851
- if (placement.publishedPlacement) return planNewsletterPreviewSubmission({
59852
- blockId: placement.blockId,
59853
- publishedContentId: placement.publishedPlacement.id,
59854
- renderedContent: placement.renderedContent,
59855
- publishedContent: placement.publishedPlacement.content
59856
- });
59857
- if (placement.stage === "preview") return { tag: "unpublished-form" };
59858
- return { tag: "unavailable" };
60117
+ const published = placement.publishedPlacement;
60118
+ if (published === null) return placement.stage === "preview" ? { tag: "unpublished-form" } : { tag: "unavailable" };
60119
+ switch (published.kind) {
60120
+ case "incomplete": return { tag: "unpublished-settings" };
60121
+ case "published": return planNewsletterPreviewSubmission({
60122
+ blockId: placement.blockId,
60123
+ publishedContentId: published.id,
60124
+ renderedContent: placement.renderedContent,
60125
+ publishedContent: published.content
60126
+ });
60127
+ }
59859
60128
  }
59860
60129
  /** Decide whether the visible draft can safely cite the published placement. */
59861
60130
  function planNewsletterPreviewSubmission(placement) {
@@ -60102,19 +60371,6 @@ function createBlockErrorBoundary() {
60102
60371
  const BlockErrorBoundary = createBlockErrorBoundary();
60103
60372
  //#endregion
60104
60373
  //#region ../blocks/src/pageRenderAdmission.ts
60105
- /** Pair a published version with the content it authorises at the render boundary. */
60106
- function readPublishedBlockPlacement(id, content) {
60107
- if (id == null && content == null) return null;
60108
- if (id == null || content == null) return {
60109
- kind: "incomplete",
60110
- id: id ?? null,
60111
- content: content ?? null
60112
- };
60113
- return {
60114
- id,
60115
- content
60116
- };
60117
- }
60118
60374
  function toPresentationPage(page) {
60119
60375
  if (!page) return null;
60120
60376
  return {
@@ -74249,942 +74505,185 @@ function toBlocksImageResolveContextInput(context) {
74249
74505
  mediaAssets: toBlocksMediaAssets(context.mediaAssets)
74250
74506
  };
74251
74507
  }
74252
- function isOverrideOnlyPageRenderer(props) {
74253
- return props.rendering?.kind === "overrides-only";
74254
- }
74255
- function normalizeSdkCustomBlocks(customBlocks) {
74256
- if (!customBlocks) return void 0;
74257
- return customBlocks.map((block) => {
74258
- return {
74259
- ...block,
74260
- fields: parseFieldDefinitions(block.fields)
74261
- };
74262
- });
74263
- }
74264
- function toBlocksBlockOverrides(overrides) {
74265
- if (!overrides) return void 0;
74266
- const result = {};
74267
- for (const [key, OverrideComponent] of Object.entries(overrides)) result[key] = function BlocksOverrideAdapter(props) {
74268
- const sdkOverride = OverrideComponent;
74269
- return React$1.createElement(sdkOverride, {
74270
- ...props,
74271
- entrySubrouteContext: props.entrySubrouteContext
74272
- });
74273
- };
74274
- return result;
74275
- }
74276
- function toBlocksPageRendererDataContext(dataContext) {
74277
- return {
74278
- ...dataContext,
74279
- mediaAssets: toBlocksMediaAssets(dataContext.mediaAssets),
74280
- imageResolveContext: toBlocksImageResolveContextInput(dataContext.imageResolveContext)
74281
- };
74282
- }
74283
- function toBlocksCommonProps(props) {
74284
- return {
74285
- page: props.page,
74286
- runtimeJoins: props.runtimeJoins,
74287
- dataContext: toBlocksPageRendererDataContext(props.dataContext),
74288
- routeMap: props.routeMap,
74289
- wrapBlock: props.wrapBlock,
74290
- registry: props.registry,
74291
- blockOverrides: toBlocksBlockOverrides(props.blockOverrides),
74292
- sdkConfig: props.sdkConfig ? { customBlocks: normalizeSdkCustomBlocks(props.sdkConfig.customBlocks) } : props.sdkConfig,
74293
- customBlocks: normalizeSdkCustomBlocks(props.customBlocks)
74294
- };
74295
- }
74296
- function PageRenderer(props) {
74297
- const commonBlocksProps = toBlocksCommonProps(props);
74298
- const blocksProps = isOverrideOnlyPageRenderer(props) ? {
74299
- ...commonBlocksProps,
74300
- rendering: { kind: "overrides-only" },
74301
- blockOverrides: toBlocksBlockOverrides(props.blockOverrides) ?? {}
74302
- } : {
74303
- ...commonBlocksProps,
74304
- theme: parseBlocksTheme(props.theme),
74305
- themeTokens: props.themeTokens
74306
- };
74307
- return React$1.createElement(PageRenderer$1, blocksProps);
74308
- }
74309
74508
  //#endregion
74310
- //#region src/rendering/blocks-theme-scope.ts
74311
- function ThemeScope(props) {
74312
- const { theme, children, ...rest } = props;
74313
- const blocksTheme = parseBlocksTheme(theme);
74314
- return React$1.createElement(ThemeScope$1, {
74315
- ...rest,
74316
- theme: blocksTheme,
74317
- children: children ?? null
74318
- });
74319
- }
74509
+ //#region ../blocks/src/structure/schema.ts
74510
+ const BlockKind = z.string();
74511
+ const blockSchema = z.object({
74512
+ id: z.string().nullable(),
74513
+ kind: BlockKind,
74514
+ purpose: z.string().min(1),
74515
+ content: z.record(z.string(), z.unknown()).optional(),
74516
+ draftContent: z.record(z.string(), z.unknown()).nullable().optional(),
74517
+ bindings: z.record(z.string(), z.unknown()).optional()
74518
+ }).passthrough();
74519
+ const pagePath = z.string().regex(/^\/[\S]*$/, "path must start with \"/\" and contain no spaces");
74520
+ z.object({
74521
+ name: z.string().min(1),
74522
+ path: pagePath,
74523
+ purpose: z.string().min(1),
74524
+ blocks: z.array(blockSchema).min(1)
74525
+ });
74320
74526
  //#endregion
74321
- //#region src/rendering/themeRuntime.tsx
74322
- const defaultLayoutThemeRuntime = { kind: "cms-theme" };
74323
- const defaultSdkChromeThemeRuntime = { kind: "responsive-only" };
74324
- const defaultPageThemeRuntime = { kind: "none" };
74325
- function planLayoutThemeRuntime(input) {
74326
- const requested = input.themeRuntime ?? defaultLayoutThemeRuntime;
74327
- if (requested.kind === "none" && input.usesSdkChrome) {
74328
- if (process.env.NODE_ENV !== "production") console.warn("[sdk] Layout themeRuntime { kind: \"none\" } is not compatible with SDK-managed header/footer chrome; using responsive-only runtime instead.");
74329
- return defaultSdkChromeThemeRuntime;
74330
- }
74331
- return requested;
74332
- }
74333
- function renderWithSdkThemeRuntime({ themeRuntime, theme, children }) {
74334
- switch (themeRuntime.kind) {
74335
- case "cms-theme": return /* @__PURE__ */ jsx(ThemeScope, {
74336
- theme,
74337
- responsiveMode: themeRuntime.responsiveMode,
74338
- children
74339
- });
74340
- case "responsive-only": return /* @__PURE__ */ jsx(ResponsiveScope, {
74341
- responsiveMode: themeRuntime.responsiveMode,
74342
- children
74343
- });
74344
- case "none": return /* @__PURE__ */ jsx(Fragment, { children });
74345
- default: return assertNever$21(themeRuntime);
74527
+ //#region ../../node_modules/.pnpm/@vibrant+image@4.0.4/node_modules/@vibrant/image/dist/esm/histogram.js
74528
+ var Histogram = class {
74529
+ constructor(pixels, opts) {
74530
+ this.pixels = pixels;
74531
+ this.opts = opts;
74532
+ const { sigBits } = opts;
74533
+ const getColorIndex = (r2, g2, b2) => (r2 << 2 * sigBits) + (g2 << sigBits) + b2;
74534
+ this.getColorIndex = getColorIndex;
74535
+ const rshift = 8 - sigBits;
74536
+ const hn = 1 << 3 * sigBits;
74537
+ const hist = new Uint32Array(hn);
74538
+ let rmax;
74539
+ let rmin;
74540
+ let gmax;
74541
+ let gmin;
74542
+ let bmax;
74543
+ let bmin;
74544
+ let r;
74545
+ let g;
74546
+ let b;
74547
+ let a;
74548
+ rmax = gmax = bmax = 0;
74549
+ rmin = gmin = bmin = Number.MAX_VALUE;
74550
+ const n = pixels.length / 4;
74551
+ let i = 0;
74552
+ while (i < n) {
74553
+ const offset = i * 4;
74554
+ i++;
74555
+ r = pixels[offset + 0];
74556
+ g = pixels[offset + 1];
74557
+ b = pixels[offset + 2];
74558
+ a = pixels[offset + 3];
74559
+ if (a === 0) continue;
74560
+ r = r >> rshift;
74561
+ g = g >> rshift;
74562
+ b = b >> rshift;
74563
+ const index = getColorIndex(r, g, b);
74564
+ if (hist[index] === void 0) hist[index] = 0;
74565
+ hist[index] += 1;
74566
+ if (r > rmax) rmax = r;
74567
+ if (r < rmin) rmin = r;
74568
+ if (g > gmax) gmax = g;
74569
+ if (g < gmin) gmin = g;
74570
+ if (b > bmax) bmax = b;
74571
+ if (b < bmin) bmin = b;
74572
+ }
74573
+ this._colorCount = hist.reduce((total, c) => c > 0 ? total + 1 : total, 0);
74574
+ this.hist = hist;
74575
+ this.rmax = rmax;
74576
+ this.rmin = rmin;
74577
+ this.gmax = gmax;
74578
+ this.gmin = gmin;
74579
+ this.bmax = bmax;
74580
+ this.bmin = bmin;
74346
74581
  }
74347
- }
74348
- function renderWithOverrideOnlyRuntime({ runtime, children }) {
74349
- switch (runtime.kind) {
74350
- case "responsive-only": return /* @__PURE__ */ jsx(ResponsiveScope, {
74351
- responsiveMode: runtime.responsiveMode,
74352
- children
74353
- });
74354
- case "none": return /* @__PURE__ */ jsx(Fragment, { children });
74355
- default: return assertNever$21(runtime);
74582
+ get colorCount() {
74583
+ return this._colorCount;
74356
74584
  }
74357
- }
74585
+ };
74358
74586
  //#endregion
74359
- //#region src/rendering/components/pageShared.tsx
74360
- function isOverrideOnlyPage(props) {
74361
- return props.rendering?.kind === "overrides-only";
74362
- }
74363
- function resolvePageThemeTokens(props) {
74364
- const baseTokens = props.themeTokens ?? buildThemeRuntime(props.theme).tokens;
74365
- return props.sdkConfig?.theme?.palette ? {
74366
- ...baseTokens,
74367
- palette: {
74368
- ...baseTokens.palette,
74369
- ...props.sdkConfig.theme.palette
74587
+ //#region ../../node_modules/.pnpm/@vibrant+image@4.0.4/node_modules/@vibrant/image/dist/esm/index.js
74588
+ var ImageBase = class {
74589
+ scaleDown(opts) {
74590
+ const width = this.getWidth();
74591
+ const height = this.getHeight();
74592
+ let ratio = 1;
74593
+ if (opts.maxDimension > 0) {
74594
+ const maxSide = Math.max(width, height);
74595
+ if (maxSide > opts.maxDimension) ratio = opts.maxDimension / maxSide;
74596
+ } else ratio = 1 / opts.quality;
74597
+ if (ratio < 1) this.resize(width * ratio, height * ratio, ratio);
74598
+ }
74599
+ };
74600
+ function applyFilters(imageData, filters) {
74601
+ if (filters.length > 0) {
74602
+ const pixels = imageData.data;
74603
+ const n = pixels.length / 4;
74604
+ let offset;
74605
+ let r;
74606
+ let g;
74607
+ let b;
74608
+ let a;
74609
+ for (let i = 0; i < n; i++) {
74610
+ offset = i * 4;
74611
+ r = pixels[offset + 0];
74612
+ g = pixels[offset + 1];
74613
+ b = pixels[offset + 2];
74614
+ a = pixels[offset + 3];
74615
+ for (let j = 0; j < filters.length; j++) if (!filters[j]?.(r, g, b, a)) {
74616
+ pixels[offset + 3] = 0;
74617
+ break;
74618
+ }
74370
74619
  }
74371
- } : baseTokens;
74372
- }
74373
- function toPageHydrationBootstrapConfig(props) {
74374
- return {
74375
- siteId: props.siteId,
74376
- supabaseUrl: props.supabaseUrl,
74377
- mediaAssets: props.mediaAssets
74378
- };
74379
- }
74380
- function resolveSdkBookingTimeZone(timeZone) {
74381
- return timeZone ?? "UTC";
74620
+ }
74621
+ return imageData;
74382
74622
  }
74383
- function buildPageRouteRenderContext(dataContext) {
74384
- return {
74385
- ...buildPageIdentityRenderContext(dataContext),
74386
- occurrenceContext: dataContext.occurrenceContext ?? null,
74387
- entrySubrouteContext: dataContext.entrySubrouteContext ?? null,
74388
- contentEntry: dataContext.contentEntry ?? null,
74389
- pageSurface: dataContext.pageSurface ?? null,
74390
- subject: dataContext.subject ?? null,
74391
- editableRouteMetadataFieldIds: dataContext.editableRouteMetadataFieldIds ?? null,
74392
- previewStage: dataContext.previewStage
74393
- };
74623
+ //#endregion
74624
+ //#region ../../node_modules/.pnpm/@vibrant+image-browser@4.0.4/node_modules/@vibrant/image-browser/dist/esm/index.js
74625
+ function isRelativeUrl(url) {
74626
+ const u = new URL(url, location.href);
74627
+ return u.protocol === location.protocol && u.host === location.host && u.port === location.port;
74394
74628
  }
74395
- function buildPageIdentityRenderContext(dataContext) {
74396
- return {
74397
- siteName: dataContext.siteName,
74398
- pathname: dataContext.pathname
74399
- };
74629
+ function isSameOrigin(a, b) {
74630
+ const ua = new URL(a);
74631
+ const ub = new URL(b);
74632
+ return ua.protocol === ub.protocol && ua.hostname === ub.hostname && ua.port === ub.port;
74400
74633
  }
74401
- function PageContent(props) {
74402
- const { page, runtimeJoins, siteId, resolvedData, bookingOfferingPresets, mailingList, bookingTimeZone, routeMap, pagesByIdentifier, entriesByIdentifier, wrapBlock, registry, blockOverrides, sdkConfig, customBlocks, supabaseUrl, mediaAssets, apiBaseUrl, portalToken, previewToken, readAuthority, dataContext } = props;
74403
- const rendererCommonProps = {
74404
- page,
74405
- runtimeJoins,
74406
- dataContext: {
74407
- siteId,
74408
- ...buildPageRouteRenderContext(dataContext),
74409
- apiBaseUrl,
74410
- portalToken,
74411
- previewToken,
74412
- readAuthority: readAuthority ?? dataContext.readAuthority,
74413
- resolvedData,
74414
- bookingOfferingPresets: bookingOfferingPresets ?? [],
74415
- mailingList: mailingList ?? dataContext.mailingList,
74416
- bookingTimeZone: resolveSdkBookingTimeZone(bookingTimeZone),
74417
- routes: routeMap,
74418
- pagesByIdentifier,
74419
- entriesByIdentifier,
74420
- supabaseUrl,
74421
- mediaAssets,
74422
- imageResolveContext: {
74423
- siteId,
74424
- supabaseUrl,
74425
- mediaAssets
74426
- }
74427
- },
74428
- routeMap,
74429
- wrapBlock,
74430
- registry,
74431
- sdkConfig: sdkConfig ? { customBlocks: sdkConfig.customBlocks } : null,
74432
- customBlocks
74433
- };
74434
- const content = isOverrideOnlyPage(props) ? /* @__PURE__ */ jsx(PageRenderer, {
74435
- ...rendererCommonProps,
74436
- rendering: { kind: "overrides-only" },
74437
- blockOverrides: props.blockOverrides
74438
- }) : /* @__PURE__ */ jsx(PageRenderer, {
74439
- ...rendererCommonProps,
74440
- theme: props.theme,
74441
- themeTokens: resolvePageThemeTokens(props),
74442
- blockOverrides
74443
- });
74444
- return isOverrideOnlyPage(props) ? renderWithOverrideOnlyRuntime({
74445
- runtime: props.rendering.runtime,
74446
- children: content
74447
- }) : renderWithSdkThemeRuntime({
74448
- themeRuntime: props.themeRuntime ?? defaultPageThemeRuntime,
74449
- theme: props.theme,
74450
- children: content
74451
- });
74452
- }
74453
- //#endregion
74454
- //#region src/rendering/components/Page.tsx
74455
- const HydratorWithContextProps$1 = BlocksIslandsHydrator;
74456
- /**
74457
- * Default renderer for Riverbank CMS pages.
74458
- *
74459
- * This component expects all data to be provided via props and automatically
74460
- * mounts the CMS island hydration bootstrap.
74461
- * For data fetching, use:
74462
- * - Server-side: `await loadPage({ client, siteId, path })`
74463
- * - Client-side: `usePage({ client, siteId, path })`
74464
- *
74465
- * @example Server-side (Next.js App Router)
74466
- * ```tsx
74467
- * import { createRiverbankClient } from '@riverbankcms/sdk';
74468
- * import { loadPage, Page } from '@riverbankcms/sdk/rendering';
74469
- *
74470
- * const client = createRiverbankClient({ apiKey, baseUrl });
74471
- *
74472
- * export default async function PageRoute({ params }) {
74473
- * const pageData = await loadPage({
74474
- * client,
74475
- * siteId: 'site-id',
74476
- * path: `/${params.slug}`,
74477
- * });
74478
- *
74479
- * return <Page {...pageData} />;
74480
- * }
74481
- * ```
74482
- *
74483
- * @example Client-side
74484
- * ```tsx
74485
- * import { createRiverbankClient } from '@riverbankcms/sdk';
74486
- * import { usePage, Page } from '@riverbankcms/sdk/rendering';
74487
- *
74488
- * const client = createRiverbankClient({ apiKey, baseUrl });
74489
- *
74490
- * function MyPage({ path }) {
74491
- * const pageData = usePage({ client, siteId: 'site-id', path });
74492
- *
74493
- * if (pageData.loading) return <LoadingState />;
74494
- * if (pageData.error) return <ErrorState error={pageData.error} />;
74495
- * if (!pageData.page) return <NotFound />;
74496
- *
74497
- * return <Page {...pageData} />;
74498
- * }
74499
- * ```
74500
- */
74501
- function Page(props) {
74502
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(HydratorWithContextProps$1, { ...toPageHydrationBootstrapConfig(props) }), /* @__PURE__ */ jsx(PageContent, { ...props })] });
74503
- }
74504
- //#endregion
74505
- //#region src/env.ts
74506
- /**
74507
- * Error thrown when required environment variables are missing
74508
- */
74509
- var RiverbankEnvError = class extends Error {
74510
- constructor(message, missingVars) {
74511
- super(message);
74512
- this.missingVars = missingVars;
74513
- this.name = "RiverbankEnvError";
74514
- }
74515
- };
74516
- /**
74517
- * Get the environment variable prefix based on target
74518
- */
74519
- function getEnvPrefix(target) {
74520
- return target === "remote" ? "RIVERBANK_REMOTE" : "RIVERBANK_LOCAL";
74521
- }
74522
- /**
74523
- * Detect the environment target from RIVERBANK_ENV
74524
- */
74525
- function detectTarget() {
74526
- const env = process.env.RIVERBANK_ENV?.toLowerCase();
74527
- if (env === "remote" || env === "production" || env === "prod") return "remote";
74528
- return "local";
74529
- }
74530
- /**
74531
- * Detect if preview mode is enabled.
74532
- * Uses RIVERBANK_PREVIEW_MODE first, then falls back to RIVERBANK_PREVIEW for backward compat.
74533
- */
74534
- function detectPreviewMode() {
74535
- const previewMode = process.env.RIVERBANK_PREVIEW_MODE;
74536
- if (previewMode !== void 0 && previewMode !== "") return previewMode === "true";
74537
- const previewLegacy = process.env.RIVERBANK_PREVIEW;
74538
- if (previewLegacy !== void 0 && previewLegacy !== "") return previewLegacy === "true";
74539
- return process.env.VERCEL_ENV === "preview";
74540
- }
74541
- /**
74542
- * Validate that an API key matches the expected format for its type
74543
- */
74544
- function validateKeyType(key, expectedType) {
74545
- const isPreviewKey = key.startsWith("bld_preview_sk_");
74546
- const isContentKey = key.startsWith("bld_live_sk_");
74547
- if (expectedType === "preview" && !isPreviewKey) {
74548
- if (isContentKey) throw new RiverbankEnvError("Preview mode is enabled (RIVERBANK_PREVIEW_MODE=true) but a content key was provided. Preview mode requires a preview API key (bld_preview_sk_...) to access draft content. Either:\n 1. Set RIVERBANK_*_PREVIEW_API_KEY with your preview key, or\n 2. Set RIVERBANK_PREVIEW_MODE=false to fetch published content instead.", []);
74549
- throw new RiverbankEnvError(`Invalid API key format for preview mode. Expected key starting with bld_preview_sk_`, []);
74550
- }
74551
- if (expectedType === "content" && !isContentKey) {
74552
- if (isPreviewKey) {
74553
- console.debug("[getRiverbankEnv] Using preview key for published content. Consider using a content key (bld_live_sk_...) for production.");
74554
- return;
74555
- }
74556
- throw new RiverbankEnvError(`Invalid API key format for content access. Expected key starting with bld_live_sk_ or bld_preview_sk_`, []);
74557
- }
74558
- }
74559
- /**
74560
- * Get runtime environment configuration with automatic API key selection.
74561
- *
74562
- * This helper reads environment variables and automatically selects the correct
74563
- * API key based on the current environment and preview mode:
74564
- *
74565
- * - When `RIVERBANK_PREVIEW_MODE=true`: Uses preview API key (bld_preview_sk_...)
74566
- * - When `RIVERBANK_PREVIEW_MODE=false` (default): Uses content API key (bld_live_sk_...)
74567
- *
74568
- * Environment variable patterns:
74569
- * - `RIVERBANK_ENV`: 'local' (default) or 'remote'
74570
- * - `RIVERBANK_PREVIEW_MODE`: 'true' or 'false' (default)
74571
- * - `RIVERBANK_{LOCAL|REMOTE}_SITE_ID`: Site ID
74572
- * - `RIVERBANK_{LOCAL|REMOTE}_DASHBOARD_URL`: Dashboard URL
74573
- * - `RIVERBANK_{LOCAL|REMOTE}_API_KEY`: Content/live API key
74574
- * - `RIVERBANK_{LOCAL|REMOTE}_PREVIEW_API_KEY`: Preview API key
74575
- *
74576
- * @returns Environment configuration with auto-selected API key
74577
- * @throws {RiverbankEnvError} If required environment variables are missing
74578
- *
74579
- * @example
74580
- * ```ts
74581
- * // lib/builder-client.ts
74582
- * import { getRiverbankEnv } from '@riverbankcms/sdk/env';
74583
- * import { createRiverbankClient } from '@riverbankcms/sdk';
74584
- *
74585
- * const env = getRiverbankEnv();
74586
- *
74587
- * export const client = createRiverbankClient({
74588
- * apiKey: env.apiKey,
74589
- * baseUrl: env.baseUrl,
74590
- * });
74591
- *
74592
- * export const siteId = env.siteId;
74593
- * ```
74594
- */
74595
- function getRiverbankEnv() {
74596
- const target = detectTarget();
74597
- const previewMode = detectPreviewMode();
74598
- const prefix = getEnvPrefix(target);
74599
- const siteId = process.env[`${prefix}_SITE_ID`];
74600
- const dashboardUrl = process.env[`${prefix}_DASHBOARD_URL`];
74601
- const contentKey = process.env[`${prefix}_API_KEY`];
74602
- const previewKey = process.env[`${prefix}_PREVIEW_API_KEY`];
74603
- const missingVars = [];
74604
- if (!siteId) missingVars.push(`${prefix}_SITE_ID`);
74605
- if (!dashboardUrl) missingVars.push(`${prefix}_DASHBOARD_URL`);
74606
- let apiKey;
74607
- let keyType;
74608
- if (previewMode) {
74609
- apiKey = previewKey;
74610
- keyType = "preview";
74611
- if (!apiKey) missingVars.push(`${prefix}_PREVIEW_API_KEY`);
74612
- } else {
74613
- apiKey = contentKey || previewKey;
74614
- keyType = contentKey ? "content" : "preview";
74615
- if (!apiKey) missingVars.push(`${prefix}_API_KEY`);
74616
- }
74617
- if (missingVars.length > 0) throw new RiverbankEnvError(`Missing required environment variables for Riverbank SDK:\n` + missingVars.map((v) => ` - ${v}`).join("\n") + `\n\nCurrent settings: RIVERBANK_ENV=${process.env.RIVERBANK_ENV || "local"}, RIVERBANK_PREVIEW_MODE=${process.env.RIVERBANK_PREVIEW_MODE || "false"}`, missingVars);
74618
- if (!apiKey || !dashboardUrl || !siteId) throw new RiverbankEnvError("Required environment variables missing", missingVars);
74619
- validateKeyType(apiKey, keyType);
74620
- let baseUrl = dashboardUrl;
74621
- if (!baseUrl.endsWith("/api")) baseUrl = baseUrl.replace(/\/$/, "") + "/api";
74622
- return {
74623
- target,
74624
- previewMode,
74625
- siteId,
74626
- baseUrl,
74627
- apiKey,
74628
- keyType
74629
- };
74630
- }
74631
- /**
74632
- * Get the fixed main navigation menu object.
74633
- * Returns null when the runtime payload is incomplete.
74634
- *
74635
- * @example
74636
- * ```ts
74637
- * const menu = getPrimaryNavigation(siteData.navigation);
74638
- * console.log(menu?.location); // "main"
74639
- * ```
74640
- */
74641
- function getPrimaryNavigation(navigation) {
74642
- if (!navigation || navigation.length === 0) return null;
74643
- return navigation.find((menu) => menu.location === "main") ?? null;
74644
- }
74645
- function getFooterNavigationByRole(navigation, role) {
74646
- if (!navigation || navigation.length === 0) return null;
74647
- const canonicalLocation = role === "main" ? "footer" : "legal";
74648
- return navigation.find((menu) => menu.location === canonicalLocation) ?? null;
74649
- }
74650
- /**
74651
- * Resolve alt text with fallback.
74652
- * Returns the provided alt if non-empty, otherwise falls back to the provided fallback or 'Site logo'.
74653
- * @internal
74654
- */
74655
- function resolveAltText(alt, fallback) {
74656
- return alt && alt.trim().length > 0 ? alt : fallback ?? "Site logo";
74657
- }
74658
- function readNavigationItemPayload(item) {
74659
- return item.url ?? null;
74660
- }
74661
- function isPortalEnabled(options) {
74662
- return options?.portalEnabled === true;
74663
- }
74664
- function isCommerceEnabled(options) {
74665
- return options?.commerceEnabled === true;
74666
- }
74667
- function resolvePortalHref(link) {
74668
- return link.path?.trim() || "/portal";
74669
- }
74670
- function resolveCheckoutHref(options) {
74671
- if (options?.checkoutHref === null) return null;
74672
- const href = options?.checkoutHref?.trim();
74673
- return href && href.length > 0 ? href : "/checkout";
74674
- }
74675
- function resolvePortalLabel(link, options) {
74676
- const loggedOutLabel = link.labels?.loggedOut?.trim() || PORTAL_NAV_DEFAULT_LABELS.loggedOut;
74677
- const loggedInLabel = link.labels?.loggedIn?.trim() || PORTAL_NAV_DEFAULT_LABELS.loggedIn;
74678
- return options?.hasPortalSession ? loggedInLabel : loggedOutLabel;
74679
- }
74680
- function resolveItemLabel(link, fallbackLabel, options) {
74681
- if (link?.kind === "portal") return resolvePortalLabel(link, options);
74682
- if (link?.kind === "cart") return resolveCartVisibleLabel(link) ?? fallbackLabel;
74683
- return fallbackLabel;
74684
- }
74685
- function resolveCartVisibleLabel(link) {
74686
- if (link.label.kind !== "icon-with-label") return null;
74687
- const label = link.label.label.trim();
74688
- return label.length > 0 ? label : null;
74689
- }
74690
- function resolveCartAriaLabel(link, fallbackLabel) {
74691
- const fallback = fallbackLabel.trim();
74692
- return resolveCartVisibleLabel(link) ?? (fallback.length > 0 ? fallback : "Cart");
74693
- }
74694
- function buildCartNavViewModel(link, fallbackLabel, options) {
74695
- return {
74696
- visibleLabel: resolveCartVisibleLabel(link),
74697
- badge: link.badge,
74698
- ariaLabel: resolveCartAriaLabel(link, fallbackLabel),
74699
- checkoutHref: resolveCheckoutHref(options)
74700
- };
74701
- }
74702
- function deriveRenderableNavigationLink(item, options) {
74703
- const payload = readNavigationItemPayload(item);
74704
- if (!payload) return null;
74705
- if (payload.kind === "portal" && !isPortalEnabled(options)) return null;
74706
- if (payload.kind === "cart" && !isCommerceEnabled(options)) return null;
74707
- return {
74708
- id: item.id,
74709
- label: resolveItemLabel(payload, item.label, options),
74710
- payload,
74711
- isExternal: isExternalLink(payload),
74712
- ...payload.kind === "cart" ? { cart: buildCartNavViewModel(payload, item.label, options) } : {}
74713
- };
74714
- }
74715
- function buildNavLinkFromResolvedHref(item, href) {
74716
- if (!href) return null;
74717
- return {
74718
- kind: "link",
74719
- id: item.id,
74720
- label: item.label,
74721
- href,
74722
- link: { href },
74723
- isExternal: item.isExternal,
74724
- ...item.cart ? { cart: item.cart } : {}
74725
- };
74726
- }
74727
- /**
74728
- * Determines if a navigation item's link is external.
74729
- */
74730
- function isExternalLink(link) {
74731
- if (!link) return false;
74732
- return link.kind === "external";
74733
- }
74734
- /**
74735
- * Build a map of children items by parent ID.
74736
- * Also warns about deeply nested items (grandchildren) which CMS shouldn't allow.
74737
- * @internal
74738
- */
74739
- function buildChildrenByParentId(items) {
74740
- const childrenByParentId = /* @__PURE__ */ new Map();
74741
- const itemsById = /* @__PURE__ */ new Map();
74742
- for (const item of items) itemsById.set(item.id, item);
74743
- for (const item of items) if (item.parentId) {
74744
- if (itemsById.get(item.parentId)?.parentId && typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
74745
- console.warn(`[SDK Navigation] Deeply nested item detected: "${item.label}" (id: ${item.id}). Only 1 level of nesting is supported. This item will be ignored.`);
74746
- continue;
74747
- }
74748
- const siblings = childrenByParentId.get(item.parentId) ?? [];
74749
- siblings.push(item);
74750
- childrenByParentId.set(item.parentId, siblings);
74751
- }
74752
- return childrenByParentId;
74753
- }
74754
- /**
74755
- * Generic nested structure builder.
74756
- * @internal
74757
- */
74758
- function buildNestedStructure(items, options) {
74759
- const childrenByParentId = buildChildrenByParentId(items);
74760
- const rootItems = items.filter((item) => !item.parentId).sort((a, b) => (a.orderIndex ?? a.position ?? 0) - (b.orderIndex ?? b.position ?? 0));
74761
- const result = [];
74762
- let ctaItem = null;
74763
- for (const item of rootItems) {
74764
- if (options.extractCta && !ctaItem && Boolean(item.isCta) && item.urlType !== "dropdown") {
74765
- const link = options.toLink(item);
74766
- if (link) {
74767
- ctaItem = link;
74768
- continue;
74769
- }
74770
- }
74771
- const childRecords = childrenByParentId.get(item.id) ?? [];
74772
- const hasChildren = childRecords.length > 0;
74773
- if (item.urlType === "dropdown" || hasChildren) {
74774
- const children = childRecords.sort((a, b) => (a.orderIndex ?? a.position ?? 0) - (b.orderIndex ?? b.position ?? 0)).map(options.toLink).filter((child) => child !== null);
74775
- if (children.length > 0) result.push(options.createDropdown(item.id, item.label, children));
74776
- continue;
74777
- }
74778
- const link = options.toLink(item);
74779
- if (link) result.push(link);
74780
- }
74781
- return {
74782
- items: result,
74783
- ctaItem
74784
- };
74785
- }
74786
- /**
74787
- * Build a Menu from navigation data with pre-resolved hrefs.
74788
- * Supports dropdown containers with nested children.
74789
- *
74790
- * @param navigation - Navigation menus from site data
74791
- * @param routes - Route map for resolving internal links
74792
- * @param options - Include identifier maps to resolve canonical `page`/`entry` links.
74793
- *
74794
- * @example
74795
- * ```ts
74796
- * const menu = buildMenu(siteData.navigation, siteData.routes, {
74797
- * pagesByIdentifier: siteData.pagesByIdentifier,
74798
- * entriesByIdentifier: siteData.entriesByIdentifier,
74799
- * });
74800
- * menu.items.forEach(item => {
74801
- * if (item.kind === 'dropdown') {
74802
- * console.log(item.children);
74803
- * }
74804
- * });
74805
- * ```
74806
- */
74807
- function buildMenu(navigation, routes, options) {
74808
- const menu = getPrimaryNavigation(navigation);
74809
- if (!menu) return {
74810
- items: [],
74811
- ctaItem: null
74812
- };
74813
- const toNavLink = (item) => {
74814
- const renderable = deriveRenderableNavigationLink(item, options);
74815
- if (!renderable) return null;
74816
- return buildNavLinkFromResolvedHref(renderable, resolveHref(renderable.payload, routes, options));
74817
- };
74818
- const { items, ctaItem } = buildNestedStructure(menu.items, {
74819
- toLink: toNavLink,
74820
- createDropdown: (id, label, children) => ({
74821
- kind: "dropdown",
74822
- id,
74823
- label,
74824
- children
74825
- }),
74826
- extractCta: true
74827
- });
74828
- return {
74829
- items,
74830
- ctaItem: ctaItem ? {
74831
- ...ctaItem,
74832
- variant: "primary"
74833
- } : null
74834
- };
74835
- }
74836
- /**
74837
- * Build a Menu from the footer navigation data.
74838
- * Returns empty menu if no footer menu is designated.
74839
- *
74840
- * @param navigation - Navigation menus from site data
74841
- * @param routes - Route map for resolving internal links
74842
- * @param options - Include identifier maps to resolve canonical `page`/`entry` links.
74843
- *
74844
- * @example
74845
- * ```ts
74846
- * const footerMenu = buildFooterMenu(siteData.navigation, siteData.routes, {
74847
- * pagesByIdentifier: siteData.pagesByIdentifier,
74848
- * entriesByIdentifier: siteData.entriesByIdentifier,
74849
- * });
74850
- * footerMenu.items.forEach(item => {
74851
- * if (item.kind === 'dropdown') {
74852
- * // Footer renders children expanded, not as hover dropdowns
74853
- * console.log(item.children);
74854
- * }
74855
- * });
74856
- * ```
74857
- */
74858
- function buildFooterMenu(navigation, routes, options) {
74859
- return buildFooterMenuForRole(navigation, routes, "main", options);
74860
- }
74861
- function buildFooterMenuForRole(navigation, routes, role, options) {
74862
- const menu = getFooterNavigationByRole(navigation, role);
74863
- if (!menu) return {
74864
- items: [],
74865
- ctaItem: null,
74866
- groups: [],
74867
- links: []
74868
- };
74869
- const toNavLink = (item) => {
74870
- const renderable = deriveRenderableNavigationLink(item, options);
74871
- if (!renderable) return null;
74872
- return buildNavLinkFromResolvedHref(renderable, resolveHref(renderable.payload, routes, options));
74873
- };
74874
- const built = buildNestedStructure(menu.items, {
74875
- toLink: toNavLink,
74876
- createDropdown: (id, label, children) => ({
74877
- kind: "dropdown",
74878
- id,
74879
- label,
74880
- children
74881
- }),
74882
- extractCta: false
74883
- });
74884
- const groups = built.items.filter((item) => item.kind === "dropdown");
74885
- const links = built.items.filter((item) => item.kind === "link");
74886
- return {
74887
- items: built.items,
74888
- ctaItem: null,
74889
- groups,
74890
- links
74891
- };
74892
- }
74893
- /**
74894
- * Resolve href from a link payload using route map.
74895
- * @internal
74896
- */
74897
- function resolveHref(link, routes, options) {
74898
- if (!link) return null;
74899
- if (link.kind === "external" || link.kind === "url") return link.href || null;
74900
- if (link.kind === "portal") return isPortalEnabled(options) ? resolvePortalHref(link) : null;
74901
- if (link.kind === "cart") return isCommerceEnabled(options) ? resolveCheckoutHref(options) : null;
74902
- const stage = normalizeRenderStage(options?.previewStage);
74903
- if (link.kind === "internal") return resolveRouteHrefWithFallback(link.routeId, link.href ?? null, routes, stage);
74904
- if (link.kind === "page") {
74905
- const routeIdFromPayload = readRouteIdFromLink(link);
74906
- const routeIdFromIdentifierMap = options?.pagesByIdentifier?.[link.identifier] ?? null;
74907
- return resolveRouteHrefWithFallback(routeIdFromPayload ?? routeIdFromIdentifierMap, readHrefFromLink(link), routes, stage);
74908
- }
74909
- if (link.kind === "entry") {
74910
- const routeIdFromPayload = readRouteIdFromLink(link);
74911
- const routeIdFromIdentifierMap = readEntryRouteIdFromIdentifierMap(options, link.contentType, link.identifier);
74912
- return resolveRouteHrefWithFallback(routeIdFromPayload ?? routeIdFromIdentifierMap, readHrefFromLink(link), routes, stage);
74913
- }
74914
- return null;
74915
- }
74916
- function resolveRouteHrefWithFallback(routeId, fallbackHref, routes, stage) {
74917
- if (!routeId) return fallbackHref;
74918
- const resolved = resolveRouteHrefForStage(routeId, routes, stage);
74919
- if (resolved) return resolved;
74920
- const route = routes[routeId];
74921
- if (!route) return fallbackHref;
74922
- if (!isRouteVisibleInStage(route, stage)) return null;
74923
- return fallbackHref;
74924
- }
74925
- function readRouteIdFromLink(link) {
74926
- if (!("routeId" in link) || typeof link.routeId !== "string") return null;
74927
- return link.routeId;
74928
- }
74929
- function readHrefFromLink(link) {
74930
- if (!("href" in link) || typeof link.href !== "string") return null;
74931
- return link.href;
74932
- }
74933
- function readEntryRouteIdFromIdentifierMap(options, contentType, identifier) {
74934
- const entryMap = options?.entriesByIdentifier?.[contentType];
74935
- if (!entryMap) return null;
74936
- return entryMap[identifier] ?? null;
74937
- }
74938
- /**
74939
- * Build a Logo from site layout data.
74940
- *
74941
- * @param logo - Logo data from site layout
74942
- * @param fallbackAlt - Fallback alt text (usually site title)
74943
- *
74944
- * @example
74945
- * ```ts
74946
- * const logo = buildLogo(siteData.layout.logo, siteData.site.title);
74947
- * // { src: 'https://...', alt: 'Site Name', width: 200, height: 50 }
74948
- * ```
74949
- */
74950
- function buildLogo(logo, fallbackAlt) {
74951
- if (!logo || !logo.url) return null;
74952
- const alt = resolveAltText(logo.alt, fallbackAlt);
74953
- const result = {
74954
- type: "image",
74955
- src: logo.url,
74956
- alt
74957
- };
74958
- if (logo.width != null) result.width = logo.width;
74959
- if (logo.height != null) result.height = logo.height;
74960
- return result;
74961
- }
74962
- /**
74963
- * Build both site logos from layout data. The default header and footer choose
74964
- * between them by the surface they sit on; custom chrome can do the same.
74965
- *
74966
- * @example
74967
- * ```ts
74968
- * const logoVariants = buildLogoVariants(siteData.layout, siteData.site.title);
74969
- * ```
74970
- */
74971
- function buildLogoVariants(layout, fallbackAlt) {
74972
- return {
74973
- forLightBackgrounds: buildLogo(layout?.logo ?? null, fallbackAlt),
74974
- forDarkBackgrounds: buildLogo(layout?.logoForDarkBackgrounds ?? null, fallbackAlt)
74975
- };
74976
- }
74977
- /**
74978
- * Header/footer block content for the site logos. `logo` stays populated with
74979
- * whichever logo exists so presence checks keep working; `logoVariants` is
74980
- * what the blocks select from at render.
74981
- */
74982
- function buildChromeLogoContent(layout, fallbackAlt) {
74983
- const logoVariants = buildLogoVariants(layout, fallbackAlt);
74984
- return {
74985
- logo: logoVariants.forLightBackgrounds ?? logoVariants.forDarkBackgrounds,
74986
- logoVariants
74987
- };
74988
- }
74989
- //#endregion
74990
- //#region src/rendering/themeAdmission.ts
74991
- const MISSING_SDK_THEME_ERROR_CODE = "missing_sdk_theme";
74992
- var MissingSdkThemeError = class extends Error {
74993
- constructor(siteId, reason = "cms_theme_absent", themeKey) {
74994
- super(`[Riverbank SDK] Site "${siteId}" has no resolvable theme. ` + (themeKey ? `Theme key "${themeKey}" is not present. ` : "") + "Select a CMS theme, provide { theme }, { themes }, or { getTheme }, or use rendering: { kind: 'overrides-only' } with complete block overrides.");
74995
- this.siteId = siteId;
74996
- this.reason = reason;
74997
- this.themeKey = themeKey;
74998
- this.code = MISSING_SDK_THEME_ERROR_CODE;
74999
- this.name = "MissingSdkThemeError";
75000
- }
75001
- };
75002
- function requireSdkTheme(theme, siteId, reason = "cms_theme_absent") {
75003
- if (theme === null || theme === void 0) throw new MissingSdkThemeError(siteId, reason);
75004
- return theme;
75005
- }
75006
- //#endregion
75007
- //#region src/rendering/renderingMode.ts
75008
- const defaultOverrideOnlyRuntime = { kind: "responsive-only" };
75009
- //#endregion
75010
- //#region ../blocks/src/structure/schema.ts
75011
- const BlockKind = z.string();
75012
- const blockSchema = z.object({
75013
- id: z.string().nullable(),
75014
- kind: BlockKind,
75015
- purpose: z.string().min(1),
75016
- content: z.record(z.string(), z.unknown()).optional(),
75017
- draftContent: z.record(z.string(), z.unknown()).nullable().optional(),
75018
- bindings: z.record(z.string(), z.unknown()).optional()
75019
- }).passthrough();
75020
- const pagePath = z.string().regex(/^\/[\S]*$/, "path must start with \"/\" and contain no spaces");
75021
- z.object({
75022
- name: z.string().min(1),
75023
- path: pagePath,
75024
- purpose: z.string().min(1),
75025
- blocks: z.array(blockSchema).min(1)
75026
- });
75027
- //#endregion
75028
- //#region ../../node_modules/.pnpm/@vibrant+image@4.0.4/node_modules/@vibrant/image/dist/esm/histogram.js
75029
- var Histogram = class {
75030
- constructor(pixels, opts) {
75031
- this.pixels = pixels;
75032
- this.opts = opts;
75033
- const { sigBits } = opts;
75034
- const getColorIndex = (r2, g2, b2) => (r2 << 2 * sigBits) + (g2 << sigBits) + b2;
75035
- this.getColorIndex = getColorIndex;
75036
- const rshift = 8 - sigBits;
75037
- const hn = 1 << 3 * sigBits;
75038
- const hist = new Uint32Array(hn);
75039
- let rmax;
75040
- let rmin;
75041
- let gmax;
75042
- let gmin;
75043
- let bmax;
75044
- let bmin;
75045
- let r;
75046
- let g;
75047
- let b;
75048
- let a;
75049
- rmax = gmax = bmax = 0;
75050
- rmin = gmin = bmin = Number.MAX_VALUE;
75051
- const n = pixels.length / 4;
75052
- let i = 0;
75053
- while (i < n) {
75054
- const offset = i * 4;
75055
- i++;
75056
- r = pixels[offset + 0];
75057
- g = pixels[offset + 1];
75058
- b = pixels[offset + 2];
75059
- a = pixels[offset + 3];
75060
- if (a === 0) continue;
75061
- r = r >> rshift;
75062
- g = g >> rshift;
75063
- b = b >> rshift;
75064
- const index = getColorIndex(r, g, b);
75065
- if (hist[index] === void 0) hist[index] = 0;
75066
- hist[index] += 1;
75067
- if (r > rmax) rmax = r;
75068
- if (r < rmin) rmin = r;
75069
- if (g > gmax) gmax = g;
75070
- if (g < gmin) gmin = g;
75071
- if (b > bmax) bmax = b;
75072
- if (b < bmin) bmin = b;
75073
- }
75074
- this._colorCount = hist.reduce((total, c) => c > 0 ? total + 1 : total, 0);
75075
- this.hist = hist;
75076
- this.rmax = rmax;
75077
- this.rmin = rmin;
75078
- this.gmax = gmax;
75079
- this.gmin = gmin;
75080
- this.bmax = bmax;
75081
- this.bmin = bmin;
75082
- }
75083
- get colorCount() {
75084
- return this._colorCount;
75085
- }
75086
- };
75087
- //#endregion
75088
- //#region ../../node_modules/.pnpm/@vibrant+image@4.0.4/node_modules/@vibrant/image/dist/esm/index.js
75089
- var ImageBase = class {
75090
- scaleDown(opts) {
75091
- const width = this.getWidth();
75092
- const height = this.getHeight();
75093
- let ratio = 1;
75094
- if (opts.maxDimension > 0) {
75095
- const maxSide = Math.max(width, height);
75096
- if (maxSide > opts.maxDimension) ratio = opts.maxDimension / maxSide;
75097
- } else ratio = 1 / opts.quality;
75098
- if (ratio < 1) this.resize(width * ratio, height * ratio, ratio);
75099
- }
75100
- };
75101
- function applyFilters(imageData, filters) {
75102
- if (filters.length > 0) {
75103
- const pixels = imageData.data;
75104
- const n = pixels.length / 4;
75105
- let offset;
75106
- let r;
75107
- let g;
75108
- let b;
75109
- let a;
75110
- for (let i = 0; i < n; i++) {
75111
- offset = i * 4;
75112
- r = pixels[offset + 0];
75113
- g = pixels[offset + 1];
75114
- b = pixels[offset + 2];
75115
- a = pixels[offset + 3];
75116
- for (let j = 0; j < filters.length; j++) if (!filters[j]?.(r, g, b, a)) {
75117
- pixels[offset + 3] = 0;
75118
- break;
75119
- }
75120
- }
75121
- }
75122
- return imageData;
75123
- }
75124
- //#endregion
75125
- //#region ../../node_modules/.pnpm/@vibrant+image-browser@4.0.4/node_modules/@vibrant/image-browser/dist/esm/index.js
75126
- function isRelativeUrl(url) {
75127
- const u = new URL(url, location.href);
75128
- return u.protocol === location.protocol && u.host === location.host && u.port === location.port;
75129
- }
75130
- function isSameOrigin(a, b) {
75131
- const ua = new URL(a);
75132
- const ub = new URL(b);
75133
- return ua.protocol === ub.protocol && ua.hostname === ub.hostname && ua.port === ub.port;
75134
- }
75135
- var BrowserImage = class extends ImageBase {
75136
- _getCanvas() {
75137
- if (!this._canvas) throw new Error("Canvas is not initialized");
75138
- return this._canvas;
75139
- }
75140
- _getContext() {
75141
- if (!this._context) throw new Error("Context is not initialized");
75142
- return this._context;
75143
- }
75144
- _getWidth() {
75145
- if (!this._width) throw new Error("Width is not initialized");
75146
- return this._width;
75147
- }
75148
- _getHeight() {
75149
- if (!this._height) throw new Error("Height is not initialized");
75150
- return this._height;
75151
- }
75152
- _initCanvas() {
75153
- const img = this.image;
75154
- if (!img) throw new Error("Image is not initialized");
75155
- const canvas = this._canvas = document.createElement("canvas");
75156
- const context = canvas.getContext("2d");
75157
- if (!context) throw new ReferenceError("Failed to create canvas context");
75158
- this._context = context;
75159
- canvas.className = "@vibrant/canvas";
75160
- canvas.style.display = "none";
75161
- this._width = canvas.width = img.width;
75162
- this._height = canvas.height = img.height;
75163
- context.drawImage(img, 0, 0);
75164
- document.body.appendChild(canvas);
75165
- }
75166
- load(image) {
75167
- let img;
75168
- let src;
75169
- if (typeof image === "string") {
75170
- img = document.createElement("img");
75171
- src = image;
75172
- if (!isRelativeUrl(src) && !isSameOrigin(window.location.href, src)) img.crossOrigin = "anonymous";
75173
- img.src = src;
75174
- } else if (image instanceof HTMLImageElement) {
75175
- img = image;
75176
- src = image.src;
75177
- } else return Promise.reject(/* @__PURE__ */ new Error(`Cannot load buffer as an image in browser`));
75178
- this.image = img;
75179
- return new Promise((resolve, reject) => {
75180
- const onImageLoad = () => {
75181
- this._initCanvas();
75182
- resolve(this);
75183
- };
75184
- if (img.complete) onImageLoad();
75185
- else {
75186
- img.onload = onImageLoad;
75187
- img.onerror = (_e) => reject(/* @__PURE__ */ new Error(`Fail to load image: ${src}`));
74634
+ var BrowserImage = class extends ImageBase {
74635
+ _getCanvas() {
74636
+ if (!this._canvas) throw new Error("Canvas is not initialized");
74637
+ return this._canvas;
74638
+ }
74639
+ _getContext() {
74640
+ if (!this._context) throw new Error("Context is not initialized");
74641
+ return this._context;
74642
+ }
74643
+ _getWidth() {
74644
+ if (!this._width) throw new Error("Width is not initialized");
74645
+ return this._width;
74646
+ }
74647
+ _getHeight() {
74648
+ if (!this._height) throw new Error("Height is not initialized");
74649
+ return this._height;
74650
+ }
74651
+ _initCanvas() {
74652
+ const img = this.image;
74653
+ if (!img) throw new Error("Image is not initialized");
74654
+ const canvas = this._canvas = document.createElement("canvas");
74655
+ const context = canvas.getContext("2d");
74656
+ if (!context) throw new ReferenceError("Failed to create canvas context");
74657
+ this._context = context;
74658
+ canvas.className = "@vibrant/canvas";
74659
+ canvas.style.display = "none";
74660
+ this._width = canvas.width = img.width;
74661
+ this._height = canvas.height = img.height;
74662
+ context.drawImage(img, 0, 0);
74663
+ document.body.appendChild(canvas);
74664
+ }
74665
+ load(image) {
74666
+ let img;
74667
+ let src;
74668
+ if (typeof image === "string") {
74669
+ img = document.createElement("img");
74670
+ src = image;
74671
+ if (!isRelativeUrl(src) && !isSameOrigin(window.location.href, src)) img.crossOrigin = "anonymous";
74672
+ img.src = src;
74673
+ } else if (image instanceof HTMLImageElement) {
74674
+ img = image;
74675
+ src = image.src;
74676
+ } else return Promise.reject(/* @__PURE__ */ new Error(`Cannot load buffer as an image in browser`));
74677
+ this.image = img;
74678
+ return new Promise((resolve, reject) => {
74679
+ const onImageLoad = () => {
74680
+ this._initCanvas();
74681
+ resolve(this);
74682
+ };
74683
+ if (img.complete) onImageLoad();
74684
+ else {
74685
+ img.onload = onImageLoad;
74686
+ img.onerror = (_e) => reject(/* @__PURE__ */ new Error(`Fail to load image: ${src}`));
75188
74687
  }
75189
74688
  });
75190
74689
  }
@@ -76064,342 +75563,1112 @@ function isRouteMapEntry(value) {
76064
75563
  if (typeof value === "string") return true;
76065
75564
  return isPlainObject$1(value);
76066
75565
  }
76067
- function isRouteMap(value) {
76068
- if (!isPlainObject$1(value)) return false;
76069
- return Object.values(value).every(isRouteMapEntry);
75566
+ function isRouteMap(value) {
75567
+ if (!isPlainObject$1(value)) return false;
75568
+ return Object.values(value).every(isRouteMapEntry);
75569
+ }
75570
+ function isPageIdentifierMap(value) {
75571
+ if (!isPlainObject$1(value)) return false;
75572
+ return Object.values(value).every((v) => typeof v === "string");
75573
+ }
75574
+ function isEntryIdentifierMap(value) {
75575
+ if (!isPlainObject$1(value)) return false;
75576
+ for (const v of Object.values(value)) {
75577
+ if (!isPlainObject$1(v)) return false;
75578
+ if (!Object.values(v).every((inner) => typeof inner === "string")) return false;
75579
+ }
75580
+ return true;
75581
+ }
75582
+ function buildTransformContext(vm) {
75583
+ const root = vm.$root;
75584
+ const stage = root && isPlainObject$1(root) && root.previewStage === "preview" ? "preview" : "published";
75585
+ const routes = root && isPlainObject$1(root) && isRouteMap(root.routes) ? root.routes : void 0;
75586
+ const pagesByIdentifier = root && isPlainObject$1(root) && isPageIdentifierMap(root.pagesByIdentifier) ? root.pagesByIdentifier : void 0;
75587
+ const entriesByIdentifier = root && isPlainObject$1(root) && isEntryIdentifierMap(root.entriesByIdentifier) ? root.entriesByIdentifier : void 0;
75588
+ return {
75589
+ theme: defaultThemeTokens,
75590
+ stage,
75591
+ data: vm.content,
75592
+ routes,
75593
+ pagesByIdentifier,
75594
+ entriesByIdentifier
75595
+ };
75596
+ }
75597
+ function resolveParamsBindings(input, vm, meta) {
75598
+ if (input === null || typeof input !== "object") return input;
75599
+ if (Array.isArray(input)) return input.map((v) => resolveParamsBindings(v, vm, meta));
75600
+ const maybeBind = input.$bind;
75601
+ if (maybeBind && typeof maybeBind === "object") try {
75602
+ const binding = bindingSchema.parse(maybeBind);
75603
+ const value = resolveBinding(binding.from, vm);
75604
+ const resolved = value === void 0 || value === null ? binding.fallback : runTransforms(value, binding.transforms, buildTransformContext(vm), defaultTransforms);
75605
+ if (resolved === void 0 || resolved === null || resolved === "") return binding.fallback;
75606
+ return resolved;
75607
+ } catch (err) {
75608
+ if (shouldLogWarnings) console.warn(`bindings: failed to parse loader param binding for block "${meta?.blockKind ?? "unknown"}"`, err);
75609
+ return;
75610
+ }
75611
+ const out = {};
75612
+ for (const [k, v] of Object.entries(input)) out[k] = resolveParamsBindings(v, vm, meta);
75613
+ return out;
75614
+ }
75615
+ function resolveBinding(path, vm) {
75616
+ const segments = splitPath(path);
75617
+ if (!segments.length) return void 0;
75618
+ const [first, ...rest] = segments;
75619
+ let source = vm;
75620
+ if (first === "$root") {
75621
+ source = vm;
75622
+ return readFromSource(source, [first, ...rest]);
75623
+ }
75624
+ if (first === "content") {
75625
+ source = vm.content;
75626
+ return readFromSource(source, rest);
75627
+ }
75628
+ const contentResult = readFromSource(vm.content, segments);
75629
+ if (contentResult !== void 0) return contentResult;
75630
+ return readFromSource(vm, segments);
75631
+ }
75632
+ function splitPath(path) {
75633
+ const PATH_SEPARATOR_REGEX = /\./g;
75634
+ const BRACKET_ACCESS_REGEX = /\[(?<token>[^\]]+)\]/g;
75635
+ const segments = [];
75636
+ const parts = path.split(PATH_SEPARATOR_REGEX);
75637
+ for (const raw of parts) {
75638
+ if (!raw) continue;
75639
+ const baseMatch = raw.match(/^([^\[]+)/);
75640
+ if (baseMatch && baseMatch[1]) segments.push(baseMatch[1]);
75641
+ const bracketMatches = raw.matchAll(BRACKET_ACCESS_REGEX);
75642
+ for (const match of bracketMatches) {
75643
+ const token = match.groups?.token ?? "";
75644
+ if (token.startsWith("\"") || token.startsWith("'")) segments.push(token.slice(1, -1));
75645
+ else if (/^\d+$/.test(token)) segments.push(Number(token));
75646
+ else segments.push(token);
75647
+ }
75648
+ if (!baseMatch && !raw.includes("[")) segments.push(raw);
75649
+ }
75650
+ return segments;
75651
+ }
75652
+ function readFromSource(source, segments) {
75653
+ return segments.reduce((current, segment) => {
75654
+ if (current === void 0 || current === null) return void 0;
75655
+ if (typeof segment === "number") {
75656
+ if (Array.isArray(current)) return current[segment];
75657
+ return;
75658
+ }
75659
+ if (typeof current === "object" && current !== null && segment in current) return current[segment];
75660
+ }, source);
75661
+ }
75662
+ function isNonProductionEnv() {
75663
+ if (typeof globalThis === "undefined") return true;
75664
+ return globalThis.process?.env?.NODE_ENV !== "production";
75665
+ }
75666
+ function isNonArrayObject(value) {
75667
+ return typeof value === "object" && value !== null && !Array.isArray(value);
75668
+ }
75669
+ function safeJsonStringify(value) {
75670
+ try {
75671
+ return JSON.stringify(value);
75672
+ } catch {
75673
+ return;
75674
+ }
75675
+ }
75676
+ /**
75677
+ * Coerce value to string for API params
75678
+ */
75679
+ function coerceToString(value) {
75680
+ if (value === null || value === void 0) return "";
75681
+ if (Array.isArray(value)) {
75682
+ if (value.some(isNonArrayObject)) {
75683
+ const json = safeJsonStringify(value);
75684
+ if (typeof json === "string") return json;
75685
+ }
75686
+ return value.map(coerceToString).join(",");
75687
+ }
75688
+ if (isNonArrayObject(value)) {
75689
+ const json = safeJsonStringify(value);
75690
+ if (typeof json === "string") return json;
75691
+ }
75692
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
75693
+ return "";
75694
+ }
75695
+ //#endregion
75696
+ //#region ../blocks/src/system/data/loaderEndpoints.ts
75697
+ const SUPPORTED_LOADER_ENDPOINTS$1 = [
75698
+ "listPublishedEntries",
75699
+ "getPublishedEntryPreview",
75700
+ "listPublicEvents",
75701
+ "listPublicEventCalendarWindow",
75702
+ "listPublicRecurringSchedule",
75703
+ "getPublicEventDetails",
75704
+ "listPublicRouteCandidates",
75705
+ "listPublicTeamMembers",
75706
+ "listPublicProducts",
75707
+ "listPublicPasses",
75708
+ "listPublicMemberships",
75709
+ "getPublicFormById",
75710
+ "getPublicBookingServices",
75711
+ "getPublicWeeklySlotAvailability"
75712
+ ];
75713
+ //#endregion
75714
+ //#region ../blocks/src/system/data/batching.ts
75715
+ function stableNormalize(value) {
75716
+ if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
75717
+ if (Array.isArray(value)) return value.map(stableNormalize);
75718
+ if (typeof value === "object" && value) {
75719
+ const obj = value;
75720
+ const keys = Object.keys(obj).sort();
75721
+ const out = {};
75722
+ for (const key of keys) {
75723
+ const v = obj[key];
75724
+ if (v === void 0) continue;
75725
+ out[key] = stableNormalize(v);
75726
+ }
75727
+ return out;
75728
+ }
75729
+ if (typeof value === "bigint" || typeof value === "symbol" || typeof value === "undefined") return String(value);
75730
+ return null;
75731
+ }
75732
+ const RichText$1 = RichText$2;
75733
+ //#endregion
75734
+ //#region ../blocks/src/system/customize/facets.ts
75735
+ function defineCustomizeFacet(definition) {
75736
+ return definition;
75737
+ }
75738
+ const systemCustomizeFacetDefinitions = [defineCustomizeFacet({
75739
+ blockKind: "block.event-calendar",
75740
+ id: "eventCalendar.listLayout",
75741
+ label: "List style",
75742
+ values: eventCalendarListLayoutOptions.map((option) => ({
75743
+ value: option.id,
75744
+ label: option.label
75745
+ })),
75746
+ defaultValue: "stack",
75747
+ target: { kind: "event-calendar-list-layout-content" },
75748
+ appliesToLayoutVariants: eventCalendarListLayoutCompatibleDisplayModeValues
75749
+ })];
75750
+ systemCustomizeFacetDefinitions.map((definition) => definition.id);
75751
+ Array.from(new Set(systemCustomizeFacetDefinitions.flatMap((definition) => definition.values.map((option) => option.value))));
75752
+ const backgroundColorTokenNames = backgroundAppearanceColorTokenNames;
75753
+ const backgroundColorTokenNameSet = new Set(backgroundColorTokenNames);
75754
+ const backgroundColorTokens = toBackgroundColorTokens(backgroundColorTokenNames);
75755
+ const quickBackgroundColorTokens = toBackgroundColorTokens(backgroundAppearanceQuickColorTokenNames);
75756
+ backgroundColorTokens.filter((token) => !quickBackgroundColorTokens.includes(token));
75757
+ function toBackgroundColorTokens(tokenNames) {
75758
+ return tokenNames.flatMap((name) => {
75759
+ const token = parseBackgroundColorToken(name);
75760
+ if (!token) return [];
75761
+ return [token];
75762
+ });
75763
+ }
75764
+ function parseBackgroundColorToken(value) {
75765
+ if (typeof value !== "string") return null;
75766
+ const normalized = value.trim();
75767
+ if (!backgroundColorTokenNameSet.has(normalized)) return null;
75768
+ const token = parseBackgroundAppearanceColorToken(normalized);
75769
+ if (!token) return null;
75770
+ return token ? token : null;
75771
+ }
75772
+ //#endregion
75773
+ //#region src/rendering/helpers/siteCustomBlocks.ts
75774
+ /**
75775
+ * Prefer the DB-backed custom block manifest list (`site.customBlocks`) when available,
75776
+ * but fall back to SDK config custom blocks (`site.sdkConfig.customBlocks`) for SDK-mode sites.
75777
+ *
75778
+ * This avoids subtle DX bugs where one source is populated but the renderer/prefetch layer
75779
+ * is looking at the other.
75780
+ */
75781
+ function resolveSiteCustomBlocks(site) {
75782
+ const dbBlocks = site.customBlocks;
75783
+ if (Array.isArray(dbBlocks) && dbBlocks.length > 0) return dbBlocks;
75784
+ const sdkBlocks = site.sdkConfig?.customBlocks;
75785
+ if (Array.isArray(sdkBlocks) && sdkBlocks.length > 0) return sdkBlocks;
75786
+ }
75787
+ function readBlockContentId(value, name) {
75788
+ if (value === null || value === void 0) return null;
75789
+ if (typeof value === "string") return value;
75790
+ throw new Error(`Invalid ${name} in page: expected string or null`);
75791
+ }
75792
+ function readTransportedBlockIdentity(block, kind, stage) {
75793
+ return {
75794
+ draftContentId: readBlockContentId(block.draftContentId, "draft content id"),
75795
+ publishedPlacement: stage === "preview" ? readSdkPreviewPublishedPlacement(block, kind) : null
75796
+ };
75797
+ }
75798
+ /** Pair SDK preview publication data whether it is transported or already admitted. */
75799
+ function readSdkPreviewPublishedPlacement(block, kind) {
75800
+ if (block.publishedPlacement !== void 0 && block.publishedPlacement !== null) {
75801
+ if (!isRecord$8(block.publishedPlacement)) throw new Error("Invalid published placement in page");
75802
+ return readPublishedBlockPlacement(readBlockContentId(block.publishedPlacement.id, "published content id"), sanitizeNullableSdkRuntimeBlockContent(kind, readContentRecord(block.publishedPlacement.content) ?? null));
75803
+ }
75804
+ return readPublishedBlockPlacement(readBlockContentId(block.publishedContentId, "published content id"), sanitizeNullableSdkRuntimeBlockContent(kind, readSdkPublishedContentRecord(block.publishedContent)));
75805
+ }
75806
+ function convertPageResponseBlock(block, stage) {
75807
+ if (!isRecord$8(block)) throw new Error("Invalid block format in page API response");
75808
+ const header = readTransportedBlockHeader(block);
75809
+ const admission = readInvalidBlockAdmission(block.admission);
75810
+ return {
75811
+ ...header,
75812
+ ...readTransportedBlockIdentity(block, header.kind, stage),
75813
+ content: sanitizeSdkRuntimeBlockContent(header.kind, readContentRecord(block.content) ?? {}),
75814
+ draftContent: sanitizeNullableSdkRuntimeBlockContent(header.kind, readNestedContentRecord(block.draftContent)),
75815
+ ...admission ? { admission } : {}
75816
+ };
75817
+ }
75818
+ function readTransportedBlockHeader(block) {
75819
+ if (typeof block.id !== "string" && block.id !== null) throw new Error(`Invalid block id in page: expected string or null, got ${typeof block.id}`);
75820
+ if (typeof block.kind !== "string") throw new Error(`Invalid block kind in page: expected string, got ${typeof block.kind}`);
75821
+ if (typeof block.purpose !== "string") throw new Error(`Invalid block purpose in page: expected string, got ${typeof block.purpose}`);
75822
+ if (block.contentVersionId !== void 0 && block.contentVersionId !== null && typeof block.contentVersionId !== "string") throw new Error(`Invalid content version id in page: expected string or null, got ${typeof block.contentVersionId}`);
75823
+ return {
75824
+ id: block.id,
75825
+ ...block.contentVersionId !== void 0 ? { contentVersionId: block.contentVersionId } : {},
75826
+ kind: block.kind,
75827
+ purpose: block.purpose
75828
+ };
75829
+ }
75830
+ function readInvalidBlockAdmission(value) {
75831
+ if (!isRecord$8(value) || value.kind !== "invalid" || !isRecord$8(value.error)) return null;
75832
+ if (value.error.kind !== "invalid_manifest_content" && value.error.kind !== "manifest_unavailable") return null;
75833
+ return value;
75834
+ }
75835
+ function buildPageOutline(input) {
75836
+ return {
75837
+ name: input.name,
75838
+ path: input.path ?? input.fallbackPath,
75839
+ purpose: input.purpose,
75840
+ blocks: input.blocks.map((block) => convertPageResponseBlock(block, input.previewStage))
75841
+ };
75842
+ }
75843
+ function buildRenderablePageOutline(input) {
75844
+ const page = buildPageOutline(input);
75845
+ return {
75846
+ ...page,
75847
+ blocks: page.blocks.map((block) => admitSdkRuntimePageBlock(block, input.customBlocks))
75848
+ };
75849
+ }
75850
+ function admitSdkRuntimePageBlock(block, customBlocks) {
75851
+ const base = {
75852
+ id: block.id,
75853
+ draftContentId: block.draftContentId,
75854
+ publishedPlacement: block.publishedPlacement,
75855
+ ...block.contentVersionId !== void 0 ? { contentVersionId: block.contentVersionId } : {},
75856
+ kind: block.kind,
75857
+ purpose: block.purpose,
75858
+ ...block.bindings ? { bindings: block.bindings } : {}
75859
+ };
75860
+ const transportedAdmission = readInvalidBlockAdmission(block.admission);
75861
+ if (transportedAdmission) return invalidRenderableBlock(base, transportedAdmission.error);
75862
+ const manifest = resolveSdkBlockManifest(block.kind, customBlocks);
75863
+ if (!manifest) return invalidRenderableBlock(base, { kind: "manifest_unavailable" });
75864
+ const content = block.content ?? {};
75865
+ const renderable = admitTransportedRenderableManifestContent(compileManifestContentContract(manifest), content);
75866
+ if (!renderable.ok) return invalidRenderableBlock(base, {
75867
+ kind: "invalid_manifest_content",
75868
+ error: renderable.error
75869
+ });
75870
+ return {
75871
+ ...base,
75872
+ admission: {
75873
+ kind: "renderable",
75874
+ content: renderable.value
75875
+ }
75876
+ };
75877
+ }
75878
+ function resolveSdkBlockManifest(blockKind, customBlocks) {
75879
+ const customBlock = customBlocks?.find((candidate) => candidate.id === blockKind);
75880
+ return customBlock ? parseFieldDefinitions(customBlock.fields) : getBlockDefinition(blockKind)?.manifest ?? null;
75881
+ }
75882
+ function invalidRenderableBlock(block, error) {
75883
+ return {
75884
+ ...block,
75885
+ admission: {
75886
+ kind: "invalid",
75887
+ error
75888
+ }
75889
+ };
75890
+ }
75891
+ function isRecord$8(value) {
75892
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
75893
+ }
75894
+ function readContentRecord(value) {
75895
+ return isRecord$8(value) ? value : void 0;
75896
+ }
75897
+ function readNestedContentRecord(value) {
75898
+ if (!isRecord$8(value)) return null;
75899
+ return readContentRecord(value.data) ?? null;
75900
+ }
75901
+ function readSdkPublishedContentRecord(value) {
75902
+ if (!isRecord$8(value)) return null;
75903
+ return "data" in value ? readContentRecord(value.data) ?? null : value;
75904
+ }
75905
+ function sanitizeSdkRuntimeBlockContent(blockKind, content) {
75906
+ if (blockKind !== "block.newsletter-signup") return content;
75907
+ const sanitized = sanitizeNewsletterSignupPublicContent(content);
75908
+ return isRecord$8(sanitized) ? sanitized : {};
75909
+ }
75910
+ function sanitizeNullableSdkRuntimeBlockContent(blockKind, content) {
75911
+ return content ? sanitizeSdkRuntimeBlockContent(blockKind, content) : null;
75912
+ }
75913
+ function isOverrideOnlyPageRenderer(props) {
75914
+ return props.rendering?.kind === "overrides-only";
75915
+ }
75916
+ function normalizeSdkCustomBlocks(customBlocks) {
75917
+ if (!customBlocks) return void 0;
75918
+ return customBlocks.map((block) => {
75919
+ return {
75920
+ ...block,
75921
+ fields: parseFieldDefinitions(block.fields)
75922
+ };
75923
+ });
75924
+ }
75925
+ function toBlocksBlockOverrides(overrides) {
75926
+ if (!overrides) return void 0;
75927
+ const result = {};
75928
+ for (const [key, OverrideComponent] of Object.entries(overrides)) result[key] = function BlocksOverrideAdapter(props) {
75929
+ const sdkOverride = OverrideComponent;
75930
+ return React$1.createElement(sdkOverride, {
75931
+ ...props,
75932
+ entrySubrouteContext: props.entrySubrouteContext
75933
+ });
75934
+ };
75935
+ return result;
75936
+ }
75937
+ function toBlocksPageRendererDataContext(dataContext) {
75938
+ return {
75939
+ ...dataContext,
75940
+ mediaAssets: toBlocksMediaAssets(dataContext.mediaAssets),
75941
+ imageResolveContext: toBlocksImageResolveContextInput(dataContext.imageResolveContext)
75942
+ };
75943
+ }
75944
+ function toBlocksCommonProps(props) {
75945
+ return {
75946
+ page: props.page,
75947
+ runtimeJoins: props.runtimeJoins,
75948
+ dataContext: toBlocksPageRendererDataContext(props.dataContext),
75949
+ routeMap: props.routeMap,
75950
+ wrapBlock: props.wrapBlock,
75951
+ registry: props.registry,
75952
+ blockOverrides: toBlocksBlockOverrides(props.blockOverrides),
75953
+ sdkConfig: props.sdkConfig ? { customBlocks: normalizeSdkCustomBlocks(props.sdkConfig.customBlocks) } : props.sdkConfig,
75954
+ customBlocks: normalizeSdkCustomBlocks(props.customBlocks)
75955
+ };
75956
+ }
75957
+ function PageRenderer(props) {
75958
+ const commonBlocksProps = toBlocksCommonProps(props);
75959
+ const blocksProps = isOverrideOnlyPageRenderer(props) ? {
75960
+ ...commonBlocksProps,
75961
+ rendering: { kind: "overrides-only" },
75962
+ blockOverrides: toBlocksBlockOverrides(props.blockOverrides) ?? {}
75963
+ } : {
75964
+ ...commonBlocksProps,
75965
+ theme: parseBlocksTheme(props.theme),
75966
+ themeTokens: props.themeTokens
75967
+ };
75968
+ return React$1.createElement(PageRenderer$1, blocksProps);
75969
+ }
75970
+ //#endregion
75971
+ //#region src/rendering/blocks-theme-scope.ts
75972
+ function ThemeScope(props) {
75973
+ const { theme, children, ...rest } = props;
75974
+ const blocksTheme = parseBlocksTheme(theme);
75975
+ return React$1.createElement(ThemeScope$1, {
75976
+ ...rest,
75977
+ theme: blocksTheme,
75978
+ children: children ?? null
75979
+ });
75980
+ }
75981
+ //#endregion
75982
+ //#region src/rendering/themeRuntime.tsx
75983
+ const defaultLayoutThemeRuntime = { kind: "cms-theme" };
75984
+ const defaultSdkChromeThemeRuntime = { kind: "responsive-only" };
75985
+ const defaultPageThemeRuntime = { kind: "none" };
75986
+ function planLayoutThemeRuntime(input) {
75987
+ const requested = input.themeRuntime ?? defaultLayoutThemeRuntime;
75988
+ if (requested.kind === "none" && input.usesSdkChrome) {
75989
+ if (process.env.NODE_ENV !== "production") console.warn("[sdk] Layout themeRuntime { kind: \"none\" } is not compatible with SDK-managed header/footer chrome; using responsive-only runtime instead.");
75990
+ return defaultSdkChromeThemeRuntime;
75991
+ }
75992
+ return requested;
75993
+ }
75994
+ function renderWithSdkThemeRuntime({ themeRuntime, theme, children }) {
75995
+ switch (themeRuntime.kind) {
75996
+ case "cms-theme": return /* @__PURE__ */ jsx(ThemeScope, {
75997
+ theme,
75998
+ responsiveMode: themeRuntime.responsiveMode,
75999
+ children
76000
+ });
76001
+ case "responsive-only": return /* @__PURE__ */ jsx(ResponsiveScope, {
76002
+ responsiveMode: themeRuntime.responsiveMode,
76003
+ children
76004
+ });
76005
+ case "none": return /* @__PURE__ */ jsx(Fragment, { children });
76006
+ default: return assertNever$21(themeRuntime);
76007
+ }
76008
+ }
76009
+ function renderWithOverrideOnlyRuntime({ runtime, children }) {
76010
+ switch (runtime.kind) {
76011
+ case "responsive-only": return /* @__PURE__ */ jsx(ResponsiveScope, {
76012
+ responsiveMode: runtime.responsiveMode,
76013
+ children
76014
+ });
76015
+ case "none": return /* @__PURE__ */ jsx(Fragment, { children });
76016
+ default: return assertNever$21(runtime);
76017
+ }
76018
+ }
76019
+ //#endregion
76020
+ //#region src/rendering/components/pageShared.tsx
76021
+ function isOverrideOnlyPage(props) {
76022
+ return props.rendering?.kind === "overrides-only";
76023
+ }
76024
+ function resolvePageThemeTokens(props) {
76025
+ const baseTokens = props.themeTokens ?? buildThemeRuntime(props.theme).tokens;
76026
+ return props.sdkConfig?.theme?.palette ? {
76027
+ ...baseTokens,
76028
+ palette: {
76029
+ ...baseTokens.palette,
76030
+ ...props.sdkConfig.theme.palette
76031
+ }
76032
+ } : baseTokens;
76033
+ }
76034
+ function toPageHydrationBootstrapConfig(props) {
76035
+ return {
76036
+ siteId: props.siteId,
76037
+ supabaseUrl: props.supabaseUrl,
76038
+ mediaAssets: props.mediaAssets
76039
+ };
76070
76040
  }
76071
- function isPageIdentifierMap(value) {
76072
- if (!isPlainObject$1(value)) return false;
76073
- return Object.values(value).every((v) => typeof v === "string");
76041
+ function resolveSdkBookingTimeZone(timeZone) {
76042
+ return timeZone ?? "UTC";
76074
76043
  }
76075
- function isEntryIdentifierMap(value) {
76076
- if (!isPlainObject$1(value)) return false;
76077
- for (const v of Object.values(value)) {
76078
- if (!isPlainObject$1(v)) return false;
76079
- if (!Object.values(v).every((inner) => typeof inner === "string")) return false;
76080
- }
76081
- return true;
76044
+ function buildPageRouteRenderContext(dataContext) {
76045
+ return {
76046
+ ...buildPageIdentityRenderContext(dataContext),
76047
+ occurrenceContext: dataContext.occurrenceContext ?? null,
76048
+ entrySubrouteContext: dataContext.entrySubrouteContext ?? null,
76049
+ contentEntry: dataContext.contentEntry ?? null,
76050
+ pageSurface: dataContext.pageSurface ?? null,
76051
+ subject: dataContext.subject ?? null,
76052
+ editableRouteMetadataFieldIds: dataContext.editableRouteMetadataFieldIds ?? null,
76053
+ previewStage: dataContext.previewStage
76054
+ };
76082
76055
  }
76083
- function buildTransformContext(vm) {
76084
- const root = vm.$root;
76085
- const stage = root && isPlainObject$1(root) && root.previewStage === "preview" ? "preview" : "published";
76086
- const routes = root && isPlainObject$1(root) && isRouteMap(root.routes) ? root.routes : void 0;
76087
- const pagesByIdentifier = root && isPlainObject$1(root) && isPageIdentifierMap(root.pagesByIdentifier) ? root.pagesByIdentifier : void 0;
76088
- const entriesByIdentifier = root && isPlainObject$1(root) && isEntryIdentifierMap(root.entriesByIdentifier) ? root.entriesByIdentifier : void 0;
76056
+ function buildPageIdentityRenderContext(dataContext) {
76089
76057
  return {
76090
- theme: defaultThemeTokens,
76091
- stage,
76092
- data: vm.content,
76093
- routes,
76094
- pagesByIdentifier,
76095
- entriesByIdentifier
76058
+ demoEmailSuppressed: dataContext.demoEmailSuppressed,
76059
+ siteName: dataContext.siteName,
76060
+ pathname: dataContext.pathname
76096
76061
  };
76097
76062
  }
76098
- function resolveParamsBindings(input, vm, meta) {
76099
- if (input === null || typeof input !== "object") return input;
76100
- if (Array.isArray(input)) return input.map((v) => resolveParamsBindings(v, vm, meta));
76101
- const maybeBind = input.$bind;
76102
- if (maybeBind && typeof maybeBind === "object") try {
76103
- const binding = bindingSchema.parse(maybeBind);
76104
- const value = resolveBinding(binding.from, vm);
76105
- const resolved = value === void 0 || value === null ? binding.fallback : runTransforms(value, binding.transforms, buildTransformContext(vm), defaultTransforms);
76106
- if (resolved === void 0 || resolved === null || resolved === "") return binding.fallback;
76107
- return resolved;
76108
- } catch (err) {
76109
- if (shouldLogWarnings) console.warn(`bindings: failed to parse loader param binding for block "${meta?.blockKind ?? "unknown"}"`, err);
76110
- return;
76111
- }
76112
- const out = {};
76113
- for (const [k, v] of Object.entries(input)) out[k] = resolveParamsBindings(v, vm, meta);
76114
- return out;
76063
+ function PageContent(props) {
76064
+ const { page, runtimeJoins, siteId, resolvedData, bookingOfferingPresets, mailingList, bookingTimeZone, routeMap, pagesByIdentifier, entriesByIdentifier, wrapBlock, registry, blockOverrides, sdkConfig, customBlocks, supabaseUrl, mediaAssets, apiBaseUrl, portalToken, previewToken, readAuthority, dataContext } = props;
76065
+ const rendererCommonProps = {
76066
+ page,
76067
+ runtimeJoins,
76068
+ dataContext: {
76069
+ siteId,
76070
+ ...buildPageRouteRenderContext(dataContext),
76071
+ apiBaseUrl,
76072
+ portalToken,
76073
+ previewToken,
76074
+ readAuthority: readAuthority ?? dataContext.readAuthority,
76075
+ resolvedData,
76076
+ bookingOfferingPresets: bookingOfferingPresets ?? [],
76077
+ mailingList: mailingList ?? dataContext.mailingList,
76078
+ bookingTimeZone: resolveSdkBookingTimeZone(bookingTimeZone),
76079
+ routes: routeMap,
76080
+ pagesByIdentifier,
76081
+ entriesByIdentifier,
76082
+ supabaseUrl,
76083
+ mediaAssets,
76084
+ imageResolveContext: {
76085
+ siteId,
76086
+ supabaseUrl,
76087
+ mediaAssets
76088
+ }
76089
+ },
76090
+ routeMap,
76091
+ wrapBlock,
76092
+ registry,
76093
+ sdkConfig: sdkConfig ? { customBlocks: sdkConfig.customBlocks } : null,
76094
+ customBlocks
76095
+ };
76096
+ const content = isOverrideOnlyPage(props) ? /* @__PURE__ */ jsx(PageRenderer, {
76097
+ ...rendererCommonProps,
76098
+ rendering: { kind: "overrides-only" },
76099
+ blockOverrides: props.blockOverrides
76100
+ }) : /* @__PURE__ */ jsx(PageRenderer, {
76101
+ ...rendererCommonProps,
76102
+ theme: props.theme,
76103
+ themeTokens: resolvePageThemeTokens(props),
76104
+ blockOverrides
76105
+ });
76106
+ return isOverrideOnlyPage(props) ? renderWithOverrideOnlyRuntime({
76107
+ runtime: props.rendering.runtime,
76108
+ children: content
76109
+ }) : renderWithSdkThemeRuntime({
76110
+ themeRuntime: props.themeRuntime ?? defaultPageThemeRuntime,
76111
+ theme: props.theme,
76112
+ children: content
76113
+ });
76115
76114
  }
76116
- function resolveBinding(path, vm) {
76117
- const segments = splitPath(path);
76118
- if (!segments.length) return void 0;
76119
- const [first, ...rest] = segments;
76120
- let source = vm;
76121
- if (first === "$root") {
76122
- source = vm;
76123
- return readFromSource(source, [first, ...rest]);
76124
- }
76125
- if (first === "content") {
76126
- source = vm.content;
76127
- return readFromSource(source, rest);
76128
- }
76129
- const contentResult = readFromSource(vm.content, segments);
76130
- if (contentResult !== void 0) return contentResult;
76131
- return readFromSource(vm, segments);
76115
+ //#endregion
76116
+ //#region src/rendering/components/Page.tsx
76117
+ const HydratorWithContextProps$1 = BlocksIslandsHydrator;
76118
+ /**
76119
+ * Default renderer for Riverbank CMS pages.
76120
+ *
76121
+ * This component expects all data to be provided via props and automatically
76122
+ * mounts the CMS island hydration bootstrap.
76123
+ * For data fetching, use:
76124
+ * - Server-side: `await loadPage({ client, siteId, path })`
76125
+ * - Client-side: `usePage({ client, siteId, path })`
76126
+ *
76127
+ * @example Server-side (Next.js App Router)
76128
+ * ```tsx
76129
+ * import { createRiverbankClient } from '@riverbankcms/sdk';
76130
+ * import { loadPage, Page } from '@riverbankcms/sdk/rendering';
76131
+ *
76132
+ * const client = createRiverbankClient({ apiKey, baseUrl });
76133
+ *
76134
+ * export default async function PageRoute({ params }) {
76135
+ * const pageData = await loadPage({
76136
+ * client,
76137
+ * siteId: 'site-id',
76138
+ * path: `/${params.slug}`,
76139
+ * });
76140
+ *
76141
+ * return <Page {...pageData} />;
76142
+ * }
76143
+ * ```
76144
+ *
76145
+ * @example Client-side
76146
+ * ```tsx
76147
+ * import { createRiverbankClient } from '@riverbankcms/sdk';
76148
+ * import { usePage, Page } from '@riverbankcms/sdk/rendering';
76149
+ *
76150
+ * const client = createRiverbankClient({ apiKey, baseUrl });
76151
+ *
76152
+ * function MyPage({ path }) {
76153
+ * const pageData = usePage({ client, siteId: 'site-id', path });
76154
+ *
76155
+ * if (pageData.loading) return <LoadingState />;
76156
+ * if (pageData.error) return <ErrorState error={pageData.error} />;
76157
+ * if (!pageData.page) return <NotFound />;
76158
+ *
76159
+ * return <Page {...pageData} />;
76160
+ * }
76161
+ * ```
76162
+ */
76163
+ function Page(props) {
76164
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(HydratorWithContextProps$1, { ...toPageHydrationBootstrapConfig(props) }), /* @__PURE__ */ jsx(PageContent, { ...props })] });
76132
76165
  }
76133
- function splitPath(path) {
76134
- const PATH_SEPARATOR_REGEX = /\./g;
76135
- const BRACKET_ACCESS_REGEX = /\[(?<token>[^\]]+)\]/g;
76136
- const segments = [];
76137
- const parts = path.split(PATH_SEPARATOR_REGEX);
76138
- for (const raw of parts) {
76139
- if (!raw) continue;
76140
- const baseMatch = raw.match(/^([^\[]+)/);
76141
- if (baseMatch && baseMatch[1]) segments.push(baseMatch[1]);
76142
- const bracketMatches = raw.matchAll(BRACKET_ACCESS_REGEX);
76143
- for (const match of bracketMatches) {
76144
- const token = match.groups?.token ?? "";
76145
- if (token.startsWith("\"") || token.startsWith("'")) segments.push(token.slice(1, -1));
76146
- else if (/^\d+$/.test(token)) segments.push(Number(token));
76147
- else segments.push(token);
76148
- }
76149
- if (!baseMatch && !raw.includes("[")) segments.push(raw);
76166
+ //#endregion
76167
+ //#region src/env.ts
76168
+ /**
76169
+ * Error thrown when required environment variables are missing
76170
+ */
76171
+ var RiverbankEnvError = class extends Error {
76172
+ constructor(message, missingVars) {
76173
+ super(message);
76174
+ this.missingVars = missingVars;
76175
+ this.name = "RiverbankEnvError";
76150
76176
  }
76151
- return segments;
76152
- }
76153
- function readFromSource(source, segments) {
76154
- return segments.reduce((current, segment) => {
76155
- if (current === void 0 || current === null) return void 0;
76156
- if (typeof segment === "number") {
76157
- if (Array.isArray(current)) return current[segment];
76158
- return;
76159
- }
76160
- if (typeof current === "object" && current !== null && segment in current) return current[segment];
76161
- }, source);
76162
- }
76163
- function isNonProductionEnv() {
76164
- if (typeof globalThis === "undefined") return true;
76165
- return globalThis.process?.env?.NODE_ENV !== "production";
76177
+ };
76178
+ /**
76179
+ * Get the environment variable prefix based on target
76180
+ */
76181
+ function getEnvPrefix(target) {
76182
+ return target === "remote" ? "RIVERBANK_REMOTE" : "RIVERBANK_LOCAL";
76166
76183
  }
76167
- function isNonArrayObject(value) {
76168
- return typeof value === "object" && value !== null && !Array.isArray(value);
76184
+ /**
76185
+ * Detect the environment target from RIVERBANK_ENV
76186
+ */
76187
+ function detectTarget() {
76188
+ const env = process.env.RIVERBANK_ENV?.toLowerCase();
76189
+ if (env === "remote" || env === "production" || env === "prod") return "remote";
76190
+ return "local";
76169
76191
  }
76170
- function safeJsonStringify(value) {
76171
- try {
76172
- return JSON.stringify(value);
76173
- } catch {
76174
- return;
76175
- }
76192
+ /**
76193
+ * Detect if preview mode is enabled.
76194
+ * Uses RIVERBANK_PREVIEW_MODE first, then falls back to RIVERBANK_PREVIEW for backward compat.
76195
+ */
76196
+ function detectPreviewMode() {
76197
+ const previewMode = process.env.RIVERBANK_PREVIEW_MODE;
76198
+ if (previewMode !== void 0 && previewMode !== "") return previewMode === "true";
76199
+ const previewLegacy = process.env.RIVERBANK_PREVIEW;
76200
+ if (previewLegacy !== void 0 && previewLegacy !== "") return previewLegacy === "true";
76201
+ return process.env.VERCEL_ENV === "preview";
76176
76202
  }
76177
76203
  /**
76178
- * Coerce value to string for API params
76204
+ * Validate that an API key matches the expected format for its type
76179
76205
  */
76180
- function coerceToString(value) {
76181
- if (value === null || value === void 0) return "";
76182
- if (Array.isArray(value)) {
76183
- if (value.some(isNonArrayObject)) {
76184
- const json = safeJsonStringify(value);
76185
- if (typeof json === "string") return json;
76186
- }
76187
- return value.map(coerceToString).join(",");
76188
- }
76189
- if (isNonArrayObject(value)) {
76190
- const json = safeJsonStringify(value);
76191
- if (typeof json === "string") return json;
76206
+ function validateKeyType(key, expectedType) {
76207
+ const isPreviewKey = key.startsWith("bld_preview_sk_");
76208
+ const isContentKey = key.startsWith("bld_live_sk_");
76209
+ if (expectedType === "preview" && !isPreviewKey) {
76210
+ if (isContentKey) throw new RiverbankEnvError("Preview mode is enabled (RIVERBANK_PREVIEW_MODE=true) but a content key was provided. Preview mode requires a preview API key (bld_preview_sk_...) to access draft content. Either:\n 1. Set RIVERBANK_*_PREVIEW_API_KEY with your preview key, or\n 2. Set RIVERBANK_PREVIEW_MODE=false to fetch published content instead.", []);
76211
+ throw new RiverbankEnvError(`Invalid API key format for preview mode. Expected key starting with bld_preview_sk_`, []);
76192
76212
  }
76193
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value);
76194
- return "";
76195
- }
76196
- //#endregion
76197
- //#region ../blocks/src/system/data/loaderEndpoints.ts
76198
- const SUPPORTED_LOADER_ENDPOINTS$1 = [
76199
- "listPublishedEntries",
76200
- "getPublishedEntryPreview",
76201
- "listPublicEvents",
76202
- "listPublicEventCalendarWindow",
76203
- "listPublicRecurringSchedule",
76204
- "getPublicEventDetails",
76205
- "listPublicRouteCandidates",
76206
- "listPublicTeamMembers",
76207
- "listPublicProducts",
76208
- "listPublicPasses",
76209
- "listPublicMemberships",
76210
- "getPublicFormById",
76211
- "getPublicBookingServices",
76212
- "getPublicWeeklySlotAvailability"
76213
- ];
76214
- //#endregion
76215
- //#region ../blocks/src/system/data/batching.ts
76216
- function stableNormalize(value) {
76217
- if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
76218
- if (Array.isArray(value)) return value.map(stableNormalize);
76219
- if (typeof value === "object" && value) {
76220
- const obj = value;
76221
- const keys = Object.keys(obj).sort();
76222
- const out = {};
76223
- for (const key of keys) {
76224
- const v = obj[key];
76225
- if (v === void 0) continue;
76226
- out[key] = stableNormalize(v);
76213
+ if (expectedType === "content" && !isContentKey) {
76214
+ if (isPreviewKey) {
76215
+ console.debug("[getRiverbankEnv] Using preview key for published content. Consider using a content key (bld_live_sk_...) for production.");
76216
+ return;
76227
76217
  }
76228
- return out;
76218
+ throw new RiverbankEnvError(`Invalid API key format for content access. Expected key starting with bld_live_sk_ or bld_preview_sk_`, []);
76229
76219
  }
76230
- if (typeof value === "bigint" || typeof value === "symbol" || typeof value === "undefined") return String(value);
76231
- return null;
76232
76220
  }
76233
- const RichText$1 = RichText$2;
76234
- //#endregion
76235
- //#region ../blocks/src/system/customize/facets.ts
76236
- function defineCustomizeFacet(definition) {
76237
- return definition;
76221
+ /**
76222
+ * Get runtime environment configuration with automatic API key selection.
76223
+ *
76224
+ * This helper reads environment variables and automatically selects the correct
76225
+ * API key based on the current environment and preview mode:
76226
+ *
76227
+ * - When `RIVERBANK_PREVIEW_MODE=true`: Uses preview API key (bld_preview_sk_...)
76228
+ * - When `RIVERBANK_PREVIEW_MODE=false` (default): Uses content API key (bld_live_sk_...)
76229
+ *
76230
+ * Environment variable patterns:
76231
+ * - `RIVERBANK_ENV`: 'local' (default) or 'remote'
76232
+ * - `RIVERBANK_PREVIEW_MODE`: 'true' or 'false' (default)
76233
+ * - `RIVERBANK_{LOCAL|REMOTE}_SITE_ID`: Site ID
76234
+ * - `RIVERBANK_{LOCAL|REMOTE}_DASHBOARD_URL`: Dashboard URL
76235
+ * - `RIVERBANK_{LOCAL|REMOTE}_API_KEY`: Content/live API key
76236
+ * - `RIVERBANK_{LOCAL|REMOTE}_PREVIEW_API_KEY`: Preview API key
76237
+ *
76238
+ * @returns Environment configuration with auto-selected API key
76239
+ * @throws {RiverbankEnvError} If required environment variables are missing
76240
+ *
76241
+ * @example
76242
+ * ```ts
76243
+ * // lib/builder-client.ts
76244
+ * import { getRiverbankEnv } from '@riverbankcms/sdk/env';
76245
+ * import { createRiverbankClient } from '@riverbankcms/sdk';
76246
+ *
76247
+ * const env = getRiverbankEnv();
76248
+ *
76249
+ * export const client = createRiverbankClient({
76250
+ * apiKey: env.apiKey,
76251
+ * baseUrl: env.baseUrl,
76252
+ * });
76253
+ *
76254
+ * export const siteId = env.siteId;
76255
+ * ```
76256
+ */
76257
+ function getRiverbankEnv() {
76258
+ const target = detectTarget();
76259
+ const previewMode = detectPreviewMode();
76260
+ const prefix = getEnvPrefix(target);
76261
+ const siteId = process.env[`${prefix}_SITE_ID`];
76262
+ const dashboardUrl = process.env[`${prefix}_DASHBOARD_URL`];
76263
+ const contentKey = process.env[`${prefix}_API_KEY`];
76264
+ const previewKey = process.env[`${prefix}_PREVIEW_API_KEY`];
76265
+ const missingVars = [];
76266
+ if (!siteId) missingVars.push(`${prefix}_SITE_ID`);
76267
+ if (!dashboardUrl) missingVars.push(`${prefix}_DASHBOARD_URL`);
76268
+ let apiKey;
76269
+ let keyType;
76270
+ if (previewMode) {
76271
+ apiKey = previewKey;
76272
+ keyType = "preview";
76273
+ if (!apiKey) missingVars.push(`${prefix}_PREVIEW_API_KEY`);
76274
+ } else {
76275
+ apiKey = contentKey || previewKey;
76276
+ keyType = contentKey ? "content" : "preview";
76277
+ if (!apiKey) missingVars.push(`${prefix}_API_KEY`);
76278
+ }
76279
+ if (missingVars.length > 0) throw new RiverbankEnvError(`Missing required environment variables for Riverbank SDK:\n` + missingVars.map((v) => ` - ${v}`).join("\n") + `\n\nCurrent settings: RIVERBANK_ENV=${process.env.RIVERBANK_ENV || "local"}, RIVERBANK_PREVIEW_MODE=${process.env.RIVERBANK_PREVIEW_MODE || "false"}`, missingVars);
76280
+ if (!apiKey || !dashboardUrl || !siteId) throw new RiverbankEnvError("Required environment variables missing", missingVars);
76281
+ validateKeyType(apiKey, keyType);
76282
+ let baseUrl = dashboardUrl;
76283
+ if (!baseUrl.endsWith("/api")) baseUrl = baseUrl.replace(/\/$/, "") + "/api";
76284
+ return {
76285
+ target,
76286
+ previewMode,
76287
+ siteId,
76288
+ baseUrl,
76289
+ apiKey,
76290
+ keyType
76291
+ };
76238
76292
  }
76239
- const systemCustomizeFacetDefinitions = [defineCustomizeFacet({
76240
- blockKind: "block.event-calendar",
76241
- id: "eventCalendar.listLayout",
76242
- label: "List style",
76243
- values: eventCalendarListLayoutOptions.map((option) => ({
76244
- value: option.id,
76245
- label: option.label
76246
- })),
76247
- defaultValue: "stack",
76248
- target: { kind: "event-calendar-list-layout-content" },
76249
- appliesToLayoutVariants: eventCalendarListLayoutCompatibleDisplayModeValues
76250
- })];
76251
- systemCustomizeFacetDefinitions.map((definition) => definition.id);
76252
- Array.from(new Set(systemCustomizeFacetDefinitions.flatMap((definition) => definition.values.map((option) => option.value))));
76253
- const backgroundColorTokenNames = backgroundAppearanceColorTokenNames;
76254
- const backgroundColorTokenNameSet = new Set(backgroundColorTokenNames);
76255
- const backgroundColorTokens = toBackgroundColorTokens(backgroundColorTokenNames);
76256
- const quickBackgroundColorTokens = toBackgroundColorTokens(backgroundAppearanceQuickColorTokenNames);
76257
- backgroundColorTokens.filter((token) => !quickBackgroundColorTokens.includes(token));
76258
- function toBackgroundColorTokens(tokenNames) {
76259
- return tokenNames.flatMap((name) => {
76260
- const token = parseBackgroundColorToken(name);
76261
- if (!token) return [];
76262
- return [token];
76263
- });
76293
+ /**
76294
+ * Get the fixed main navigation menu object.
76295
+ * Returns null when the runtime payload is incomplete.
76296
+ *
76297
+ * @example
76298
+ * ```ts
76299
+ * const menu = getPrimaryNavigation(siteData.navigation);
76300
+ * console.log(menu?.location); // "main"
76301
+ * ```
76302
+ */
76303
+ function getPrimaryNavigation(navigation) {
76304
+ if (!navigation || navigation.length === 0) return null;
76305
+ return navigation.find((menu) => menu.location === "main") ?? null;
76264
76306
  }
76265
- function parseBackgroundColorToken(value) {
76266
- if (typeof value !== "string") return null;
76267
- const normalized = value.trim();
76268
- if (!backgroundColorTokenNameSet.has(normalized)) return null;
76269
- const token = parseBackgroundAppearanceColorToken(normalized);
76270
- if (!token) return null;
76271
- return token ? token : null;
76307
+ function getFooterNavigationByRole(navigation, role) {
76308
+ if (!navigation || navigation.length === 0) return null;
76309
+ const canonicalLocation = role === "main" ? "footer" : "legal";
76310
+ return navigation.find((menu) => menu.location === canonicalLocation) ?? null;
76272
76311
  }
76273
- //#endregion
76274
- //#region src/rendering/helpers/siteCustomBlocks.ts
76275
76312
  /**
76276
- * Prefer the DB-backed custom block manifest list (`site.customBlocks`) when available,
76277
- * but fall back to SDK config custom blocks (`site.sdkConfig.customBlocks`) for SDK-mode sites.
76278
- *
76279
- * This avoids subtle DX bugs where one source is populated but the renderer/prefetch layer
76280
- * is looking at the other.
76313
+ * Resolve alt text with fallback.
76314
+ * Returns the provided alt if non-empty, otherwise falls back to the provided fallback or 'Site logo'.
76315
+ * @internal
76281
76316
  */
76282
- function resolveSiteCustomBlocks(site) {
76283
- const dbBlocks = site.customBlocks;
76284
- if (Array.isArray(dbBlocks) && dbBlocks.length > 0) return dbBlocks;
76285
- const sdkBlocks = site.sdkConfig?.customBlocks;
76286
- if (Array.isArray(sdkBlocks) && sdkBlocks.length > 0) return sdkBlocks;
76317
+ function resolveAltText(alt, fallback) {
76318
+ return alt && alt.trim().length > 0 ? alt : fallback ?? "Site logo";
76287
76319
  }
76288
- function readBlockContentId(value, name) {
76289
- if (value === null || value === void 0) return null;
76290
- if (typeof value === "string") return value;
76291
- throw new Error(`Invalid ${name} in page: expected string or null`);
76320
+ function readNavigationItemPayload(item) {
76321
+ return item.url ?? null;
76292
76322
  }
76293
- function readTransportedBlockIdentity(block, kind, stage) {
76294
- return {
76295
- draftContentId: readBlockContentId(block.draftContentId, "draft content id"),
76296
- publishedPlacement: stage === "preview" ? readPublishedBlockPlacement(readBlockContentId(block.publishedContentId, "published content id"), sanitizeNullableSdkRuntimeBlockContent(kind, readNestedContentRecord(block.publishedContent))) : null
76297
- };
76323
+ function isPortalEnabled(options) {
76324
+ return options?.portalEnabled === true;
76298
76325
  }
76299
- function convertPageResponseBlock(block, stage) {
76300
- if (!isRecord$8(block)) throw new Error("Invalid block format in page API response");
76301
- const header = readTransportedBlockHeader(block);
76302
- const admission = readInvalidBlockAdmission(block.admission);
76326
+ function isCommerceEnabled(options) {
76327
+ return options?.commerceEnabled === true;
76328
+ }
76329
+ function resolvePortalHref(link) {
76330
+ return link.path?.trim() || "/portal";
76331
+ }
76332
+ function resolveCheckoutHref(options) {
76333
+ if (options?.checkoutHref === null) return null;
76334
+ const href = options?.checkoutHref?.trim();
76335
+ return href && href.length > 0 ? href : "/checkout";
76336
+ }
76337
+ function resolvePortalLabel(link, options) {
76338
+ const loggedOutLabel = link.labels?.loggedOut?.trim() || PORTAL_NAV_DEFAULT_LABELS.loggedOut;
76339
+ const loggedInLabel = link.labels?.loggedIn?.trim() || PORTAL_NAV_DEFAULT_LABELS.loggedIn;
76340
+ return options?.hasPortalSession ? loggedInLabel : loggedOutLabel;
76341
+ }
76342
+ function resolveItemLabel(link, fallbackLabel, options) {
76343
+ if (link?.kind === "portal") return resolvePortalLabel(link, options);
76344
+ if (link?.kind === "cart") return resolveCartVisibleLabel(link) ?? fallbackLabel;
76345
+ return fallbackLabel;
76346
+ }
76347
+ function resolveCartVisibleLabel(link) {
76348
+ if (link.label.kind !== "icon-with-label") return null;
76349
+ const label = link.label.label.trim();
76350
+ return label.length > 0 ? label : null;
76351
+ }
76352
+ function resolveCartAriaLabel(link, fallbackLabel) {
76353
+ const fallback = fallbackLabel.trim();
76354
+ return resolveCartVisibleLabel(link) ?? (fallback.length > 0 ? fallback : "Cart");
76355
+ }
76356
+ function buildCartNavViewModel(link, fallbackLabel, options) {
76303
76357
  return {
76304
- ...header,
76305
- ...readTransportedBlockIdentity(block, header.kind, stage),
76306
- content: sanitizeSdkRuntimeBlockContent(header.kind, readContentRecord(block.content) ?? {}),
76307
- draftContent: sanitizeNullableSdkRuntimeBlockContent(header.kind, readNestedContentRecord(block.draftContent)),
76308
- ...admission ? { admission } : {}
76358
+ visibleLabel: resolveCartVisibleLabel(link),
76359
+ badge: link.badge,
76360
+ ariaLabel: resolveCartAriaLabel(link, fallbackLabel),
76361
+ checkoutHref: resolveCheckoutHref(options)
76309
76362
  };
76310
76363
  }
76311
- function readTransportedBlockHeader(block) {
76312
- if (typeof block.id !== "string" && block.id !== null) throw new Error(`Invalid block id in page: expected string or null, got ${typeof block.id}`);
76313
- if (typeof block.kind !== "string") throw new Error(`Invalid block kind in page: expected string, got ${typeof block.kind}`);
76314
- if (typeof block.purpose !== "string") throw new Error(`Invalid block purpose in page: expected string, got ${typeof block.purpose}`);
76315
- if (block.contentVersionId !== void 0 && block.contentVersionId !== null && typeof block.contentVersionId !== "string") throw new Error(`Invalid content version id in page: expected string or null, got ${typeof block.contentVersionId}`);
76364
+ function deriveRenderableNavigationLink(item, options) {
76365
+ const payload = readNavigationItemPayload(item);
76366
+ if (!payload) return null;
76367
+ if (payload.kind === "portal" && !isPortalEnabled(options)) return null;
76368
+ if (payload.kind === "cart" && !isCommerceEnabled(options)) return null;
76316
76369
  return {
76317
- id: block.id,
76318
- ...block.contentVersionId !== void 0 ? { contentVersionId: block.contentVersionId } : {},
76319
- kind: block.kind,
76320
- purpose: block.purpose
76370
+ id: item.id,
76371
+ label: resolveItemLabel(payload, item.label, options),
76372
+ payload,
76373
+ isExternal: isExternalLink(payload),
76374
+ ...payload.kind === "cart" ? { cart: buildCartNavViewModel(payload, item.label, options) } : {}
76321
76375
  };
76322
76376
  }
76323
- function readInvalidBlockAdmission(value) {
76324
- if (!isRecord$8(value) || value.kind !== "invalid" || !isRecord$8(value.error)) return null;
76325
- if (value.error.kind !== "invalid_manifest_content" && value.error.kind !== "manifest_unavailable") return null;
76326
- return value;
76327
- }
76328
- function buildPageOutline(input) {
76377
+ function buildNavLinkFromResolvedHref(item, href) {
76378
+ if (!href) return null;
76329
76379
  return {
76330
- name: input.name,
76331
- path: input.path ?? input.fallbackPath,
76332
- purpose: input.purpose,
76333
- blocks: input.blocks.map((block) => convertPageResponseBlock(block, input.previewStage))
76380
+ kind: "link",
76381
+ id: item.id,
76382
+ label: item.label,
76383
+ href,
76384
+ link: { href },
76385
+ isExternal: item.isExternal,
76386
+ ...item.cart ? { cart: item.cart } : {}
76334
76387
  };
76335
76388
  }
76336
- function buildRenderablePageOutline(input) {
76337
- const page = buildPageOutline(input);
76389
+ /**
76390
+ * Determines if a navigation item's link is external.
76391
+ */
76392
+ function isExternalLink(link) {
76393
+ if (!link) return false;
76394
+ return link.kind === "external";
76395
+ }
76396
+ /**
76397
+ * Build a map of children items by parent ID.
76398
+ * Also warns about deeply nested items (grandchildren) which CMS shouldn't allow.
76399
+ * @internal
76400
+ */
76401
+ function buildChildrenByParentId(items) {
76402
+ const childrenByParentId = /* @__PURE__ */ new Map();
76403
+ const itemsById = /* @__PURE__ */ new Map();
76404
+ for (const item of items) itemsById.set(item.id, item);
76405
+ for (const item of items) if (item.parentId) {
76406
+ if (itemsById.get(item.parentId)?.parentId && typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
76407
+ console.warn(`[SDK Navigation] Deeply nested item detected: "${item.label}" (id: ${item.id}). Only 1 level of nesting is supported. This item will be ignored.`);
76408
+ continue;
76409
+ }
76410
+ const siblings = childrenByParentId.get(item.parentId) ?? [];
76411
+ siblings.push(item);
76412
+ childrenByParentId.set(item.parentId, siblings);
76413
+ }
76414
+ return childrenByParentId;
76415
+ }
76416
+ /**
76417
+ * Generic nested structure builder.
76418
+ * @internal
76419
+ */
76420
+ function buildNestedStructure(items, options) {
76421
+ const childrenByParentId = buildChildrenByParentId(items);
76422
+ const rootItems = items.filter((item) => !item.parentId).sort((a, b) => (a.orderIndex ?? a.position ?? 0) - (b.orderIndex ?? b.position ?? 0));
76423
+ const result = [];
76424
+ let ctaItem = null;
76425
+ for (const item of rootItems) {
76426
+ if (options.extractCta && !ctaItem && Boolean(item.isCta) && item.urlType !== "dropdown") {
76427
+ const link = options.toLink(item);
76428
+ if (link) {
76429
+ ctaItem = link;
76430
+ continue;
76431
+ }
76432
+ }
76433
+ const childRecords = childrenByParentId.get(item.id) ?? [];
76434
+ const hasChildren = childRecords.length > 0;
76435
+ if (item.urlType === "dropdown" || hasChildren) {
76436
+ const children = childRecords.sort((a, b) => (a.orderIndex ?? a.position ?? 0) - (b.orderIndex ?? b.position ?? 0)).map(options.toLink).filter((child) => child !== null);
76437
+ if (children.length > 0) result.push(options.createDropdown(item.id, item.label, children));
76438
+ continue;
76439
+ }
76440
+ const link = options.toLink(item);
76441
+ if (link) result.push(link);
76442
+ }
76338
76443
  return {
76339
- ...page,
76340
- blocks: page.blocks.map((block) => admitSdkRuntimePageBlock(block, input.customBlocks))
76444
+ items: result,
76445
+ ctaItem
76341
76446
  };
76342
76447
  }
76343
- function admitSdkRuntimePageBlock(block, customBlocks) {
76344
- const base = {
76345
- id: block.id,
76346
- draftContentId: block.draftContentId,
76347
- publishedPlacement: block.publishedPlacement,
76348
- ...block.contentVersionId !== void 0 ? { contentVersionId: block.contentVersionId } : {},
76349
- kind: block.kind,
76350
- purpose: block.purpose,
76351
- ...block.bindings ? { bindings: block.bindings } : {}
76448
+ /**
76449
+ * Build a Menu from navigation data with pre-resolved hrefs.
76450
+ * Supports dropdown containers with nested children.
76451
+ *
76452
+ * @param navigation - Navigation menus from site data
76453
+ * @param routes - Route map for resolving internal links
76454
+ * @param options - Include identifier maps to resolve canonical `page`/`entry` links.
76455
+ *
76456
+ * @example
76457
+ * ```ts
76458
+ * const menu = buildMenu(siteData.navigation, siteData.routes, {
76459
+ * pagesByIdentifier: siteData.pagesByIdentifier,
76460
+ * entriesByIdentifier: siteData.entriesByIdentifier,
76461
+ * });
76462
+ * menu.items.forEach(item => {
76463
+ * if (item.kind === 'dropdown') {
76464
+ * console.log(item.children);
76465
+ * }
76466
+ * });
76467
+ * ```
76468
+ */
76469
+ function buildMenu(navigation, routes, options) {
76470
+ const menu = getPrimaryNavigation(navigation);
76471
+ if (!menu) return {
76472
+ items: [],
76473
+ ctaItem: null
76352
76474
  };
76353
- const transportedAdmission = readInvalidBlockAdmission(block.admission);
76354
- if (transportedAdmission) return invalidRenderableBlock(base, transportedAdmission.error);
76355
- const manifest = resolveSdkBlockManifest(block.kind, customBlocks);
76356
- if (!manifest) return invalidRenderableBlock(base, { kind: "manifest_unavailable" });
76357
- const content = block.content ?? {};
76358
- const renderable = admitTransportedRenderableManifestContent(compileManifestContentContract(manifest), content);
76359
- if (!renderable.ok) return invalidRenderableBlock(base, {
76360
- kind: "invalid_manifest_content",
76361
- error: renderable.error
76475
+ const toNavLink = (item) => {
76476
+ const renderable = deriveRenderableNavigationLink(item, options);
76477
+ if (!renderable) return null;
76478
+ return buildNavLinkFromResolvedHref(renderable, resolveHref(renderable.payload, routes, options));
76479
+ };
76480
+ const { items, ctaItem } = buildNestedStructure(menu.items, {
76481
+ toLink: toNavLink,
76482
+ createDropdown: (id, label, children) => ({
76483
+ kind: "dropdown",
76484
+ id,
76485
+ label,
76486
+ children
76487
+ }),
76488
+ extractCta: true
76362
76489
  });
76363
76490
  return {
76364
- ...base,
76365
- admission: {
76366
- kind: "renderable",
76367
- content: renderable.value
76368
- }
76491
+ items,
76492
+ ctaItem: ctaItem ? {
76493
+ ...ctaItem,
76494
+ variant: "primary"
76495
+ } : null
76369
76496
  };
76370
76497
  }
76371
- function resolveSdkBlockManifest(blockKind, customBlocks) {
76372
- const customBlock = customBlocks?.find((candidate) => candidate.id === blockKind);
76373
- return customBlock ? parseFieldDefinitions(customBlock.fields) : getBlockDefinition(blockKind)?.manifest ?? null;
76498
+ /**
76499
+ * Build a Menu from the footer navigation data.
76500
+ * Returns empty menu if no footer menu is designated.
76501
+ *
76502
+ * @param navigation - Navigation menus from site data
76503
+ * @param routes - Route map for resolving internal links
76504
+ * @param options - Include identifier maps to resolve canonical `page`/`entry` links.
76505
+ *
76506
+ * @example
76507
+ * ```ts
76508
+ * const footerMenu = buildFooterMenu(siteData.navigation, siteData.routes, {
76509
+ * pagesByIdentifier: siteData.pagesByIdentifier,
76510
+ * entriesByIdentifier: siteData.entriesByIdentifier,
76511
+ * });
76512
+ * footerMenu.items.forEach(item => {
76513
+ * if (item.kind === 'dropdown') {
76514
+ * // Footer renders children expanded, not as hover dropdowns
76515
+ * console.log(item.children);
76516
+ * }
76517
+ * });
76518
+ * ```
76519
+ */
76520
+ function buildFooterMenu(navigation, routes, options) {
76521
+ return buildFooterMenuForRole(navigation, routes, "main", options);
76374
76522
  }
76375
- function invalidRenderableBlock(block, error) {
76523
+ function buildFooterMenuForRole(navigation, routes, role, options) {
76524
+ const menu = getFooterNavigationByRole(navigation, role);
76525
+ if (!menu) return {
76526
+ items: [],
76527
+ ctaItem: null,
76528
+ groups: [],
76529
+ links: []
76530
+ };
76531
+ const toNavLink = (item) => {
76532
+ const renderable = deriveRenderableNavigationLink(item, options);
76533
+ if (!renderable) return null;
76534
+ return buildNavLinkFromResolvedHref(renderable, resolveHref(renderable.payload, routes, options));
76535
+ };
76536
+ const built = buildNestedStructure(menu.items, {
76537
+ toLink: toNavLink,
76538
+ createDropdown: (id, label, children) => ({
76539
+ kind: "dropdown",
76540
+ id,
76541
+ label,
76542
+ children
76543
+ }),
76544
+ extractCta: false
76545
+ });
76546
+ const groups = built.items.filter((item) => item.kind === "dropdown");
76547
+ const links = built.items.filter((item) => item.kind === "link");
76376
76548
  return {
76377
- ...block,
76378
- admission: {
76379
- kind: "invalid",
76380
- error
76381
- }
76549
+ items: built.items,
76550
+ ctaItem: null,
76551
+ groups,
76552
+ links
76382
76553
  };
76383
76554
  }
76384
- function isRecord$8(value) {
76385
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
76555
+ /**
76556
+ * Resolve href from a link payload using route map.
76557
+ * @internal
76558
+ */
76559
+ function resolveHref(link, routes, options) {
76560
+ if (!link) return null;
76561
+ if (link.kind === "external" || link.kind === "url") return link.href || null;
76562
+ if (link.kind === "portal") return isPortalEnabled(options) ? resolvePortalHref(link) : null;
76563
+ if (link.kind === "cart") return isCommerceEnabled(options) ? resolveCheckoutHref(options) : null;
76564
+ const stage = normalizeRenderStage(options?.previewStage);
76565
+ if (link.kind === "internal") return resolveRouteHrefWithFallback(link.routeId, link.href ?? null, routes, stage);
76566
+ if (link.kind === "page") {
76567
+ const routeIdFromPayload = readRouteIdFromLink(link);
76568
+ const routeIdFromIdentifierMap = options?.pagesByIdentifier?.[link.identifier] ?? null;
76569
+ return resolveRouteHrefWithFallback(routeIdFromPayload ?? routeIdFromIdentifierMap, readHrefFromLink(link), routes, stage);
76570
+ }
76571
+ if (link.kind === "entry") {
76572
+ const routeIdFromPayload = readRouteIdFromLink(link);
76573
+ const routeIdFromIdentifierMap = readEntryRouteIdFromIdentifierMap(options, link.contentType, link.identifier);
76574
+ return resolveRouteHrefWithFallback(routeIdFromPayload ?? routeIdFromIdentifierMap, readHrefFromLink(link), routes, stage);
76575
+ }
76576
+ return null;
76386
76577
  }
76387
- function readContentRecord(value) {
76388
- return isRecord$8(value) ? value : void 0;
76578
+ function resolveRouteHrefWithFallback(routeId, fallbackHref, routes, stage) {
76579
+ if (!routeId) return fallbackHref;
76580
+ const resolved = resolveRouteHrefForStage(routeId, routes, stage);
76581
+ if (resolved) return resolved;
76582
+ const route = routes[routeId];
76583
+ if (!route) return fallbackHref;
76584
+ if (!isRouteVisibleInStage(route, stage)) return null;
76585
+ return fallbackHref;
76389
76586
  }
76390
- function readNestedContentRecord(value) {
76391
- if (!isRecord$8(value)) return null;
76392
- return readContentRecord(value.data) ?? null;
76587
+ function readRouteIdFromLink(link) {
76588
+ if (!("routeId" in link) || typeof link.routeId !== "string") return null;
76589
+ return link.routeId;
76393
76590
  }
76394
- function sanitizeSdkRuntimeBlockContent(blockKind, content) {
76395
- if (blockKind !== "block.newsletter-signup") return content;
76396
- const sanitized = sanitizeNewsletterSignupPublicContent(content);
76397
- return isRecord$8(sanitized) ? sanitized : {};
76591
+ function readHrefFromLink(link) {
76592
+ if (!("href" in link) || typeof link.href !== "string") return null;
76593
+ return link.href;
76398
76594
  }
76399
- function sanitizeNullableSdkRuntimeBlockContent(blockKind, content) {
76400
- return content ? sanitizeSdkRuntimeBlockContent(blockKind, content) : null;
76595
+ function readEntryRouteIdFromIdentifierMap(options, contentType, identifier) {
76596
+ const entryMap = options?.entriesByIdentifier?.[contentType];
76597
+ if (!entryMap) return null;
76598
+ return entryMap[identifier] ?? null;
76599
+ }
76600
+ /**
76601
+ * Build a Logo from site layout data.
76602
+ *
76603
+ * @param logo - Logo data from site layout
76604
+ * @param fallbackAlt - Fallback alt text (usually site title)
76605
+ *
76606
+ * @example
76607
+ * ```ts
76608
+ * const logo = buildLogo(siteData.layout.logo, siteData.site.title);
76609
+ * // { src: 'https://...', alt: 'Site Name', width: 200, height: 50 }
76610
+ * ```
76611
+ */
76612
+ function buildLogo(logo, fallbackAlt) {
76613
+ if (!logo || !logo.url) return null;
76614
+ const alt = resolveAltText(logo.alt, fallbackAlt);
76615
+ const result = {
76616
+ type: "image",
76617
+ src: logo.url,
76618
+ alt
76619
+ };
76620
+ if (logo.width != null) result.width = logo.width;
76621
+ if (logo.height != null) result.height = logo.height;
76622
+ return result;
76623
+ }
76624
+ /**
76625
+ * Build both site logos from layout data. The default header and footer choose
76626
+ * between them by the surface they sit on; custom chrome can do the same.
76627
+ *
76628
+ * @example
76629
+ * ```ts
76630
+ * const logoVariants = buildLogoVariants(siteData.layout, siteData.site.title);
76631
+ * ```
76632
+ */
76633
+ function buildLogoVariants(layout, fallbackAlt) {
76634
+ return {
76635
+ forLightBackgrounds: buildLogo(layout?.logo ?? null, fallbackAlt),
76636
+ forDarkBackgrounds: buildLogo(layout?.logoForDarkBackgrounds ?? null, fallbackAlt)
76637
+ };
76638
+ }
76639
+ /**
76640
+ * Header/footer block content for the site logos. `logo` stays populated with
76641
+ * whichever logo exists so presence checks keep working; `logoVariants` is
76642
+ * what the blocks select from at render.
76643
+ */
76644
+ function buildChromeLogoContent(layout, fallbackAlt) {
76645
+ const logoVariants = buildLogoVariants(layout, fallbackAlt);
76646
+ return {
76647
+ logo: logoVariants.forLightBackgrounds ?? logoVariants.forDarkBackgrounds,
76648
+ logoVariants
76649
+ };
76650
+ }
76651
+ //#endregion
76652
+ //#region src/rendering/themeAdmission.ts
76653
+ const MISSING_SDK_THEME_ERROR_CODE = "missing_sdk_theme";
76654
+ var MissingSdkThemeError = class extends Error {
76655
+ constructor(siteId, reason = "cms_theme_absent", themeKey) {
76656
+ super(`[Riverbank SDK] Site "${siteId}" has no resolvable theme. ` + (themeKey ? `Theme key "${themeKey}" is not present. ` : "") + "Select a CMS theme, provide { theme }, { themes }, or { getTheme }, or use rendering: { kind: 'overrides-only' } with complete block overrides.");
76657
+ this.siteId = siteId;
76658
+ this.reason = reason;
76659
+ this.themeKey = themeKey;
76660
+ this.code = MISSING_SDK_THEME_ERROR_CODE;
76661
+ this.name = "MissingSdkThemeError";
76662
+ }
76663
+ };
76664
+ function requireSdkTheme(theme, siteId, reason = "cms_theme_absent") {
76665
+ if (theme === null || theme === void 0) throw new MissingSdkThemeError(siteId, reason);
76666
+ return theme;
76401
76667
  }
76402
76668
  //#endregion
76669
+ //#region src/rendering/renderingMode.ts
76670
+ const defaultOverrideOnlyRuntime = { kind: "responsive-only" };
76671
+ //#endregion
76403
76672
  //#region src/rendering/helpers/footerPageOutline.ts
76404
76673
  /**
76405
76674
  * Admit footer blocks returned by the site API for public rendering.
@@ -78291,6 +78560,7 @@ const SDK_EVENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
78291
78560
  responseKind: "json",
78292
78561
  errors: [
78293
78562
  "resource:not_found",
78563
+ "validation:invalid_input",
78294
78564
  "resource:conflict",
78295
78565
  "server:internal_error"
78296
78566
  ]
@@ -78745,28 +79015,6 @@ const EVENT_MANAGEMENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
78745
79015
  "resource:conflict",
78746
79016
  "server:internal_error"
78747
79017
  ]
78748
- },
78749
- /**
78750
- * The Content tab's one write: the short introduction, image and
78751
- * description of an event's page, published without its layout.
78752
- */
78753
- saveEventPageWords: {
78754
- path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/words",
78755
- method: "PUT",
78756
- tags: [
78757
- TAG_TEMPLATES.siteCollection,
78758
- TAG_TEMPLATES.siteRoutableContent,
78759
- TAG_TEMPLATES.pageSurfaceById
78760
- ],
78761
- auth: "user",
78762
- responseKind: "json",
78763
- errors: [
78764
- "auth:forbidden",
78765
- "validation:invalid_input",
78766
- "resource:not_found",
78767
- "resource:conflict",
78768
- "server:internal_error"
78769
- ]
78770
79018
  }
78771
79019
  });
78772
79020
  //#endregion
@@ -79191,6 +79439,15 @@ const BILLING_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
79191
79439
  auth: "user",
79192
79440
  responseKind: "json"
79193
79441
  },
79442
+ /** Continue on Free from the onboarding card page; only the attempt's owner. */
79443
+ continueOnboardingOnFree: {
79444
+ path: "/onboarding/attempts/{attemptToken}/plan/free",
79445
+ method: "POST",
79446
+ tags: ["billing"],
79447
+ auth: "user",
79448
+ errors: [],
79449
+ responseKind: "json"
79450
+ },
79194
79451
  createBillingPortalSession: {
79195
79452
  path: "/billing/portal/session",
79196
79453
  method: "POST",
@@ -79200,6 +79457,161 @@ const BILLING_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
79200
79457
  }
79201
79458
  });
79202
79459
  //#endregion
79460
+ //#region ../api/src/editLeaseEndpoints.ts
79461
+ const path = "/sites/{siteId}/edit-leases/{nodeType}/{nodeId}";
79462
+ const lifecycleErrors = [
79463
+ "auth:lease_required",
79464
+ "auth:forbidden",
79465
+ "resource:not_found",
79466
+ "validation:invalid_input",
79467
+ "server:internal_error"
79468
+ ];
79469
+ const EDIT_LEASE_ENDPOINT_DEFINITIONS = {
79470
+ readEditLease: {
79471
+ path,
79472
+ method: "GET",
79473
+ editLease: "lifecycle",
79474
+ errors: lifecycleErrors,
79475
+ auth: "user",
79476
+ responseKind: "json"
79477
+ },
79478
+ acquireEditLease: {
79479
+ path,
79480
+ method: "POST",
79481
+ editLease: "lifecycle",
79482
+ errors: lifecycleErrors,
79483
+ auth: "user",
79484
+ responseKind: "json"
79485
+ },
79486
+ takeOverEditLease: {
79487
+ path,
79488
+ method: "PUT",
79489
+ editLease: "lifecycle",
79490
+ errors: lifecycleErrors,
79491
+ auth: "user",
79492
+ responseKind: "json"
79493
+ },
79494
+ heartbeatEditLease: {
79495
+ path,
79496
+ method: "PATCH",
79497
+ editLease: "lifecycle",
79498
+ errors: [...lifecycleErrors, "auth:lease_lost"],
79499
+ auth: "user",
79500
+ responseKind: "json"
79501
+ },
79502
+ releaseEditLease: {
79503
+ path,
79504
+ method: "DELETE",
79505
+ editLease: "lifecycle",
79506
+ errors: lifecycleErrors,
79507
+ auth: "user",
79508
+ responseKind: "json"
79509
+ }
79510
+ };
79511
+ //#endregion
79512
+ //#region ../api/src/pageSurfaceEditorEndpoints.ts
79513
+ const surfaceTags = [TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById];
79514
+ const PAGE_SURFACE_EDITOR_ENDPOINT_DEFINITIONS = {
79515
+ getPageSurfaceEditorDocument: {
79516
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/content",
79517
+ method: "GET",
79518
+ errors: [
79519
+ "auth:forbidden",
79520
+ "validation:invalid_input",
79521
+ "resource:not_found",
79522
+ "resource:conflict",
79523
+ "server:internal_error"
79524
+ ],
79525
+ tags: surfaceTags,
79526
+ auth: "user",
79527
+ responseKind: "json"
79528
+ },
79529
+ updatePageSurfaceDraftContent: {
79530
+ editLease: "managed",
79531
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/content",
79532
+ method: "PUT",
79533
+ errors: [
79534
+ "validation:invalid_input",
79535
+ "resource:not_found",
79536
+ "resource:conflict",
79537
+ "server:internal_error"
79538
+ ],
79539
+ tags: surfaceTags,
79540
+ auth: "user",
79541
+ responseKind: "json"
79542
+ },
79543
+ discardPageSurfaceDraftContent: {
79544
+ editLease: "managed",
79545
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/content/draft",
79546
+ method: "DELETE",
79547
+ errors: [
79548
+ "validation:invalid_input",
79549
+ "resource:not_found",
79550
+ "resource:conflict",
79551
+ "server:internal_error"
79552
+ ],
79553
+ tags: surfaceTags,
79554
+ auth: "user",
79555
+ responseKind: "json"
79556
+ },
79557
+ updatePageSurfaceRouteMetadata: {
79558
+ editLease: "managed",
79559
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/metadata",
79560
+ method: "PATCH",
79561
+ errors: [
79562
+ "validation:invalid_input",
79563
+ "resource:not_found",
79564
+ "resource:conflict",
79565
+ "server:internal_error"
79566
+ ],
79567
+ tags: [
79568
+ TAG_TEMPLATES.siteCollection,
79569
+ TAG_TEMPLATES.siteRoutableContent,
79570
+ TAG_TEMPLATES.pageSurfaceById
79571
+ ],
79572
+ auth: "user",
79573
+ responseKind: "json"
79574
+ },
79575
+ publishPageSurface: {
79576
+ editLease: "managed",
79577
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/publication",
79578
+ method: "POST",
79579
+ errors: [
79580
+ "auth:forbidden",
79581
+ "validation:invalid_input",
79582
+ "resource:not_found",
79583
+ "resource:conflict",
79584
+ "server:internal_error"
79585
+ ],
79586
+ tags: [
79587
+ TAG_TEMPLATES.siteCollection,
79588
+ TAG_TEMPLATES.siteRoutableContent,
79589
+ TAG_TEMPLATES.pageSurfaceById
79590
+ ],
79591
+ auth: "user",
79592
+ responseKind: "json"
79593
+ },
79594
+ saveEventContentTab: {
79595
+ editLease: "managed",
79596
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/event-content",
79597
+ method: "PUT",
79598
+ errors: [
79599
+ "auth:forbidden",
79600
+ "validation:invalid_input",
79601
+ "resource:not_found",
79602
+ "resource:conflict",
79603
+ "server:internal_error"
79604
+ ],
79605
+ tags: [
79606
+ TAG_TEMPLATES.siteCollection,
79607
+ TAG_TEMPLATES.siteRoutableContent,
79608
+ TAG_TEMPLATES.pageSurfaceById
79609
+ ],
79610
+ auth: "user",
79611
+ responseKind: "json"
79612
+ }
79613
+ };
79614
+ //#endregion
79203
79615
  //#region ../api/src/bookingPeopleEndpointDefinitions.ts
79204
79616
  /**
79205
79617
  * People endpoints (#1356): the People list, its CSV export, and deleting a
@@ -79263,7 +79675,8 @@ const CLIENT_ERROR_REPORT_LIMITS = {
79263
79675
  stack: 8e3,
79264
79676
  digest: 128,
79265
79677
  componentStack: 8e3,
79266
- sourceLocation: 1024
79678
+ sourceLocation: 1024,
79679
+ navigationAgeMs: 6e4
79267
79680
  };
79268
79681
  const clientErrorEventSchema = z$1.enum([
79269
79682
  "dashboard:route-error",
@@ -79280,7 +79693,17 @@ z$1.object({
79280
79693
  stack: z$1.string().max(CLIENT_ERROR_REPORT_LIMITS.stack).nullable(),
79281
79694
  digest: z$1.string().max(CLIENT_ERROR_REPORT_LIMITS.digest).nullable(),
79282
79695
  componentStack: z$1.string().max(CLIENT_ERROR_REPORT_LIMITS.componentStack).nullable(),
79283
- sourceLocation: z$1.string().max(CLIENT_ERROR_REPORT_LIMITS.sourceLocation).nullable()
79696
+ sourceLocation: z$1.string().max(CLIENT_ERROR_REPORT_LIMITS.sourceLocation).nullable(),
79697
+ navigation: z$1.object({
79698
+ fromPathname: z$1.string().regex(/^\/[^?#]*$/).max(CLIENT_ERROR_REPORT_LIMITS.pathname),
79699
+ toPathname: z$1.string().regex(/^\/[^?#]*$/).max(CLIENT_ERROR_REPORT_LIMITS.pathname),
79700
+ type: z$1.enum([
79701
+ "push",
79702
+ "replace",
79703
+ "traverse"
79704
+ ]),
79705
+ ageMs: z$1.number().int().min(0).max(CLIENT_ERROR_REPORT_LIMITS.navigationAgeMs)
79706
+ }).strict().nullable().optional()
79284
79707
  }).strict();
79285
79708
  ({
79286
79709
  ...SITE_LIFECYCLE_ENDPOINT_DEFINITIONS,
@@ -79292,12 +79715,14 @@ z$1.object({
79292
79715
  ...GIFTING_ENDPOINT_DEFINITIONS,
79293
79716
  ...PUBLIC_READ_ENDPOINT_DEFINITIONS,
79294
79717
  ...BILLING_ENDPOINT_DEFINITIONS,
79718
+ ...EDIT_LEASE_ENDPOINT_DEFINITIONS,
79719
+ ...PAGE_SURFACE_EDITOR_ENDPOINT_DEFINITIONS,
79295
79720
  ...SITE_MANAGEMENT_ENDPOINT_DEFINITIONS
79296
79721
  }), TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, { ...SITE_API_KEY_ENDPOINT_DEFINITIONS }, TAG_TEMPLATES.site, TAG_TEMPLATES.siteBookingSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteBookingSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings, {
79297
79722
  ...NEWSLETTER_ENDPOINT_DEFINITIONS,
79298
79723
  ...APPOINTMENT_ENDPOINT_DEFINITIONS,
79299
79724
  ...EVENT_SERIES_REGISTRATION_ENDPOINT_DEFINITIONS
79300
- }, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteById, TAG_TEMPLATES.siteBySlug, TAG_TEMPLATES.siteByDomain, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteById, TAG_TEMPLATES.siteBySlug, TAG_TEMPLATES.siteByDomain, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.workflowRunById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.routeById, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.navigationItemById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.navigationItemById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicBookingServices, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRedirects, TAG_TEMPLATES.siteRouteOutcomes, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRedirects, TAG_TEMPLATES.siteRouteOutcomes, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, { ...PUBLIC_BOOKING_AVAILABILITY_ENDPOINT_DEFINITIONS }, TAG_TEMPLATES.publicEventFilters, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicShop, TAG_TEMPLATES.publicCheckout, TAG_TEMPLATES.siteRoutableContent, { ...PUBLIC_EVENT_CHECKOUT_ENDPOINT_DEFINITIONS }, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents, { ...EVENT_MANAGEMENT_ENDPOINT_DEFINITIONS }, { ...BOOKING_PEOPLE_ENDPOINT_DEFINITIONS }, { ...SDK_MEDIA_ENDPOINT_DEFINITIONS }, { ...SDK_ENDPOINT_DEFINITIONS }, { ...SDK_PAGE_DESIGN_ENDPOINT_DEFINITIONS }, { ...SDK_EVENT_ENDPOINT_DEFINITIONS }, { ...SDK_ENTRY_READ_ENDPOINTS };
79725
+ }, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteById, TAG_TEMPLATES.siteBySlug, TAG_TEMPLATES.siteByDomain, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteById, TAG_TEMPLATES.siteBySlug, TAG_TEMPLATES.siteByDomain, TAG_TEMPLATES.workflowRunById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.routeById, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.site, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.navigationItemById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.navigationItemById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteNavigation, TAG_TEMPLATES.navigationMenuById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteSettings, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicBookingServices, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.siteTheme, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteCollection, TAG_TEMPLATES.pageSurfaceById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.pageById, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRedirects, TAG_TEMPLATES.siteRouteOutcomes, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteRedirects, TAG_TEMPLATES.siteRouteOutcomes, TAG_TEMPLATES.siteRoutableContent, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, TAG_TEMPLATES.formSubmissionsBySlug, TAG_TEMPLATES.siteForms, { ...PUBLIC_BOOKING_AVAILABILITY_ENDPOINT_DEFINITIONS }, TAG_TEMPLATES.publicEventFilters, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicShop, TAG_TEMPLATES.publicCheckout, TAG_TEMPLATES.siteRoutableContent, { ...PUBLIC_EVENT_CHECKOUT_ENDPOINT_DEFINITIONS }, TAG_TEMPLATES.publicEvents, TAG_TEMPLATES.publicEvents, { ...EVENT_MANAGEMENT_ENDPOINT_DEFINITIONS }, { ...BOOKING_PEOPLE_ENDPOINT_DEFINITIONS }, { ...SDK_MEDIA_ENDPOINT_DEFINITIONS }, { ...SDK_ENDPOINT_DEFINITIONS }, { ...SDK_PAGE_DESIGN_ENDPOINT_DEFINITIONS }, { ...SDK_EVENT_ENDPOINT_DEFINITIONS }, { ...SDK_ENTRY_READ_ENDPOINTS };
79301
79726
  z$1.object({ refreshToken: z$1.string().min(1).max(4096) }).strict();
79302
79727
  z$1.object({
79303
79728
  accessToken: z$1.string().min(1).max(4096),
@@ -80169,6 +80594,7 @@ const CANONICAL_REFUND_PLANNER_ERROR_CODES = [
80169
80594
  "refund_failed"
80170
80595
  ];
80171
80596
  const CANONICAL_ADMIN_REFUND_FAILURE_CODES = [
80597
+ "refund_blocked_by_live_payment_terms",
80172
80598
  ...CANONICAL_REFUND_PLANNER_ERROR_CODES,
80173
80599
  "payment_intent_not_found",
80174
80600
  "stripe_error",
@@ -80184,6 +80610,7 @@ const CANONICAL_ADMIN_REFUND_FAILURE_CODES = [
80184
80610
  //#endregion
80185
80611
  //#region ../api/src/bookingRefundOutcomes.ts
80186
80612
  const STANDARD_LINE_ITEM_REFUND_INVALID_CODES = [
80613
+ "refund_blocked_by_live_payment_terms",
80187
80614
  "missing_amount",
80188
80615
  "invalid_amount",
80189
80616
  "amount_exceeds_remaining",
@@ -80549,68 +80976,6 @@ function stableSerialize(value) {
80549
80976
  }
80550
80977
  z$1.enum(["public", "unlisted"], { error: "visibility must be 'public' or 'unlisted'" });
80551
80978
  //#endregion
80552
- //#region ../api/src/bookingPaymentTermSchemas.ts
80553
- const bookingDepositRefundPolicySchema = z$1.enum(["refundable", "non_refundable"]);
80554
- const bookingInstalmentPlanSchema = z$1.discriminatedUnion("kind", [
80555
- z$1.object({
80556
- kind: z$1.literal("deposit_plus_one_remainder"),
80557
- depositAmountCents: z$1.number().int().nonnegative(),
80558
- depositRefundability: bookingDepositRefundPolicySchema,
80559
- remainderDueCount: z$1.number().int().positive(),
80560
- intervalUnit: z$1.enum([
80561
- "day",
80562
- "week",
80563
- "month"
80564
- ])
80565
- }),
80566
- z$1.object({
80567
- kind: z$1.literal("deposit_plus_scheduled_instalments"),
80568
- depositAmountCents: z$1.number().int().nonnegative(),
80569
- depositRefundability: bookingDepositRefundPolicySchema,
80570
- instalmentCount: z$1.number().int().positive(),
80571
- intervalCount: z$1.number().int().positive(),
80572
- intervalUnit: z$1.enum([
80573
- "day",
80574
- "week",
80575
- "month"
80576
- ])
80577
- }),
80578
- z$1.object({
80579
- kind: z$1.literal("equal_scheduled_instalments"),
80580
- instalmentCount: z$1.number().int().positive(),
80581
- intervalCount: z$1.number().int().positive(),
80582
- intervalUnit: z$1.enum([
80583
- "day",
80584
- "week",
80585
- "month"
80586
- ])
80587
- })
80588
- ]);
80589
- const bookingFlexibleBalanceDueDateRuleSchema = z$1.discriminatedUnion("kind", [z$1.object({
80590
- kind: z$1.literal("relative_to_start_date"),
80591
- daysBeforeStart: z$1.number().int().positive()
80592
- }), z$1.object({
80593
- kind: z$1.literal("fixed_calendar_date"),
80594
- dueAt: z$1.string().datetime()
80595
- })]);
80596
- const bookingFlexibleBalanceConfigSchema = z$1.object({
80597
- upfrontAmountCents: z$1.number().int().nonnegative(),
80598
- dueDateRule: bookingFlexibleBalanceDueDateRuleSchema,
80599
- depositRefundability: bookingDepositRefundPolicySchema
80600
- });
80601
- z$1.discriminatedUnion("kind", [
80602
- z$1.object({ kind: z$1.literal("upfront") }),
80603
- z$1.object({ kind: z$1.literal("deferred_manual") }),
80604
- z$1.object({
80605
- kind: z$1.literal("instalment_plan"),
80606
- plan: bookingInstalmentPlanSchema
80607
- }),
80608
- z$1.object({
80609
- kind: z$1.literal("flexible_balance"),
80610
- config: bookingFlexibleBalanceConfigSchema
80611
- })
80612
- ]);
80613
- //#endregion
80614
80979
  //#region ../api/src/navigationMenuValidation.ts
80615
80980
  function hasChildren(item) {
80616
80981
  return Array.isArray(item.children) && item.children.length > 0;
@@ -81670,20 +82035,20 @@ const BUILTIN_CONTENT_TYPE_SCHEMAS = {
81670
82035
  id: "summary",
81671
82036
  type: "textarea",
81672
82037
  label: "Short introduction",
81673
- description: "Write one or two sentences that help people quickly understand what this is. It appears wherever the event is listed and near the top of its page.",
82038
+ description: "Shown in your listings and search results, and at the top of its page.",
81674
82039
  rows: 3
81675
82040
  },
81676
82041
  {
81677
82042
  id: "image",
81678
82043
  type: "media",
81679
82044
  label: "Event image",
81680
- description: "Choose the main image people will see wherever the event is listed and on its page."
82045
+ description: "At the top of its page and beside it in your listings."
81681
82046
  },
81682
82047
  {
81683
82048
  id: "body",
81684
82049
  type: "richText",
81685
- label: "About this event",
81686
- description: "Add the main information people need before booking—what to expect, who it’s for, what’s included, and anything they should bring or know."
82050
+ label: "Full description",
82051
+ description: "The main text on its page, under the introduction."
81687
82052
  }
81688
82053
  ],
81689
82054
  routing: {
@@ -82073,7 +82438,6 @@ const DEFAULT_TEMPLATE_DEFINITIONS = {
82073
82438
  maxTickets: "5",
82074
82439
  showVenue: true,
82075
82440
  showCapacity: true,
82076
- successMessage: "Thank you for registering! Check your email for confirmation details.",
82077
82441
  buttonText: "Complete Registration",
82078
82442
  buttonVariant: "primary"
82079
82443
  },