@riverbankcms/sdk 0.88.0 → 0.90.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 (198) hide show
  1. package/README.md +27 -4
  2. package/dist/{PreviewEditorSidebar-EVRS3C7T.mjs → PreviewEditorSidebar-KVXNF3VW.mjs} +3 -3
  3. package/dist/{PreviewEditorUI-54WD4IGE.mjs → PreviewEditorUI-J3JN5Z7T.mjs} +3 -3
  4. package/dist/SdkPreviewModeRuntime-UBL6MSNP.mjs +8 -0
  5. package/dist/_dts/ai/src/contracts/proposals.d.ts +216 -0
  6. package/dist/_dts/altcha/src/AltchaWidget.d.ts +1 -1
  7. package/dist/_dts/api/src/accessAdmin.d.ts +7 -0
  8. package/dist/_dts/api/src/bookingOperations.d.ts +2 -0
  9. package/dist/_dts/api/src/bookingRecords.d.ts +4 -2
  10. package/dist/_dts/api/src/bookings.d.ts +3 -1
  11. package/dist/_dts/api/src/endpoints.d.ts +8 -0
  12. package/dist/_dts/api/src/index.d.ts +7 -6
  13. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +15 -5
  14. package/dist/_dts/api/src/request.d.ts +21 -0
  15. package/dist/_dts/api/src/sdk-event-upsert.d.ts +3 -1
  16. package/dist/_dts/api/src/sdkContracts.d.ts +2 -0
  17. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +5 -1
  18. package/dist/_dts/api/src/siteMembers.d.ts +6 -1
  19. package/dist/_dts/api/src/types.d.ts +4 -2
  20. package/dist/_dts/api/src/url.d.ts +6 -3
  21. package/dist/_dts/block-form/src/utils/visibleWhen.d.ts +1 -0
  22. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterThumbnailCard.d.ts +5 -1
  23. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterThumbnailGrid.d.ts +9 -1
  24. package/dist/_dts/block-form/src/widgets/RepeaterField/components/index.d.ts +1 -0
  25. package/dist/_dts/blocks/src/contracts/non-block-islands.d.ts +7 -11
  26. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +6 -0
  27. package/dist/_dts/blocks/src/index.d.ts +2 -1
  28. package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +14 -6
  29. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +4 -4
  30. package/dist/_dts/blocks/src/system/blocks/hero.d.ts +0 -2
  31. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +3 -3
  32. package/dist/_dts/blocks/src/system/blocks/shop.shared.d.ts +8 -0
  33. package/dist/_dts/blocks/src/system/constants/events.d.ts +4 -1
  34. package/dist/_dts/blocks/src/system/icons/cta.d.ts +3 -3
  35. package/dist/_dts/blocks/src/system/icons/index.d.ts +1 -0
  36. package/dist/_dts/blocks/src/system/icons/registry.d.ts +2 -2
  37. package/dist/_dts/blocks/src/system/icons/semantic.d.ts +3 -3
  38. package/dist/_dts/blocks/src/system/icons/svg.d.ts +72 -0
  39. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +3 -1
  40. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -0
  41. package/dist/_dts/blocks/src/system/runtime/api/types.d.ts +18 -5
  42. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +51 -6
  43. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +24 -0
  44. package/dist/_dts/blocks/src/system/runtime/hooks/loadStateError.d.ts +1 -0
  45. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableDates.d.ts +1 -1
  46. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableDates.state.d.ts +55 -0
  47. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableSlots.state.d.ts +39 -0
  48. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingFormConfig.d.ts +4 -27
  49. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingFormConfig.state.d.ts +40 -0
  50. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +20 -0
  51. package/dist/_dts/blocks/src/system/runtime/hooks/useEventFilters.state.d.ts +31 -0
  52. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.d.ts +3 -3
  53. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.state.d.ts +39 -0
  54. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.d.ts +2 -2
  55. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/logic.d.ts +1 -17
  56. package/dist/_dts/blocks/src/system/runtime/nodes/event-details.client.d.ts +5 -9
  57. package/dist/_dts/blocks/src/system/runtime/nodes/event-details.server.d.ts +5 -9
  58. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +2 -1
  59. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventPaymentOptions.d.ts +24 -0
  60. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +5 -0
  61. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.d.ts +4 -4
  62. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.state.d.ts +50 -0
  63. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +2 -2
  64. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +21 -0
  65. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.server.d.ts +1 -1
  66. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +11 -1
  67. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +2 -1
  68. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +11 -1
  69. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventPaginatedListView.client.d.ts +1 -1
  70. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/calendarViewOptions.d.ts +10 -0
  71. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventProductEligibility.d.ts +24 -0
  72. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.client.state.d.ts +24 -2
  73. package/dist/_dts/blocks/src/system/runtime/nodes/shared/MagicLinkForm.state.d.ts +24 -0
  74. package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +5 -2
  75. package/dist/_dts/blocks/src/system/runtime/nodes/shop-checkout-form.d.ts +2 -2
  76. package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.state.d.ts +35 -0
  77. package/dist/_dts/content-model/src/entry-slots/index.d.ts +1 -0
  78. package/dist/_dts/content-model/src/entry-slots/sdkBlocks.d.ts +21 -0
  79. package/dist/_dts/content-model/src/entry-slots/types.d.ts +61 -0
  80. package/dist/_dts/core/src/branded.d.ts +7 -0
  81. package/dist/_dts/core/src/index.d.ts +1 -0
  82. package/dist/_dts/core/src/money-input.d.ts +18 -0
  83. package/dist/_dts/core/src/site-route-target.d.ts +40 -0
  84. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +209 -2
  85. package/dist/_dts/media-core/src/fileDomain.d.ts +4 -0
  86. package/dist/_dts/media-editor/src/MediaEditor.d.ts +2 -1
  87. package/dist/_dts/media-editor/src/fieldUi.d.ts +6 -0
  88. package/dist/_dts/media-editor/src/index.d.ts +1 -1
  89. package/dist/_dts/preview-next/src/client/index.d.ts +1 -0
  90. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +3 -2
  91. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +3 -2
  92. package/dist/_dts/preview-next/src/client/preview/PreviewThemedSiteDocument.d.ts +3 -2
  93. package/dist/_dts/preview-next/src/client/preview/SiteChromeEditableSurface.d.ts +2 -2
  94. package/dist/_dts/preview-next/src/client/preview/themeRuntime.d.ts +6 -0
  95. package/dist/_dts/preview-next/src/client/sdk/SdkPreviewMode.d.ts +2 -1
  96. package/dist/_dts/sdk/src/cli/commands/pull-dated-offering-scope.d.ts +10 -0
  97. package/dist/_dts/sdk/src/cli/content/reader.d.ts +12 -5
  98. package/dist/_dts/sdk/src/client/management/types.d.ts +6 -55
  99. package/dist/_dts/sdk/src/client/runtimeCachePolicy.d.ts +160 -0
  100. package/dist/_dts/sdk/src/client/types.d.ts +26 -1
  101. package/dist/_dts/sdk/src/components.d.ts +1 -0
  102. package/dist/_dts/sdk/src/config/field-definitions.d.ts +3 -1
  103. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +3 -1
  104. package/dist/_dts/sdk/src/index.d.ts +3 -1
  105. package/dist/_dts/sdk/src/next/types.d.ts +8 -11
  106. package/dist/_dts/sdk/src/preview-next/client/index.d.ts +1 -1
  107. package/dist/_dts/sdk/src/rendering/blocks-theme-scope.d.ts +2 -1
  108. package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +8 -7
  109. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +5 -6
  110. package/dist/_dts/sdk/src/rendering/index.d.ts +1 -0
  111. package/dist/_dts/sdk/src/rendering/server.d.ts +1 -0
  112. package/dist/_dts/sdk/src/rendering/themeRuntime.d.ts +26 -0
  113. package/dist/_dts/sdk/src/version.d.ts +1 -1
  114. package/dist/_dts/site-commands/src/commands.d.ts +18 -0
  115. package/dist/_dts/theme-core/src/ResponsiveScope.d.ts +12 -0
  116. package/dist/_dts/theme-core/src/accordions/types.d.ts +1 -1
  117. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +2 -2
  118. package/dist/_dts/theme-core/src/buttons/types.d.ts +5 -5
  119. package/dist/_dts/theme-core/src/cards/types.d.ts +2 -2
  120. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  121. package/dist/_dts/theme-core/src/index.d.ts +2 -0
  122. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +21 -21
  123. package/dist/_dts/theme-core/src/schema.d.ts +18 -18
  124. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +2 -2
  125. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +2 -2
  126. package/dist/_dts/theme-core/src/site-styles/logoBranding.d.ts +4 -4
  127. package/dist/_dts/theme-core/src/themeRuntime.d.ts +11 -0
  128. package/dist/{chunk-ER4UIW4X.mjs → chunk-AEOYWPE4.mjs} +91 -55
  129. package/dist/{chunk-O4LVYUVH.mjs → chunk-BOQXMCSP.mjs} +147 -101
  130. package/dist/{chunk-HVOBXA3Y.mjs → chunk-GSPFFUVB.mjs} +2 -2
  131. package/dist/{chunk-7KOO7RPP.mjs → chunk-PMBB6MQ7.mjs} +2273 -1113
  132. package/dist/{chunk-K3JWH6HE.mjs → chunk-RQ3XZ4SJ.mjs} +9 -1
  133. package/dist/{chunk-YDMBIIS5.mjs → chunk-UG7I7S7W.mjs} +1 -1
  134. package/dist/cli/index.mjs +1564 -546
  135. package/dist/cli/init-docs/content/cli-reference.md +6 -1
  136. package/dist/cli/init-docs/content/content-management.md +27 -0
  137. package/dist/client/{accordion-PT5CGW5N.mjs → accordion-GXQNWQ6O.mjs} +2 -2
  138. package/dist/client/{bookingForm-2HLRTEYS.mjs → bookingForm-STLUJ36H.mjs} +206 -335
  139. package/dist/client/bookings.mjs +821 -413
  140. package/dist/client/{carousel-Z2LKYSWA.mjs → carousel-CVRN6EPP.mjs} +4 -3
  141. package/dist/client/{cart-ND5IK4A6.mjs → cart-IYIBA5CL.mjs} +8 -8
  142. package/dist/client/{checkout-EYUSGAY7.mjs → checkout-O3BGM4GS.mjs} +8 -8
  143. package/dist/client/chunk-4RTFGHZN.mjs +433 -0
  144. package/dist/client/{chunk-DIRW2LNG.mjs → chunk-6DPXDOIL.mjs} +336 -225
  145. package/dist/client/chunk-6N7YRNYU.mjs +183 -0
  146. package/dist/client/{chunk-O5JNI3E4.mjs → chunk-7DH35FGA.mjs} +2 -2
  147. package/dist/client/{chunk-S4G65LGR.mjs → chunk-D3ETC2SU.mjs} +1 -1
  148. package/dist/client/{chunk-BAWHZ5GM.mjs → chunk-DAS5CIER.mjs} +460 -157
  149. package/dist/client/{chunk-6DVPO44G.mjs → chunk-FHU6PFPM.mjs} +1 -1
  150. package/dist/client/{chunk-SDIYSQAY.mjs → chunk-HIHOQGIP.mjs} +2 -3
  151. package/dist/client/{chunk-BL66UWGD.mjs → chunk-MFPKS6QS.mjs} +13 -16
  152. package/dist/client/{chunk-X7GVFB7Y.mjs → chunk-NBFRJ5NB.mjs} +157 -5
  153. package/dist/client/{chunk-WCVK4MBJ.mjs → chunk-VFHZLZAC.mjs} +1 -1
  154. package/dist/client/{chunk-GOFO7HRH.mjs → chunk-WHZQDPBZ.mjs} +19 -1
  155. package/dist/client/{chunk-MHBEWDT7.mjs → chunk-Z62JYS5O.mjs} +122 -50
  156. package/dist/client/client.mjs +5979 -5198
  157. package/dist/client/{courseRegistration-H3AZBUEG.mjs → courseRegistration-2D3ACMJR.mjs} +20 -58
  158. package/dist/client/{eventCalendar-FPKJGLGS.mjs → eventCalendar-QY4UZUFF.mjs} +11 -11
  159. package/dist/client/{eventCombined-QCGIZBUY.mjs → eventCombined-RRCDKJC2.mjs} +11 -11
  160. package/dist/client/{eventDetails-HIT3BJWU.mjs → eventDetails-YO335BUT.mjs} +11 -11
  161. package/dist/client/{eventListing-R4HNWJDN.mjs → eventListing-PXA6GFQ3.mjs} +11 -11
  162. package/dist/client/{eventRegistration-Q7BYY5HF.mjs → eventRegistration-2ZHEDDXO.mjs} +11 -11
  163. package/dist/client/{form-NI6YOG6S.mjs → form-ZS6KX4U2.mjs} +7 -7
  164. package/dist/client/{headerSection-SDYGII36.mjs → headerSection-QK5SLIIB.mjs} +3 -3
  165. package/dist/client/hooks.mjs +1102 -1029
  166. package/dist/client/{locationMap-BDETEUQD.mjs → locationMap-GFNIUD2X.mjs} +3 -3
  167. package/dist/client/{newsletterForm-EKYIU67X.mjs → newsletterForm-PGLTTCUG.mjs} +61 -25
  168. package/dist/client/{productDetail-5UTGNN76.mjs → productDetail-OPBE5ZPI.mjs} +8 -8
  169. package/dist/client/{productList-7YA5KXZQ.mjs → productList-NI72Q62Z.mjs} +8 -8
  170. package/dist/client/rendering/client.mjs +4390 -4245
  171. package/dist/client/rendering/islands.mjs +19 -19
  172. package/dist/client/rendering.mjs +3327 -3181
  173. package/dist/client/{shop-AIMUMZYC.mjs → shop-3ZQPEWYI.mjs} +8 -8
  174. package/dist/client/spam-protection.mjs +4 -5
  175. package/dist/preview-next/before-render.mjs +20 -2
  176. package/dist/preview-next/client/runtime.mjs +5 -5
  177. package/dist/preview-next/middleware.mjs +18 -0
  178. package/dist/{sdk-runtime-NW472WNT.mjs → sdk-runtime-FSHXCWDS.mjs} +6 -6
  179. package/dist/server/components.mjs +2580 -2783
  180. package/dist/server/config-validation.mjs +1334 -1261
  181. package/dist/server/config.mjs +1334 -1261
  182. package/dist/server/data.mjs +1102 -1029
  183. package/dist/server/index.mjs +1097 -476
  184. package/dist/server/navigation.mjs +20 -30
  185. package/dist/server/next.mjs +3282 -2847
  186. package/dist/server/page-converter.mjs +1009 -946
  187. package/dist/server/prebuild.mjs +1 -1
  188. package/dist/server/rendering/server.mjs +2580 -2783
  189. package/dist/server/rendering.mjs +2586 -2789
  190. package/dist/server/routing.mjs +1440 -1053
  191. package/dist/server/server.mjs +1886 -1153
  192. package/dist/server/theme-bridge.mjs +34 -5
  193. package/dist/styles/index.css +26 -0
  194. package/package.json +3 -2
  195. package/dist/SdkPreviewModeRuntime-ZALZDJEK.mjs +0 -8
  196. package/dist/client/chunk-H4MHEXYS.mjs +0 -184
  197. package/dist/client/chunk-ZFHRN6W2.mjs +0 -66
  198. /package/dist/client/{chunk-LI2C6M5O.mjs → chunk-25W2EQUN.mjs} +0 -0
@@ -527,6 +527,12 @@ var init_stable_json = __esm({
527
527
  }
528
528
  });
529
529
 
530
+ // ../core/src/site-route-target.ts
531
+ var init_site_route_target = __esm({
532
+ "../core/src/site-route-target.ts"() {
533
+ }
534
+ });
535
+
530
536
  // ../core/src/index.ts
531
537
  var init_src = __esm({
532
538
  "../core/src/index.ts"() {
@@ -573,6 +579,7 @@ var init_src = __esm({
573
579
  init_string();
574
580
  init_uuid();
575
581
  init_stable_json();
582
+ init_site_route_target();
576
583
  }
577
584
  });
578
585
 
@@ -1538,12 +1545,17 @@ var init_schema2 = __esm({
1538
1545
  minItems: z.number().int().nonnegative().optional(),
1539
1546
  maxItems: z.number().int().nonnegative().optional()
1540
1547
  });
1541
- visibleWhenSchema = z.union([
1542
- visibleWhenPredicateSchema,
1543
- z.object({
1544
- allOf: z.array(visibleWhenPredicateSchema).min(1)
1545
- })
1546
- ]);
1548
+ visibleWhenSchema = z.lazy(
1549
+ () => z.union([
1550
+ visibleWhenPredicateSchema,
1551
+ z.object({
1552
+ allOf: z.array(visibleWhenSchema).min(1)
1553
+ }),
1554
+ z.object({
1555
+ anyOf: z.array(visibleWhenSchema).min(1)
1556
+ })
1557
+ ])
1558
+ );
1547
1559
  uiSchema = z.object({
1548
1560
  widget: z.string().optional(),
1549
1561
  // Container/widget presets (used by Group/Repeater widgets themselves, not for widget selection)
@@ -13381,11 +13393,11 @@ function bind(from, options) {
13381
13393
  }
13382
13394
  });
13383
13395
  }
13384
- function when(path27, options) {
13396
+ function when(path28, options) {
13385
13397
  return (node) => ({
13386
13398
  ...node,
13387
13399
  $when: {
13388
- when: { from: path27 },
13400
+ when: { from: path28 },
13389
13401
  ...options?.equals !== void 0 ? { equals: options.equals } : {},
13390
13402
  ...options?.not ? { not: true } : {}
13391
13403
  }
@@ -13492,7 +13504,7 @@ var init_builder2 = __esm({
13492
13504
  });
13493
13505
 
13494
13506
  // ../blocks/src/system/node/fragments/backgroundLayer.ts
13495
- function backgroundLayer(path27, options = {}) {
13507
+ function backgroundLayer(path28, options = {}) {
13496
13508
  const {
13497
13509
  styleClassName = "background-style rb-absolute rb-inset-0 rb-z-neg-10 rb-h-full rb-w-full rb-pointer-events-none",
13498
13510
  imageClassName,
@@ -13506,7 +13518,7 @@ function backgroundLayer(path27, options = {}) {
13506
13518
  className: styleClassName,
13507
13519
  style: {
13508
13520
  $bind: {
13509
- from: path27,
13521
+ from: path28,
13510
13522
  transforms: [
13511
13523
  {
13512
13524
  id: "background.resolveStyle",
@@ -13516,20 +13528,20 @@ function backgroundLayer(path27, options = {}) {
13516
13528
  }
13517
13529
  }
13518
13530
  });
13519
- const imageLayer = createBackgroundImageNode(path27, imageClassName, {
13531
+ const imageLayer = createBackgroundImageNode(path28, imageClassName, {
13520
13532
  loading: imageLoading,
13521
13533
  fetchPriority: imageFetchPriority
13522
13534
  });
13523
- const overlayLayer = createBackgroundOverlayNode(path27, overlayClassName);
13535
+ const overlayLayer = createBackgroundOverlayNode(path28, overlayClassName);
13524
13536
  return omitImageLayer ? [styleLayer, overlayLayer] : [styleLayer, imageLayer, overlayLayer];
13525
13537
  }
13526
- function createBackgroundImageNode(path27, baseClassName = "rb-absolute rb-z-neg-10", options = {}) {
13527
- const imagePath = `${path27}.image`;
13538
+ function createBackgroundImageNode(path28, baseClassName = "rb-absolute rb-z-neg-10", options = {}) {
13539
+ const imagePath = `${path28}.image`;
13528
13540
  return media(
13529
13541
  {
13530
13542
  className: {
13531
13543
  $bind: {
13532
- from: path27,
13544
+ from: path28,
13533
13545
  transforms: [
13534
13546
  {
13535
13547
  id: "background.resolveImageClassName",
@@ -13540,7 +13552,7 @@ function createBackgroundImageNode(path27, baseClassName = "rb-absolute rb-z-neg
13540
13552
  },
13541
13553
  style: {
13542
13554
  $bind: {
13543
- from: path27,
13555
+ from: path28,
13544
13556
  transforms: [{ id: "background.resolveImageStyle" }]
13545
13557
  }
13546
13558
  },
@@ -13552,8 +13564,8 @@ function createBackgroundImageNode(path27, baseClassName = "rb-absolute rb-z-neg
13552
13564
  bind(imagePath)
13553
13565
  );
13554
13566
  }
13555
- function createBackgroundOverlayNode(path27, className = "background-overlay rb-absolute rb-inset-0 rb-z-neg-10 rb-h-full rb-w-full rb-pointer-events-none") {
13556
- const overlayPath = `${path27}.overlay`;
13567
+ function createBackgroundOverlayNode(path28, className = "background-overlay rb-absolute rb-inset-0 rb-z-neg-10 rb-h-full rb-w-full rb-pointer-events-none") {
13568
+ const overlayPath = `${path28}.overlay`;
13557
13569
  return el("div", {
13558
13570
  className,
13559
13571
  style: {
@@ -14393,10 +14405,10 @@ var init_sectionForegroundStyles = __esm({
14393
14405
  });
14394
14406
 
14395
14407
  // ../blocks/src/system/transforms/registry/boxStyles.ts
14396
- function readPath(source, path27) {
14397
- if (!source || !path27) return void 0;
14398
- if (!path27.includes(".")) return source[path27];
14399
- return path27.split(".").reduce((acc, segment) => {
14408
+ function readPath(source, path28) {
14409
+ if (!source || !path28) return void 0;
14410
+ if (!path28.includes(".")) return source[path28];
14411
+ return path28.split(".").reduce((acc, segment) => {
14400
14412
  if (acc && typeof acc === "object" && segment in acc) {
14401
14413
  return acc[segment];
14402
14414
  }
@@ -15388,27 +15400,27 @@ function scopePropValue(value, scope) {
15388
15400
  }
15389
15401
  return value;
15390
15402
  }
15391
- function scopeContentPath(path27, scope) {
15403
+ function scopeContentPath(path28, scope) {
15392
15404
  if (!scope || scope.length === 0) {
15393
- return path27;
15405
+ return path28;
15394
15406
  }
15395
- if (path27 === "content") {
15407
+ if (path28 === "content") {
15396
15408
  return `content.${scope}`;
15397
15409
  }
15398
- if (path27.startsWith("content.")) {
15399
- const remainder = path27.slice("content.".length);
15410
+ if (path28.startsWith("content.")) {
15411
+ const remainder = path28.slice("content.".length);
15400
15412
  return remainder.length > 0 ? `content.${scope}.${remainder}` : `content.${scope}`;
15401
15413
  }
15402
- if (path27.startsWith("content[")) {
15403
- return path27.replace(/^content/, `content.${scope}`);
15414
+ if (path28.startsWith("content[")) {
15415
+ return path28.replace(/^content/, `content.${scope}`);
15404
15416
  }
15405
- if (path27.startsWith("$root.")) {
15406
- return path27;
15417
+ if (path28.startsWith("$root.")) {
15418
+ return path28;
15407
15419
  }
15408
- if (path27.includes(".")) {
15409
- return path27;
15420
+ if (path28.includes(".")) {
15421
+ return path28;
15410
15422
  }
15411
- return `content.${scope}.${path27}`;
15423
+ return `content.${scope}.${path28}`;
15412
15424
  }
15413
15425
  var FRAGMENT_ID_PATTERN, FIELD_ID_PATTERN, dataLoaderSchema, fragmentDataSchema, fragmentConfigSchema, FragmentConfigError;
15414
15426
  var init_types14 = __esm({
@@ -15693,9 +15705,6 @@ var init_heroCopy = __esm({
15693
15705
  maxLength: 600
15694
15706
  }
15695
15707
  ],
15696
- // Layout order is [eyebrow, headline, subheadline]. The hero block's
15697
- // `splitEditorial` variant reads these nodes by index; keep the order stable
15698
- // (it fails fast at import if the count changes).
15699
15708
  layout: [
15700
15709
  text(
15701
15710
  {
@@ -18327,8 +18336,8 @@ function decodeSuccess(value) {
18327
18336
  function decodeFailure(issues) {
18328
18337
  return { ok: false, issues };
18329
18338
  }
18330
- function zodIssuePath(path27) {
18331
- return path27.flatMap((segment) => {
18339
+ function zodIssuePath(path28) {
18340
+ return path28.flatMap((segment) => {
18332
18341
  if (typeof segment === "string" || typeof segment === "number") {
18333
18342
  return [segment];
18334
18343
  }
@@ -19225,6 +19234,40 @@ var init_shared2 = __esm({
19225
19234
  init_filtering();
19226
19235
  }
19227
19236
  });
19237
+ var publicPassProductSchema, publicPassProductCollectionSchema, publicMembershipProductSchema, publicMembershipProductCollectionSchema;
19238
+ var init_shop_shared = __esm({
19239
+ "../blocks/src/system/blocks/shop.shared.ts"() {
19240
+ publicPassProductSchema = z.object({
19241
+ id: z.string(),
19242
+ productUseCase: z.enum(["event_pass", "appointment_package"]).default("event_pass"),
19243
+ name: z.string(),
19244
+ description: z.string().nullable(),
19245
+ price: z.number(),
19246
+ currency: z.string(),
19247
+ creditsTotal: z.number(),
19248
+ pricePerCredit: z.number(),
19249
+ validDays: z.number().nullable(),
19250
+ eligibleCategoryIds: z.array(z.string()),
19251
+ eligibleCategoryNames: z.array(z.string())
19252
+ });
19253
+ publicPassProductCollectionSchema = z.object({
19254
+ passes: z.array(publicPassProductSchema)
19255
+ });
19256
+ publicMembershipProductSchema = z.object({
19257
+ id: z.string(),
19258
+ name: z.string(),
19259
+ description: z.string().nullable(),
19260
+ price: z.number(),
19261
+ currency: z.string(),
19262
+ billingInterval: z.enum(["month", "year"]),
19263
+ eligibleCategoryIds: z.array(z.string()),
19264
+ eligibleCategoryNames: z.array(z.string())
19265
+ });
19266
+ publicMembershipProductCollectionSchema = z.object({
19267
+ memberships: z.array(publicMembershipProductSchema)
19268
+ });
19269
+ }
19270
+ });
19228
19271
  var occurrenceContextSchema;
19229
19272
  var init_event_registration_shared = __esm({
19230
19273
  "../blocks/src/system/blocks/event-registration.shared.ts"() {
@@ -19244,6 +19287,9 @@ var init_event_registration_shared = __esm({
19244
19287
  function isEventCalendarDisplayMode(value) {
19245
19288
  return typeof value === "string" && eventCalendarDisplayModeValues.includes(value);
19246
19289
  }
19290
+ function isEventCalendarDefaultView(value) {
19291
+ return typeof value === "string" && eventCalendarDefaultViewValues.includes(value);
19292
+ }
19247
19293
  function isEventCalendarListLayout(value) {
19248
19294
  return typeof value === "string" && eventCalendarListLayoutValues.includes(value);
19249
19295
  }
@@ -19251,11 +19297,12 @@ function isEventContentType(slug) {
19251
19297
  if (!slug) return false;
19252
19298
  return EVENT_CONTENT_TYPE_SLUGS.includes(slug);
19253
19299
  }
19254
- var EVENT_CONTENT_TYPE_SLUGS, eventCalendarDisplayModeValues, eventCalendarListLayoutValues, eventCalendarListLayoutOptions;
19300
+ var EVENT_CONTENT_TYPE_SLUGS, eventCalendarDisplayModeValues, eventCalendarDefaultViewValues, eventCalendarListLayoutValues, eventCalendarListLayoutOptions;
19255
19301
  var init_events = __esm({
19256
19302
  "../blocks/src/system/constants/events.ts"() {
19257
19303
  EVENT_CONTENT_TYPE_SLUGS = ["event", "events"];
19258
- eventCalendarDisplayModeValues = ["combined", "month", "week", "list", "timetable"];
19304
+ eventCalendarDisplayModeValues = ["combined", "calendar", "list", "timetable"];
19305
+ eventCalendarDefaultViewValues = ["month", "week"];
19259
19306
  eventCalendarListLayoutValues = ["stack", "grid", "compact"];
19260
19307
  eventCalendarListLayoutOptions = [
19261
19308
  { id: "stack", label: "Stack" },
@@ -19400,7 +19447,7 @@ var init_pricing = __esm({
19400
19447
  DEFAULT_EVENT_CURRENCY = "USD";
19401
19448
  }
19402
19449
  });
19403
- var previewStageSchema, registrationButtonVariantSchema, eventButtonVariantSchema, eventLayoutSchema, eventCalendarDisplayModeSchema, columnOptionSchema, weekStartSchema, filterAutoShowSchema, calendarTabViewsSchema;
19450
+ var previewStageSchema, registrationButtonVariantSchema, eventButtonVariantSchema, eventLayoutSchema, eventCalendarDisplayModeSchema, eventCalendarDefaultViewSchema, columnOptionSchema, weekStartSchema, filterAutoShowSchema, calendarTabViewsSchema;
19404
19451
  var init_contract_schemas = __esm({
19405
19452
  "../blocks/src/system/runtime/nodes/shared/contract-schemas.ts"() {
19406
19453
  init_events();
@@ -19409,6 +19456,7 @@ var init_contract_schemas = __esm({
19409
19456
  eventButtonVariantSchema = z.enum(["primary", "secondary", "outline", "link"]);
19410
19457
  eventLayoutSchema = z.enum(eventCalendarListLayoutValues);
19411
19458
  eventCalendarDisplayModeSchema = z.enum(eventCalendarDisplayModeValues);
19459
+ eventCalendarDefaultViewSchema = z.enum(eventCalendarDefaultViewValues);
19412
19460
  columnOptionSchema = z.enum(["2", "3", "4"]);
19413
19461
  weekStartSchema = z.enum(["sunday", "monday"]);
19414
19462
  filterAutoShowSchema = z.enum(["auto", "always", "never"]);
@@ -19436,7 +19484,7 @@ function eventMatchesOccurrenceId(event, occurrenceId) {
19436
19484
  function findPreSelectedEvent(input) {
19437
19485
  const occurrenceContext = input.occurrenceContext;
19438
19486
  if (!occurrenceContext) {
19439
- return null;
19487
+ return input.scopedEvents.length === 1 ? input.scopedEvents[0] ?? null : null;
19440
19488
  }
19441
19489
  const contextDate = getBookingLocalDateKey(toScheduledBookingDateTime({
19442
19490
  startsAt: occurrenceContext.startsAt,
@@ -19573,6 +19621,7 @@ var EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS, EVENT_REGISTRATION_SHELL_STEP_
19573
19621
  var init_event_registration_interactive = __esm({
19574
19622
  "../blocks/src/system/runtime/nodes/event-registration.interactive.ts"() {
19575
19623
  init_schemas2();
19624
+ init_shop_shared();
19576
19625
  init_event_registration_shared();
19577
19626
  init_events();
19578
19627
  init_pricing();
@@ -19612,7 +19661,9 @@ var init_event_registration_interactive = __esm({
19612
19661
  overlayEnabled: z.boolean().optional(),
19613
19662
  spamProtectionEnabled: z.boolean().optional(),
19614
19663
  stage: previewStageSchema.optional(),
19615
- supportEmail: z.string().optional()
19664
+ supportEmail: z.string().optional(),
19665
+ sitePasses: publicPassProductCollectionSchema.nullable().optional(),
19666
+ siteMemberships: publicMembershipProductCollectionSchema.nullable().optional()
19616
19667
  });
19617
19668
  eventRegistrationDisplaySchema = z.object({
19618
19669
  kind: z.literal("event-registration"),
@@ -19635,7 +19686,9 @@ var init_event_registration_interactive = __esm({
19635
19686
  buttonVariant: registrationButtonVariantSchema.optional(),
19636
19687
  overlayEnabled: z.boolean().optional(),
19637
19688
  spamProtectionEnabled: z.boolean().optional(),
19638
- supportEmail: z.string().optional()
19689
+ supportEmail: z.string().optional(),
19690
+ sitePasses: publicPassProductCollectionSchema.nullable().optional(),
19691
+ siteMemberships: publicMembershipProductCollectionSchema.nullable().optional()
19639
19692
  });
19640
19693
  eventRegistrationRenderSchema = z.object({
19641
19694
  display: eventRegistrationDisplaySchema,
@@ -19668,7 +19721,9 @@ var init_event_registration_interactive = __esm({
19668
19721
  buttonVariant: source.buttonVariant,
19669
19722
  overlayEnabled: source.overlayEnabled,
19670
19723
  spamProtectionEnabled: source.spamProtectionEnabled,
19671
- supportEmail: source.supportEmail
19724
+ supportEmail: source.supportEmail,
19725
+ sitePasses: source.sitePasses ?? null,
19726
+ siteMemberships: source.siteMemberships ?? null
19672
19727
  }
19673
19728
  })
19674
19729
  });
@@ -19804,34 +19859,6 @@ var init_course_registration_interactive = __esm({
19804
19859
  });
19805
19860
  }
19806
19861
  });
19807
- var publicPassProductSchema, publicMembershipProductSchema;
19808
- var init_shop_shared = __esm({
19809
- "../blocks/src/system/blocks/shop.shared.ts"() {
19810
- publicPassProductSchema = z.object({
19811
- id: z.string(),
19812
- productUseCase: z.enum(["event_pass", "appointment_package"]).default("event_pass"),
19813
- name: z.string(),
19814
- description: z.string().nullable(),
19815
- price: z.number(),
19816
- currency: z.string(),
19817
- creditsTotal: z.number(),
19818
- pricePerCredit: z.number(),
19819
- validDays: z.number().nullable(),
19820
- eligibleCategoryIds: z.array(z.string()),
19821
- eligibleCategoryNames: z.array(z.string())
19822
- });
19823
- publicMembershipProductSchema = z.object({
19824
- id: z.string(),
19825
- name: z.string(),
19826
- description: z.string().nullable(),
19827
- price: z.number(),
19828
- currency: z.string(),
19829
- billingInterval: z.enum(["month", "year"]),
19830
- eligibleCategoryIds: z.array(z.string()),
19831
- eligibleCategoryNames: z.array(z.string())
19832
- });
19833
- }
19834
- });
19835
19862
  var eventDetailsManifest, occurrenceContextSchema2, eventAutoApplyDiscountPreviewBaseSchema, eventAutoApplyDiscountPreviewSchema, eventDetailsBlockDefinition;
19836
19863
  var init_event_details = __esm({
19837
19864
  "../blocks/src/system/blocks/event-details.ts"() {
@@ -20005,8 +20032,8 @@ var init_event_details = __esm({
20005
20032
  dataSchemas: {
20006
20033
  eventDetailsData: z.object({
20007
20034
  events: publicEventsArraySchema,
20008
- sitePasses: z.object({ passes: z.array(publicPassProductSchema) }),
20009
- siteMemberships: z.object({ memberships: z.array(publicMembershipProductSchema) }),
20035
+ sitePasses: publicPassProductCollectionSchema,
20036
+ siteMemberships: publicMembershipProductCollectionSchema,
20010
20037
  autoApplyDiscount: eventAutoApplyDiscountPreviewSchema.nullable().optional().default(null)
20011
20038
  }).optional(),
20012
20039
  occurrenceContext: occurrenceContextSchema2.optional()
@@ -20378,6 +20405,7 @@ function buildEventCalendarDisplay(source) {
20378
20405
  }),
20379
20406
  startOfWeek: source.startOfWeek ?? "monday",
20380
20407
  calendarTabViews: source.calendarTabViews ?? "both",
20408
+ defaultCalendarView: source.defaultCalendarView ?? "month",
20381
20409
  showFilters: source.showFilters ?? true,
20382
20410
  showCategoryFilter: source.showCategoryFilter ?? "auto",
20383
20411
  showVenueFilter: source.showVenueFilter ?? false,
@@ -20429,6 +20457,7 @@ var init_EventCalendar_interactive = __esm({
20429
20457
  loadMoreText: z.string().optional(),
20430
20458
  startOfWeek: weekStartSchema.optional(),
20431
20459
  calendarTabViews: calendarTabViewsSchema.optional(),
20460
+ defaultCalendarView: eventCalendarDefaultViewSchema.optional(),
20432
20461
  showFilters: z.boolean().nullable().optional(),
20433
20462
  showCategoryFilter: filterAutoShowSchema.optional(),
20434
20463
  showVenueFilter: z.boolean().nullable().optional(),
@@ -20460,6 +20489,7 @@ var init_EventCalendar_interactive = __esm({
20460
20489
  paginationAction: eventListPaginationActionSchema,
20461
20490
  startOfWeek: weekStartSchema,
20462
20491
  calendarTabViews: calendarTabViewsSchema,
20492
+ defaultCalendarView: eventCalendarDefaultViewSchema,
20463
20493
  showFilters: z.boolean(),
20464
20494
  showCategoryFilter: filterAutoShowSchema,
20465
20495
  showVenueFilter: z.boolean(),
@@ -23647,6 +23677,24 @@ var ENDPOINT_DEFINITIONS = {
23647
23677
  auth: "user",
23648
23678
  responseKind: "json"
23649
23679
  },
23680
+ resendSiteInvitation: {
23681
+ path: "/sites/{siteId}/members/invitations/{invitationId}/resend",
23682
+ method: "POST",
23683
+ errors: [
23684
+ "auth:forbidden",
23685
+ "resource:not_found",
23686
+ "validation:invalid_input",
23687
+ "external:service_error",
23688
+ "server:internal_error"
23689
+ ],
23690
+ tags: [
23691
+ "site-{siteId}",
23692
+ "site-members-{siteId}",
23693
+ "site-invite-{invitationId}"
23694
+ ],
23695
+ auth: "user",
23696
+ responseKind: "json"
23697
+ },
23650
23698
  transferSiteOwnership: {
23651
23699
  path: "/sites/{siteId}/members/transfer-ownership",
23652
23700
  method: "POST",
@@ -28912,11 +28960,11 @@ function validationContext(options = {}) {
28912
28960
  allowIncomplete: isDraft || (options.allowIncomplete ?? false)
28913
28961
  };
28914
28962
  }
28915
- function formatFieldPath(path27) {
28916
- return path27.map((segment) => String(segment)).join(".");
28963
+ function formatFieldPath(path28) {
28964
+ return path28.map((segment) => String(segment)).join(".");
28917
28965
  }
28918
- function toZodIssuePath(path27) {
28919
- return [...path27];
28966
+ function toZodIssuePath(path28) {
28967
+ return [...path28];
28920
28968
  }
28921
28969
  function fieldIssueToMessage(issue5) {
28922
28970
  switch (issue5.kind) {
@@ -28970,7 +29018,7 @@ function pluralize(label, count) {
28970
29018
  if (count === 1) return label;
28971
29019
  return label.endsWith("s") ? label : `${label}s`;
28972
29020
  }
28973
- function deriveFieldValidationPlan(field, path27 = [field.id]) {
29021
+ function deriveFieldValidationPlan(field, path28 = [field.id]) {
28974
29022
  const required = Boolean(field.required);
28975
29023
  switch (field.type) {
28976
29024
  case "text": {
@@ -28981,7 +29029,7 @@ function deriveFieldValidationPlan(field, path27 = [field.id]) {
28981
29029
  });
28982
29030
  if (typeof field.ui?.min === "number") constraints2.push({ kind: "numberMin", minimum: field.ui.min });
28983
29031
  if (typeof field.ui?.max === "number") constraints2.push({ kind: "numberMax", maximum: field.ui.max });
28984
- return makePlan("number", "number", field, path27, required, constraints2);
29032
+ return makePlan("number", "number", field, path28, required, constraints2);
28985
29033
  }
28986
29034
  const constraints = commonConstraints(required, {
28987
29035
  kind: field.ui?.widget === "iconPicker" ? "blockIconValue" : "textType"
@@ -28990,7 +29038,7 @@ function deriveFieldValidationPlan(field, path27 = [field.id]) {
28990
29038
  if (inputType === "tel") constraints.push({ kind: "phoneFormat" });
28991
29039
  if (field.ui?.pattern) constraints.push({ kind: "patternFormat", pattern: field.ui.pattern });
28992
29040
  if (typeof field.maxLength === "number") constraints.push({ kind: "maxLength", maximum: field.maxLength });
28993
- return makePlan("string", "string", field, path27, required, constraints);
29041
+ return makePlan("string", "string", field, path28, required, constraints);
28994
29042
  }
28995
29043
  case "number": {
28996
29044
  const constraints = commonConstraints(required, {
@@ -28998,34 +29046,34 @@ function deriveFieldValidationPlan(field, path27 = [field.id]) {
28998
29046
  });
28999
29047
  if (typeof field.min === "number") constraints.push({ kind: "numberMin", minimum: field.min });
29000
29048
  if (typeof field.max === "number") constraints.push({ kind: "numberMax", maximum: field.max });
29001
- return makePlan("number", "number", field, path27, required, constraints);
29049
+ return makePlan("number", "number", field, path28, required, constraints);
29002
29050
  }
29003
29051
  case "slug": {
29004
29052
  const constraints = commonConstraints(required, { kind: "textType" }, { kind: "slugFormat" });
29005
29053
  if (typeof field.maxLength === "number") constraints.push({ kind: "maxLength", maximum: field.maxLength });
29006
- return makePlan("string", "string", field, path27, required, constraints);
29054
+ return makePlan("string", "string", field, path28, required, constraints);
29007
29055
  }
29008
29056
  case "url":
29009
29057
  return makePlan(
29010
29058
  "string",
29011
29059
  "string",
29012
29060
  field,
29013
- path27,
29061
+ path28,
29014
29062
  required,
29015
29063
  commonConstraints(required, { kind: "textType" }, { kind: "urlFormat", allowRelative: Boolean(field.allowRelative) })
29016
29064
  );
29017
29065
  case "reference":
29018
- return makePlan("string", "string", field, path27, required, commonConstraints(required, { kind: "referenceText" }));
29066
+ return makePlan("string", "string", field, path28, required, commonConstraints(required, { kind: "referenceText" }));
29019
29067
  case "date":
29020
- return makePlan("string", "string", field, path27, required, commonConstraints(required, { kind: "textType" }, { kind: "dateFormat" }));
29068
+ return makePlan("string", "string", field, path28, required, commonConstraints(required, { kind: "textType" }, { kind: "dateFormat" }));
29021
29069
  case "time":
29022
- return makePlan("string", "string", field, path27, required, commonConstraints(required, { kind: "textType" }, { kind: "timeFormat" }));
29070
+ return makePlan("string", "string", field, path28, required, commonConstraints(required, { kind: "textType" }, { kind: "timeFormat" }));
29023
29071
  case "datetime":
29024
29072
  return makePlan(
29025
29073
  "string",
29026
29074
  "string",
29027
29075
  field,
29028
- path27,
29076
+ path28,
29029
29077
  required,
29030
29078
  commonConstraints(required, { kind: "textType" }, { kind: "datetimeFormat" })
29031
29079
  );
@@ -29034,7 +29082,7 @@ function deriveFieldValidationPlan(field, path27 = [field.id]) {
29034
29082
  "select",
29035
29083
  "select",
29036
29084
  field,
29037
- path27,
29085
+ path28,
29038
29086
  required,
29039
29087
  commonConstraints(required, {
29040
29088
  kind: "selectOption",
@@ -29043,40 +29091,40 @@ function deriveFieldValidationPlan(field, path27 = [field.id]) {
29043
29091
  })
29044
29092
  );
29045
29093
  case "richText":
29046
- return makePlan("richText", "object", field, path27, required, commonConstraints(required, { kind: "richTextDoc" }));
29094
+ return makePlan("richText", "object", field, path28, required, commonConstraints(required, { kind: "richTextDoc" }));
29047
29095
  case "media":
29048
29096
  case "file":
29049
- return makePlan("media", "object", field, path27, required, commonConstraints(required, { kind: "mediaObject" }));
29097
+ return makePlan("media", "object", field, path28, required, commonConstraints(required, { kind: "mediaObject" }));
29050
29098
  case "link":
29051
- return makePlan("link", "object", field, path27, required, commonConstraints(required, { kind: "linkObject" }));
29099
+ return makePlan("link", "object", field, path28, required, commonConstraints(required, { kind: "linkObject" }));
29052
29100
  case "boolean":
29053
- return makePlan("boolean", "boolean", field, path27, required, requiredConstraints(required));
29101
+ return makePlan("boolean", "boolean", field, path28, required, requiredConstraints(required));
29054
29102
  case "repeater":
29055
29103
  return {
29056
- ...makePlan("repeater", "array", field, path27, required, commonConstraints(required, { kind: "arrayType" })),
29104
+ ...makePlan("repeater", "array", field, path28, required, commonConstraints(required, { kind: "arrayType" })),
29057
29105
  ...field.polymorphic && field.itemTypes ? {
29058
- repeatedItemVariants: deriveRepeatedItemVariants(field, [...path27, 0])
29106
+ repeatedItemVariants: deriveRepeatedItemVariants(field, [...path28, 0])
29059
29107
  } : {
29060
- repeatedItemPlan: deriveNestedFieldPlans(getRepeaterFields(field), [...path27, 0])
29108
+ repeatedItemPlan: deriveNestedFieldPlans(getRepeaterFields(field), [...path28, 0])
29061
29109
  },
29062
29110
  constraints: withRepeaterItemConstraints(field, commonConstraints(required, { kind: "arrayType" }))
29063
29111
  };
29064
29112
  case "group":
29065
29113
  case "modal":
29066
29114
  return {
29067
- ...makePlan("group", "object", field, path27, required, requiredConstraints(required)),
29068
- children: deriveNestedFieldPlans(field.schema?.fields ?? [], path27),
29115
+ ...makePlan("group", "object", field, path28, required, requiredConstraints(required)),
29116
+ children: deriveNestedFieldPlans(field.schema?.fields ?? [], path28),
29069
29117
  allowNullChildren: field.type === "group" && field.ui?.widget === "locationPicker"
29070
29118
  };
29071
29119
  case "tabGroup":
29072
29120
  return {
29073
- ...makePlan("group", "object", field, path27, required, requiredConstraints(required)),
29074
- children: field.tabs.flatMap((tab) => deriveNestedFieldPlans(tab.fields, path27))
29121
+ ...makePlan("group", "object", field, path28, required, requiredConstraints(required)),
29122
+ children: field.tabs.flatMap((tab) => deriveNestedFieldPlans(tab.fields, path28))
29075
29123
  };
29076
29124
  case "presetOrCustom":
29077
29125
  case "contentTypeSelect":
29078
29126
  case "entryPicker":
29079
- return makePlan("passthrough", "unknown", field, path27, false, []);
29127
+ return makePlan("passthrough", "unknown", field, path28, false, []);
29080
29128
  default:
29081
29129
  return assertNever2(field);
29082
29130
  }
@@ -29090,14 +29138,14 @@ function commonConstraints(required, ...specific) {
29090
29138
  function requiredConstraints(required) {
29091
29139
  return required ? [{ kind: "required" }] : [];
29092
29140
  }
29093
- function makePlan(kind, valueKind2, field, path27, required, constraints) {
29141
+ function makePlan(kind, valueKind2, field, path28, required, constraints) {
29094
29142
  return {
29095
29143
  kind,
29096
29144
  valueKind: valueKind2,
29097
29145
  fieldId: field.id,
29098
29146
  label: field.label,
29099
29147
  fieldType: field.type,
29100
- path: path27,
29148
+ path: path28,
29101
29149
  required,
29102
29150
  visibility: fieldVisibility(field),
29103
29151
  constraints
@@ -29434,18 +29482,18 @@ function materializeRepeaterItemPlan(plan, parentPath, index) {
29434
29482
  return rebaseFieldPlanPath(plan, [...parentPath, 0], [...parentPath, index]);
29435
29483
  }
29436
29484
  function rebaseFieldPlanPath(plan, fromPrefix, toPrefix) {
29437
- const path27 = rebaseFieldPath(plan.path, fromPrefix, toPrefix);
29485
+ const path28 = rebaseFieldPath(plan.path, fromPrefix, toPrefix);
29438
29486
  switch (plan.kind) {
29439
29487
  case "group":
29440
29488
  return {
29441
29489
  ...plan,
29442
- path: path27,
29490
+ path: path28,
29443
29491
  children: plan.children.map((childPlan) => rebaseFieldPlanPath(childPlan, fromPrefix, toPrefix))
29444
29492
  };
29445
29493
  case "repeater":
29446
29494
  return {
29447
29495
  ...plan,
29448
- path: path27,
29496
+ path: path28,
29449
29497
  ...plan.repeatedItemVariants ? {
29450
29498
  repeatedItemVariants: plan.repeatedItemVariants.map((variant) => ({
29451
29499
  ...variant,
@@ -29466,20 +29514,20 @@ function rebaseFieldPlanPath(plan, fromPrefix, toPrefix) {
29466
29514
  case "passthrough":
29467
29515
  return {
29468
29516
  ...plan,
29469
- path: path27
29517
+ path: path28
29470
29518
  };
29471
29519
  default:
29472
29520
  return assertNever2(plan);
29473
29521
  }
29474
29522
  }
29475
- function rebaseFieldPath(path27, fromPrefix, toPrefix) {
29476
- if (!startsWithFieldPath(path27, fromPrefix)) {
29477
- throw new Error(`Cannot rebase field path ${formatFieldPath(path27)} from ${formatFieldPath(fromPrefix)}`);
29523
+ function rebaseFieldPath(path28, fromPrefix, toPrefix) {
29524
+ if (!startsWithFieldPath(path28, fromPrefix)) {
29525
+ throw new Error(`Cannot rebase field path ${formatFieldPath(path28)} from ${formatFieldPath(fromPrefix)}`);
29478
29526
  }
29479
- return [...toPrefix, ...path27.slice(fromPrefix.length)];
29527
+ return [...toPrefix, ...path28.slice(fromPrefix.length)];
29480
29528
  }
29481
- function startsWithFieldPath(path27, prefix) {
29482
- return prefix.every((segment, index) => path27[index] === segment);
29529
+ function startsWithFieldPath(path28, prefix) {
29530
+ return prefix.every((segment, index) => path28[index] === segment);
29483
29531
  }
29484
29532
  function issue(plan, kind, extra) {
29485
29533
  return {
@@ -29505,8 +29553,8 @@ function fieldPlanToZod(plan, options = {}) {
29505
29553
  }
29506
29554
  function addFieldIssueToZodContext(zodCtx, validationIssue, rootPath) {
29507
29555
  const message = fieldIssueToMessage(validationIssue);
29508
- const path27 = relativeZodIssuePath(validationIssue.path, rootPath);
29509
- const issuePath = path27.length > 0 ? { path: toZodIssuePath(path27) } : {};
29556
+ const path28 = relativeZodIssuePath(validationIssue.path, rootPath);
29557
+ const issuePath = path28.length > 0 ? { path: toZodIssuePath(path28) } : {};
29510
29558
  switch (validationIssue.kind) {
29511
29559
  case "required":
29512
29560
  if (validationIssue.emptyOrigin) {
@@ -29559,8 +29607,8 @@ function addFieldIssueToZodContext(zodCtx, validationIssue, rootPath) {
29559
29607
  assertNever2(validationIssue);
29560
29608
  }
29561
29609
  }
29562
- function relativeZodIssuePath(path27, rootPath) {
29563
- return startsWithFieldPath(path27, rootPath) ? path27.slice(rootPath.length) : path27;
29610
+ function relativeZodIssuePath(path28, rootPath) {
29611
+ return startsWithFieldPath(path28, rootPath) ? path28.slice(rootPath.length) : path28;
29564
29612
  }
29565
29613
  function compilePattern(pattern) {
29566
29614
  try {
@@ -29929,32 +29977,6 @@ var splitReverseLayout = splitLayoutWith([
29929
29977
  splitContentColumn,
29930
29978
  splitImageColumn
29931
29979
  ]);
29932
- var heroEyebrowNode = heroCopyFragment.layout[0];
29933
- var heroHeadlineNode = heroCopyFragment.layout[1];
29934
- var heroSubheadlineNode = heroCopyFragment.layout[2];
29935
- var heroCtaRowNode = heroCtaRowFragment.layout[0];
29936
- if (!heroEyebrowNode || !heroHeadlineNode || !heroSubheadlineNode || !heroCtaRowNode) {
29937
- throw new Error("Hero copy/CTA fragments are missing their expected layout nodes.");
29938
- }
29939
- var heroEditorialBottomRow = inline(
29940
- {
29941
- gap: "lg",
29942
- align: "end",
29943
- justify: "start",
29944
- wrap: true,
29945
- className: "rb-w-full"
29946
- },
29947
- [heroSubheadlineNode, heroCtaRowNode]
29948
- );
29949
- var splitEditorialContentColumn = heroContentWrapper(
29950
- [heroEyebrowNode, heroHeadlineNode, heroEditorialBottomRow],
29951
- "md",
29952
- "rb-w-full rb-text-left"
29953
- );
29954
- var splitEditorialLayout = splitLayoutWith([
29955
- splitEditorialContentColumn,
29956
- splitImageColumn
29957
- ]);
29958
29980
  var heroConfig = {
29959
29981
  id: "block.hero",
29960
29982
  title: "Hero",
@@ -29978,7 +30000,8 @@ var heroConfig = {
29978
30000
  id: "imageShape",
29979
30001
  label: "Image shape",
29980
30002
  defaultValue: "default",
29981
- uiIntent: "display"
30003
+ uiIntent: "display",
30004
+ visibleWhen: { field: "variant", oneOf: ["split", "splitReverse"] }
29982
30005
  })
29983
30006
  ],
29984
30007
  layout: classicLayout,
@@ -29986,8 +30009,7 @@ var heroConfig = {
29986
30009
  classic: classicLayout,
29987
30010
  micro: microLayout,
29988
30011
  split: splitLayout,
29989
- splitReverse: splitReverseLayout,
29990
- splitEditorial: splitEditorialLayout
30012
+ splitReverse: splitReverseLayout
29991
30013
  },
29992
30014
  defaultVariant: "classic",
29993
30015
  description: "Hero section with headline, subtitle, and repeatable CTAs.",
@@ -31634,8 +31656,10 @@ function resolveGeneratedHeroLayoutStyles(content) {
31634
31656
  return isPlainObject2(raw) ? raw : null;
31635
31657
  }
31636
31658
  function readHeroLayoutString(content, generatedKey, fallbackKey = generatedKey) {
31659
+ const explicitValue = readString(content, fallbackKey);
31660
+ if (explicitValue !== void 0) return explicitValue;
31637
31661
  const generated = resolveGeneratedHeroLayoutStyles(content);
31638
- return generated && typeof generated[generatedKey] === "string" ? generated[generatedKey] : readString(content, fallbackKey);
31662
+ return generated && typeof generated[generatedKey] === "string" ? generated[generatedKey] : void 0;
31639
31663
  }
31640
31664
  function resolveHeroVariant(content) {
31641
31665
  const variant = readString(content, "variant");
@@ -31648,7 +31672,7 @@ function resolveHeroContentAlignment(content) {
31648
31672
  const raw = readHeroLayoutString(content, "contentAlignment");
31649
31673
  if (raw === "left" || raw === "center" || raw === "right") return raw;
31650
31674
  const variant = resolveHeroVariant(content);
31651
- if (variant === "split" || variant === "splitReverse" || variant === "splitEditorial") return "left";
31675
+ if (variant === "split" || variant === "splitReverse") return "left";
31652
31676
  return "center";
31653
31677
  }
31654
31678
  function resolveHeroVerticalAlignment(content) {
@@ -31658,7 +31682,7 @@ function resolveHeroVerticalAlignment(content) {
31658
31682
  const minHeight = sectionStyles?.minHeight;
31659
31683
  if (minHeight === "banner" || minHeight === "hero" || minHeight === "immersive") return "center";
31660
31684
  const variant = resolveHeroVariant(content);
31661
- if (variant === "split" || variant === "splitReverse" || variant === "splitEditorial") return "center";
31685
+ if (variant === "split" || variant === "splitReverse") return "center";
31662
31686
  return "top";
31663
31687
  }
31664
31688
  function resolveHeroContentMaxWidth(content) {
@@ -32718,9 +32742,9 @@ function maybeBuildSupabaseTransformUrl(inputUrl, options) {
32718
32742
  const remainder = url.pathname.slice(idx + marker.length);
32719
32743
  const parts = remainder.split("/").filter(Boolean);
32720
32744
  const bucket = parts[0];
32721
- const path27 = parts.slice(1).join("/");
32722
- if (!bucket || !path27) return inputUrl;
32723
- url.pathname = `/storage/v1/render/image/public/${bucket}/${path27}`;
32745
+ const path28 = parts.slice(1).join("/");
32746
+ if (!bucket || !path28) return inputUrl;
32747
+ url.pathname = `/storage/v1/render/image/public/${bucket}/${path28}`;
32724
32748
  url.search = "";
32725
32749
  if (width) url.searchParams.set("width", String(width));
32726
32750
  if (height) url.searchParams.set("height", String(height));
@@ -35279,6 +35303,7 @@ init_styledSection();
35279
35303
  init_fragments();
35280
35304
  init_api_bindings();
35281
35305
  init_shared2();
35306
+ init_shop_shared();
35282
35307
  init_defineBlock();
35283
35308
  init_event_registration_shared();
35284
35309
  init_event_registration_interactive();
@@ -35433,6 +35458,8 @@ var eventRegistrationManifest = createBlockManifest({
35433
35458
  },
35434
35459
  // Event data from loader
35435
35460
  events: { $bind: { from: "data.events" } },
35461
+ sitePasses: { $bind: { from: "data.sitePasses" } },
35462
+ siteMemberships: { $bind: { from: "data.siteMemberships" } },
35436
35463
  // Stage for preview mode (allows registering for draft events)
35437
35464
  stage: {
35438
35465
  $bind: { from: "$root.previewStage", fallback: "published" }
@@ -35451,7 +35478,9 @@ var eventRegistrationBlockDefinition = {
35451
35478
  manifest: eventRegistrationManifest,
35452
35479
  runtime: eventRegistrationBlockRuntime,
35453
35480
  dataSchemas: {
35454
- events: z.array(publicEventSchema).optional(),
35481
+ events: publicEventsArraySchema.optional(),
35482
+ sitePasses: publicPassProductCollectionSchema.optional(),
35483
+ siteMemberships: publicMembershipProductCollectionSchema.optional(),
35455
35484
  occurrenceContext: occurrenceContextSchema.optional()
35456
35485
  },
35457
35486
  dataLoaders: {
@@ -35470,6 +35499,20 @@ var eventRegistrationBlockDefinition = {
35470
35499
  entryId: { $bind: { from: "$root.contentEntry._entryId", fallback: "" } }
35471
35500
  },
35472
35501
  mode: "server"
35502
+ },
35503
+ sitePasses: {
35504
+ endpoint: "listPublicPasses",
35505
+ params: {
35506
+ siteId: { $bind: { from: "$root.siteId" } }
35507
+ },
35508
+ mode: "server"
35509
+ },
35510
+ siteMemberships: {
35511
+ endpoint: "listPublicMemberships",
35512
+ params: {
35513
+ siteId: { $bind: { from: "$root.siteId" } }
35514
+ },
35515
+ mode: "server"
35473
35516
  }
35474
35517
  }
35475
35518
  };
@@ -36294,6 +36337,9 @@ function normalizeEventCalendarContent(content) {
36294
36337
  ...variant ? { variant } : {},
36295
36338
  displayMode: normalizeEventCalendarDisplayMode(record.displayMode),
36296
36339
  listLayout: normalizeEventCalendarListLayout(record.listLayout),
36340
+ defaultCalendarView: normalizeEventCalendarDefaultView(
36341
+ record.defaultCalendarView
36342
+ ),
36297
36343
  kind,
36298
36344
  eventSurface: normalizeEventSurfaceScope(record.eventSurface),
36299
36345
  filterEventPresets: normalizeEventSurfacePresets(record.filterEventPresets),
@@ -36311,6 +36357,9 @@ function normalizeEventCalendarDisplayMode(value) {
36311
36357
  function normalizeEventCalendarListLayout(value) {
36312
36358
  return isEventCalendarListLayout(value) ? value : void 0;
36313
36359
  }
36360
+ function normalizeEventCalendarDefaultView(value) {
36361
+ return isEventCalendarDefaultView(value) ? value : void 0;
36362
+ }
36314
36363
  var eventCalendarLayout = [
36315
36364
  styledSection({
36316
36365
  children: sectionContainer(
@@ -36370,6 +36419,9 @@ var eventCalendarLayout = [
36370
36419
  calendarTabViews: {
36371
36420
  $bind: { from: "content.calendarTabViews", fallback: "both" }
36372
36421
  },
36422
+ defaultCalendarView: {
36423
+ $bind: { from: "content.defaultCalendarView", fallback: "month" }
36424
+ },
36373
36425
  // Filtering options
36374
36426
  showFilters: {
36375
36427
  $bind: { from: "content.showFilters", fallback: true }
@@ -36436,8 +36488,7 @@ var eventCalendarAdditionalFields = [
36436
36488
  defaultValue: "combined",
36437
36489
  options: [
36438
36490
  { value: "combined", label: "Combined (List + Calendar tabs)" },
36439
- { value: "month", label: "Month calendar" },
36440
- { value: "week", label: "Week agenda" },
36491
+ { value: "calendar", label: "Calendar" },
36441
36492
  { value: "timetable", label: "Timetable" },
36442
36493
  { value: "list", label: "List" }
36443
36494
  ],
@@ -36476,7 +36527,12 @@ var eventCalendarAdditionalFields = [
36476
36527
  ],
36477
36528
  ui: {
36478
36529
  intent: "display",
36479
- visibleWhen: { field: "listLayout", equals: "grid" }
36530
+ visibleWhen: {
36531
+ allOf: [
36532
+ { field: "variant", oneOf: ["combined", "list"] },
36533
+ { field: "listLayout", equals: "grid" }
36534
+ ]
36535
+ }
36480
36536
  }
36481
36537
  },
36482
36538
  {
@@ -36524,7 +36580,12 @@ var eventCalendarAdditionalFields = [
36524
36580
  required: false,
36525
36581
  ui: {
36526
36582
  intent: "display",
36527
- visibleWhen: { field: "paginationMode", equals: "seeAllLink" }
36583
+ visibleWhen: {
36584
+ allOf: [
36585
+ { field: "variant", oneOf: ["combined", "list"] },
36586
+ { field: "paginationMode", equals: "seeAllLink" }
36587
+ ]
36588
+ }
36528
36589
  }
36529
36590
  },
36530
36591
  {
@@ -36557,7 +36618,7 @@ var eventCalendarAdditionalFields = [
36557
36618
  intent: "display",
36558
36619
  visibleWhen: {
36559
36620
  field: "variant",
36560
- oneOf: ["combined", "month", "week"]
36621
+ oneOf: ["combined", "calendar", "timetable"]
36561
36622
  }
36562
36623
  }
36563
36624
  },
@@ -36580,6 +36641,33 @@ var eventCalendarAdditionalFields = [
36580
36641
  visibleWhen: { field: "variant", equals: "combined" }
36581
36642
  }
36582
36643
  },
36644
+ {
36645
+ id: "defaultCalendarView",
36646
+ type: "select",
36647
+ label: "Calendar view",
36648
+ description: "Choose the standalone calendar view, or the first view in combined mode",
36649
+ required: false,
36650
+ multiple: false,
36651
+ defaultValue: "month",
36652
+ options: [
36653
+ { value: "month", label: "Month" },
36654
+ { value: "week", label: "Week" }
36655
+ ],
36656
+ ui: {
36657
+ intent: "display",
36658
+ visibleWhen: {
36659
+ anyOf: [
36660
+ { field: "variant", equals: "calendar" },
36661
+ {
36662
+ allOf: [
36663
+ { field: "variant", equals: "combined" },
36664
+ { field: "calendarTabViews", equals: "both" }
36665
+ ]
36666
+ }
36667
+ ]
36668
+ }
36669
+ }
36670
+ },
36583
36671
  // Filtering options
36584
36672
  {
36585
36673
  id: "kind",
@@ -36607,7 +36695,7 @@ var eventCalendarAdditionalFields = [
36607
36695
  intent: "display",
36608
36696
  visibleWhen: {
36609
36697
  field: "variant",
36610
- oneOf: ["combined", "list", "timetable"]
36698
+ oneOf: ["combined", "calendar", "list", "timetable"]
36611
36699
  }
36612
36700
  }
36613
36701
  },
@@ -36627,8 +36715,10 @@ var eventCalendarAdditionalFields = [
36627
36715
  ui: {
36628
36716
  intent: "display",
36629
36717
  visibleWhen: {
36630
- field: "variant",
36631
- oneOf: ["combined", "list", "timetable"]
36718
+ allOf: [
36719
+ { field: "variant", oneOf: ["combined", "calendar", "list", "timetable"] },
36720
+ { field: "showFilters", equals: true }
36721
+ ]
36632
36722
  }
36633
36723
  }
36634
36724
  },
@@ -36642,8 +36732,10 @@ var eventCalendarAdditionalFields = [
36642
36732
  ui: {
36643
36733
  intent: "display",
36644
36734
  visibleWhen: {
36645
- field: "variant",
36646
- oneOf: ["combined", "list", "timetable"]
36735
+ allOf: [
36736
+ { field: "variant", oneOf: ["combined", "calendar", "list", "timetable"] },
36737
+ { field: "showFilters", equals: true }
36738
+ ]
36647
36739
  }
36648
36740
  }
36649
36741
  },
@@ -36657,8 +36749,10 @@ var eventCalendarAdditionalFields = [
36657
36749
  ui: {
36658
36750
  intent: "display",
36659
36751
  visibleWhen: {
36660
- field: "variant",
36661
- oneOf: ["combined", "list", "timetable"]
36752
+ allOf: [
36753
+ { field: "variant", oneOf: ["combined", "calendar", "list", "timetable"] },
36754
+ { field: "showFilters", equals: true }
36755
+ ]
36662
36756
  }
36663
36757
  }
36664
36758
  },
@@ -36672,8 +36766,15 @@ var eventCalendarAdditionalFields = [
36672
36766
  ui: {
36673
36767
  intent: "display",
36674
36768
  visibleWhen: {
36675
- field: "variant",
36676
- oneOf: ["combined", "list", "week", "timetable"]
36769
+ anyOf: [
36770
+ { field: "variant", oneOf: ["combined", "list", "timetable"] },
36771
+ {
36772
+ allOf: [
36773
+ { field: "variant", equals: "calendar" },
36774
+ { field: "defaultCalendarView", equals: "week" }
36775
+ ]
36776
+ }
36777
+ ]
36677
36778
  }
36678
36779
  }
36679
36780
  },
@@ -36789,8 +36890,7 @@ var eventCalendarAdditionalFields = [
36789
36890
  ];
36790
36891
  var eventCalendarVariants = {
36791
36892
  combined: eventCalendarLayout[0],
36792
- month: eventCalendarLayout[0],
36793
- week: eventCalendarLayout[0],
36893
+ calendar: eventCalendarLayout[0],
36794
36894
  timetable: eventCalendarLayout[0],
36795
36895
  list: eventCalendarLayout[0]
36796
36896
  };
@@ -36802,8 +36902,7 @@ var eventCalendarVariants = {
36802
36902
  multiple: false,
36803
36903
  options: [
36804
36904
  { value: "combined" },
36805
- { value: "month" },
36806
- { value: "week" },
36905
+ { value: "calendar" },
36807
36906
  { value: "timetable" },
36808
36907
  { value: "list" }
36809
36908
  ]
@@ -36816,6 +36915,13 @@ var eventCalendarVariants = {
36816
36915
  options: eventCalendarListLayoutOptions.map((option) => ({
36817
36916
  value: option.id
36818
36917
  }))
36918
+ },
36919
+ {
36920
+ id: "defaultCalendarView",
36921
+ type: "select",
36922
+ required: false,
36923
+ multiple: false,
36924
+ options: [{ value: "month" }, { value: "week" }]
36819
36925
  }
36820
36926
  ];
36821
36927
  var eventCalendarConfig = {
@@ -36859,8 +36965,7 @@ var eventCalendarConfig = {
36859
36965
  defaultVariant: "combined",
36860
36966
  variantOptions: {
36861
36967
  combined: { label: "Combined" },
36862
- month: { label: "Month" },
36863
- week: { label: "Week" },
36968
+ calendar: { label: "Calendar" },
36864
36969
  timetable: { label: "Timetable" },
36865
36970
  list: { label: "List" }
36866
36971
  }
@@ -39059,9 +39164,9 @@ var shopBlockDefinition = {
39059
39164
  runtime: shopBlockRuntime,
39060
39165
  dataSchemas: {
39061
39166
  // listPublicPasses returns { passes: [...] }
39062
- passes: z.object({ passes: z.array(publicPassProductSchema) }).optional(),
39167
+ passes: publicPassProductCollectionSchema.optional(),
39063
39168
  // listPublicMemberships returns { memberships: [...] }
39064
- memberships: z.object({ memberships: z.array(publicMembershipProductSchema) }).optional()
39169
+ memberships: publicMembershipProductCollectionSchema.optional()
39065
39170
  },
39066
39171
  dataLoaders: {
39067
39172
  // Load passes for display
@@ -40511,13 +40616,6 @@ var systemBlockDefinitionsRaw = [
40511
40616
  weight: "featured",
40512
40617
  bias: "clear",
40513
40618
  surfaces: heroSectionSurfaces
40514
- }),
40515
- layoutProfile({
40516
- variantKey: "splitEditorial",
40517
- family: "split",
40518
- weight: "featured",
40519
- bias: "clear",
40520
- surfaces: heroSectionSurfaces
40521
40619
  })
40522
40620
  ]
40523
40621
  })),
@@ -40761,9 +40859,8 @@ var systemBlockDefinitionsRaw = [
40761
40859
  flow: offeringsFlow,
40762
40860
  layoutProfiles: [
40763
40861
  layoutProfile({ variantKey: "combined", family: "grid", weight: "standard" }),
40862
+ layoutProfile({ variantKey: "calendar", family: "stack", weight: "standard" }),
40764
40863
  layoutProfile({ variantKey: "list", family: "stack", weight: "standard" }),
40765
- layoutProfile({ variantKey: "month", family: "grid", weight: "standard" }),
40766
- layoutProfile({ variantKey: "week", family: "stack", weight: "standard" }),
40767
40864
  layoutProfile({ variantKey: "timetable", family: "stack", weight: "standard" })
40768
40865
  ]
40769
40866
  })),
@@ -41345,10 +41442,7 @@ function normalizeRenderStage(stage) {
41345
41442
  return stage === "preview" ? "preview" : "published";
41346
41443
  }
41347
41444
  function isRouteVisibleInStage(routeEntry, stageInput) {
41348
- const stage = normalizeRenderStage(stageInput);
41349
- if (stage === "preview" || !isRouteRecord(routeEntry)) {
41350
- return true;
41351
- }
41445
+ if (normalizeRenderStage(stageInput) === "preview" || !isRouteRecord(routeEntry)) return true;
41352
41446
  const status = routeEntry.status;
41353
41447
  return !(typeof status === "string" && status !== "published");
41354
41448
  }
@@ -41357,52 +41451,45 @@ function extractRouteHref(candidate, stageInput = "published") {
41357
41451
  const trimmed = candidate.trim();
41358
41452
  return trimmed.length > 0 ? trimmed : null;
41359
41453
  }
41360
- if (!isRouteRecord(candidate)) {
41361
- return null;
41362
- }
41363
- const stage = normalizeRenderStage(stageInput);
41364
- const fields3 = stage === "preview" ? ["draftPath", "path", "href", "url"] : ["path", "href", "url"];
41454
+ if (!isRouteRecord(candidate)) return null;
41455
+ const fields3 = normalizeRenderStage(stageInput) === "preview" ? [
41456
+ "draftPath",
41457
+ "path",
41458
+ "href",
41459
+ "url"
41460
+ ] : [
41461
+ "path",
41462
+ "href",
41463
+ "url"
41464
+ ];
41365
41465
  for (const field of fields3) {
41366
41466
  const value = candidate[field];
41367
- if (typeof value === "string" && value.trim().length > 0) {
41368
- return value.trim();
41369
- }
41467
+ if (typeof value === "string" && value.trim().length > 0) return value.trim();
41370
41468
  }
41371
41469
  return null;
41372
41470
  }
41373
41471
  function extractRouteUpdatedAt(candidate) {
41374
- if (!isRouteRecord(candidate)) {
41375
- return null;
41376
- }
41377
- const fields3 = [
41472
+ if (!isRouteRecord(candidate)) return null;
41473
+ for (const field of [
41378
41474
  "updatedAt",
41379
41475
  "updated_at",
41380
41476
  "publishedAt",
41381
41477
  "published_at",
41382
41478
  "modifiedAt",
41383
41479
  "modified_at"
41384
- ];
41385
- for (const field of fields3) {
41480
+ ]) {
41386
41481
  const value = candidate[field];
41387
- if (typeof value === "string" && value.length > 0) {
41388
- return value;
41389
- }
41482
+ if (typeof value === "string" && value.length > 0) return value;
41390
41483
  }
41391
41484
  return null;
41392
41485
  }
41393
41486
  function resolveRouteTargetForStage(routeIdValue, routes, stageInput) {
41394
41487
  const routeId = typeof routeIdValue === "string" ? routeIdValue : null;
41395
- if (!routeId || !routes) {
41396
- return null;
41397
- }
41488
+ if (!routeId || !routes) return null;
41398
41489
  const routeEntry = routes[routeId];
41399
- if (!isRouteVisibleInStage(routeEntry, stageInput)) {
41400
- return null;
41401
- }
41490
+ if (!isRouteVisibleInStage(routeEntry, stageInput)) return null;
41402
41491
  const href = extractRouteHref(routeEntry, stageInput);
41403
- if (!href) {
41404
- return null;
41405
- }
41492
+ if (!href) return null;
41406
41493
  return {
41407
41494
  routeId,
41408
41495
  href,
@@ -42557,19 +42644,23 @@ function normalizeDashboardOrigin(input) {
42557
42644
  }
42558
42645
  function deriveCmsApiUrlFromDashboardUrl(input) {
42559
42646
  const origin = normalizeDashboardOrigin(input);
42560
- return origin ? `${origin}/api` : "";
42647
+ return origin ? normalizeCmsApiBaseUrl(`${origin}/api`) : "";
42648
+ }
42649
+ function normalizeCmsApiBaseUrl(input) {
42650
+ return input.trim().replace(/\/+$/, "").replace(/(?:\/api)+$/i, "/api");
42561
42651
  }
42562
42652
  function getCmsApiUrl() {
42563
42653
  if (typeof window !== "undefined") {
42564
- return "/api";
42654
+ return normalizeCmsApiBaseUrl("/api");
42565
42655
  }
42566
42656
  const internalUrl = process.env.CMS_API_URL;
42567
42657
  if (internalUrl) {
42568
- return internalUrl.replace(/\/$/, "");
42658
+ return normalizeCmsApiBaseUrl(internalUrl);
42569
42659
  }
42570
42660
  const dashboardUrl = process.env.NEXT_PUBLIC_DASHBOARD_URL;
42571
42661
  if (dashboardUrl) {
42572
- return deriveCmsApiUrlFromDashboardUrl(dashboardUrl);
42662
+ const apiUrl = deriveCmsApiUrlFromDashboardUrl(dashboardUrl);
42663
+ if (apiUrl) return apiUrl;
42573
42664
  }
42574
42665
  throw new Error(
42575
42666
  "CMS_API_URL or NEXT_PUBLIC_DASHBOARD_URL is not configured. Set NEXT_PUBLIC_DASHBOARD_URL to your dashboard URL (e.g., http://localhost:4000)"
@@ -42703,6 +42794,27 @@ function serializeQueryValue(value) {
42703
42794
  if (value instanceof Date) return value.toISOString();
42704
42795
  return null;
42705
42796
  }
42797
+ function normalizeHeaders(source) {
42798
+ const normalized = {};
42799
+ if (!source) return normalized;
42800
+ new Headers(source).forEach((value, key) => {
42801
+ normalized[key] = value;
42802
+ });
42803
+ return normalized;
42804
+ }
42805
+ function buildRequestHeaders(input) {
42806
+ const headers = {
42807
+ ...normalizeHeaders(input.optionsHeaders),
42808
+ ...normalizeHeaders(input.authHeaders)
42809
+ };
42810
+ if (input.sdkVersion) {
42811
+ headers["x-sdk-version"] = input.sdkVersion;
42812
+ }
42813
+ if (input.includeJsonContentType) {
42814
+ headers["Content-Type"] = "application/json";
42815
+ }
42816
+ return headers;
42817
+ }
42706
42818
  function serializePathParam(endpoint, key, value) {
42707
42819
  if (typeof value === "string") {
42708
42820
  return value;
@@ -42838,104 +42950,20 @@ function createRawCMSClient(headers = {}, baseUrl) {
42838
42950
  params,
42839
42951
  options = {}
42840
42952
  }) => {
42841
- const resolvedBaseUrl = baseUrl ?? resolveApiBaseUrl();
42842
- let url = buildEndpointURL(resolvedBaseUrl, endpoint);
42843
- const originalPath = API_ENDPOINTS[endpoint].path;
42844
- const unusedParams = {};
42845
- if (params) {
42846
- Object.entries(params).forEach(([key, value]) => {
42847
- const bracePlaceholder = `{${key}}`;
42848
- const colonPlaceholder = `:${key}`;
42849
- if (originalPath.includes(bracePlaceholder) || originalPath.includes(colonPlaceholder)) {
42850
- const stringValue2 = serializePathParam(endpoint, key, value);
42851
- url = url.replace(bracePlaceholder, stringValue2);
42852
- url = url.replace(colonPlaceholder, stringValue2);
42853
- } else {
42854
- unusedParams[key] = value;
42855
- }
42856
- });
42857
- }
42858
- const unresolvedPathParams = [
42859
- ...url.match(/\{[^}]+\}/g) ?? [],
42860
- ...url.match(/(^|\/):([A-Za-z][A-Za-z0-9_]*)\b/g) ?? []
42861
- ];
42862
- if (unresolvedPathParams.length > 0) {
42863
- const missingParams = Array.from(
42864
- new Set(
42865
- unresolvedPathParams.map((token) => {
42866
- if (token.startsWith("{") && token.endsWith("}")) {
42867
- return token.slice(1, -1);
42868
- }
42869
- return token.replace(/^\//, "").slice(1);
42870
- })
42871
- )
42872
- );
42873
- throw new Error(
42874
- `Missing required path params for endpoint ${String(endpoint)}: ${missingParams.join(", ")}`
42875
- );
42876
- }
42877
- const endpointConfig = API_ENDPOINTS[endpoint];
42878
- const method = endpointConfig.method;
42879
- const isGetOrHead = method === "GET" || method === "HEAD";
42880
- const queryParams = new URLSearchParams();
42881
- Object.entries(unusedParams).forEach(([key, value]) => {
42882
- appendQueryParam(queryParams, key, value);
42953
+ const plan = buildApiRequestPlan({
42954
+ endpoint,
42955
+ body,
42956
+ params,
42957
+ options,
42958
+ headers,
42959
+ baseUrl: normalizeCmsApiBaseUrl(baseUrl ?? resolveApiBaseUrl()),
42960
+ sdkVersion
42883
42961
  });
42884
- if (isGetOrHead && typeof body === "object" && body !== null && !isFormDataBody(body)) {
42885
- Object.entries(body).forEach(([key, value]) => {
42886
- appendQueryParam(queryParams, key, value);
42887
- });
42888
- }
42889
- const queryString = queryParams.toString();
42890
- if (queryString) {
42891
- url += (url.includes("?") ? "&" : "?") + queryString;
42892
- }
42893
- const formDataBody = isFormDataBody(body) ? body : void 0;
42894
- const optionsNext = options?.next;
42895
- const nextOptions = { ...optionsNext ?? {} };
42896
- const cacheIsNoStore = options?.cache === "no-store";
42897
- if (cacheIsNoStore) {
42898
- delete nextOptions.revalidate;
42899
- } else if (isGetOrHead && nextOptions.revalidate === void 0 && "revalidate" in endpointConfig && typeof endpointConfig.revalidate === "number") {
42900
- nextOptions.revalidate = endpointConfig.revalidate;
42901
- }
42902
- if ("tags" in endpointConfig && Array.isArray(endpointConfig.tags)) {
42903
- const processedTags = endpointConfig.tags.map((tag) => {
42904
- let processedTag = tag;
42905
- if (params) {
42906
- Object.entries(params).forEach(([key, value]) => {
42907
- processedTag = processedTag.replace(`{${key}}`, String(value));
42908
- });
42909
- }
42910
- return /\{[^}]+\}/.test(processedTag) ? null : processedTag;
42911
- }).filter((tag) => tag !== null);
42912
- nextOptions.tags = Array.from(/* @__PURE__ */ new Set([...nextOptions.tags ?? [], ...processedTags]));
42913
- }
42914
- const requestInit = {
42915
- method,
42916
- ...options,
42917
- // Include credentials for same-origin requests (sends cookies for auth)
42918
- credentials: "same-origin",
42919
- // Don't include body for GET/HEAD requests
42920
- // FormData is pre-narrowed via isFormDataBody() above
42921
- body: isGetOrHead || body == null ? void 0 : formDataBody ?? JSON.stringify(body),
42922
- headers: {
42923
- ...options.headers,
42924
- ...headers,
42925
- // Include SDK version if set
42926
- ...sdkVersion && { "x-sdk-version": sdkVersion },
42927
- // Don't set Content-Type for GET/HEAD requests without body
42928
- ...isGetOrHead ? {} : formDataBody ? {} : { "Content-Type": "application/json" }
42929
- },
42930
- // Add Next.js caching options
42931
- next: Object.keys(nextOptions).length > 0 ? nextOptions : void 0
42932
- };
42933
- const fetchPromise = fetch(url, requestInit);
42934
- if (!isGetOrHead && "tags" in endpointConfig && Array.isArray(endpointConfig.tags)) {
42935
- const tags2 = endpointConfig.tags.map((tag) => tag);
42962
+ const fetchPromise = fetch(plan.url, plan.init);
42963
+ if (plan.cacheInvalidationTags) {
42936
42964
  return fetchPromise.then((response) => {
42937
42965
  if (response.ok) {
42938
- invalidateCacheTags(tags2, params);
42966
+ invalidateCacheTags(plan.cacheInvalidationTags, params);
42939
42967
  }
42940
42968
  return response;
42941
42969
  });
@@ -42943,6 +42971,100 @@ function createRawCMSClient(headers = {}, baseUrl) {
42943
42971
  return fetchPromise;
42944
42972
  };
42945
42973
  }
42974
+ function buildApiRequestPlan(input) {
42975
+ const { endpoint, body, params, headers = {}, baseUrl } = input;
42976
+ const options = input.options ?? {};
42977
+ let url = buildEndpointURL(baseUrl, endpoint);
42978
+ const originalPath = API_ENDPOINTS[endpoint].path;
42979
+ const unusedParams = {};
42980
+ if (params) {
42981
+ Object.entries(params).forEach(([key, value]) => {
42982
+ const bracePlaceholder = `{${key}}`;
42983
+ const colonPlaceholder = `:${key}`;
42984
+ if (originalPath.includes(bracePlaceholder) || originalPath.includes(colonPlaceholder)) {
42985
+ const stringValue2 = serializePathParam(endpoint, key, value);
42986
+ url = url.replace(bracePlaceholder, stringValue2);
42987
+ url = url.replace(colonPlaceholder, stringValue2);
42988
+ } else {
42989
+ unusedParams[key] = value;
42990
+ }
42991
+ });
42992
+ }
42993
+ const unresolvedPathParams = [
42994
+ ...url.match(/\{[^}]+\}/g) ?? [],
42995
+ ...url.match(/(^|\/):([A-Za-z][A-Za-z0-9_]*)\b/g) ?? []
42996
+ ];
42997
+ if (unresolvedPathParams.length > 0) {
42998
+ const missingParams = Array.from(
42999
+ new Set(
43000
+ unresolvedPathParams.map((token) => {
43001
+ if (token.startsWith("{") && token.endsWith("}")) {
43002
+ return token.slice(1, -1);
43003
+ }
43004
+ return token.replace(/^\//, "").slice(1);
43005
+ })
43006
+ )
43007
+ );
43008
+ throw new Error(
43009
+ `Missing required path params for endpoint ${String(endpoint)}: ${missingParams.join(", ")}`
43010
+ );
43011
+ }
43012
+ const endpointConfig = API_ENDPOINTS[endpoint];
43013
+ const method = endpointConfig.method;
43014
+ const isGetOrHead = method === "GET" || method === "HEAD";
43015
+ const queryParams = new URLSearchParams();
43016
+ Object.entries(unusedParams).forEach(([key, value]) => {
43017
+ appendQueryParam(queryParams, key, value);
43018
+ });
43019
+ if (isGetOrHead && typeof body === "object" && body !== null && !isFormDataBody(body)) {
43020
+ Object.entries(body).forEach(([key, value]) => {
43021
+ appendQueryParam(queryParams, key, value);
43022
+ });
43023
+ }
43024
+ const queryString = queryParams.toString();
43025
+ if (queryString) {
43026
+ url += (url.includes("?") ? "&" : "?") + queryString;
43027
+ }
43028
+ const formDataBody = isFormDataBody(body) ? body : void 0;
43029
+ const optionsNext = options?.next;
43030
+ const nextOptions = { ...optionsNext ?? {} };
43031
+ const cacheIsNoStore = options?.cache === "no-store";
43032
+ if (cacheIsNoStore) {
43033
+ delete nextOptions.revalidate;
43034
+ } else if (isGetOrHead && nextOptions.revalidate === void 0 && "revalidate" in endpointConfig && typeof endpointConfig.revalidate === "number") {
43035
+ nextOptions.revalidate = endpointConfig.revalidate;
43036
+ }
43037
+ if ("tags" in endpointConfig && Array.isArray(endpointConfig.tags)) {
43038
+ const processedTags = endpointConfig.tags.map((tag) => {
43039
+ let processedTag = tag;
43040
+ if (params) {
43041
+ Object.entries(params).forEach(([key, value]) => {
43042
+ processedTag = processedTag.replace(`{${key}}`, String(value));
43043
+ });
43044
+ }
43045
+ return /\{[^}]+\}/.test(processedTag) ? null : processedTag;
43046
+ }).filter((tag) => tag !== null);
43047
+ nextOptions.tags = Array.from(/* @__PURE__ */ new Set([...nextOptions.tags ?? [], ...processedTags]));
43048
+ }
43049
+ const init = {
43050
+ method,
43051
+ ...options,
43052
+ credentials: "same-origin",
43053
+ body: isGetOrHead || body == null ? void 0 : formDataBody ?? JSON.stringify(body),
43054
+ headers: buildRequestHeaders({
43055
+ optionsHeaders: options.headers,
43056
+ authHeaders: headers,
43057
+ sdkVersion: input.sdkVersion,
43058
+ includeJsonContentType: !isGetOrHead && !formDataBody
43059
+ }),
43060
+ ...Object.keys(nextOptions).length > 0 ? { next: nextOptions } : {}
43061
+ };
43062
+ return {
43063
+ url,
43064
+ init,
43065
+ ...!isGetOrHead && "tags" in endpointConfig && Array.isArray(endpointConfig.tags) ? { cacheInvalidationTags: endpointConfig.tags.map((tag) => tag) } : {}
43066
+ };
43067
+ }
42946
43068
  function createParsedClient(rawClient) {
42947
43069
  return async (params) => {
42948
43070
  const response = await rawClient(params);
@@ -43884,8 +44006,8 @@ var TEMPLATE_BINDING_META_PATHS = [
43884
44006
  "createdAt",
43885
44007
  "updatedAt"
43886
44008
  ];
43887
- function describeInvalidTemplateBindingMetaPath(path27) {
43888
- return `Meta path "${path27}" is not valid. Allowed: ${TEMPLATE_BINDING_META_PATHS.join(", ")}`;
44009
+ function describeInvalidTemplateBindingMetaPath(path28) {
44010
+ return `Meta path "${path28}" is not valid. Allowed: ${TEMPLATE_BINDING_META_PATHS.join(", ")}`;
43889
44011
  }
43890
44012
 
43891
44013
  // ../content-model/src/routeTemplate.ts
@@ -43964,6 +44086,25 @@ function splitRouteSegments(routePattern) {
43964
44086
  function isUnsupportedDynamicSegment(segment) {
43965
44087
  return segment.startsWith(":") || segment.includes("{") || segment.includes("}");
43966
44088
  }
44089
+ var defaultContentSchema = z.record(
44090
+ z.string(),
44091
+ z.unknown()
44092
+ );
44093
+ function createSdkEntrySlotBlockInputSchema(contentSchema = defaultContentSchema) {
44094
+ return z.object({
44095
+ identifier: z.string().nullable().optional(),
44096
+ kind: z.string().min(1, "Block kind is required"),
44097
+ content: contentSchema
44098
+ });
44099
+ }
44100
+ function createSdkEntrySlotBlocksInputSchema(contentSchema) {
44101
+ return z.record(
44102
+ z.string(),
44103
+ z.array(createSdkEntrySlotBlockInputSchema(contentSchema))
44104
+ );
44105
+ }
44106
+ createSdkEntrySlotBlockInputSchema();
44107
+ var sdkEntrySlotBlocksInputSchema = createSdkEntrySlotBlocksInputSchema();
43967
44108
 
43968
44109
  // src/contracts/bindings.ts
43969
44110
  var BINDING_TRANSFORMS = {
@@ -44274,7 +44415,7 @@ var contentConfigSchema = contentConfigBaseSchema.superRefine((data, ctx) => {
44274
44415
  });
44275
44416
  }
44276
44417
  const paths = data.pages.map((p) => p.path);
44277
- const duplicatePaths = paths.filter((path27, i) => paths.indexOf(path27) !== i);
44418
+ const duplicatePaths = paths.filter((path28, i) => paths.indexOf(path28) !== i);
44278
44419
  if (duplicatePaths.length > 0) {
44279
44420
  ctx.addIssue({
44280
44421
  code: z.ZodIssueCode.custom,
@@ -44331,18 +44472,18 @@ function validateLayoutNodeTypes(layout) {
44331
44472
  errors
44332
44473
  };
44333
44474
  }
44334
- function validateNodeTypesRecursive(node, path27, errors) {
44475
+ function validateNodeTypesRecursive(node, path28, errors) {
44335
44476
  if (!ALLOWED_NODE_TYPES_SET.has(node.type)) {
44336
44477
  errors.push({
44337
- path: `${path27}.type`,
44478
+ path: `${path28}.type`,
44338
44479
  type: "invalid_node_type",
44339
44480
  value: node.type,
44340
- message: `Unknown node type "${node.type}" at ${path27}. Valid types: section, stack, text, etc.`
44481
+ message: `Unknown node type "${node.type}" at ${path28}. Valid types: section, stack, text, etc.`
44341
44482
  });
44342
44483
  }
44343
44484
  if (node.children && Array.isArray(node.children)) {
44344
44485
  node.children.forEach((child, index) => {
44345
- validateNodeTypesRecursive(child, `${path27}.children[${index}]`, errors);
44486
+ validateNodeTypesRecursive(child, `${path28}.children[${index}]`, errors);
44346
44487
  });
44347
44488
  }
44348
44489
  }
@@ -44354,45 +44495,45 @@ function validateTransformIds(layout) {
44354
44495
  errors
44355
44496
  };
44356
44497
  }
44357
- function validateTransformIdsRecursive(node, path27, errors) {
44498
+ function validateTransformIdsRecursive(node, path28, errors) {
44358
44499
  if (node.$bind?.transforms && Array.isArray(node.$bind.transforms)) {
44359
- validateTransformList(node.$bind.transforms, `${path27}.$bind.transforms`, errors);
44500
+ validateTransformList(node.$bind.transforms, `${path28}.$bind.transforms`, errors);
44360
44501
  }
44361
44502
  if (node.$repeat?.collection?.transforms && Array.isArray(node.$repeat.collection.transforms)) {
44362
- validateTransformList(node.$repeat.collection.transforms, `${path27}.$repeat.collection.transforms`, errors);
44503
+ validateTransformList(node.$repeat.collection.transforms, `${path28}.$repeat.collection.transforms`, errors);
44363
44504
  }
44364
44505
  if (node.$when?.when?.transforms && Array.isArray(node.$when.when.transforms)) {
44365
- validateTransformList(node.$when.when.transforms, `${path27}.$when.when.transforms`, errors);
44506
+ validateTransformList(node.$when.when.transforms, `${path28}.$when.when.transforms`, errors);
44366
44507
  }
44367
44508
  if (node.$scopes && Array.isArray(node.$scopes)) {
44368
44509
  node.$scopes.forEach((scope, index) => {
44369
44510
  if (scope.from?.transforms && Array.isArray(scope.from.transforms)) {
44370
- validateTransformList(scope.from.transforms, `${path27}.$scopes[${index}].from.transforms`, errors);
44511
+ validateTransformList(scope.from.transforms, `${path28}.$scopes[${index}].from.transforms`, errors);
44371
44512
  }
44372
44513
  });
44373
44514
  }
44374
44515
  if (node.props) {
44375
- validatePropsTransforms(node.props, `${path27}.props`, errors);
44516
+ validatePropsTransforms(node.props, `${path28}.props`, errors);
44376
44517
  }
44377
44518
  if (node.children && Array.isArray(node.children)) {
44378
44519
  node.children.forEach((child, index) => {
44379
- validateTransformIdsRecursive(child, `${path27}.children[${index}]`, errors);
44520
+ validateTransformIdsRecursive(child, `${path28}.children[${index}]`, errors);
44380
44521
  });
44381
44522
  }
44382
44523
  }
44383
- function validateTransformList(transforms, path27, errors) {
44524
+ function validateTransformList(transforms, path28, errors) {
44384
44525
  transforms.forEach((transform, index) => {
44385
44526
  if (!ALLOWED_TRANSFORM_IDS_SET.has(transform.id)) {
44386
44527
  errors.push({
44387
- path: `${path27}[${index}].id`,
44528
+ path: `${path28}[${index}].id`,
44388
44529
  type: "invalid_transform_id",
44389
44530
  value: transform.id,
44390
- message: `Unknown transform "${transform.id}" at ${path27}. Valid transforms: string.uppercase, value.fallback, etc.`
44531
+ message: `Unknown transform "${transform.id}" at ${path28}. Valid transforms: string.uppercase, value.fallback, etc.`
44391
44532
  });
44392
44533
  }
44393
44534
  });
44394
44535
  }
44395
- function validatePropsTransforms(props2, path27, errors) {
44536
+ function validatePropsTransforms(props2, path28, errors) {
44396
44537
  for (const [key, value] of Object.entries(props2)) {
44397
44538
  if (isBindingObject(value)) {
44398
44539
  const binding = value;
@@ -44400,16 +44541,16 @@ function validatePropsTransforms(props2, path27, errors) {
44400
44541
  binding.$bind.transforms.forEach((transform, index) => {
44401
44542
  if (!ALLOWED_TRANSFORM_IDS_SET.has(transform.id)) {
44402
44543
  errors.push({
44403
- path: `${path27}.${key}.$bind.transforms[${index}].id`,
44544
+ path: `${path28}.${key}.$bind.transforms[${index}].id`,
44404
44545
  type: "invalid_transform_id",
44405
44546
  value: transform.id,
44406
- message: `Unknown transform "${transform.id}" at ${path27}.${key}. Valid transforms: string.uppercase, value.fallback, etc.`
44547
+ message: `Unknown transform "${transform.id}" at ${path28}.${key}. Valid transforms: string.uppercase, value.fallback, etc.`
44407
44548
  });
44408
44549
  }
44409
44550
  });
44410
44551
  }
44411
44552
  } else if (value && typeof value === "object" && !Array.isArray(value)) {
44412
- validatePropsTransforms(value, `${path27}.${key}`, errors);
44553
+ validatePropsTransforms(value, `${path28}.${key}`, errors);
44413
44554
  }
44414
44555
  }
44415
44556
  }
@@ -44939,8 +45080,8 @@ async function readApiResponse(response, requestInfo, options = {}) {
44939
45080
  function createHttpClient(config2) {
44940
45081
  const baseUrl = `${config2.dashboardUrl}/api/sdk/${config2.siteId}`;
44941
45082
  const timeout = config2.timeout ?? 3e4;
44942
- async function request(method, path27, options) {
44943
- let url = `${baseUrl}${path27}`;
45083
+ async function request(method, path28, options) {
45084
+ let url = `${baseUrl}${path28}`;
44944
45085
  if (options?.params && Object.keys(options.params).length > 0) {
44945
45086
  const searchParams = new URLSearchParams(options.params);
44946
45087
  url = `${url}?${searchParams.toString()}`;
@@ -44963,7 +45104,7 @@ function createHttpClient(config2) {
44963
45104
  } catch (error) {
44964
45105
  const requestInfo2 = buildRequestInfo({
44965
45106
  method,
44966
- path: path27,
45107
+ path: path28,
44967
45108
  url,
44968
45109
  baseUrl,
44969
45110
  dashboardUrl: config2.dashboardUrl,
@@ -44988,7 +45129,7 @@ function createHttpClient(config2) {
44988
45129
  }
44989
45130
  const requestInfo = buildRequestInfo({
44990
45131
  method,
44991
- path: path27,
45132
+ path: path28,
44992
45133
  url,
44993
45134
  baseUrl,
44994
45135
  dashboardUrl: config2.dashboardUrl,
@@ -45018,17 +45159,17 @@ function createHttpClient(config2) {
45018
45159
  return json.data;
45019
45160
  }
45020
45161
  return {
45021
- async get(path27, params) {
45022
- return request("GET", path27, { params });
45162
+ async get(path28, params) {
45163
+ return request("GET", path28, { params });
45023
45164
  },
45024
- async post(path27, body) {
45025
- return request("POST", path27, { body });
45165
+ async post(path28, body) {
45166
+ return request("POST", path28, { body });
45026
45167
  },
45027
- async patch(path27, body) {
45028
- return request("PATCH", path27, { body });
45168
+ async patch(path28, body) {
45169
+ return request("PATCH", path28, { body });
45029
45170
  },
45030
- async delete(path27, body) {
45031
- await request("DELETE", path27, { body });
45171
+ async delete(path28, body) {
45172
+ await request("DELETE", path28, { body });
45032
45173
  }
45033
45174
  };
45034
45175
  }
@@ -46473,12 +46614,12 @@ function collectPushConfigSyncWarnings(sync) {
46473
46614
  async function pushToDashboard(output, dashboardUrl, siteId, apiKey, config2, options) {
46474
46615
  const normalizedDashboardUrl = dashboardUrl.replace(/\/+$/, "");
46475
46616
  const baseUrl = `${normalizedDashboardUrl}/api`;
46476
- const path27 = `/sites/${siteId}/sdk-config`;
46477
- const pushUrl = `${baseUrl}${path27}`;
46617
+ const path28 = `/sites/${siteId}/sdk-config`;
46618
+ const pushUrl = `${baseUrl}${path28}`;
46478
46619
  output.info(`Pushing config to ${pushUrl}...`);
46479
46620
  const requestInfo = {
46480
46621
  method: "POST",
46481
- path: path27,
46622
+ path: path28,
46482
46623
  url: pushUrl,
46483
46624
  baseUrl,
46484
46625
  dashboardUrl: normalizedDashboardUrl,
@@ -47282,6 +47423,7 @@ function toWritableLocalEvent(event) {
47282
47423
  identifier: event.identifier,
47283
47424
  title: event.title,
47284
47425
  slug: event.slug,
47426
+ path: event.path,
47285
47427
  status: event.status,
47286
47428
  visibility: event.visibility,
47287
47429
  schedule: event.schedule,
@@ -47294,7 +47436,8 @@ function toWritableLocalEvent(event) {
47294
47436
  formRef: event.formRef,
47295
47437
  settings: event.settings,
47296
47438
  presentation: event.presentation,
47297
- tags: event.tags
47439
+ tags: event.tags,
47440
+ blocks: event.blocks
47298
47441
  };
47299
47442
  }
47300
47443
  async function writeCourses(contentDir, pulledCourses, options) {
@@ -47683,13 +47826,16 @@ async function readEventCategories(contentDir) {
47683
47826
  return categories;
47684
47827
  }
47685
47828
  async function readEvents(contentDir) {
47829
+ return (await readEventsWithFilePaths(contentDir)).map(({ filePath: _filePath, ...event }) => event);
47830
+ }
47831
+ async function readEventsWithFilePaths(contentDir) {
47686
47832
  const eventsDir = path5.join(contentDir, "events");
47687
47833
  const events = [];
47688
47834
  const files = await listFiles(eventsDir, ".json");
47689
47835
  for (const filePath of files) {
47690
47836
  try {
47691
47837
  const event = await readJsonFile(filePath);
47692
- events.push(event);
47838
+ events.push({ ...event, filePath });
47693
47839
  } catch (error) {
47694
47840
  console.warn(`Warning: Could not parse ${filePath}:`, error);
47695
47841
  }
@@ -49352,11 +49498,11 @@ function findChangedFields(local, remote, prefix = "") {
49352
49498
  const changes = [];
49353
49499
  const allKeys = /* @__PURE__ */ new Set([...Object.keys(local), ...Object.keys(remote)]);
49354
49500
  for (const key of allKeys) {
49355
- const path27 = prefix ? `${prefix}.${key}` : key;
49501
+ const path28 = prefix ? `${prefix}.${key}` : key;
49356
49502
  const localVal = local[key];
49357
49503
  const remoteVal = remote[key];
49358
49504
  if (!equal(localVal, remoteVal)) {
49359
- changes.push(path27);
49505
+ changes.push(path28);
49360
49506
  }
49361
49507
  }
49362
49508
  return changes;
@@ -50426,11 +50572,11 @@ function findChangedFieldsWithValues(local, remote, prefix = "") {
50426
50572
  const changes = [];
50427
50573
  const allKeys = /* @__PURE__ */ new Set([...Object.keys(local), ...Object.keys(remote)]);
50428
50574
  for (const key of allKeys) {
50429
- const path27 = prefix ? `${prefix}.${key}` : key;
50575
+ const path28 = prefix ? `${prefix}.${key}` : key;
50430
50576
  const localVal = local[key];
50431
50577
  const remoteVal = remote[key];
50432
50578
  if (!equal(localVal, remoteVal)) {
50433
- changes.push({ path: path27, before: remoteVal, after: localVal });
50579
+ changes.push({ path: path28, before: remoteVal, after: localVal });
50434
50580
  }
50435
50581
  }
50436
50582
  return changes;
@@ -50847,6 +50993,19 @@ function maskPullDiffForScope(diff, pullScope) {
50847
50993
  }
50848
50994
  return diff;
50849
50995
  }
50996
+
50997
+ // src/cli/commands/pull-dated-offering-scope.ts
50998
+ function isDatedOfferingPullScope(scope) {
50999
+ return scope === "venues" || scope === "event-categories" || scope === "events" || scope === "courses";
51000
+ }
51001
+ function filterPullItemsByIdentifier(items, identifier, getIdentifier) {
51002
+ return identifier ? items.filter((item) => getIdentifier(item) === identifier) : [...items];
51003
+ }
51004
+ function reportMissingScopedPullItem(input) {
51005
+ if (!input.identifier || input.found) return false;
51006
+ input.output.error(`${input.scope} item not found: ${input.identifier}`);
51007
+ return true;
51008
+ }
50850
51009
  var CANONICAL_EVENT_ENTRY_TYPE = "event";
50851
51010
  var EVENT_MIGRATION_COMMAND = "riverbankcms migrate events";
50852
51011
  var EVENT_PUSH_COMMAND = "riverbankcms push events";
@@ -51145,7 +51304,8 @@ function mapRemoteEventToLocalComparable(e) {
51145
51304
  formRef: e.formRef,
51146
51305
  settings: e.settings,
51147
51306
  presentation: e.presentation,
51148
- tags: e.tags
51307
+ tags: e.tags,
51308
+ blocks: e.blocks
51149
51309
  };
51150
51310
  }
51151
51311
  function mapLocalEventToComparable(e) {
@@ -51164,7 +51324,8 @@ function mapLocalEventToComparable(e) {
51164
51324
  formRef: e.formRef,
51165
51325
  settings: e.settings,
51166
51326
  presentation: e.presentation,
51167
- tags: e.tags
51327
+ tags: e.tags,
51328
+ blocks: e.blocks
51168
51329
  };
51169
51330
  }
51170
51331
  function mapRemoteCourseToLocalComparable(course) {
@@ -51476,7 +51637,7 @@ async function warnForLocalLegacyEventEntries(input) {
51476
51637
  formatLegacyEventEntryWarning(legacyEventEntryFiles)
51477
51638
  );
51478
51639
  }
51479
- var pullCommand = new Command("pull").description("Pull content from CMS").argument("[scope]", "What to pull: entries, pages, navigation, settings, forms, theme, footer, venues, event-categories, events, courses, or all (default)").argument("[type]", "Content type (entries) or page identifier (pages)").argument("[identifier]", 'Entry identifier (when scope is "entries" and type is set)').option("--output <dir>", "Output directory", "./content").option("--force", "Overwrite existing files without prompting").option("--yes", "Skip confirmation prompt (same as --force)").option("--sync-media", "Sync media files from source to target environment").option("--overwrite-media", "When using --sync-media, overwrite target media on checksum mismatch").option("--local-media", "Download media referenced by identifiers to content/media").option("--dry-run", "Show what would be pulled without writing files").option("--json-diff [mode]", "Output diff as JSON (summary or full)", "summary").option("--with-theme", "Also pull theme when pulling all content").option("--name <name>", "Theme name for theme pull / --with-theme (default: current)").option("--no-meta", "Skip writing .meta/ and media manifest files (content files still written)").option("--diff", "Show human-readable field-level diff with before/after values (requires --dry-run)").addHelpText("after", `
51640
+ var pullCommand = new Command("pull").description("Pull content from CMS").argument("[scope]", "What to pull: entries, pages, navigation, settings, forms, theme, footer, venues, event-categories, events, courses, or all (default)").argument("[type]", "Content type (entries) or item identifier (pages, venues, event-categories, events, courses)").argument("[identifier]", 'Entry identifier (when scope is "entries" and type is set)').option("--output <dir>", "Output directory", "./content").option("--force", "Overwrite existing files without prompting").option("--yes", "Skip confirmation prompt (same as --force)").option("--sync-media", "Sync media files from source to target environment").option("--overwrite-media", "When using --sync-media, overwrite target media on checksum mismatch").option("--local-media", "Download media referenced by identifiers to content/media").option("--dry-run", "Show what would be pulled without writing files").option("--json-diff [mode]", "Output diff as JSON (summary or full)", "summary").option("--with-theme", "Also pull theme when pulling all content").option("--name <name>", "Theme name for theme pull / --with-theme (default: current)").option("--no-meta", "Skip writing .meta/ and media manifest files (content files still written)").option("--diff", "Show human-readable field-level diff with before/after values (requires --dry-run)").addHelpText("after", `
51480
51641
  Examples:
51481
51642
  $ riverbankcms pull # Pull all content
51482
51643
  $ riverbankcms pull --dry-run # Preview what would be pulled
@@ -51495,7 +51656,9 @@ Examples:
51495
51656
  $ riverbankcms pull venues # Pull venues
51496
51657
  $ riverbankcms pull event-categories # Pull event categories
51497
51658
  $ riverbankcms pull events # Pull events
51659
+ $ riverbankcms pull events the-whole-in-your-heart # Pull a specific event
51498
51660
  $ riverbankcms pull courses # Pull courses
51661
+ $ riverbankcms pull courses beginners # Pull a specific course
51499
51662
  $ riverbankcms pull theme # Pull theme to content/themes/current.json
51500
51663
  $ riverbankcms pull theme --name=neon # Pull theme to content/themes/neon.json
51501
51664
  $ riverbankcms pull --output ./src/content # Custom output directory
@@ -51563,7 +51726,7 @@ Media Sync:
51563
51726
  const resolvedJsonDiffMode = jsonDiffMode ?? (options.jsonDiff === true ? "summary" : void 0);
51564
51727
  if (identifier && pullScope2 !== "entries") {
51565
51728
  output.error("An item identifier is only supported for entries pulls", {
51566
- suggestion: 'Use "riverbankcms pull pages <page-identifier>" for a single page.'
51729
+ suggestion: 'Use "riverbankcms pull events <event-identifier>" or "riverbankcms pull pages <page-identifier>" with the identifier as the second argument.'
51567
51730
  });
51568
51731
  return;
51569
51732
  }
@@ -51707,17 +51870,23 @@ Media Sync:
51707
51870
  }
51708
51871
  process.exitCode = 1;
51709
51872
  };
51710
- if (pullScope2 === "venues" || pullScope2 === "event-categories" || pullScope2 === "events" || pullScope2 === "courses") {
51873
+ if (isDatedOfferingPullScope(pullScope2)) {
51711
51874
  const hasLocal = await contentDirExists(contentDir);
51712
51875
  const label = pullScope2 === "venues" ? "Venues" : pullScope2 === "event-categories" ? "Event Categories" : pullScope2 === "events" ? "Events" : "Courses";
51713
51876
  if (pullScope2 === "venues") {
51714
51877
  const result = await client.pull.venues();
51878
+ if (reportMissingScopedPullItem({
51879
+ output,
51880
+ scope: pullScope2,
51881
+ identifier: type,
51882
+ found: result.venues.some((venue) => venue.slug === type)
51883
+ })) return;
51715
51884
  const local = hasLocal ? await readVenues(contentDir) : [];
51716
51885
  await handleDryRunKeyedArrayScope({
51717
51886
  scope: "venues",
51718
51887
  label,
51719
- remoteItems: result.venues,
51720
- localItems: local,
51888
+ remoteItems: filterPullItemsByIdentifier(result.venues, type, (venue) => venue.slug),
51889
+ localItems: filterPullItemsByIdentifier(local, type, (venue) => venue.slug),
51721
51890
  getRemoteId: (v) => v.slug,
51722
51891
  getLocalId: (v) => v.slug,
51723
51892
  remoteToComparable: mapRemoteVenueToLocalComparable,
@@ -51727,12 +51896,18 @@ Media Sync:
51727
51896
  }
51728
51897
  if (pullScope2 === "event-categories") {
51729
51898
  const result = await client.pull.eventCategories();
51899
+ if (reportMissingScopedPullItem({
51900
+ output,
51901
+ scope: pullScope2,
51902
+ identifier: type,
51903
+ found: result.eventCategories.some((category) => category.identifier === type)
51904
+ })) return;
51730
51905
  const local = hasLocal ? await readEventCategories(contentDir) : [];
51731
51906
  await handleDryRunKeyedArrayScope({
51732
51907
  scope: "event-categories",
51733
51908
  label,
51734
- remoteItems: result.eventCategories,
51735
- localItems: local,
51909
+ remoteItems: filterPullItemsByIdentifier(result.eventCategories, type, (category) => category.identifier),
51910
+ localItems: filterPullItemsByIdentifier(local, type, (category) => category.identifier),
51736
51911
  getRemoteId: (c) => c.identifier,
51737
51912
  getLocalId: (c) => c.identifier,
51738
51913
  remoteToComparable: mapRemoteEventCategoryToLocalComparable,
@@ -51742,12 +51917,18 @@ Media Sync:
51742
51917
  }
51743
51918
  if (pullScope2 === "courses") {
51744
51919
  const result = await client.pull.courses();
51920
+ if (reportMissingScopedPullItem({
51921
+ output,
51922
+ scope: pullScope2,
51923
+ identifier: type,
51924
+ found: result.courses.some((course) => course.identifier === type)
51925
+ })) return;
51745
51926
  const local = hasLocal ? await readCourses(contentDir) : [];
51746
51927
  await handleDryRunKeyedArrayScope({
51747
51928
  scope: "courses",
51748
51929
  label,
51749
- remoteItems: result.courses,
51750
- localItems: local,
51930
+ remoteItems: filterPullItemsByIdentifier(result.courses, type, (course) => course.identifier),
51931
+ localItems: filterPullItemsByIdentifier(local, type, (course) => course.identifier),
51751
51932
  getRemoteId: (course) => course.identifier,
51752
51933
  getLocalId: (course) => course.identifier,
51753
51934
  remoteToComparable: mapRemoteCourseToLocalComparable,
@@ -51757,12 +51938,18 @@ Media Sync:
51757
51938
  }
51758
51939
  {
51759
51940
  const result = await client.pull.events();
51941
+ if (reportMissingScopedPullItem({
51942
+ output,
51943
+ scope: pullScope2,
51944
+ identifier: type,
51945
+ found: result.events.some((event) => event.identifier === type)
51946
+ })) return;
51760
51947
  const local = hasLocal ? await readEvents(contentDir) : [];
51761
51948
  await handleDryRunKeyedArrayScope({
51762
51949
  scope: "events",
51763
51950
  label,
51764
- remoteItems: result.events,
51765
- localItems: local,
51951
+ remoteItems: filterPullItemsByIdentifier(result.events, type, (event) => event.identifier),
51952
+ localItems: filterPullItemsByIdentifier(local, type, (event) => event.identifier),
51766
51953
  getRemoteId: (e) => e.identifier,
51767
51954
  getLocalId: (e) => e.identifier,
51768
51955
  remoteToComparable: mapRemoteEventToLocalComparable,
@@ -51931,7 +52118,7 @@ Media Sync:
51931
52118
  const dirExists = await contentDirExists(contentDir);
51932
52119
  if (identifier && pullScope !== "entries") {
51933
52120
  output.error("An item identifier is only supported for entries pulls", {
51934
- suggestion: 'Use "riverbankcms pull pages <page-identifier>" for a single page.'
52121
+ suggestion: 'Use "riverbankcms pull events <event-identifier>" or "riverbankcms pull pages <page-identifier>" with the identifier as the second argument.'
51935
52122
  });
51936
52123
  return;
51937
52124
  }
@@ -52161,8 +52348,15 @@ Media Sync:
52161
52348
  break;
52162
52349
  }
52163
52350
  case "venues": {
52164
- output.info("Pulling venues");
52351
+ output.info(`Pulling venues${type ? ` ${type}` : ""}`);
52165
52352
  const result = await client.pull.venues();
52353
+ if (reportMissingScopedPullItem({
52354
+ output,
52355
+ scope: "venues",
52356
+ identifier: type,
52357
+ found: result.venues.some((venue) => venue.slug === type)
52358
+ })) return;
52359
+ result.venues = filterPullItemsByIdentifier(result.venues, type, (venue) => venue.slug);
52166
52360
  const mediaContent = createScopedPullContent(result.meta, { venues: result.venues });
52167
52361
  await applyMediaIdentifiers(mediaContent);
52168
52362
  await syncMediaIfRequested(mediaContent);
@@ -52171,8 +52365,15 @@ Media Sync:
52171
52365
  break;
52172
52366
  }
52173
52367
  case "event-categories": {
52174
- output.info("Pulling event categories");
52368
+ output.info(`Pulling event categories${type ? ` ${type}` : ""}`);
52175
52369
  const result = await client.pull.eventCategories();
52370
+ if (reportMissingScopedPullItem({
52371
+ output,
52372
+ scope: "event-categories",
52373
+ identifier: type,
52374
+ found: result.eventCategories.some((category) => category.identifier === type)
52375
+ })) return;
52376
+ result.eventCategories = filterPullItemsByIdentifier(result.eventCategories, type, (category) => category.identifier);
52176
52377
  const mediaContent = createScopedPullContent(result.meta, { eventCategories: result.eventCategories });
52177
52378
  await applyMediaIdentifiers(mediaContent);
52178
52379
  await syncMediaIfRequested(mediaContent);
@@ -52181,8 +52382,15 @@ Media Sync:
52181
52382
  break;
52182
52383
  }
52183
52384
  case "events": {
52184
- output.info("Pulling events");
52385
+ output.info(`Pulling events${type ? ` ${type}` : ""}`);
52185
52386
  const result = await client.pull.events();
52387
+ if (reportMissingScopedPullItem({
52388
+ output,
52389
+ scope: "events",
52390
+ identifier: type,
52391
+ found: result.events.some((event) => event.identifier === type)
52392
+ })) return;
52393
+ result.events = filterPullItemsByIdentifier(result.events, type, (event) => event.identifier);
52186
52394
  const mediaContent = createScopedPullContent(result.meta, { events: result.events });
52187
52395
  await applyMediaIdentifiers(mediaContent);
52188
52396
  await syncMediaIfRequested(mediaContent);
@@ -52192,8 +52400,15 @@ Media Sync:
52192
52400
  break;
52193
52401
  }
52194
52402
  case "courses": {
52195
- output.info("Pulling courses");
52403
+ output.info(`Pulling courses${type ? ` ${type}` : ""}`);
52196
52404
  const result = await client.pull.courses();
52405
+ if (reportMissingScopedPullItem({
52406
+ output,
52407
+ scope: "courses",
52408
+ identifier: type,
52409
+ found: result.courses.some((course) => course.identifier === type)
52410
+ })) return;
52411
+ result.courses = filterPullItemsByIdentifier(result.courses, type, (course) => course.identifier);
52197
52412
  const mediaContent = createScopedPullContent(result.meta, { courses: result.courses });
52198
52413
  await applyMediaIdentifiers(mediaContent);
52199
52414
  await syncMediaIfRequested(mediaContent);
@@ -52587,8 +52802,8 @@ function normalizeLocalContentShape(content) {
52587
52802
  var identifierRegex = /^[a-z0-9][a-z0-9-]*$/;
52588
52803
  var currencyRegex = /^[A-Z]{3}$/;
52589
52804
  var isoDateTimeRegex = /^\d{4}-\d{2}-\d{2}T.+/;
52590
- function issue2(path27, message) {
52591
- return { path: path27, message };
52805
+ function issue2(path28, message) {
52806
+ return { path: path28, message };
52592
52807
  }
52593
52808
  function isRecord15(value) {
52594
52809
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -52605,27 +52820,27 @@ function isWholeMinuteIsoDateTime(value) {
52605
52820
  return Number.isFinite(epochMs) && epochMs % 6e4 === 0;
52606
52821
  }
52607
52822
  function validateTicketType(raw, index, currency) {
52608
- const path27 = ["ticketTypes", String(index)];
52609
- if (!isRecord15(raw)) return [issue2(path27, "Ticket type must be an object")];
52823
+ const path28 = ["ticketTypes", String(index)];
52824
+ if (!isRecord15(raw)) return [issue2(path28, "Ticket type must be an object")];
52610
52825
  const issues = [];
52611
52826
  const identifier = raw.identifier;
52612
52827
  if (typeof identifier !== "string" || !identifierRegex.test(identifier)) {
52613
52828
  issues.push(
52614
52829
  issue2(
52615
- [...path27, "identifier"],
52830
+ [...path28, "identifier"],
52616
52831
  "Ticket identifier must use lowercase letters, numbers, and hyphens"
52617
52832
  )
52618
52833
  );
52619
52834
  }
52620
52835
  const name = raw.name;
52621
52836
  if (typeof name !== "string" || name.trim().length === 0) {
52622
- issues.push(issue2([...path27, "name"], "Ticket name is required"));
52837
+ issues.push(issue2([...path28, "name"], "Ticket name is required"));
52623
52838
  }
52624
52839
  const priceAmount = raw.priceAmount;
52625
52840
  if (!isWholeNumber(priceAmount) || priceAmount < 0) {
52626
52841
  issues.push(
52627
52842
  issue2(
52628
- [...path27, "priceAmount"],
52843
+ [...path28, "priceAmount"],
52629
52844
  "Ticket priceAmount must be a non-negative integer"
52630
52845
  )
52631
52846
  );
@@ -52634,7 +52849,7 @@ function validateTicketType(raw, index, currency) {
52634
52849
  if (priceCurrency !== void 0 && priceCurrency !== null && priceCurrency !== currency) {
52635
52850
  issues.push(
52636
52851
  issue2(
52637
- [...path27, "priceCurrency"],
52852
+ [...path28, "priceCurrency"],
52638
52853
  "Ticket priceCurrency must match pricing.priceCurrency"
52639
52854
  )
52640
52855
  );
@@ -52643,7 +52858,7 @@ function validateTicketType(raw, index, currency) {
52643
52858
  if (sortOrder !== void 0 && (!isWholeNumber(sortOrder) || sortOrder < 0)) {
52644
52859
  issues.push(
52645
52860
  issue2(
52646
- [...path27, "sortOrder"],
52861
+ [...path28, "sortOrder"],
52647
52862
  "Ticket sortOrder must be a non-negative integer"
52648
52863
  )
52649
52864
  );
@@ -52652,7 +52867,7 @@ function validateTicketType(raw, index, currency) {
52652
52867
  if (capacityLimit2 !== void 0 && capacityLimit2 !== null && (!isWholeNumber(capacityLimit2) || capacityLimit2 < 1)) {
52653
52868
  issues.push(
52654
52869
  issue2(
52655
- [...path27, "capacityLimit"],
52870
+ [...path28, "capacityLimit"],
52656
52871
  "Ticket capacityLimit must be a positive integer"
52657
52872
  )
52658
52873
  );
@@ -52661,7 +52876,7 @@ function validateTicketType(raw, index, currency) {
52661
52876
  if (attendanceScope !== void 0 && attendanceScope !== "in_person" && attendanceScope !== "online" && attendanceScope !== "both") {
52662
52877
  issues.push(
52663
52878
  issue2(
52664
- [...path27, "attendanceScope"],
52879
+ [...path28, "attendanceScope"],
52665
52880
  "Ticket attendanceScope must be in_person, online, or both"
52666
52881
  )
52667
52882
  );
@@ -52670,7 +52885,7 @@ function validateTicketType(raw, index, currency) {
52670
52885
  if (saleStartsAt !== void 0 && saleStartsAt !== null && (typeof saleStartsAt !== "string" || !isWholeMinuteIsoDateTime(saleStartsAt))) {
52671
52886
  issues.push(
52672
52887
  issue2(
52673
- [...path27, "saleStartsAt"],
52888
+ [...path28, "saleStartsAt"],
52674
52889
  "Ticket saleStartsAt must be an ISO datetime aligned to a whole minute"
52675
52890
  )
52676
52891
  );
@@ -52679,7 +52894,7 @@ function validateTicketType(raw, index, currency) {
52679
52894
  if (saleEndsAt !== void 0 && saleEndsAt !== null && (typeof saleEndsAt !== "string" || !isWholeMinuteIsoDateTime(saleEndsAt))) {
52680
52895
  issues.push(
52681
52896
  issue2(
52682
- [...path27, "saleEndsAt"],
52897
+ [...path28, "saleEndsAt"],
52683
52898
  "Ticket saleEndsAt must be an ISO datetime aligned to a whole minute"
52684
52899
  )
52685
52900
  );
@@ -52687,7 +52902,7 @@ function validateTicketType(raw, index, currency) {
52687
52902
  if (typeof saleStartsAt === "string" && typeof saleEndsAt === "string" && Date.parse(saleEndsAt) <= Date.parse(saleStartsAt)) {
52688
52903
  issues.push(
52689
52904
  issue2(
52690
- [...path27, "saleEndsAt"],
52905
+ [...path28, "saleEndsAt"],
52691
52906
  "Ticket saleEndsAt must be after saleStartsAt"
52692
52907
  )
52693
52908
  );
@@ -52696,7 +52911,7 @@ function validateTicketType(raw, index, currency) {
52696
52911
  if (cmsTicketTypeId !== void 0 && cmsTicketTypeId !== null && (typeof cmsTicketTypeId !== "string" || cmsTicketTypeId.length === 0)) {
52697
52912
  issues.push(
52698
52913
  issue2(
52699
- [...path27, "cmsTicketTypeId"],
52914
+ [...path28, "cmsTicketTypeId"],
52700
52915
  "Ticket cmsTicketTypeId must be a non-empty string"
52701
52916
  )
52702
52917
  );
@@ -52880,8 +53095,8 @@ var supportedKinds = /* @__PURE__ */ new Set([
52880
53095
  "deferred_manual",
52881
53096
  "flexible_balance"
52882
53097
  ]);
52883
- function issue3(path27, message) {
52884
- return { path: path27, message };
53098
+ function issue3(path28, message) {
53099
+ return { path: path28, message };
52885
53100
  }
52886
53101
  function isRecord16(value) {
52887
53102
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -52898,15 +53113,15 @@ function isDepositRefundability(value) {
52898
53113
  function isSupportedOptionKind(value) {
52899
53114
  return typeof value === "string" && supportedKinds.has(value);
52900
53115
  }
52901
- function validateFlexibleBalanceDueDateRule(raw, path27) {
53116
+ function validateFlexibleBalanceDueDateRule(raw, path28) {
52902
53117
  if (!isRecord16(raw)) {
52903
- return [issue3(path27, "Flexible balance dueDateRule must be an object")];
53118
+ return [issue3(path28, "Flexible balance dueDateRule must be an object")];
52904
53119
  }
52905
53120
  if (raw.kind === "relative_to_start_date") {
52906
53121
  if (!isPositiveWholeNumber(raw.daysBeforeStart)) {
52907
53122
  return [
52908
53123
  issue3(
52909
- [...path27, "daysBeforeStart"],
53124
+ [...path28, "daysBeforeStart"],
52910
53125
  "Flexible balance daysBeforeStart must be a positive integer"
52911
53126
  )
52912
53127
  ];
@@ -52920,7 +53135,7 @@ function validateFlexibleBalanceDueDateRule(raw, path27) {
52920
53135
  if (typeof raw.dueAt !== "string" || !Number.isFinite(Date.parse(raw.dueAt))) {
52921
53136
  return [
52922
53137
  issue3(
52923
- [...path27, "dueAt"],
53138
+ [...path28, "dueAt"],
52924
53139
  "Flexible balance fixed dueAt must be an ISO datetime"
52925
53140
  )
52926
53141
  ];
@@ -52932,14 +53147,14 @@ function validateFlexibleBalanceDueDateRule(raw, path27) {
52932
53147
  }
52933
53148
  return [
52934
53149
  issue3(
52935
- [...path27, "kind"],
53150
+ [...path28, "kind"],
52936
53151
  "Flexible balance dueDateRule kind must be relative_to_start_date or fixed_calendar_date"
52937
53152
  )
52938
53153
  ];
52939
53154
  }
52940
- function validateFlexibleBalanceConfig(raw, path27) {
53155
+ function validateFlexibleBalanceConfig(raw, path28) {
52941
53156
  if (!isRecord16(raw)) {
52942
- return [issue3(path27, "Flexible balance config must be an object")];
53157
+ return [issue3(path28, "Flexible balance config must be an object")];
52943
53158
  }
52944
53159
  const issues = [];
52945
53160
  const upfrontAmountCents = raw.upfrontAmountCents;
@@ -52949,7 +53164,7 @@ function validateFlexibleBalanceConfig(raw, path27) {
52949
53164
  if (!isWholeNumber2(upfrontAmountCents) || upfrontAmountCents < 0) {
52950
53165
  issues.push(
52951
53166
  issue3(
52952
- [...path27, "upfrontAmountCents"],
53167
+ [...path28, "upfrontAmountCents"],
52953
53168
  "Flexible balance upfrontAmountCents must be a non-negative integer"
52954
53169
  )
52955
53170
  );
@@ -52959,7 +53174,7 @@ function validateFlexibleBalanceConfig(raw, path27) {
52959
53174
  if (!isDepositRefundability(depositRefundability)) {
52960
53175
  issues.push(
52961
53176
  issue3(
52962
- [...path27, "depositRefundability"],
53177
+ [...path28, "depositRefundability"],
52963
53178
  "Flexible balance depositRefundability must be refundable or non_refundable"
52964
53179
  )
52965
53180
  );
@@ -52968,7 +53183,7 @@ function validateFlexibleBalanceConfig(raw, path27) {
52968
53183
  }
52969
53184
  const dueDateRule = validateFlexibleBalanceDueDateRule(
52970
53185
  raw.dueDateRule,
52971
- [...path27, "dueDateRule"]
53186
+ [...path28, "dueDateRule"]
52972
53187
  );
52973
53188
  if (Array.isArray(dueDateRule)) {
52974
53189
  issues.push(...dueDateRule);
@@ -52983,14 +53198,14 @@ function validateFlexibleBalanceConfig(raw, path27) {
52983
53198
  };
52984
53199
  }
52985
53200
  function validateCollectionOption(raw, index) {
52986
- const path27 = ["allowedOptions", String(index)];
53201
+ const path28 = ["allowedOptions", String(index)];
52987
53202
  if (!isRecord16(raw)) {
52988
- return [issue3(path27, "Payment option must be an object")];
53203
+ return [issue3(path28, "Payment option must be an object")];
52989
53204
  }
52990
53205
  if (raw.kind === "instalment_plan") {
52991
53206
  return [
52992
53207
  issue3(
52993
- [...path27, "kind"],
53208
+ [...path28, "kind"],
52994
53209
  "Event instalment plans are not supported yet. Use upfront, deferred_manual, or flexible_balance."
52995
53210
  )
52996
53211
  ];
@@ -52998,7 +53213,7 @@ function validateCollectionOption(raw, index) {
52998
53213
  if (!isSupportedOptionKind(raw.kind)) {
52999
53214
  return [
53000
53215
  issue3(
53001
- [...path27, "kind"],
53216
+ [...path28, "kind"],
53002
53217
  "Payment option kind must be upfront, deferred_manual, or flexible_balance"
53003
53218
  )
53004
53219
  ];
@@ -53009,7 +53224,7 @@ function validateCollectionOption(raw, index) {
53009
53224
  return { kind: raw.kind };
53010
53225
  case "flexible_balance": {
53011
53226
  const config2 = validateFlexibleBalanceConfig(raw.config, [
53012
- ...path27,
53227
+ ...path28,
53013
53228
  "config"
53014
53229
  ]);
53015
53230
  if (Array.isArray(config2)) {
@@ -54479,6 +54694,7 @@ var upsertEventSeriesCommandSchema = z.object({
54479
54694
  ref: eventSeriesRefSchema,
54480
54695
  input: z.object({
54481
54696
  slug: z.string().min(1),
54697
+ path: z.string().startsWith("/").nullable().optional(),
54482
54698
  title: z.string().min(1),
54483
54699
  archetype: z.enum(offeringArchetypes),
54484
54700
  status: z.enum(["draft", "active", "archived", "cancelled"]).optional(),
@@ -54503,6 +54719,7 @@ var upsertEventSeriesCommandSchema = z.object({
54503
54719
  paymentTerms: z.unknown().optional(),
54504
54720
  presentation: unknownRecordSchema.nullable().optional(),
54505
54721
  tags: z.array(z.string()).readonly().optional(),
54722
+ blocks: entrySlotBlocksSchema.optional(),
54506
54723
  staffRefs: z.array(staffRefSchema).readonly().optional()
54507
54724
  }).strict()
54508
54725
  }).strict();
@@ -55880,13 +56097,13 @@ function collectOfferingRequires(input, intervals, intervalPath) {
55880
56097
  function optionalRef(ref, field) {
55881
56098
  return ref ? [{ ref, field }] : [];
55882
56099
  }
55883
- function collectVenueRefsFromIntervals(intervals, path27) {
55884
- return intervals.flatMap((interval, index) => optionalRef(interval.venueRef, `${path27}[${index}].venueRef`));
56100
+ function collectVenueRefsFromIntervals(intervals, path28) {
56101
+ return intervals.flatMap((interval, index) => optionalRef(interval.venueRef, `${path28}[${index}].venueRef`));
55885
56102
  }
55886
- function collectNavigationRefs(items, path27) {
56103
+ function collectNavigationRefs(items, path28) {
55887
56104
  return items.flatMap((item, index) => {
55888
56105
  if (!isRecord18(item)) return [];
55889
- const itemPath = `${path27}[${index}]`;
56106
+ const itemPath = `${path28}[${index}]`;
55890
56107
  const refs = [];
55891
56108
  if (typeof item.pageRef === "string") {
55892
56109
  refs.push({ ref: item.pageRef, field: `${itemPath}.pageRef` });
@@ -55900,26 +56117,26 @@ function collectNavigationRefs(items, path27) {
55900
56117
  return refs;
55901
56118
  });
55902
56119
  }
55903
- function collectBlockRefs(blocks, path27) {
56120
+ function collectBlockRefs(blocks, path28) {
55904
56121
  return blocks.flatMap((block, index) => {
55905
56122
  if (!isRecord18(block)) return [];
55906
- const blockPath = `${path27}[${index}]`;
56123
+ const blockPath = `${path28}[${index}]`;
55907
56124
  return [
55908
56125
  ...collectNestedRefs(block.props, `${blockPath}.props`),
55909
56126
  ...collectNestedRefs(block.children, `${blockPath}.children`)
55910
56127
  ];
55911
56128
  });
55912
56129
  }
55913
- function collectNestedRefs(value, path27) {
56130
+ function collectNestedRefs(value, path28) {
55914
56131
  if (typeof value === "string") {
55915
56132
  const parsed = parseResourceRef(value);
55916
- return parsed.ok ? [{ ref: value, field: path27 }] : [];
56133
+ return parsed.ok ? [{ ref: value, field: path28 }] : [];
55917
56134
  }
55918
56135
  if (Array.isArray(value)) {
55919
- return value.flatMap((item, index) => collectNestedRefs(item, `${path27}[${index}]`));
56136
+ return value.flatMap((item, index) => collectNestedRefs(item, `${path28}[${index}]`));
55920
56137
  }
55921
56138
  if (!isRecord18(value)) return [];
55922
- return Object.entries(value).flatMap(([key, child]) => collectNestedRefs(child, `${path27}.${key}`));
56139
+ return Object.entries(value).flatMap(([key, child]) => collectNestedRefs(child, `${path28}.${key}`));
55923
56140
  }
55924
56141
 
55925
56142
  // ../site-commands/src/staticExecutionGaps.ts
@@ -56198,8 +56415,8 @@ function invalidPayloadError(input, issue5) {
56198
56415
  message: `${field}: ${issue5.message}`
56199
56416
  };
56200
56417
  }
56201
- function commandIndexForIssuePath(path27) {
56202
- return path27[0] === "commands" && typeof path27[1] === "number" ? path27[1] : -1;
56418
+ function commandIndexForIssuePath(path28) {
56419
+ return path28[0] === "commands" && typeof path28[1] === "number" ? path28[1] : -1;
56203
56420
  }
56204
56421
  function commandTypeForIssue(input, commandIndex) {
56205
56422
  if (!isRecord18(input) || !isUnknownArray3(input.commands)) return null;
@@ -56209,9 +56426,9 @@ function commandTypeForIssue(input, commandIndex) {
56209
56426
  function isUnknownArray3(value) {
56210
56427
  return Array.isArray(value);
56211
56428
  }
56212
- function formatIssuePath(path27) {
56213
- if (path27.length === 0) return "<root>";
56214
- return path27.reduce((formatted, segment) => {
56429
+ function formatIssuePath(path28) {
56430
+ if (path28.length === 0) return "<root>";
56431
+ return path28.reduce((formatted, segment) => {
56215
56432
  if (typeof segment === "number") return `${formatted}[${segment}]`;
56216
56433
  if (formatted.length === 0) return String(segment);
56217
56434
  return `${formatted}.${String(segment)}`;
@@ -56880,8 +57097,8 @@ init_src();
56880
57097
  var timeRegex = /^([01]\d|2[0-3]):([0-5]\d)(:([0-5]\d))?$/;
56881
57098
  var explicitOffsetDateTimeRegex = /^(\d{4})-(\d{2})-(\d{2})T([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?(\.\d{1,3})?(Z|[+-]([01]\d|2[0-3]):[0-5]\d)$/;
56882
57099
  var localDateTimeRegex = /^(\d{4})-(\d{2})-(\d{2})T([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?(\.\d{1,3})?$/;
56883
- function issue4(path27, message) {
56884
- return { path: path27, message };
57100
+ function issue4(path28, message) {
57101
+ return { path: path28, message };
56885
57102
  }
56886
57103
  function isValidDateParts(year, month, day) {
56887
57104
  const date = new Date(Date.UTC(year, month - 1, day));
@@ -57305,6 +57522,7 @@ function eventSeriesCommand(event) {
57305
57522
  ref: createEventSeriesRef([event.identifier]),
57306
57523
  input: {
57307
57524
  slug: event.slug,
57525
+ path: event.path,
57308
57526
  title: event.title,
57309
57527
  archetype: "custom",
57310
57528
  status: event.status === "completed" ? void 0 : event.status,
@@ -57329,7 +57547,8 @@ function eventSeriesCommand(event) {
57329
57547
  settings: event.settings,
57330
57548
  paymentTerms: event.paymentTerms,
57331
57549
  presentation: event.presentation,
57332
- tags: event.tags
57550
+ tags: event.tags,
57551
+ blocks: event.blocks
57333
57552
  }
57334
57553
  });
57335
57554
  }
@@ -57493,6 +57712,7 @@ function eventSeriesUpsertInput(command) {
57493
57712
  identifier: command.input.slug,
57494
57713
  title: command.input.title,
57495
57714
  slug: command.input.slug,
57715
+ path: command.input.path,
57496
57716
  status: command.input.status,
57497
57717
  visibility: managementVisibility(command.input.visibility),
57498
57718
  schedule: scheduleFromOccurrence(occurrence),
@@ -57507,7 +57727,8 @@ function eventSeriesUpsertInput(command) {
57507
57727
  formRef: command.input.formIdentifier ?? (command.input.formRef ? refSlug(command.input.formRef) : null),
57508
57728
  settings: command.input.settings,
57509
57729
  presentation: command.input.presentation,
57510
- tags: command.input.tags ? [...command.input.tags] : void 0
57730
+ tags: command.input.tags ? [...command.input.tags] : void 0,
57731
+ blocks: command.input.blocks
57511
57732
  };
57512
57733
  }
57513
57734
  function eventContentInput(content) {
@@ -60382,13 +60603,118 @@ async function pushEventCategoriesScope(ctx, options) {
60382
60603
  })
60383
60604
  });
60384
60605
  }
60385
-
60386
- // src/cli/commands/push/scopes/events.ts
60606
+ function findDuplicateLocalEventIdentifiers(events) {
60607
+ const filePathsByIdentifier = /* @__PURE__ */ new Map();
60608
+ for (const event of events) {
60609
+ const filePaths = filePathsByIdentifier.get(event.identifier) ?? [];
60610
+ filePaths.push(event.filePath);
60611
+ filePathsByIdentifier.set(event.identifier, filePaths);
60612
+ }
60613
+ return [...filePathsByIdentifier.entries()].filter(([, filePaths]) => filePaths.length > 1).map(([identifier, filePaths]) => ({ identifier, filePaths }));
60614
+ }
60615
+ function formatDuplicateEventFilePath(contentDir, filePath) {
60616
+ return path5.relative(contentDir, filePath) || filePath;
60617
+ }
60618
+ function normalizeLocalPath(value) {
60619
+ const [withoutHash] = value.split("#");
60620
+ const [withoutQuery] = (withoutHash ?? "").split("?");
60621
+ if (!withoutQuery || !withoutQuery.startsWith("/")) return value;
60622
+ return withoutQuery.length > 1 ? withoutQuery.replace(/\/+$/u, "") || "/" : "/";
60623
+ }
60624
+ function localEventPath(event) {
60625
+ return normalizeLocalPath(event.path?.trim() || `/events/${event.slug}`);
60626
+ }
60627
+ function collectNavigationPathReferences(navigation) {
60628
+ if (!navigation) return [];
60629
+ const references = [];
60630
+ const visit = (items, menuName) => {
60631
+ for (const item of items) {
60632
+ const link2 = item.link;
60633
+ if (link2 && typeof link2 === "object" && "href" in link2) {
60634
+ const href = link2.href;
60635
+ if (typeof href === "string" && href.startsWith("/")) {
60636
+ references.push({
60637
+ path: normalizeLocalPath(href),
60638
+ menuName,
60639
+ label: item.label
60640
+ });
60641
+ }
60642
+ }
60643
+ if (item.children?.length) {
60644
+ visit(item.children, menuName);
60645
+ }
60646
+ }
60647
+ };
60648
+ for (const menu of navigation.menus) {
60649
+ visit(menu.items, menu.name);
60650
+ }
60651
+ return references;
60652
+ }
60653
+ function findEventNavigationPathMismatches(events, navigation) {
60654
+ const references = collectNavigationPathReferences(navigation);
60655
+ const mismatches = [];
60656
+ for (const event of events) {
60657
+ const eventPath = localEventPath(event);
60658
+ const slugSuffix = `/${event.slug}`;
60659
+ for (const reference of references) {
60660
+ if (reference.path.endsWith(slugSuffix) && reference.path !== eventPath && !reference.path.startsWith(`${eventPath}/`)) {
60661
+ mismatches.push({
60662
+ eventIdentifier: event.identifier,
60663
+ eventPath,
60664
+ navigationPath: reference.path,
60665
+ menuName: reference.menuName,
60666
+ label: reference.label
60667
+ });
60668
+ }
60669
+ }
60670
+ }
60671
+ return mismatches;
60672
+ }
60673
+ function warnForEventNavigationPathMismatches(ctx, mismatches) {
60674
+ if (mismatches.length === 0) return;
60675
+ ctx.output.warn("Navigation links may not match canonical event paths", {
60676
+ details: mismatches.map(
60677
+ (mismatch) => ` - ${mismatch.menuName} > ${mismatch.label}: ${mismatch.navigationPath} points at event "${mismatch.eventIdentifier}", but content/events uses ${mismatch.eventPath}`
60678
+ ).join("\n"),
60679
+ suggestion: "Update content/events/*.json path or content/navigation.json so event links resolve to the same route."
60680
+ });
60681
+ }
60387
60682
  async function pushEventsScope(ctx, options) {
60388
60683
  const { client } = ctx;
60389
60684
  const only = options?.only;
60390
- const events = await readEvents(ctx.contentDir);
60391
- const mediaContent = { ...createEmptyLocalContent(), events };
60685
+ const events = await readEventsWithFilePaths(ctx.contentDir);
60686
+ const duplicateIdentifiers = findDuplicateLocalEventIdentifiers(
60687
+ only ? events.filter((event) => only.has(event.identifier)) : events
60688
+ );
60689
+ if (duplicateIdentifiers.length > 0) {
60690
+ ctx.output.error("Duplicate event identifiers detected", {
60691
+ details: duplicateIdentifiers.map(
60692
+ (duplicate) => ` ${duplicate.identifier}:
60693
+ ${duplicate.filePaths.map((filePath) => ` - ${formatDuplicateEventFilePath(ctx.contentDir, filePath)}`).join("\n")}`
60694
+ ).join("\n"),
60695
+ suggestion: "Each content/events/*.json file must have a unique identifier. Delete or merge stale duplicate event files before pushing."
60696
+ });
60697
+ return {
60698
+ status: "aborted",
60699
+ scopeCommand: "events",
60700
+ scopeName: "events",
60701
+ created: 0,
60702
+ updated: 0,
60703
+ deleted: 0,
60704
+ failed: duplicateIdentifiers.length,
60705
+ errors: duplicateIdentifiers.map((duplicate) => ({
60706
+ identifier: duplicate.identifier,
60707
+ error: `Duplicate event identifier in ${duplicate.filePaths.map((filePath) => formatDuplicateEventFilePath(ctx.contentDir, filePath)).join(", ")}`
60708
+ }))
60709
+ };
60710
+ }
60711
+ const eventItems = events.map(({ filePath: _filePath, ...event }) => event);
60712
+ const selectedEventItems = only ? eventItems.filter((event) => only.has(event.identifier)) : eventItems;
60713
+ warnForEventNavigationPathMismatches(
60714
+ ctx,
60715
+ findEventNavigationPathMismatches(selectedEventItems, await readNavigation(ctx.contentDir))
60716
+ );
60717
+ const mediaContent = { ...createEmptyLocalContent(), events: eventItems };
60392
60718
  const mediaResult = await syncLocalMediaForScopePush(ctx, mediaContent);
60393
60719
  if (!mediaResult.ok) {
60394
60720
  ctx.output.error("Local media sync failed", {
@@ -60413,7 +60739,7 @@ async function pushEventsScope(ctx, options) {
60413
60739
  getIdentifier: (event) => event.identifier,
60414
60740
  getDisplayLabel: (event) => event.title,
60415
60741
  shouldPushItem: only ? (event) => only.has(event.identifier) : void 0,
60416
- readLocal: async () => events,
60742
+ readLocal: async () => eventItems,
60417
60743
  readMeta: async (dir) => {
60418
60744
  const meta = await readEventsMeta(dir);
60419
60745
  return meta?.events ?? null;
@@ -60648,7 +60974,7 @@ function firstNestedContainerChange(localChanges, remoteChanges) {
60648
60974
  }
60649
60975
  function firstSameFieldConflictPath(localChanges, remoteChanges) {
60650
60976
  const remotePaths = new Set(remoteChanges.keys());
60651
- return [...localChanges.keys()].filter((path27) => remotePaths.has(path27)).sort()[0] ?? null;
60977
+ return [...localChanges.keys()].filter((path28) => remotePaths.has(path28)).sort()[0] ?? null;
60652
60978
  }
60653
60979
  function unsupportedNestedMerge(subject, fieldPath) {
60654
60980
  return {
@@ -60730,37 +61056,37 @@ function valueKind(value) {
60730
61056
  if (typeof value === "object") return "object";
60731
61057
  return "scalar";
60732
61058
  }
60733
- function entryChange(path27, value, containerKind) {
61059
+ function entryChange(path28, value, containerKind) {
60734
61060
  switch (containerKind) {
60735
61061
  case "array":
60736
- if (Array.isArray(value)) return { path: path27, value, containerKind };
61062
+ if (Array.isArray(value)) return { path: path28, value, containerKind };
60737
61063
  break;
60738
61064
  case "object":
60739
61065
  if (value && typeof value === "object" && !Array.isArray(value)) {
60740
- return { path: path27, value, containerKind };
61066
+ return { path: path28, value, containerKind };
60741
61067
  }
60742
61068
  break;
60743
61069
  case "null":
60744
- if (value === null || value === void 0) return { path: path27, value, containerKind };
61070
+ if (value === null || value === void 0) return { path: path28, value, containerKind };
60745
61071
  break;
60746
61072
  case "scalar":
60747
- if (isScalarEntryChangeValue(value)) return { path: path27, value, containerKind };
61073
+ if (isScalarEntryChangeValue(value)) return { path: path28, value, containerKind };
60748
61074
  break;
60749
61075
  default:
60750
61076
  assertNever(containerKind);
60751
61077
  }
60752
- throw new Error(`Invalid entry merge change at ${path27}.`);
61078
+ throw new Error(`Invalid entry merge change at ${path28}.`);
60753
61079
  }
60754
61080
  function isScalarEntryChangeValue(value) {
60755
61081
  return value === void 0 || value === null || ["boolean", "number", "string"].includes(typeof value);
60756
61082
  }
60757
- function expectStringValue(path27, value) {
61083
+ function expectStringValue(path28, value) {
60758
61084
  if (typeof value === "string") return value;
60759
- throw new Error(`Entry merge expected ${path27} to be a string.`);
61085
+ throw new Error(`Entry merge expected ${path28} to be a string.`);
60760
61086
  }
60761
- function expectBooleanValue(path27, value) {
61087
+ function expectBooleanValue(path28, value) {
60762
61088
  if (typeof value === "boolean") return value;
60763
- throw new Error(`Entry merge expected ${path27} to be a boolean.`);
61089
+ throw new Error(`Entry merge expected ${path28} to be a boolean.`);
60764
61090
  }
60765
61091
  function expectStatusValue(value) {
60766
61092
  if (value === "draft" || value === "published") return value;
@@ -61272,7 +61598,7 @@ async function unlinkIfExists(filePath) {
61272
61598
  }
61273
61599
 
61274
61600
  // src/cli/commands/push-execute.ts
61275
- async function executeScopedPush(output, isRemote, options, globalOpts, scopeLabel, pullCommand2, shouldDeleteOrphans, pushFn) {
61601
+ async function executeScopedPush(output, isRemote, options, globalOpts, scopeLabel, pullCommand2, shouldDeleteOrphans, pushFn, scopedOptions) {
61276
61602
  const cliConfig = await loadCliConfig();
61277
61603
  const contentDir = path5.resolve(options.contentDir ?? cliConfig.contentDir);
61278
61604
  if (!await contentDirExists(contentDir)) {
@@ -61286,21 +61612,24 @@ async function executeScopedPush(output, isRemote, options, globalOpts, scopeLab
61286
61612
  managementApiKey: env.managementApiKey,
61287
61613
  siteId: env.siteId
61288
61614
  });
61289
- const result = await pushFn({
61290
- output,
61291
- contentDir,
61292
- siteId: env.siteId,
61293
- targetEnv: isRemote ? "remote" : "local",
61294
- client,
61295
- dryRun: options.dryRun,
61296
- force: options.force ?? false,
61297
- isJsonOutput: globalOpts.json ?? false,
61298
- forceUpdateAsset: options.forceUpdateAsset,
61299
- deleteOrphaned: shouldDeleteOrphans,
61300
- autoPullStale: options.autoPullStale ?? false,
61301
- skipMeta: !(options.meta ?? true),
61302
- humanDiff: options.diff ?? false
61303
- });
61615
+ const result = await pushFn(
61616
+ {
61617
+ output,
61618
+ contentDir,
61619
+ siteId: env.siteId,
61620
+ targetEnv: isRemote ? "remote" : "local",
61621
+ client,
61622
+ dryRun: options.dryRun,
61623
+ force: options.force ?? false,
61624
+ isJsonOutput: globalOpts.json ?? false,
61625
+ forceUpdateAsset: options.forceUpdateAsset,
61626
+ deleteOrphaned: shouldDeleteOrphans,
61627
+ autoPullStale: options.autoPullStale ?? false,
61628
+ skipMeta: !(options.meta ?? true),
61629
+ humanDiff: options.diff ?? false
61630
+ },
61631
+ scopedOptions
61632
+ );
61304
61633
  if (result.status === "pushed" && result.failed > 0 || result.status === "failed") {
61305
61634
  process.exitCode = 1;
61306
61635
  output.result(false, `${scopeLabel} push had failures`, result);
@@ -61557,6 +61886,7 @@ ${errors}`
61557
61886
  return { success: true };
61558
61887
  }
61559
61888
  if (pushScope === "venues") {
61889
+ const only = type ? /* @__PURE__ */ new Set([type]) : void 0;
61560
61890
  return executeScopedPush(
61561
61891
  output,
61562
61892
  isRemote,
@@ -61565,10 +61895,12 @@ ${errors}`
61565
61895
  "Venues",
61566
61896
  "venues",
61567
61897
  shouldDeleteOrphans,
61568
- pushVenuesScope
61898
+ pushVenuesScope,
61899
+ only ? { only } : void 0
61569
61900
  );
61570
61901
  }
61571
61902
  if (pushScope === "event-categories") {
61903
+ const only = type ? /* @__PURE__ */ new Set([type]) : void 0;
61572
61904
  return executeScopedPush(
61573
61905
  output,
61574
61906
  isRemote,
@@ -61577,10 +61909,12 @@ ${errors}`
61577
61909
  "Event categories",
61578
61910
  "event-categories",
61579
61911
  shouldDeleteOrphans,
61580
- pushEventCategoriesScope
61912
+ pushEventCategoriesScope,
61913
+ only ? { only } : void 0
61581
61914
  );
61582
61915
  }
61583
61916
  if (pushScope === "events") {
61917
+ const only = type ? /* @__PURE__ */ new Set([type]) : void 0;
61584
61918
  return executeScopedPush(
61585
61919
  output,
61586
61920
  isRemote,
@@ -61589,10 +61923,12 @@ ${errors}`
61589
61923
  "Events",
61590
61924
  "events",
61591
61925
  shouldDeleteOrphans,
61592
- pushEventsScope
61926
+ pushEventsScope,
61927
+ only ? { only } : void 0
61593
61928
  );
61594
61929
  }
61595
61930
  if (pushScope === "courses") {
61931
+ const only = type ? /* @__PURE__ */ new Set([type]) : void 0;
61596
61932
  return executeScopedPush(
61597
61933
  output,
61598
61934
  isRemote,
@@ -61601,7 +61937,8 @@ ${errors}`
61601
61937
  "Courses",
61602
61938
  "courses",
61603
61939
  shouldDeleteOrphans,
61604
- pushCoursesScope
61940
+ pushCoursesScope,
61941
+ only ? { only } : void 0
61605
61942
  );
61606
61943
  }
61607
61944
  if (pushScope === "footer") {
@@ -65171,7 +65508,7 @@ var SimpleCache = class {
65171
65508
  };
65172
65509
 
65173
65510
  // src/version.ts
65174
- var SDK_VERSION = "0.88.0";
65511
+ var SDK_VERSION = "0.90.0";
65175
65512
 
65176
65513
  // src/client/error.ts
65177
65514
  var RiverbankApiError = class _RiverbankApiError extends Error {
@@ -65328,6 +65665,476 @@ function attachResilienceStatusToError(error, resilienceStatus) {
65328
65665
  return target;
65329
65666
  }
65330
65667
 
65668
+ // src/public-api/runtime.ts
65669
+ var PUBLIC_ENDPOINT_NAMES2 = [
65670
+ "getSite",
65671
+ "getContentByPath",
65672
+ "listPublishedEntries",
65673
+ "getPublishedEntryPreview",
65674
+ "getPublicFormById",
65675
+ "listPublicForms",
65676
+ "getPublicBookingServices",
65677
+ "getPublicChallenge",
65678
+ "listPublicEvents",
65679
+ "batchBlockLoaders",
65680
+ "listPublicCourses",
65681
+ "listPublicTeamMembers",
65682
+ "listPublicProducts",
65683
+ "listPublicPasses",
65684
+ "listPublicMemberships",
65685
+ "resolveEntrySubroute",
65686
+ "resolveEventOccurrence",
65687
+ "checkRedirect",
65688
+ "getRoutableContent",
65689
+ "getPublicRoutableContent",
65690
+ "getPublicSitemapRoutes"
65691
+ ];
65692
+ var API_ENDPOINTS2 = Object.freeze({
65693
+ getSite: {
65694
+ path: "/sites",
65695
+ method: "GET",
65696
+ revalidate: 900,
65697
+ tags: ["riverbank:site", "riverbank:site:id:{id}", "riverbank:site:slug:{slug}", "riverbank:site:domain:{domain}"],
65698
+ auth: "public",
65699
+ responseKind: "json"
65700
+ },
65701
+ getContentByPath: {
65702
+ path: "/sites/{siteId}/pages",
65703
+ method: "GET",
65704
+ tags: ["riverbank:site:{siteId}:routable-content"],
65705
+ auth: "public",
65706
+ responseKind: "json"
65707
+ },
65708
+ listPublishedEntries: {
65709
+ path: "/public/content/{siteId}/{type}/entries",
65710
+ method: "GET",
65711
+ revalidate: 60,
65712
+ tags: ["content-{siteId}-{type}"],
65713
+ auth: "public",
65714
+ responseKind: "json"
65715
+ },
65716
+ getPublishedEntryPreview: {
65717
+ path: "/public/content/{siteId}/{type}/{slug}/preview",
65718
+ method: "GET",
65719
+ revalidate: 60,
65720
+ tags: ["content-{siteId}-{type}-{slug}"],
65721
+ auth: "public",
65722
+ responseKind: "json"
65723
+ },
65724
+ getPublicFormById: {
65725
+ path: "/public/forms/{formId}",
65726
+ method: "GET",
65727
+ revalidate: 60,
65728
+ tags: ["riverbank:form:{formId}"],
65729
+ auth: "public",
65730
+ responseKind: "json"
65731
+ },
65732
+ listPublicForms: {
65733
+ path: "/public/sites/{siteId}/forms",
65734
+ method: "GET",
65735
+ revalidate: 60,
65736
+ tags: ["riverbank:site:{siteId}:forms"],
65737
+ auth: "public",
65738
+ responseKind: "json"
65739
+ },
65740
+ getPublicBookingServices: {
65741
+ path: "/public/bookings/services",
65742
+ method: "GET",
65743
+ revalidate: 60,
65744
+ tags: ["site-{siteId}"],
65745
+ auth: "public",
65746
+ responseKind: "json"
65747
+ },
65748
+ getPublicChallenge: {
65749
+ path: "/public/challenge",
65750
+ method: "GET",
65751
+ auth: "public",
65752
+ responseKind: "text"
65753
+ },
65754
+ listPublicEvents: {
65755
+ path: "/public/sites/{siteId}/events",
65756
+ method: "GET",
65757
+ revalidate: 60,
65758
+ tags: ["riverbank:site:{siteId}:public-events"],
65759
+ auth: "public",
65760
+ responseKind: "json"
65761
+ },
65762
+ batchBlockLoaders: {
65763
+ path: "/public/sites/{siteId}/block-loaders/batch",
65764
+ method: "POST",
65765
+ auth: "public",
65766
+ responseKind: "json"
65767
+ },
65768
+ listPublicCourses: {
65769
+ path: "/public/sites/{siteId}/courses",
65770
+ method: "GET",
65771
+ revalidate: 60,
65772
+ tags: ["riverbank:site:{siteId}:public-courses"],
65773
+ auth: "public",
65774
+ responseKind: "json"
65775
+ },
65776
+ listPublicTeamMembers: {
65777
+ path: "/public/sites/{siteId}/team-members",
65778
+ method: "GET",
65779
+ revalidate: 60,
65780
+ tags: ["riverbank:site:{siteId}:public-team-members"],
65781
+ auth: "public",
65782
+ responseKind: "json"
65783
+ },
65784
+ listPublicProducts: {
65785
+ path: "/public/sites/{siteId}/products",
65786
+ method: "GET",
65787
+ revalidate: 300,
65788
+ tags: ["riverbank:site:{siteId}:public-products"],
65789
+ auth: "public",
65790
+ responseKind: "json"
65791
+ },
65792
+ listPublicPasses: {
65793
+ path: "/public/sites/{siteId}/bookings/products/passes",
65794
+ method: "GET",
65795
+ revalidate: 300,
65796
+ tags: ["riverbank:site:{siteId}:public-passes"],
65797
+ auth: "public",
65798
+ responseKind: "json"
65799
+ },
65800
+ listPublicMemberships: {
65801
+ path: "/public/sites/{siteId}/bookings/products/memberships",
65802
+ method: "GET",
65803
+ revalidate: 300,
65804
+ tags: ["riverbank:site:{siteId}:public-memberships"],
65805
+ auth: "public",
65806
+ responseKind: "json"
65807
+ },
65808
+ resolveEntrySubroute: {
65809
+ path: "/public/sites/{siteId}/routing/subroutes/resolve",
65810
+ method: "GET",
65811
+ revalidate: 60,
65812
+ tags: ["site-{siteId}", "entry-subroute"],
65813
+ auth: "public",
65814
+ responseKind: "json"
65815
+ },
65816
+ resolveEventOccurrence: {
65817
+ path: "/public/sites/{siteId}/events/occurrences/resolve",
65818
+ method: "GET",
65819
+ revalidate: 60,
65820
+ tags: ["riverbank:site:{siteId}:public-events", "event-occurrence"],
65821
+ auth: "public",
65822
+ responseKind: "json"
65823
+ },
65824
+ checkRedirect: {
65825
+ path: "/public/content/redirect",
65826
+ method: "GET",
65827
+ revalidate: 86400,
65828
+ tags: ["redirect"],
65829
+ auth: "public",
65830
+ responseKind: "json"
65831
+ },
65832
+ getRoutableContent: {
65833
+ path: "/sites/{siteId}/routable-content",
65834
+ method: "GET",
65835
+ revalidate: 60,
65836
+ tags: ["riverbank:site:{siteId}:routable-content"],
65837
+ auth: "user",
65838
+ responseKind: "json"
65839
+ },
65840
+ getPublicRoutableContent: {
65841
+ path: "/public/sites/{siteId}/routable-content",
65842
+ method: "GET",
65843
+ revalidate: 60,
65844
+ tags: ["riverbank:site:{siteId}:routable-content"],
65845
+ auth: "public",
65846
+ responseKind: "json"
65847
+ },
65848
+ getPublicSitemapRoutes: {
65849
+ path: "/public/sites/{siteId}/sitemap",
65850
+ method: "GET",
65851
+ revalidate: 60,
65852
+ tags: ["riverbank:site:{siteId}:routable-content", "riverbank:site:{siteId}:settings"],
65853
+ auth: "public",
65854
+ responseKind: "json"
65855
+ }
65856
+ });
65857
+
65858
+ // src/client/runtimeCachePolicy.ts
65859
+ var DEFAULT_PUBLISHED_RUNTIME_CACHE_PAYLOAD_SCHEMA_VERSION = 1;
65860
+ var DEFAULT_STALE_TTL_SEC = 24 * 60 * 60;
65861
+ var DEFAULT_MEMORY_TTL_SEC = 60;
65862
+ var RUNTIME_CACHE_DURABILITY_OVERRIDES = {
65863
+ getSite: {
65864
+ kind: "durable-public-stale",
65865
+ staleTtlSec: DEFAULT_STALE_TTL_SEC
65866
+ },
65867
+ getContentByPath: {
65868
+ kind: "durable-public-stale",
65869
+ staleTtlSec: DEFAULT_STALE_TTL_SEC
65870
+ },
65871
+ listPublishedEntries: {
65872
+ kind: "memory-only",
65873
+ reason: "durable_rollout_pending"
65874
+ },
65875
+ getPublishedEntryPreview: {
65876
+ kind: "memory-only",
65877
+ reason: "durable_rollout_pending"
65878
+ },
65879
+ getPublicFormById: {
65880
+ kind: "memory-only",
65881
+ reason: "durable_rollout_pending"
65882
+ },
65883
+ listPublicForms: {
65884
+ kind: "memory-only",
65885
+ reason: "durable_rollout_pending"
65886
+ },
65887
+ getPublicBookingServices: {
65888
+ kind: "live-only",
65889
+ reason: "safety_sensitive_booking"
65890
+ },
65891
+ getPublicChallenge: {
65892
+ kind: "live-only",
65893
+ reason: "challenge_endpoint"
65894
+ },
65895
+ listPublicEvents: {
65896
+ kind: "memory-only",
65897
+ reason: "durable_rollout_pending"
65898
+ },
65899
+ batchBlockLoaders: {
65900
+ kind: "live-only",
65901
+ reason: "opaque_batch_loader"
65902
+ },
65903
+ listPublicCourses: {
65904
+ kind: "memory-only",
65905
+ reason: "durable_rollout_pending"
65906
+ },
65907
+ listPublicTeamMembers: {
65908
+ kind: "memory-only",
65909
+ reason: "durable_rollout_pending"
65910
+ },
65911
+ listPublicProducts: {
65912
+ kind: "memory-only",
65913
+ reason: "durable_rollout_pending"
65914
+ },
65915
+ listPublicPasses: {
65916
+ kind: "live-only",
65917
+ reason: "safety_sensitive_booking"
65918
+ },
65919
+ listPublicMemberships: {
65920
+ kind: "live-only",
65921
+ reason: "safety_sensitive_booking"
65922
+ },
65923
+ resolveEntrySubroute: {
65924
+ kind: "memory-only",
65925
+ reason: "durable_rollout_pending"
65926
+ },
65927
+ resolveEventOccurrence: {
65928
+ kind: "memory-only",
65929
+ reason: "durable_rollout_pending"
65930
+ },
65931
+ checkRedirect: {
65932
+ kind: "memory-only",
65933
+ reason: "durable_rollout_pending"
65934
+ },
65935
+ getRoutableContent: {
65936
+ kind: "live-only",
65937
+ reason: "auth_required"
65938
+ },
65939
+ getPublicRoutableContent: {
65940
+ kind: "memory-only",
65941
+ reason: "durable_rollout_pending"
65942
+ },
65943
+ getPublicSitemapRoutes: {
65944
+ kind: "memory-only",
65945
+ reason: "durable_rollout_pending"
65946
+ }
65947
+ };
65948
+ var PUBLIC_ENDPOINT_NAME_SET = new Set(PUBLIC_ENDPOINT_NAMES2);
65949
+ function isPublicEndpointName(endpoint) {
65950
+ return PUBLIC_ENDPOINT_NAME_SET.has(endpoint);
65951
+ }
65952
+ function isTruthyParam(value) {
65953
+ return value === true || value === "true" || value === 1 || value === "1";
65954
+ }
65955
+ function isPreviewRequest(endpoint, params) {
65956
+ if (endpoint === "getContentByPath") {
65957
+ return isTruthyParam(params.preview);
65958
+ }
65959
+ if (endpoint === "listPublishedEntries" || endpoint === "resolveEntrySubroute" || endpoint === "resolveEventOccurrence") {
65960
+ return params.stage === "preview";
65961
+ }
65962
+ return false;
65963
+ }
65964
+ function getEndpointFreshTtlSec(endpoint) {
65965
+ return API_ENDPOINTS2[endpoint].revalidate ?? DEFAULT_MEMORY_TTL_SEC;
65966
+ }
65967
+ function assertNever5(value) {
65968
+ throw new Error(`Unhandled runtime cache policy override: ${String(value)}`);
65969
+ }
65970
+ function resolveKnownEndpointPolicy(endpoint, params) {
65971
+ if (isPreviewRequest(endpoint, params)) {
65972
+ return { kind: "live-only", endpoint, reason: "preview_request" };
65973
+ }
65974
+ if (endpoint === "getSite" && isTruthyParam(params.force)) {
65975
+ return { kind: "live-only", endpoint, reason: "force_refresh" };
65976
+ }
65977
+ const override = RUNTIME_CACHE_DURABILITY_OVERRIDES[endpoint];
65978
+ if (override.kind === "live-only") {
65979
+ return { kind: "live-only", endpoint, reason: override.reason };
65980
+ }
65981
+ const endpointDefinition = API_ENDPOINTS2[endpoint];
65982
+ if (endpointDefinition.method !== "GET") {
65983
+ return { kind: "live-only", endpoint, reason: "non_get_request" };
65984
+ }
65985
+ if (endpointDefinition.auth === "user") {
65986
+ return { kind: "live-only", endpoint, reason: "auth_required" };
65987
+ }
65988
+ switch (override.kind) {
65989
+ case "durable-public-stale":
65990
+ return {
65991
+ kind: "durable-public-stale",
65992
+ endpoint,
65993
+ freshTtlSec: getEndpointFreshTtlSec(endpoint),
65994
+ staleTtlSec: override.staleTtlSec
65995
+ };
65996
+ case "memory-only":
65997
+ return {
65998
+ kind: "memory-only",
65999
+ endpoint,
66000
+ freshTtlSec: getEndpointFreshTtlSec(endpoint),
66001
+ reason: override.reason
66002
+ };
66003
+ default:
66004
+ return assertNever5(override);
66005
+ }
66006
+ }
66007
+ function resolveRuntimeCachePolicy(input) {
66008
+ if (input.method && input.method.toUpperCase() !== "GET") {
66009
+ return {
66010
+ kind: "live-only",
66011
+ endpoint: input.endpoint,
66012
+ reason: "non_get_request"
66013
+ };
66014
+ }
66015
+ if (!isPublicEndpointName(input.endpoint)) {
66016
+ return {
66017
+ kind: "live-only",
66018
+ endpoint: input.endpoint,
66019
+ reason: "unknown_endpoint"
66020
+ };
66021
+ }
66022
+ return resolveKnownEndpointPolicy(input.endpoint, input.params ?? {});
66023
+ }
66024
+ function toNonEmptyString(value) {
66025
+ if (value === null || value === void 0) return null;
66026
+ if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") {
66027
+ return null;
66028
+ }
66029
+ const normalized = String(value).trim();
66030
+ return normalized.length > 0 ? normalized : null;
66031
+ }
66032
+ function normalizeRuntimePublicPath(value) {
66033
+ const raw = toNonEmptyString(value) ?? "/";
66034
+ const withoutQuery = raw.split(/[?#]/, 1)[0] ?? "/";
66035
+ const withLeadingSlash = withoutQuery.startsWith("/") ? withoutQuery : `/${withoutQuery}`;
66036
+ const collapsed = withLeadingSlash.replace(/\/{2,}/g, "/");
66037
+ const withoutTrailingSlash = collapsed.length > 1 ? collapsed.replace(/\/+$/g, "") : collapsed;
66038
+ return withoutTrailingSlash || "/";
66039
+ }
66040
+ function normalizeRuntimeHostname(value) {
66041
+ const trimmed = value.trim().toLowerCase();
66042
+ const url = /^[a-z][a-z0-9+.-]*:\/\//.test(trimmed) ? new URL(trimmed) : new URL(`http://${trimmed}`);
66043
+ return url.hostname.replace(/\.$/, "");
66044
+ }
66045
+ function normalizeScalar(value) {
66046
+ return value.trim().toLowerCase();
66047
+ }
66048
+ function encodeKeyPart(key, value) {
66049
+ return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
66050
+ }
66051
+ function unsafeAsPublishedRuntimeCacheKey(value) {
66052
+ return value;
66053
+ }
66054
+ function buildPublishedRuntimeCacheKey(endpoint, normalizedParams) {
66055
+ const encodedParams = Object.entries(normalizedParams).sort(([left], [right]) => left.localeCompare(right)).map(([key, value]) => encodeKeyPart(key, value)).join(":");
66056
+ return unsafeAsPublishedRuntimeCacheKey(
66057
+ `published-runtime:v1:${endpoint}:${encodedParams}`
66058
+ );
66059
+ }
66060
+ function selectSiteRuntimeIdentity(params) {
66061
+ const slug = toNonEmptyString(params.slug);
66062
+ if (slug !== null) return { slug: normalizeScalar(slug) };
66063
+ const domain = toNonEmptyString(params.domain);
66064
+ if (domain !== null) return { domain: normalizeRuntimeHostname(domain) };
66065
+ const id = toNonEmptyString(params.id);
66066
+ if (id !== null) return { id: normalizeScalar(id) };
66067
+ return null;
66068
+ }
66069
+ function deriveGetSiteKey(params) {
66070
+ const identity = selectSiteRuntimeIdentity(params);
66071
+ if (identity === null) {
66072
+ return {
66073
+ ok: false,
66074
+ error: {
66075
+ kind: "missing_site_identity",
66076
+ acceptedParams: ["slug", "domain", "id"]
66077
+ }
66078
+ };
66079
+ }
66080
+ const normalizedParams = {
66081
+ ...identity,
66082
+ currentPath: normalizeRuntimePublicPath(params.currentPath)
66083
+ };
66084
+ return {
66085
+ ok: true,
66086
+ endpoint: "getSite",
66087
+ key: buildPublishedRuntimeCacheKey("getSite", normalizedParams),
66088
+ normalizedParams
66089
+ };
66090
+ }
66091
+ function deriveGetContentByPathKey(params) {
66092
+ const siteId = toNonEmptyString(params.siteId);
66093
+ if (siteId === null) {
66094
+ return {
66095
+ ok: false,
66096
+ error: {
66097
+ kind: "missing_required_param",
66098
+ endpoint: "getContentByPath",
66099
+ param: "siteId"
66100
+ }
66101
+ };
66102
+ }
66103
+ const normalizedParams = {
66104
+ siteId: normalizeScalar(siteId),
66105
+ path: normalizeRuntimePublicPath(params.path)
66106
+ };
66107
+ return {
66108
+ ok: true,
66109
+ endpoint: "getContentByPath",
66110
+ key: buildPublishedRuntimeCacheKey("getContentByPath", normalizedParams),
66111
+ normalizedParams
66112
+ };
66113
+ }
66114
+ var DURABLE_RUNTIME_CACHE_KEY_DERIVERS = {
66115
+ getSite: deriveGetSiteKey,
66116
+ getContentByPath: deriveGetContentByPathKey
66117
+ };
66118
+ function derivePublishedRuntimeCacheKey(input) {
66119
+ const policy = resolveRuntimeCachePolicy({
66120
+ endpoint: input.endpoint,
66121
+ method: "GET",
66122
+ params: input.params
66123
+ });
66124
+ if (policy.kind !== "durable-public-stale") {
66125
+ return {
66126
+ ok: false,
66127
+ error: { kind: "not_durable_eligible", policy }
66128
+ };
66129
+ }
66130
+ switch (input.endpoint) {
66131
+ case "getSite":
66132
+ return DURABLE_RUNTIME_CACHE_KEY_DERIVERS.getSite(input.params);
66133
+ case "getContentByPath":
66134
+ return DURABLE_RUNTIME_CACHE_KEY_DERIVERS.getContentByPath(input.params);
66135
+ }
66136
+ }
66137
+
65331
66138
  // src/client/resilience.ts
65332
66139
  var DEFAULT_RETRY_CONFIG2 = {
65333
66140
  maxAttempts: 3,
@@ -65637,12 +66444,57 @@ setSdkVersion(SDK_VERSION);
65637
66444
  var DEFAULT_BROWSER_TIMEOUT_MS = 5e3;
65638
66445
  var DEFAULT_SERVER_TIMEOUT_MS = 8e3;
65639
66446
  var MAX_GET_ENTRIES_BY_IDENTIFIERS_REFS = 50;
66447
+ function isDurableRuntimeCacheTier(cacheTier) {
66448
+ return cacheTier === "durable-fresh" || cacheTier === "durable-stale";
66449
+ }
66450
+ function isDegradedResilienceStatus(source, details) {
66451
+ return source === "stale" || source === "error" || isDurableRuntimeCacheTier(details.cacheTier) && details.error !== void 0;
66452
+ }
65640
66453
  function generateRequestId2() {
65641
66454
  return `req-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
65642
66455
  }
65643
66456
  function toRecord(value) {
65644
66457
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
65645
66458
  }
66459
+ function getRuntimePayloadSiteId(value) {
66460
+ const site = toRecord(value).site;
66461
+ if (!site || typeof site !== "object" || Array.isArray(site)) {
66462
+ return null;
66463
+ }
66464
+ const id = site.id;
66465
+ return typeof id === "string" && id.trim().length > 0 ? id : null;
66466
+ }
66467
+ function getRiverbankErrorInfo(error) {
66468
+ if (error instanceof RiverbankApiError) {
66469
+ return { code: error.code, message: error.message, status: error.status };
66470
+ }
66471
+ if (error instanceof Error) {
66472
+ return { message: error.message };
66473
+ }
66474
+ return { message: String(error) };
66475
+ }
66476
+ function planPublishedRuntimeCache(input) {
66477
+ const policy = resolveRuntimeCachePolicy({
66478
+ endpoint: input.endpoint,
66479
+ method: "GET",
66480
+ params: input.params
66481
+ });
66482
+ if (policy.kind !== "durable-public-stale") {
66483
+ return null;
66484
+ }
66485
+ const keyResult = derivePublishedRuntimeCacheKey(input);
66486
+ if (!keyResult.ok) {
66487
+ return null;
66488
+ }
66489
+ return {
66490
+ cacheKey: keyResult.key,
66491
+ endpoint: keyResult.endpoint,
66492
+ normalizedParams: keyResult.normalizedParams,
66493
+ freshTtlSec: policy.freshTtlSec,
66494
+ staleTtlSec: policy.staleTtlSec,
66495
+ siteId: input.siteId ?? null
66496
+ };
66497
+ }
65646
66498
  function normalizeEntryIdentifierRefs(identifiers) {
65647
66499
  const trimmed = identifiers.map((identifier) => identifier.trim()).filter((identifier) => identifier.length > 0);
65648
66500
  if (trimmed.length === 0) {
@@ -65876,6 +66728,8 @@ function createRiverbankClient(config2) {
65876
66728
  source,
65877
66729
  isPreview: details.isPreview,
65878
66730
  cacheKey: details.cacheKey,
66731
+ cacheTier: details.cacheTier,
66732
+ durableCache: details.durableCache,
65879
66733
  error: details.error,
65880
66734
  staleAgeSec: details.staleAgeSec,
65881
66735
  prebuildAgeSec: details.prebuildAgeSec,
@@ -65885,7 +66739,7 @@ function createRiverbankClient(config2) {
65885
66739
  };
65886
66740
  lastStatus = status;
65887
66741
  config2.resilience?.onStatusChange?.(status);
65888
- const nowDegraded = source === "stale" || source === "error";
66742
+ const nowDegraded = isDegradedResilienceStatus(source, details);
65889
66743
  if (nowDegraded !== isDegraded) {
65890
66744
  isDegraded = nowDegraded;
65891
66745
  config2.resilience?.onDegradedMode?.(nowDegraded, status);
@@ -65895,6 +66749,80 @@ function createRiverbankClient(config2) {
65895
66749
  resilience: status
65896
66750
  };
65897
66751
  }
66752
+ async function tryPublishedRuntimeCacheFallback(plan, statusDetails, errorInfo) {
66753
+ const reader = config2.publishedRuntimeCache?.read;
66754
+ if (!plan || !reader) {
66755
+ return null;
66756
+ }
66757
+ try {
66758
+ const result = await reader({
66759
+ cacheKey: plan.cacheKey,
66760
+ endpoint: plan.endpoint,
66761
+ payloadSchemaVersion: DEFAULT_PUBLISHED_RUNTIME_CACHE_PAYLOAD_SCHEMA_VERSION
66762
+ });
66763
+ if (result.kind === "miss") {
66764
+ return {
66765
+ kind: "miss",
66766
+ diagnostic: {
66767
+ outcome: "miss",
66768
+ reason: result.reason
66769
+ }
66770
+ };
66771
+ }
66772
+ if (result.kind === "error") {
66773
+ return {
66774
+ kind: "error",
66775
+ diagnostic: {
66776
+ outcome: "error",
66777
+ error: result.error
66778
+ }
66779
+ };
66780
+ }
66781
+ return {
66782
+ kind: "hit",
66783
+ result: emitStatus(
66784
+ result.freshness === "fresh" ? "cache" : "stale",
66785
+ result.payload,
66786
+ statusDetails({
66787
+ error: errorInfo,
66788
+ staleAgeSec: result.staleAgeSec,
66789
+ cacheTier: result.freshness === "fresh" ? "durable-fresh" : "durable-stale"
66790
+ })
66791
+ )
66792
+ };
66793
+ } catch (error) {
66794
+ return {
66795
+ kind: "error",
66796
+ diagnostic: {
66797
+ outcome: "error",
66798
+ error: {
66799
+ kind: "adapter_exception",
66800
+ message: error instanceof Error ? error.message : String(error)
66801
+ }
66802
+ }
66803
+ };
66804
+ }
66805
+ }
66806
+ async function writePublishedRuntimeCache(plan, payload) {
66807
+ const writer = config2.publishedRuntimeCache?.write;
66808
+ if (!plan || !writer) {
66809
+ return;
66810
+ }
66811
+ try {
66812
+ await writer({
66813
+ cacheKey: plan.cacheKey,
66814
+ endpoint: plan.endpoint,
66815
+ normalizedParams: plan.normalizedParams,
66816
+ payload,
66817
+ siteId: plan.siteId ?? getRuntimePayloadSiteId(payload),
66818
+ freshTtlSec: plan.freshTtlSec,
66819
+ staleTtlSec: plan.staleTtlSec,
66820
+ payloadSchemaVersion: DEFAULT_PUBLISHED_RUNTIME_CACHE_PAYLOAD_SCHEMA_VERSION,
66821
+ writeReason: "live_success"
66822
+ });
66823
+ } catch {
66824
+ }
66825
+ }
65898
66826
  async function resilientFetch(cacheKey, fetcher, options) {
65899
66827
  const requestId = generateRequestId2();
65900
66828
  const startTime = Date.now();
@@ -65910,7 +66838,11 @@ function createRiverbankClient(config2) {
65910
66838
  if (cacheEnabled && !options.force) {
65911
66839
  const fresh = cache.getFresh(cacheKey);
65912
66840
  if (fresh !== null) {
65913
- return emitStatus("cache", fresh, statusDetails());
66841
+ return emitStatus(
66842
+ "cache",
66843
+ fresh,
66844
+ statusDetails({ cacheTier: "memory-fresh" })
66845
+ );
65914
66846
  }
65915
66847
  }
65916
66848
  if (resilienceEnabled && circuitBreaker.isOpen()) {
@@ -65922,6 +66854,7 @@ function createRiverbankClient(config2) {
65922
66854
  stale.value,
65923
66855
  statusDetails({
65924
66856
  staleAgeSec: stale.staleAgeSec,
66857
+ cacheTier: "memory-stale",
65925
66858
  error: {
65926
66859
  code: "circuit_open",
65927
66860
  message: "Circuit breaker is open"
@@ -65930,6 +66863,15 @@ function createRiverbankClient(config2) {
65930
66863
  );
65931
66864
  }
65932
66865
  }
66866
+ const durableFallback = allowFallbacks && !isPreview ? await tryPublishedRuntimeCacheFallback(
66867
+ options.publishedRuntimeCache,
66868
+ statusDetails,
66869
+ { code: "circuit_open", message: "Circuit breaker is open" }
66870
+ ) : null;
66871
+ const durableCache = durableFallback?.kind === "miss" || durableFallback?.kind === "error" ? durableFallback.diagnostic : void 0;
66872
+ if (durableFallback?.kind === "hit") {
66873
+ return durableFallback.result;
66874
+ }
65933
66875
  if (allowFallbacks && !isPreview && options.prebuildFallback) {
65934
66876
  const prebuildResult = options.prebuildFallback();
65935
66877
  if (prebuildResult) {
@@ -65938,6 +66880,8 @@ function createRiverbankClient(config2) {
65938
66880
  prebuildResult.data,
65939
66881
  statusDetails({
65940
66882
  prebuildAgeSec: prebuildResult.prebuildAgeSec,
66883
+ cacheTier: "prebuild",
66884
+ durableCache,
65941
66885
  error: {
65942
66886
  code: "circuit_open",
65943
66887
  message: "Circuit breaker is open"
@@ -65951,6 +66895,7 @@ function createRiverbankClient(config2) {
65951
66895
  "error",
65952
66896
  null,
65953
66897
  statusDetails({
66898
+ durableCache,
65954
66899
  error: { code: "circuit_open", message: "Circuit breaker is open" }
65955
66900
  })
65956
66901
  );
@@ -65991,6 +66936,9 @@ function createRiverbankClient(config2) {
65991
66936
  if (cacheEnabled) {
65992
66937
  cache.set(cacheKey, data);
65993
66938
  }
66939
+ if (allowFallbacks && !isPreview) {
66940
+ await writePublishedRuntimeCache(options.publishedRuntimeCache, data);
66941
+ }
65994
66942
  return emitStatus("live", data, statusDetails());
65995
66943
  } catch (error) {
65996
66944
  if (resilienceEnabled && error instanceof Error) {
@@ -65999,44 +66947,47 @@ function createRiverbankClient(config2) {
65999
66947
  if (allowFallbacks && !isPreview && staleIfError && cacheEnabled) {
66000
66948
  const stale = cache.getStale(cacheKey);
66001
66949
  if (stale) {
66002
- const errorInfo2 = error instanceof RiverbankApiError ? {
66003
- code: error.code,
66004
- message: error.message,
66005
- status: error.status
66006
- } : { message: error.message };
66950
+ const errorInfo2 = getRiverbankErrorInfo(error);
66007
66951
  return emitStatus(
66008
66952
  "stale",
66009
66953
  stale.value,
66010
66954
  statusDetails({
66011
66955
  staleAgeSec: stale.staleAgeSec,
66956
+ cacheTier: "memory-stale",
66012
66957
  error: errorInfo2
66013
66958
  })
66014
66959
  );
66015
66960
  }
66016
66961
  }
66962
+ const errorInfo = getRiverbankErrorInfo(error);
66963
+ const durableFallback = allowFallbacks && !isPreview ? await tryPublishedRuntimeCacheFallback(
66964
+ options.publishedRuntimeCache,
66965
+ statusDetails,
66966
+ errorInfo
66967
+ ) : null;
66968
+ const durableCache = durableFallback?.kind === "miss" || durableFallback?.kind === "error" ? durableFallback.diagnostic : void 0;
66969
+ if (durableFallback?.kind === "hit") {
66970
+ return durableFallback.result;
66971
+ }
66017
66972
  if (allowFallbacks && !isPreview && options.prebuildFallback) {
66018
66973
  const prebuildResult = options.prebuildFallback();
66019
66974
  if (prebuildResult) {
66020
- const errorInfo2 = error instanceof RiverbankApiError ? {
66021
- code: error.code,
66022
- message: error.message,
66023
- status: error.status
66024
- } : { message: error.message };
66025
66975
  return emitStatus(
66026
66976
  "prebuild",
66027
66977
  prebuildResult.data,
66028
66978
  statusDetails({
66029
66979
  prebuildAgeSec: prebuildResult.prebuildAgeSec,
66030
- error: errorInfo2
66980
+ cacheTier: "prebuild",
66981
+ durableCache,
66982
+ error: errorInfo
66031
66983
  })
66032
66984
  );
66033
66985
  }
66034
66986
  }
66035
- const errorInfo = error instanceof RiverbankApiError ? { code: error.code, message: error.message, status: error.status } : { message: error.message };
66036
66987
  const failure = emitStatus(
66037
66988
  "error",
66038
66989
  null,
66039
- statusDetails({ error: errorInfo })
66990
+ statusDetails({ error: errorInfo, durableCache })
66040
66991
  );
66041
66992
  throw attachResilienceStatusToError(error, failure.resilience);
66042
66993
  }
@@ -66086,8 +67037,12 @@ function createRiverbankClient(config2) {
66086
67037
  );
66087
67038
  }
66088
67039
  const siteIdentifier = slug || domain || id;
66089
- const cacheKey = `site:${siteIdentifier ?? "unknown"}:${currentPath ?? ""}`;
66090
67040
  const siteId = id || slug || domain;
67041
+ const publishedRuntimeCache = planPublishedRuntimeCache({
67042
+ endpoint: "getSite",
67043
+ params: { slug, domain, id, currentPath, force }
67044
+ });
67045
+ const cacheKey = publishedRuntimeCache?.cacheKey ?? `site:${siteIdentifier ?? "unknown"}:${currentPath ?? ""}`;
66091
67046
  return resilientFetch(
66092
67047
  cacheKey,
66093
67048
  async (sig) => {
@@ -66110,27 +67065,34 @@ function createRiverbankClient(config2) {
66110
67065
  {
66111
67066
  signal,
66112
67067
  force,
67068
+ publishedRuntimeCache,
66113
67069
  prebuildFallback: prebuildLoader && siteId ? () => prebuildLoader.loadSite(siteId) : void 0
66114
67070
  }
66115
67071
  );
66116
67072
  }
66117
67073
  async function getPageWithResilienceInternal(params) {
66118
- const { siteId, path: path27, preview = false, signal } = params;
66119
- const cacheKey = `page:${siteId}:${path27}:${preview}`;
67074
+ const { siteId, path: path28, preview = false, signal } = params;
67075
+ const publishedRuntimeCache = planPublishedRuntimeCache({
67076
+ endpoint: "getContentByPath",
67077
+ params: { siteId, path: path28, preview },
67078
+ siteId
67079
+ });
67080
+ const cacheKey = publishedRuntimeCache?.cacheKey ?? `page:${siteId}:${path28}:${preview}`;
66120
67081
  return resilientFetch(
66121
67082
  cacheKey,
66122
67083
  async (sig) => {
66123
67084
  return await apiClient({
66124
67085
  endpoint: "getContentByPath",
66125
- params: { siteId, path: path27, preview: String(preview) },
67086
+ params: { siteId, path: path28, preview: String(preview) },
66126
67087
  options: { signal: sig }
66127
67088
  });
66128
67089
  },
66129
67090
  {
66130
67091
  preview,
66131
67092
  signal,
67093
+ publishedRuntimeCache,
66132
67094
  // Prebuild fallback only for published pages (not preview)
66133
- prebuildFallback: prebuildLoader && !preview ? () => prebuildLoader.loadPage(siteId, path27) : void 0
67095
+ prebuildFallback: prebuildLoader && !preview ? () => prebuildLoader.loadPage(siteId, path28) : void 0
66134
67096
  }
66135
67097
  );
66136
67098
  }
@@ -66590,17 +67552,17 @@ function createRiverbankClient(config2) {
66590
67552
  };
66591
67553
  },
66592
67554
  async checkRedirect(params) {
66593
- const { siteId, path: path27, signal } = params;
66594
- if (!siteId || !path27) {
67555
+ const { siteId, path: path28, signal } = params;
67556
+ if (!siteId || !path28) {
66595
67557
  throw new Error("checkRedirect() requires siteId and path");
66596
67558
  }
66597
- const cacheKey = `redirect:${siteId}:${path27}`;
67559
+ const cacheKey = `redirect:${siteId}:${path28}`;
66598
67560
  return resilientFetchData(
66599
67561
  cacheKey,
66600
67562
  async (sig) => {
66601
67563
  return await apiClient({
66602
67564
  endpoint: "checkRedirect",
66603
- params: { site: siteId, path: path27 },
67565
+ params: { site: siteId, path: path28 },
66604
67566
  options: { signal: sig }
66605
67567
  });
66606
67568
  },
@@ -67010,7 +67972,7 @@ async function loadDeployConfig() {
67010
67972
  }
67011
67973
  async function checkWorkingDirectoryClean(git, prebuildOutput) {
67012
67974
  const status = await git.status();
67013
- const dirtyFiles = status.files.map((f) => f.path).filter((path27) => !path27.startsWith(prebuildOutput));
67975
+ const dirtyFiles = status.files.map((f) => f.path).filter((path28) => !path28.startsWith(prebuildOutput));
67014
67976
  return {
67015
67977
  clean: dirtyFiles.length === 0,
67016
67978
  dirtyFiles
@@ -67541,25 +68503,25 @@ function mapMediaGuardDiagnosticsToAuditIssues(diagnostics) {
67541
68503
  }
67542
68504
  }));
67543
68505
  }
67544
- function extractEmbedReferences(data, path27 = []) {
68506
+ function extractEmbedReferences(data, path28 = []) {
67545
68507
  const refs = [];
67546
68508
  if (!data || typeof data !== "object") return refs;
67547
68509
  if (Array.isArray(data)) {
67548
68510
  data.forEach((item, index) => {
67549
- refs.push(...extractEmbedReferences(item, [...path27, String(index)]));
68511
+ refs.push(...extractEmbedReferences(item, [...path28, String(index)]));
67550
68512
  });
67551
68513
  return refs;
67552
68514
  }
67553
68515
  const obj = data;
67554
68516
  if (obj.kind === "embed" && typeof obj.contentType === "string" && typeof obj.identifier === "string") {
67555
68517
  refs.push({
67556
- path: path27.join("."),
68518
+ path: path28.join("."),
67557
68519
  contentType: obj.contentType,
67558
68520
  identifier: obj.identifier
67559
68521
  });
67560
68522
  }
67561
68523
  for (const [key, value] of Object.entries(obj)) {
67562
- refs.push(...extractEmbedReferences(value, [...path27, key]));
68524
+ refs.push(...extractEmbedReferences(value, [...path28, key]));
67563
68525
  }
67564
68526
  return refs;
67565
68527
  }
@@ -68493,7 +69455,7 @@ function formatThemeSummaryForPrompt(summary) {
68493
69455
  }
68494
69456
 
68495
69457
  // src/manifest/validation/layout-utils.ts
68496
- function collectLayoutNodeInfos(node, path27 = "layout", out = []) {
69458
+ function collectLayoutNodeInfos(node, path28 = "layout", out = []) {
68497
69459
  if (!node || typeof node !== "object") return out;
68498
69460
  const n = node;
68499
69461
  const type = typeof n.type === "string" ? n.type : "unknown";
@@ -68502,10 +69464,10 @@ function collectLayoutNodeInfos(node, path27 = "layout", out = []) {
68502
69464
  const b = n.$bind;
68503
69465
  if (typeof b.from === "string") bindFrom = b.from;
68504
69466
  }
68505
- out.push({ path: path27, type, bindFrom });
69467
+ out.push({ path: path28, type, bindFrom });
68506
69468
  if (Array.isArray(n.children)) {
68507
69469
  for (let i = 0; i < n.children.length; i++) {
68508
- collectLayoutNodeInfos(n.children[i], `${path27}.children[${i}]`, out);
69470
+ collectLayoutNodeInfos(n.children[i], `${path28}.children[${i}]`, out);
68509
69471
  }
68510
69472
  }
68511
69473
  return out;
@@ -68927,7 +69889,7 @@ function extractNestedHrefBindFromProps(props2) {
68927
69889
  const bind2 = href.$bind;
68928
69890
  return bind2 && typeof bind2 === "object" ? bind2 : null;
68929
69891
  }
68930
- function findMissingLinkHrefs(node, blockId, fields3, path27 = "layout", repeatStack = []) {
69892
+ function findMissingLinkHrefs(node, blockId, fields3, path28 = "layout", repeatStack = []) {
68931
69893
  const errors = [];
68932
69894
  if (!node || typeof node !== "object") return errors;
68933
69895
  const n = node;
@@ -68956,21 +69918,21 @@ function findMissingLinkHrefs(node, blockId, fields3, path27 = "layout", repeatS
68956
69918
  if (isBoundToLinkField) {
68957
69919
  if (!hrefBind || !hrefFrom) {
68958
69920
  errors.push({
68959
- path: path27,
68960
- message: `Block "${blockId}": ${nodeType} node at ${path27} is bound to a link field but is missing props.href binding`,
69921
+ path: path28,
69922
+ message: `Block "${blockId}": ${nodeType} node at ${path28} is bound to a link field but is missing props.href binding`,
68961
69923
  suggestion: `Add props.href: { "$bind": { "from": "${bindFrom ?? "content.yourLinkField"}", "fallback": null, "transforms": [{ "id": "links.resolve" }] } }`
68962
69924
  });
68963
69925
  } else if (!bindingHasTransform(hrefBind, "links.resolve")) {
68964
69926
  errors.push({
68965
- path: path27,
68966
- message: `Block "${blockId}": ${nodeType} node at ${path27} has props.href binding but is missing transforms: [{id:"links.resolve"}]`,
69927
+ path: path28,
69928
+ message: `Block "${blockId}": ${nodeType} node at ${path28} has props.href binding but is missing transforms: [{id:"links.resolve"}]`,
68967
69929
  suggestion: `Set props.href.$bind.transforms to [{ "id": "links.resolve" }].`
68968
69930
  });
68969
69931
  }
68970
69932
  if (bindFrom && bindFieldType === "link" && !bindingHasTransform(bind2, "links.label")) {
68971
69933
  errors.push({
68972
- path: path27,
68973
- message: `Block "${blockId}": ${nodeType} node at ${path27} binds label from a link field but is missing links.label transform`,
69934
+ path: path28,
69935
+ message: `Block "${blockId}": ${nodeType} node at ${path28} binds label from a link field but is missing links.label transform`,
68974
69936
  suggestion: `Set node.$bind.transforms to [{ "id": "links.label" }] so the label renders as text.`
68975
69937
  });
68976
69938
  }
@@ -68983,7 +69945,7 @@ function findMissingLinkHrefs(node, blockId, fields3, path27 = "layout", repeatS
68983
69945
  n.children[i],
68984
69946
  blockId,
68985
69947
  fields3,
68986
- `${path27}.children[${i}]`,
69948
+ `${path28}.children[${i}]`,
68987
69949
  nextRepeatStack
68988
69950
  )
68989
69951
  );
@@ -68991,7 +69953,7 @@ function findMissingLinkHrefs(node, blockId, fields3, path27 = "layout", repeatS
68991
69953
  }
68992
69954
  return errors;
68993
69955
  }
68994
- function detectRedundantLinkLabels(node, blockId, fields3, path27 = "layout", repeatStack = []) {
69956
+ function detectRedundantLinkLabels(node, blockId, fields3, path28 = "layout", repeatStack = []) {
68995
69957
  const errors = [];
68996
69958
  if (!node || typeof node !== "object") return errors;
68997
69959
  const n = node;
@@ -69013,7 +69975,7 @@ function detectRedundantLinkLabels(node, blockId, fields3, path27 = "layout", re
69013
69975
  const redundancies = findRedundantLinkTextSiblings(
69014
69976
  children,
69015
69977
  nextRepeatStack,
69016
- path27
69978
+ path28
69017
69979
  );
69018
69980
  errors.push(
69019
69981
  ...redundancies.map((r) => ({
@@ -69030,7 +69992,7 @@ function detectRedundantLinkLabels(node, blockId, fields3, path27 = "layout", re
69030
69992
  n.children[i],
69031
69993
  blockId,
69032
69994
  fields3,
69033
- `${path27}.children[${i}]`,
69995
+ `${path28}.children[${i}]`,
69034
69996
  nextRepeatStack
69035
69997
  )
69036
69998
  );
@@ -69269,19 +70231,19 @@ function extractBlockIdFromSelector(selector) {
69269
70231
  const match = selector.match(/\[data-block=(["'])(custom\.[^"']+)\1\]/);
69270
70232
  return match?.[2] ?? null;
69271
70233
  }
69272
- function validateNodeType(nodeType, path27, ctx) {
70234
+ function validateNodeType(nodeType, path28, ctx) {
69273
70235
  if (!ALLOWED_NODE_TYPES.includes(
69274
70236
  nodeType
69275
70237
  )) {
69276
70238
  return {
69277
- path: `${path27}.type`,
69278
- message: `Block "${ctx.blockId}": Unknown node type "${nodeType}" at ${path27}`,
70239
+ path: `${path28}.type`,
70240
+ message: `Block "${ctx.blockId}": Unknown node type "${nodeType}" at ${path28}`,
69279
70241
  suggestion: `ALLOWED: ${ALLOWED_NODE_TYPES.slice(0, 10).join(", ")}... FIX: Replace "${nodeType}" with a valid node type.`
69280
70242
  };
69281
70243
  }
69282
70244
  return null;
69283
70245
  }
69284
- function validateTransforms(transforms, path27, ctx) {
70246
+ function validateTransforms(transforms, path28, ctx) {
69285
70247
  const errors = [];
69286
70248
  for (let i = 0; i < transforms.length; i++) {
69287
70249
  const transform = transforms[i];
@@ -69290,7 +70252,7 @@ function validateTransforms(transforms, path27, ctx) {
69290
70252
  transform.id
69291
70253
  )) {
69292
70254
  errors.push({
69293
- path: `${path27}.transforms[${i}].id`,
70255
+ path: `${path28}.transforms[${i}].id`,
69294
70256
  message: `Block "${ctx.blockId}": Unknown transform "${transform.id}"`,
69295
70257
  suggestion: `ALLOWED: ${ALLOWED_TRANSFORM_IDS.slice(0, 8).join(", ")}... FIX: Replace with a valid transform ID or remove.`
69296
70258
  });
@@ -69299,7 +70261,7 @@ function validateTransforms(transforms, path27, ctx) {
69299
70261
  }
69300
70262
  return errors;
69301
70263
  }
69302
- function validateBinding(bind2, path27, ctx) {
70264
+ function validateBinding(bind2, path28, ctx) {
69303
70265
  const errors = [];
69304
70266
  if ("from" in bind2 && typeof bind2.from === "string") {
69305
70267
  const bindPath = bind2.from;
@@ -69307,7 +70269,7 @@ function validateBinding(bind2, path27, ctx) {
69307
70269
  const fieldId = bindPath.replace("content.", "").split(".")[0] ?? "";
69308
70270
  if (fieldId && !ctx.fieldIds.has(fieldId)) {
69309
70271
  errors.push({
69310
- path: `${path27}.from`,
70272
+ path: `${path28}.from`,
69311
70273
  message: `Block "${ctx.blockId}": $bind references unknown field "${fieldId}"`,
69312
70274
  suggestion: `DEFINED FIELDS: ${Array.from(ctx.fieldIds).join(", ")}. FIX: Add field { id: '${fieldId}', type: '...' } or use existing field.`
69313
70275
  });
@@ -69315,31 +70277,31 @@ function validateBinding(bind2, path27, ctx) {
69315
70277
  }
69316
70278
  }
69317
70279
  if ("transforms" in bind2 && Array.isArray(bind2.transforms)) {
69318
- errors.push(...validateTransforms(bind2.transforms, path27, ctx));
70280
+ errors.push(...validateTransforms(bind2.transforms, path28, ctx));
69319
70281
  }
69320
70282
  return errors;
69321
70283
  }
69322
- function validateLayoutDeep(node, blockId, fields3, path27 = "layout") {
70284
+ function validateLayoutDeep(node, blockId, fields3, path28 = "layout") {
69323
70285
  const ctx = {
69324
70286
  blockId,
69325
70287
  fieldIds: collectFieldIds(fields3)
69326
70288
  };
69327
- return validateLayoutNode(node, path27, ctx);
70289
+ return validateLayoutNode(node, path28, ctx);
69328
70290
  }
69329
- function validateLayoutNode(node, path27, ctx) {
70291
+ function validateLayoutNode(node, path28, ctx) {
69330
70292
  const errors = [];
69331
70293
  if (!node || typeof node !== "object") {
69332
70294
  return errors;
69333
70295
  }
69334
70296
  const n = node;
69335
70297
  if ("type" in n && typeof n.type === "string") {
69336
- const typeError = validateNodeType(n.type, path27, ctx);
70298
+ const typeError = validateNodeType(n.type, path28, ctx);
69337
70299
  if (typeError) errors.push(typeError);
69338
70300
  }
69339
70301
  if ("$bind" in n && n.$bind && typeof n.$bind === "object") {
69340
70302
  const bindErrors = validateBinding(
69341
70303
  n.$bind,
69342
- `${path27}.$bind`,
70304
+ `${path28}.$bind`,
69343
70305
  ctx
69344
70306
  );
69345
70307
  errors.push(...bindErrors);
@@ -69347,7 +70309,7 @@ function validateLayoutNode(node, path27, ctx) {
69347
70309
  if ("props" in n && n.props && typeof n.props === "object") {
69348
70310
  const propsErrors = validatePropsBindings(
69349
70311
  n.props,
69350
- `${path27}.props`,
70312
+ `${path28}.props`,
69351
70313
  ctx
69352
70314
  );
69353
70315
  errors.push(...propsErrors);
@@ -69356,7 +70318,7 @@ function validateLayoutNode(node, path27, ctx) {
69356
70318
  for (let i = 0; i < n.children.length; i++) {
69357
70319
  const childErrors = validateLayoutNode(
69358
70320
  n.children[i],
69359
- `${path27}.children[${i}]`,
70321
+ `${path28}.children[${i}]`,
69360
70322
  ctx
69361
70323
  );
69362
70324
  errors.push(...childErrors);
@@ -69364,17 +70326,17 @@ function validateLayoutNode(node, path27, ctx) {
69364
70326
  }
69365
70327
  return errors;
69366
70328
  }
69367
- function validatePropsBindings(props2, path27, ctx) {
70329
+ function validatePropsBindings(props2, path28, ctx) {
69368
70330
  const errors = [];
69369
70331
  for (const [key, value] of Object.entries(props2)) {
69370
70332
  if (value && typeof value === "object" && "$bind" in value) {
69371
70333
  const bind2 = value.$bind;
69372
- const bindErrors = validateBinding(bind2, `${path27}.${key}.$bind`, ctx);
70334
+ const bindErrors = validateBinding(bind2, `${path28}.${key}.$bind`, ctx);
69373
70335
  errors.push(...bindErrors);
69374
70336
  } else if (value && typeof value === "object" && !Array.isArray(value)) {
69375
70337
  const nestedErrors = validatePropsBindings(
69376
70338
  value,
69377
- `${path27}.${key}`,
70339
+ `${path28}.${key}`,
69378
70340
  ctx
69379
70341
  );
69380
70342
  errors.push(...nestedErrors);
@@ -69507,7 +70469,7 @@ function collectUsedFieldRefs(node) {
69507
70469
  visit(node, []);
69508
70470
  return { topLevel, nestedByRepeater, itemNameByRepeater };
69509
70471
  }
69510
- function findMissingBindings(node, blockId, path27 = "layout") {
70472
+ function findMissingBindings(node, blockId, path28 = "layout") {
69511
70473
  const errors = [];
69512
70474
  if (!node || typeof node !== "object") {
69513
70475
  return errors;
@@ -69517,15 +70479,15 @@ function findMissingBindings(node, blockId, path27 = "layout") {
69517
70479
  if ("$repeat" in n && n.$repeat && typeof n.$repeat === "object") {
69518
70480
  if (nodeType && CONTENT_NODE_TYPES.includes(nodeType)) {
69519
70481
  errors.push({
69520
- path: path27,
69521
- message: `Block "${blockId}": ${nodeType} node at ${path27} uses $repeat, but content nodes cannot be repeat containers`,
70482
+ path: path28,
70483
+ message: `Block "${blockId}": ${nodeType} node at ${path28} uses $repeat, but content nodes cannot be repeat containers`,
69522
70484
  suggestion: `Move $repeat to a container node (grid/stack/div) and put a ${nodeType} child inside with $bind.from like "item.field".`
69523
70485
  });
69524
70486
  }
69525
70487
  if (!Array.isArray(n.children) || n.children.length === 0) {
69526
70488
  errors.push({
69527
- path: path27,
69528
- message: `Block "${blockId}": node at ${path27} uses $repeat but has no children to repeat`,
70489
+ path: path28,
70490
+ message: `Block "${blockId}": node at ${path28} uses $repeat but has no children to repeat`,
69529
70491
  suggestion: 'Add one or more child nodes under children[] that bind to the repeat item (e.g., $bind.from: "item.text").'
69530
70492
  });
69531
70493
  }
@@ -69534,15 +70496,15 @@ function findMissingBindings(node, blockId, path27 = "layout") {
69534
70496
  const hasBind = "$bind" in n && n.$bind && typeof n.$bind === "object" && "from" in n.$bind;
69535
70497
  if (Array.isArray(n.children) && n.children.length > 0) {
69536
70498
  errors.push({
69537
- path: path27,
69538
- message: `Block "${blockId}": ${nodeType} node at ${path27} has children, but content nodes must have children: null`,
70499
+ path: path28,
70500
+ message: `Block "${blockId}": ${nodeType} node at ${path28} has children, but content nodes must have children: null`,
69539
70501
  suggestion: `Replace this ${nodeType} with a container node (div/stack/inline) and put the ${nodeType} nodes inside it.`
69540
70502
  });
69541
70503
  }
69542
70504
  if (!hasBind) {
69543
70505
  errors.push({
69544
- path: `${path27}`,
69545
- message: `Block "${blockId}": ${nodeType} node at ${path27} has no $bind - it won't display any content`,
70506
+ path: `${path28}`,
70507
+ message: `Block "${blockId}": ${nodeType} node at ${path28} has no $bind - it won't display any content`,
69546
70508
  suggestion: `Add $bind: { from: "content.fieldName" } to connect this ${nodeType} to a field. Example: { "type": "${nodeType}", "$bind": { "from": "content.headline" } }`
69547
70509
  });
69548
70510
  }
@@ -69552,7 +70514,7 @@ function findMissingBindings(node, blockId, path27 = "layout") {
69552
70514
  const childErrors = findMissingBindings(
69553
70515
  n.children[i],
69554
70516
  blockId,
69555
- `${path27}.children[${i}]`
70517
+ `${path28}.children[${i}]`
69556
70518
  );
69557
70519
  errors.push(...childErrors);
69558
70520
  }
@@ -69569,13 +70531,13 @@ function getMaxDepth(node, currentDepth = 0) {
69569
70531
  );
69570
70532
  }
69571
70533
  var CONTAINER_NODE_TYPES = ["section", "stack", "grid", "div", "inline"];
69572
- function detectPotentialTruncation(node, maxAllowedDepth, currentDepth = 0, path27 = "layout") {
70534
+ function detectPotentialTruncation(node, maxAllowedDepth, currentDepth = 0, path28 = "layout") {
69573
70535
  if (!node || typeof node !== "object") return [];
69574
70536
  const n = node;
69575
70537
  const truncatedPaths = [];
69576
70538
  if (currentDepth === maxAllowedDepth && n.children === null) {
69577
70539
  if (CONTAINER_NODE_TYPES.includes(n.type || "")) {
69578
- truncatedPaths.push(`${path27} (${n.type ?? "node"} at depth ${currentDepth})`);
70540
+ truncatedPaths.push(`${path28} (${n.type ?? "node"} at depth ${currentDepth})`);
69579
70541
  }
69580
70542
  }
69581
70543
  if (n.children && Array.isArray(n.children)) {
@@ -69585,7 +70547,7 @@ function detectPotentialTruncation(node, maxAllowedDepth, currentDepth = 0, path
69585
70547
  child,
69586
70548
  maxAllowedDepth,
69587
70549
  currentDepth + 1,
69588
- `${path27}.children[${i}]`
70550
+ `${path28}.children[${i}]`
69589
70551
  )
69590
70552
  );
69591
70553
  });
@@ -69605,8 +70567,8 @@ function formatValidationFeedback(errors, output) {
69605
70567
  `The layout reached the maximum depth of ${MAX_LAYOUT_DEPTH} levels.`
69606
70568
  );
69607
70569
  lines.push("These container nodes at the depth limit have no children:");
69608
- for (const path27 of truncatedPaths) {
69609
- lines.push(` \u26A0\uFE0F ${path27}`);
70570
+ for (const path28 of truncatedPaths) {
70571
+ lines.push(` \u26A0\uFE0F ${path28}`);
69610
70572
  }
69611
70573
  lines.push("");
69612
70574
  lines.push(
@@ -70069,11 +71031,11 @@ var pass3bOutputSchema = z.object({
70069
71031
  customCssAtRules: z.array(llmMediaAtRuleSchema).nullable(),
70070
71032
  rationale: z.string()
70071
71033
  });
70072
- function getNodeAtPath(layout, path27) {
70073
- if (path27 === "" || path27 === "root" || path27 === "layout") {
71034
+ function getNodeAtPath(layout, path28) {
71035
+ if (path28 === "" || path28 === "root" || path28 === "layout") {
70074
71036
  return layout;
70075
71037
  }
70076
- let normalizedPath = path27;
71038
+ let normalizedPath = path28;
70077
71039
  if (normalizedPath.startsWith("layout.")) {
70078
71040
  normalizedPath = normalizedPath.slice(7);
70079
71041
  }
@@ -71760,6 +72722,7 @@ var eventUpsertInputSchema = z.object({
71760
72722
  identifier: z.string().min(1).optional(),
71761
72723
  title: z.string().min(1, "title is required"),
71762
72724
  slug: z.string().min(1).optional(),
72725
+ path: z.string().startsWith("/", "path must start with /").nullable().optional(),
71763
72726
  status: z.enum(["draft", "active", "archived", "cancelled", "completed"]).optional(),
71764
72727
  visibility: z.enum(["private", "public", "unlisted"]).optional(),
71765
72728
  schedule: eventScheduleInputSchema,
@@ -71772,7 +72735,8 @@ var eventUpsertInputSchema = z.object({
71772
72735
  formRef: z.string().nullable().optional(),
71773
72736
  settings: z.record(z.string(), z.unknown()).optional(),
71774
72737
  presentation: z.record(z.string(), z.unknown()).nullable().optional(),
71775
- tags: z.array(z.string()).optional()
72738
+ tags: z.array(z.string()).optional(),
72739
+ blocks: sdkEntrySlotBlocksInputSchema.optional()
71776
72740
  });
71777
72741
  var formatEventRow = (event) => [
71778
72742
  event.identifier,
@@ -72379,9 +73343,6 @@ function mergeLegacyEventIntoCanonical(legacy, event) {
72379
73343
  unmappableFields.push(`data.${key}`);
72380
73344
  }
72381
73345
  }
72382
- if (legacy.entry.blocks && Object.keys(legacy.entry.blocks).length > 0) {
72383
- unmappableFields.push("blocks");
72384
- }
72385
73346
  if (unmappableFields.length > 0) {
72386
73347
  return { tag: "unmappable", fields: unmappableFields.sort() };
72387
73348
  }
@@ -72446,6 +73407,17 @@ function mergeLegacyEventIntoCanonical(legacy, event) {
72446
73407
  conflicts.push(result.field);
72447
73408
  }
72448
73409
  }
73410
+ const blocksResult = mergeBlocks({
73411
+ current: event.blocks,
73412
+ incoming: legacy.entry.blocks,
73413
+ set: (blocks) => ({ ...mergedEvent, blocks })
73414
+ });
73415
+ if (blocksResult.tag === "changed") {
73416
+ mergedEvent = blocksResult.event;
73417
+ mergedFields.push(...blocksResult.fields);
73418
+ } else if (blocksResult.tag === "conflict") {
73419
+ conflicts.push(...blocksResult.fields);
73420
+ }
72449
73421
  if (hasMeaningfulValue(data.presentation)) {
72450
73422
  if (!isRecord21(data.presentation)) {
72451
73423
  return { tag: "unmappable", fields: ["data.presentation"] };
@@ -72477,6 +73449,52 @@ function mergeLegacyEventIntoCanonical(legacy, event) {
72477
73449
  conflicts
72478
73450
  };
72479
73451
  }
73452
+ function mergeBlocks(input) {
73453
+ if (!hasMeaningfulValue(input.incoming)) {
73454
+ return { tag: "ignored" };
73455
+ }
73456
+ const incoming = input.incoming;
73457
+ const current = input.current;
73458
+ if (!incoming) {
73459
+ return { tag: "ignored" };
73460
+ }
73461
+ if (!current || !hasMeaningfulValue(current)) {
73462
+ return {
73463
+ tag: "changed",
73464
+ event: input.set(incoming),
73465
+ fields: Object.keys(incoming).sort().map((slotKey) => `blocks.${slotKey}`)
73466
+ };
73467
+ }
73468
+ const nextBlocks = { ...current };
73469
+ const changedFields = [];
73470
+ const conflictFields = [];
73471
+ for (const slotKey of Object.keys(incoming).sort()) {
73472
+ const incomingBlocks = incoming[slotKey] ?? [];
73473
+ const currentBlocks = current[slotKey];
73474
+ if (currentBlocks === void 0) {
73475
+ nextBlocks[slotKey] = incomingBlocks;
73476
+ changedFields.push(`blocks.${slotKey}`);
73477
+ continue;
73478
+ }
73479
+ if (!valuesMatch(currentBlocks, incomingBlocks)) {
73480
+ conflictFields.push(`blocks.${slotKey}`);
73481
+ }
73482
+ }
73483
+ if (conflictFields.length > 0) {
73484
+ return {
73485
+ tag: "conflict",
73486
+ fields: conflictFields
73487
+ };
73488
+ }
73489
+ if (changedFields.length === 0) {
73490
+ return { tag: "unchanged" };
73491
+ }
73492
+ return {
73493
+ tag: "changed",
73494
+ event: input.set(nextBlocks),
73495
+ fields: changedFields
73496
+ };
73497
+ }
72480
73498
  async function planEventMigration(contentDir) {
72481
73499
  const legacyReadResults = await readLegacyEventEntries(contentDir);
72482
73500
  const invalidLegacyItems = legacyReadResults.filter((result) => result.tag === "invalid").map((result) => ({