@riverbankcms/sdk 0.78.0 → 0.79.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 (222) hide show
  1. package/README.md +125 -43
  2. package/dist/{PreviewEditorSidebar-RIKFQ72L.mjs → PreviewEditorSidebar-56NMJMIK.mjs} +750 -65
  3. package/dist/{PreviewEditorUI-XO7TUWKK.mjs → PreviewEditorUI-27KJVEET.mjs} +4 -4
  4. package/dist/SdkPreviewModeRuntime-H4BSP6E7.mjs +8 -0
  5. package/dist/_dts/ai/src/contracts/proposals.d.ts +72 -0
  6. package/dist/_dts/api/src/contentRuntime.d.ts +1 -0
  7. package/dist/_dts/api/src/endpoints.d.ts +64 -0
  8. package/dist/_dts/api/src/index.d.ts +8 -6
  9. package/dist/_dts/api/src/media.d.ts +8 -1
  10. package/dist/_dts/api/src/navigation/dashboardSettingsNav.d.ts +1 -1
  11. package/dist/_dts/api/src/navigation/dashboardSiteNav.d.ts +8 -8
  12. package/dist/_dts/api/src/navigation/identity.d.ts +59 -0
  13. package/dist/_dts/api/src/navigation.d.ts +2 -0
  14. package/dist/_dts/api/src/public/types.d.ts +1 -1
  15. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +4 -0
  16. package/dist/_dts/api/src/request.d.ts +3 -11
  17. package/dist/_dts/api/src/sdkConfig/contracts.d.ts +1 -0
  18. package/dist/_dts/api/src/sdkContracts.d.ts +8 -1
  19. package/dist/_dts/api/src/siteIcons.d.ts +128 -0
  20. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +26 -0
  21. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +8 -0
  22. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +21 -20
  23. package/dist/_dts/api/src/types.d.ts +12 -27
  24. package/dist/_dts/api/src/webhooks.d.ts +239 -0
  25. package/dist/_dts/block-form/src/fields/types.d.ts +6 -0
  26. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterList.d.ts +3 -2
  27. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterRow.d.ts +6 -3
  28. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterRowActions.d.ts +8 -3
  29. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/index.d.ts +1 -1
  30. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/useLinearRepeaterDnd.d.ts +1 -0
  31. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/useRepeaterPointerDragCapability.d.ts +1 -0
  32. package/dist/_dts/block-form/src/widgets/RepeaterField/hooks/useResolvedItemLabel.d.ts +7 -0
  33. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/buildSummary.d.ts +1 -0
  34. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/index.d.ts +3 -1
  35. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/repeaterDndDomain.d.ts +1 -1
  36. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/repeaterLabelSource.d.ts +15 -0
  37. package/dist/_dts/block-form/src/widgets/RepeaterField/utils/repeaterRowActionsDomain.d.ts +50 -0
  38. package/dist/_dts/blocks/src/index.d.ts +4 -0
  39. package/dist/_dts/blocks/src/system/blocks/appointment-booking.d.ts +879 -288
  40. package/dist/_dts/blocks/src/system/blocks/blog-listing.d.ts +879 -288
  41. package/dist/_dts/blocks/src/system/blocks/cart.d.ts +879 -288
  42. package/dist/_dts/blocks/src/system/blocks/checkout.d.ts +879 -288
  43. package/dist/_dts/blocks/src/system/blocks/collection.d.ts +879 -288
  44. package/dist/_dts/blocks/src/system/blocks/faq.d.ts +885 -289
  45. package/dist/_dts/blocks/src/system/blocks/feature-card-icons.d.ts +57 -0
  46. package/dist/_dts/blocks/src/system/blocks/feature-cards.d.ts +4 -0
  47. package/dist/_dts/blocks/src/system/blocks/gifting.d.ts +879 -288
  48. package/dist/_dts/blocks/src/system/blocks/index.d.ts +1 -0
  49. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +3 -1
  50. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +69 -22
  51. package/dist/_dts/blocks/src/system/blocks/product-detail.d.ts +879 -288
  52. package/dist/_dts/blocks/src/system/blocks/product-list.d.ts +879 -288
  53. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +879 -288
  54. package/dist/_dts/blocks/src/system/blocks/team-members.d.ts +3 -0
  55. package/dist/_dts/blocks/src/system/blocks/testimonials.d.ts +7 -1
  56. package/dist/_dts/blocks/src/system/customize/backgrounds.d.ts +170 -0
  57. package/dist/_dts/blocks/src/system/fragments/library/testimonialsCarousel.d.ts +5 -0
  58. package/dist/_dts/blocks/src/system/helpers/resolveBackground.d.ts +3 -1
  59. package/dist/_dts/blocks/src/system/icons/ids.d.ts +13 -0
  60. package/dist/_dts/blocks/src/system/icons/index.d.ts +6 -0
  61. package/dist/_dts/blocks/src/system/icons/presets.d.ts +4 -0
  62. package/dist/_dts/blocks/src/system/icons/registry.d.ts +18 -0
  63. package/dist/_dts/blocks/src/system/icons/semantic.d.ts +239 -0
  64. package/dist/_dts/blocks/src/system/icons/value.d.ts +94 -0
  65. package/dist/_dts/blocks/src/system/index.d.ts +1 -0
  66. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +4 -1
  67. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +187 -0
  68. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.state.d.ts +1 -1
  69. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +1 -1
  70. package/dist/_dts/blocks/src/system/runtime/nodes/feature-card-icon.d.ts +13 -0
  71. package/dist/_dts/content-editor/src/index.d.ts +1 -1
  72. package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +2 -2
  73. package/dist/_dts/content-model/src/content-types/schema.d.ts +14 -0
  74. package/dist/_dts/content-model/src/contentManifest.d.ts +3 -1
  75. package/dist/_dts/content-model/src/templates/bindingTypeCompatibility.d.ts +3 -1
  76. package/dist/_dts/content-model/src/templates/bindingValidation.d.ts +10 -4
  77. package/dist/_dts/content-model/src/templates/fieldPaths.d.ts +20 -0
  78. package/dist/_dts/content-model/src/templates/manifestAdapter.d.ts +5 -2
  79. package/dist/_dts/core/src/branded.d.ts +114 -85
  80. package/dist/_dts/core/src/csv-types.d.ts +2 -2
  81. package/dist/_dts/core/src/editor-state.d.ts +7 -7
  82. package/dist/_dts/core/src/participants.d.ts +2 -2
  83. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +202 -0
  84. package/dist/_dts/editor-blocks/src/block-editor/BlockCard.d.ts +12 -1
  85. package/dist/_dts/editor-blocks/src/block-editor/BlockCardBody.d.ts +12 -1
  86. package/dist/_dts/editor-blocks/src/block-editor/BlockCardHeader.d.ts +12 -2
  87. package/dist/_dts/editor-blocks/src/block-editor/FeatureCardIconsPanel.d.ts +21 -0
  88. package/dist/_dts/editor-blocks/src/block-editor/GeneratedIconSetDialog.d.ts +40 -0
  89. package/dist/_dts/editor-blocks/src/block-editor/SortableBlockItem.d.ts +11 -1
  90. package/dist/_dts/editor-blocks/src/block-editor/featureCardIconActions.d.ts +82 -0
  91. package/dist/_dts/editor-blocks/src/blockPayload.d.ts +1 -1
  92. package/dist/_dts/editor-blocks/src/widgets/icon-picker/IconPickerField.d.ts +1 -1
  93. package/dist/_dts/media-core/src/fileDomain.d.ts +8 -1
  94. package/dist/_dts/media-editor/src/MediaEditor.d.ts +5 -2
  95. package/dist/_dts/media-editor/src/MediaPreview.d.ts +3 -1
  96. package/dist/_dts/media-editor/src/fieldUi.d.ts +5 -0
  97. package/dist/_dts/media-editor/src/index.d.ts +1 -1
  98. package/dist/_dts/media-react/src/components/MediaLibrary.d.ts +2 -1
  99. package/dist/_dts/media-react/src/components/MediaPickerMini.d.ts +2 -1
  100. package/dist/_dts/preview-next/src/client/blocks/previewCustomizeActions.d.ts +17 -0
  101. package/dist/_dts/preview-next/src/client/preview/PageDesignEditorStateContext.d.ts +4 -0
  102. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +3 -2
  103. package/dist/_dts/preview-next/src/client/preview/previewCustomizeHistory.d.ts +6 -0
  104. package/dist/_dts/sdk/src/cli/commands/push/consts.d.ts +1 -1
  105. package/dist/_dts/sdk/src/cli/commands/push/metadata.d.ts +2 -0
  106. package/dist/_dts/sdk/src/cli/commands/push/stale.d.ts +3 -3
  107. package/dist/_dts/sdk/src/cli/commands/push-execute.d.ts +7 -0
  108. package/dist/_dts/sdk/src/cli/commands/push.d.ts +2 -0
  109. package/dist/_dts/sdk/src/cli/content/reader.d.ts +13 -0
  110. package/dist/_dts/sdk/src/cli/content/writer.d.ts +2 -1
  111. package/dist/_dts/sdk/src/cli/helpers.d.ts +2 -0
  112. package/dist/_dts/sdk/src/cli/navigationIdentity.d.ts +11 -0
  113. package/dist/_dts/sdk/src/cli/site-commands/commandKeys.d.ts +6 -6
  114. package/dist/_dts/sdk/src/cli/site-commands/commandRuntime.d.ts +5 -0
  115. package/dist/_dts/sdk/src/cli/site-commands/commandSurfaceDispatch.d.ts +4 -0
  116. package/dist/_dts/sdk/src/cli/site-commands/navigationCommands.d.ts +4 -0
  117. package/dist/_dts/sdk/src/cli/site-commands/oneOffCommands.d.ts +1 -0
  118. package/dist/_dts/sdk/src/cli/site-commands/pageCommands.d.ts +5 -2
  119. package/dist/_dts/sdk/src/cli/site-commands/pushExecution.d.ts +10 -1
  120. package/dist/_dts/sdk/src/cli/site-commands/pushExecutionTypes.d.ts +1 -1
  121. package/dist/_dts/sdk/src/cli/sync/diff.d.ts +9 -0
  122. package/dist/_dts/sdk/src/client/management/types.d.ts +8 -0
  123. package/dist/_dts/sdk/src/client/types.d.ts +2 -2
  124. package/dist/_dts/sdk/src/config/content-types.d.ts +7 -0
  125. package/dist/_dts/sdk/src/config/field-definitions.d.ts +5 -1
  126. package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
  127. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +19 -2
  128. package/dist/_dts/sdk/src/next/index.d.ts +1 -1
  129. package/dist/_dts/sdk/src/next/revalidate.d.ts +26 -5
  130. package/dist/_dts/sdk/src/next/static-params.d.ts +28 -3
  131. package/dist/_dts/sdk/src/public-api/contracts.d.ts +5 -1
  132. package/dist/_dts/sdk/src/public-api/runtime.d.ts +1 -1
  133. package/dist/_dts/sdk/src/version.d.ts +1 -1
  134. package/dist/_dts/sdk/src/webhooks/index.d.ts +1 -1
  135. package/dist/_dts/sdk/src/webhooks/verify.d.ts +6 -102
  136. package/dist/_dts/site-commands/src/commands.d.ts +6 -0
  137. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  138. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +3 -3
  139. package/dist/_dts/theme-core/src/schema.d.ts +5 -5
  140. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +25 -2
  141. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +5 -5
  142. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +4 -2
  143. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +4 -4
  144. package/dist/_dts/theme-core/src/tokens/themeColorTokens.d.ts +2 -0
  145. package/dist/_dts/ui/src/combobox.d.ts +1 -0
  146. package/dist/{altcha-B5XGSXP5.mjs → altcha-EKUEQ4RP.mjs} +1 -1
  147. package/dist/{chunk-F7RTCZYN.mjs → chunk-4HCW7FHJ.mjs} +504 -63
  148. package/dist/{chunk-SXOLGNMX.mjs → chunk-A3HHFKVT.mjs} +1 -1
  149. package/dist/{chunk-TXDES5P2.mjs → chunk-GP555I66.mjs} +180 -10
  150. package/dist/{chunk-SVMMM2NA.mjs → chunk-K2IIF34C.mjs} +79 -5
  151. package/dist/{chunk-NIDXI46P.mjs → chunk-LCY32PXF.mjs} +1 -1
  152. package/dist/{chunk-XGB3TDIC.mjs → chunk-R7POPVJR.mjs} +2 -8
  153. package/dist/{chunk-OECWLDHN.mjs → chunk-V47ZU33I.mjs} +2762 -732
  154. package/dist/cli/index.mjs +1799 -345
  155. package/dist/cli/init-docs/content/cli-reference.md +3 -2
  156. package/dist/cli/init-docs/content/content-management.md +2 -2
  157. package/dist/cli/init-docs/content/workflow-editor-workflows.md +2 -0
  158. package/dist/cli/init-docs/content/workflow-isr-revalidation.md +138 -0
  159. package/dist/cli/init-docs/content/workflow-preview-mode.md +68 -2
  160. package/dist/client/{accordion-EVDEOUPR.mjs → accordion-QLA7KBYO.mjs} +2 -2
  161. package/dist/client/analytics.mjs +1 -1
  162. package/dist/client/{bookingForm-DIHBLC64.mjs → bookingForm-PYZIPA5G.mjs} +55 -48
  163. package/dist/client/bookings.mjs +172 -57
  164. package/dist/client/{carousel-FEBQHIWI.mjs → carousel-5EIULWBI.mjs} +3 -3
  165. package/dist/client/{cart-7CKSXAE4.mjs → cart-DOP3FNI4.mjs} +7 -7
  166. package/dist/client/{checkout-WKYCANLV.mjs → checkout-BVMF6FBV.mjs} +7 -7
  167. package/dist/client/{chunk-GUK2FPXQ.mjs → chunk-44K2U3QI.mjs} +37 -15
  168. package/dist/client/{chunk-IVNCUVAV.mjs → chunk-AUJ5DBZJ.mjs} +18 -18
  169. package/dist/client/{chunk-VPPMNXCF.mjs → chunk-CCNTDRCF.mjs} +2 -2
  170. package/dist/client/{chunk-36WJCERQ.mjs → chunk-CE7IBGVW.mjs} +3 -1
  171. package/dist/client/{chunk-2SAVKN2M.mjs → chunk-GG4M2NP6.mjs} +2 -2
  172. package/dist/client/{chunk-65F47D7Y.mjs → chunk-R5ESWNKX.mjs} +49 -39
  173. package/dist/client/{chunk-RZDWX7QW.mjs → chunk-TYONZMST.mjs} +1 -1
  174. package/dist/client/{chunk-OFMSCGNY.mjs → chunk-UDS3NTWA.mjs} +2 -2
  175. package/dist/client/{chunk-YDSEG6GZ.mjs → chunk-V6M5FCR5.mjs} +2 -2
  176. package/dist/client/{chunk-F7LHOKEH.mjs → chunk-XSV6KW4D.mjs} +1 -1
  177. package/dist/client/{chunk-RV6FX7UH.mjs → chunk-YLDYVRZL.mjs} +9 -9
  178. package/dist/client/{chunk-PD6NBCEY.mjs → chunk-ZFHRN6W2.mjs} +1 -1
  179. package/dist/client/client.mjs +21501 -19812
  180. package/dist/client/{courseRegistration-5QF2PHKM.mjs → courseRegistration-E6EAA6NL.mjs} +10 -10
  181. package/dist/client/{eventCalendar-4ZOSETDU.mjs → eventCalendar-HBG3HAK6.mjs} +9 -9
  182. package/dist/client/{eventCombined-WQGU7JUX.mjs → eventCombined-6K5ZZWAK.mjs} +9 -9
  183. package/dist/client/{eventDetails-AYWVUJ5Y.mjs → eventDetails-Q75ICXLT.mjs} +9 -9
  184. package/dist/client/{eventListing-NT7C6UT5.mjs → eventListing-27P5F7DZ.mjs} +9 -9
  185. package/dist/client/{eventRegistration-OH24F4ZJ.mjs → eventRegistration-IQ7AMASR.mjs} +9 -9
  186. package/dist/client/{form-7L42SRBB.mjs → form-JRTD65FN.mjs} +6 -3
  187. package/dist/client/{headerSection-OZRZNZ52.mjs → headerSection-7FPSSZHS.mjs} +3 -3
  188. package/dist/client/hooks.mjs +428 -83
  189. package/dist/client/{locationMap-ZBXRPQ7C.mjs → locationMap-7NGFNYBH.mjs} +3 -3
  190. package/dist/client/{newsletterForm-SNAGFF2I.mjs → newsletterForm-F3BADCI2.mjs} +2 -2
  191. package/dist/client/{productDetail-I46BOFGV.mjs → productDetail-V3HP7ITJ.mjs} +7 -7
  192. package/dist/client/{productList-BOYHTYI6.mjs → productList-L3EGJUF2.mjs} +7 -7
  193. package/dist/client/rendering/client.mjs +2886 -1513
  194. package/dist/client/rendering/islands.mjs +19 -19
  195. package/dist/client/rendering.mjs +2244 -564
  196. package/dist/client/{shop-XTXPZTKR.mjs → shop-DQUB5E2C.mjs} +7 -7
  197. package/dist/preview-next/before-render.mjs +65 -1
  198. package/dist/preview-next/client/runtime.mjs +6 -6
  199. package/dist/preview-next/middleware.mjs +65 -1
  200. package/dist/preview-next/tailwind-sources.css +1 -0
  201. package/dist/sdk-runtime-AF6KXJU4.mjs +8 -0
  202. package/dist/server/components.mjs +2270 -835
  203. package/dist/server/config-template-validation.mjs +221 -15
  204. package/dist/server/config-validation.mjs +426 -77
  205. package/dist/server/config.mjs +426 -77
  206. package/dist/server/data.mjs +427 -82
  207. package/dist/server/index.mjs +94 -10
  208. package/dist/server/next/revalidate.mjs +229 -34
  209. package/dist/server/next.mjs +2439 -888
  210. package/dist/server/page-converter.mjs +335 -74
  211. package/dist/server/prebuild.mjs +1 -1
  212. package/dist/server/rendering/server.mjs +2281 -846
  213. package/dist/server/rendering.mjs +2298 -860
  214. package/dist/server/routing.mjs +860 -113
  215. package/dist/server/server.mjs +452 -92
  216. package/dist/server/theme-bridge.mjs +164 -2
  217. package/dist/server/theme.mjs +2 -2
  218. package/dist/server/webhooks.mjs +129 -25
  219. package/dist/styles/index.css +55 -0
  220. package/package.json +2 -1
  221. package/dist/SdkPreviewModeRuntime-LAGYMPNF.mjs +0 -8
  222. package/dist/sdk-runtime-ZJLKC6DR.mjs +0 -8
@@ -30,14 +30,42 @@ var __export = (target, all) => {
30
30
  __defProp(target, name, { get: all[name], enumerable: true });
31
31
  };
32
32
 
33
+ // ../core/src/result.ts
34
+ function ok(value) {
35
+ return { ok: true, value };
36
+ }
37
+ function err(error) {
38
+ return { ok: false, error };
39
+ }
40
+ var init_result = __esm({
41
+ "../core/src/result.ts"() {
42
+ }
43
+ });
44
+
33
45
  // ../core/src/branded.ts
34
- var asSiteId, asStorageBucketName, unsafeAsPositiveByteCount, unsafeAsPositiveSeconds;
46
+ function parseUuidBrand(value, unsafeConstructor) {
47
+ if (typeof value !== "string") {
48
+ return err({ kind: "not_string" });
49
+ }
50
+ const normalized = value.trim().toLowerCase();
51
+ if (normalized.length === 0) {
52
+ return err({ kind: "empty_string" });
53
+ }
54
+ if (!UUID_PATTERN.test(normalized)) {
55
+ return err({ kind: "invalid_uuid" });
56
+ }
57
+ return ok(unsafeConstructor(normalized));
58
+ }
59
+ var UUID_PATTERN, unsafeAsSiteId, unsafeAsStorageBucketName, unsafeAsPositiveByteCount, unsafeAsPositiveSeconds, parseSiteId;
35
60
  var init_branded = __esm({
36
61
  "../core/src/branded.ts"() {
37
- asSiteId = (id) => id;
38
- asStorageBucketName = (value) => value;
62
+ init_result();
63
+ UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
64
+ unsafeAsSiteId = (id) => id;
65
+ unsafeAsStorageBucketName = (value) => value;
39
66
  unsafeAsPositiveByteCount = (value) => value;
40
67
  unsafeAsPositiveSeconds = (value) => value;
68
+ parseSiteId = (value) => parseUuidBrand(value, unsafeAsSiteId);
41
69
  }
42
70
  });
43
71
 
@@ -111,18 +139,6 @@ var init_booking_instalments = __esm({
111
139
  }
112
140
  });
113
141
 
114
- // ../core/src/result.ts
115
- function ok(value) {
116
- return { ok: true, value };
117
- }
118
- function err(error) {
119
- return { ok: false, error };
120
- }
121
- var init_result = __esm({
122
- "../core/src/result.ts"() {
123
- }
124
- });
125
-
126
142
  // ../core/src/booking-date-time.ts
127
143
  var init_booking_date_time = __esm({
128
144
  "../core/src/booking-date-time.ts"() {
@@ -423,9 +439,24 @@ var init_fileSafety = __esm({
423
439
  "../media-core/src/fileSafety.ts"() {
424
440
  }
425
441
  });
442
+
443
+ // ../media-core/src/fileDomain.ts
444
+ var AMBIENT_BACKGROUND_ROLES2;
426
445
  var init_fileDomain = __esm({
427
446
  "../media-core/src/fileDomain.ts"() {
428
447
  init_src();
448
+ AMBIENT_BACKGROUND_ROLES2 = [
449
+ "light-texture",
450
+ "proof-band-dark",
451
+ "cta-wash",
452
+ "footer-detail",
453
+ "style-atmosphere-1",
454
+ "style-atmosphere-2"
455
+ ];
456
+ [
457
+ "selected-background",
458
+ ...AMBIENT_BACKGROUND_ROLES2
459
+ ];
429
460
  ({
430
461
  audio: unsafeAsPositiveByteCount(250 * 1024 * 1024),
431
462
  rawVideoBeforeCompression: unsafeAsPositiveByteCount(500 * 1024 * 1024),
@@ -449,15 +480,15 @@ var init_fileStorage = __esm({
449
480
  "../media-core/src/fileStorage.ts"() {
450
481
  init_src();
451
482
  FILE_STORAGE_BUCKETS = {
452
- publicSite: asStorageBucketName("media"),
453
- privateSite: asStorageBucketName("site-files-private"),
454
- temporary: asStorageBucketName("temp-uploads")
483
+ publicSite: unsafeAsStorageBucketName("media"),
484
+ privateSite: unsafeAsStorageBucketName("site-files-private"),
485
+ temporary: unsafeAsStorageBucketName("temp-uploads")
455
486
  };
456
487
  [
457
488
  FILE_STORAGE_BUCKETS.publicSite,
458
489
  // Existing site logo and font uploads predate the unified file buckets.
459
- asStorageBucketName("site-assets"),
460
- asStorageBucketName("site-fonts")
490
+ unsafeAsStorageBucketName("site-assets"),
491
+ unsafeAsStorageBucketName("site-fonts")
461
492
  ];
462
493
  PRIVATE_SITE_FILE_BUCKET_MIME_TYPES = [
463
494
  "application/pdf",
@@ -851,14 +882,14 @@ function rotateNormalizedPoint(point, rotation) {
851
882
  const x = point.x;
852
883
  const y = point.y;
853
884
  switch (rotation) {
885
+ case 0:
886
+ return { x, y };
854
887
  case 90:
855
888
  return { x: 1 - y, y: x };
856
889
  case 180:
857
890
  return { x: 1 - x, y: 1 - y };
858
891
  case 270:
859
892
  return { x: y, y: 1 - x };
860
- default:
861
- return { x, y };
862
893
  }
863
894
  }
864
895
  var init_rotation = __esm({
@@ -1143,6 +1174,14 @@ var init_repeaterGrid = __esm({
1143
1174
  DEFAULT_REPEATER_GRID_COLUMN_FIELD_ID = "gridColumn";
1144
1175
  }
1145
1176
  });
1177
+
1178
+ // ../blocks/src/system/icons/presets.ts
1179
+ var ICON_PICKER_PRESETS;
1180
+ var init_presets = __esm({
1181
+ "../blocks/src/system/icons/presets.ts"() {
1182
+ ICON_PICKER_PRESETS = ["cta", "feature"];
1183
+ }
1184
+ });
1146
1185
  function isDisplayMediaKind(kind) {
1147
1186
  return DISPLAY_MEDIA_KINDS.includes(kind);
1148
1187
  }
@@ -1230,6 +1269,7 @@ var init_schema2 = __esm({
1230
1269
  init_src2();
1231
1270
  init_node();
1232
1271
  init_repeaterGrid();
1272
+ init_presets();
1233
1273
  visibilityLevels = ["admin", "designer", "author"];
1234
1274
  MEDIA_KINDS = [
1235
1275
  "image",
@@ -1301,6 +1341,8 @@ var init_schema2 = __esm({
1301
1341
  mediaPickerAutoOpen: z.boolean().optional(),
1302
1342
  showMediaPreview: z.boolean().optional(),
1303
1343
  showMediaOverlayActions: z.boolean().optional(),
1344
+ mediaPreviewMaxWidth: z.enum(["xs", "sm", "md", "none"]).optional(),
1345
+ preventMediaPreviewUpscale: z.boolean().optional(),
1304
1346
  mediaDelivery: mediaDeliverySchema.optional(),
1305
1347
  mediaDeliveryByVariant: z.record(z.string(), mediaDeliverySchema).optional(),
1306
1348
  // Optional input hints for validators/widgets
@@ -1379,7 +1421,7 @@ var init_schema2 = __esm({
1379
1421
  layoutGridColumnField: z.string().optional(),
1380
1422
  layoutGridMaxRows: z.number().int().positive().optional(),
1381
1423
  // Icon picker configuration (used when ui.widget === 'iconPicker')
1382
- iconPickerPreset: z.enum(["cta"]).optional(),
1424
+ iconPickerPreset: z.enum(ICON_PICKER_PRESETS).optional(),
1383
1425
  // Entry picker configuration
1384
1426
  contentTypeField: z.string().optional(),
1385
1427
  fixedContentType: z.string().optional(),
@@ -1550,6 +1592,9 @@ var init_schema2 = __esm({
1550
1592
  type: z.literal("repeater"),
1551
1593
  itemLabel: z.string().default("Item"),
1552
1594
  itemLabelSource: z.string().optional(),
1595
+ showSummary: z.boolean().optional(),
1596
+ summaryFields: z.string().array().optional(),
1597
+ summaryMaxChars: z.number().int().positive().optional(),
1553
1598
  minItems: z.number().int().min(0).default(0),
1554
1599
  maxItems: z.number().int().positive().optional(),
1555
1600
  // Monomorphic mode
@@ -3046,7 +3091,7 @@ function parseThemeColorToken(value) {
3046
3091
  if (!isThemeColorToken(value)) return null;
3047
3092
  return value.trim();
3048
3093
  }
3049
- var PALETTE_TOKEN_NAMES, paletteTokenNameSchema, themeColorBaseTokenNames, themeColorBaseTokenSet, SHADE_STEPS, shadeStepSet, themeColorTokenSchema;
3094
+ var PALETTE_TOKEN_NAMES, paletteTokenNameSchema, themeColorBaseTokenNames, themeColorBaseTokenSet, themeColorShadeSteps, shadeStepSet, themeColorTokenSchema;
3050
3095
  var init_themeColorTokens = __esm({
3051
3096
  "../theme-core/src/tokens/themeColorTokens.ts"() {
3052
3097
  init_blockColorTokens();
@@ -3080,7 +3125,7 @@ var init_themeColorTokens = __esm({
3080
3125
  "accentForeground"
3081
3126
  ];
3082
3127
  themeColorBaseTokenSet = new Set(themeColorBaseTokenNames);
3083
- SHADE_STEPS = [
3128
+ themeColorShadeSteps = [
3084
3129
  "50",
3085
3130
  "100",
3086
3131
  "200",
@@ -3093,7 +3138,7 @@ var init_themeColorTokens = __esm({
3093
3138
  "900",
3094
3139
  "950"
3095
3140
  ];
3096
- shadeStepSet = new Set(SHADE_STEPS);
3141
+ shadeStepSet = new Set(themeColorShadeSteps);
3097
3142
  themeColorTokenSchema = z.string().min(1).refine((value) => Boolean(isThemeColorToken(value)), "Expected a known Theme V2 color token");
3098
3143
  }
3099
3144
  });
@@ -4262,7 +4307,7 @@ var init_generateButtonCss = __esm({
4262
4307
  });
4263
4308
 
4264
4309
  // ../theme-core/src/buttons/presets.ts
4265
- var init_presets = __esm({
4310
+ var init_presets2 = __esm({
4266
4311
  "../theme-core/src/buttons/presets.ts"() {
4267
4312
  }
4268
4313
  });
@@ -4287,7 +4332,7 @@ var init_buttons = __esm({
4287
4332
  init_generateButtonCss();
4288
4333
  init_generateDefaultButtonSystem();
4289
4334
  init_constants();
4290
- init_presets();
4335
+ init_presets2();
4291
4336
  init_personalities();
4292
4337
  init_types5();
4293
4338
  init_registry();
@@ -7452,6 +7497,7 @@ var init_curatedSiteStyles = __esm({
7452
7497
  "site-style:personal-retreat-journal",
7453
7498
  "site-style:tactile-workshop",
7454
7499
  "site-style:modern-wellness",
7500
+ "site-style:clarity-zen-blue",
7455
7501
  SOFT_EARTH_SITE_STYLE_ID_VALUE,
7456
7502
  "site-style:bold-launch",
7457
7503
  "site-style:south-west-twerk-school"
@@ -7804,6 +7850,114 @@ var init_curatedSiteStyles = __esm({
7804
7850
  paletteChoice("warm-neutral-clay")
7805
7851
  ]
7806
7852
  }),
7853
+ defineCuratedSiteStyle({
7854
+ id: "site-style:clarity-zen-blue",
7855
+ name: "Clarity Zen",
7856
+ description: "Calm, editorial, and reassuring for therapy, counselling, and wellbeing support practices.",
7857
+ generationBrief: "Use a calm, soft palette, editorial serif headings, warm grounded copy, rounded cards, calm proof sections, and clear booking routes. Keep the tone compassionate and straightforward, with professional trust rather than hard-sell wellness language.",
7858
+ siteCreatorSelection: {
7859
+ kind: "site_creator_keyword_heuristic",
7860
+ priority: 25
7861
+ },
7862
+ selectionKeywordRules: [
7863
+ { kind: "substring", value: "psychotherap" },
7864
+ { kind: "phrase", value: "mental health" },
7865
+ { kind: "phrase", value: "talk therapy" },
7866
+ { kind: "phrase", value: "therapy and wellbeing" }
7867
+ ],
7868
+ tokenRecipes: {
7869
+ palette: "brand-led",
7870
+ contrast: "standard",
7871
+ radius: "rounded",
7872
+ shadow: "subtle",
7873
+ typography: "serif-editorial",
7874
+ spacing: "airy",
7875
+ motion: "subtle"
7876
+ },
7877
+ compositionBudget: balancedBudget,
7878
+ themeOverrides: {
7879
+ typography: {
7880
+ body: {
7881
+ family: "Inter, system-ui, sans-serif",
7882
+ size: "md",
7883
+ weight: "regular",
7884
+ lineHeight: "relaxed",
7885
+ letterSpacing: "normal"
7886
+ },
7887
+ headings: {
7888
+ default: {
7889
+ family: '"Cormorant Garamond", Georgia, serif',
7890
+ weight: "regular",
7891
+ lineHeight: "normal",
7892
+ letterSpacing: "normal",
7893
+ colorToken: "text",
7894
+ italic: null,
7895
+ case: null
7896
+ },
7897
+ h1: {
7898
+ size: "xl",
7899
+ weight: "regular",
7900
+ lineHeight: "normal",
7901
+ letterSpacing: "normal",
7902
+ italic: null
7903
+ },
7904
+ h2: {
7905
+ size: "lg",
7906
+ weight: "regular",
7907
+ lineHeight: "normal",
7908
+ letterSpacing: "normal",
7909
+ italic: null
7910
+ },
7911
+ h3: {
7912
+ size: "md",
7913
+ weight: "regular",
7914
+ lineHeight: "normal",
7915
+ letterSpacing: "normal",
7916
+ italic: null
7917
+ }
7918
+ },
7919
+ scale: "majorThird"
7920
+ },
7921
+ bodyText: {
7922
+ intro: {
7923
+ paragraphSize: "default",
7924
+ headingSize: "editorial"
7925
+ }
7926
+ }
7927
+ },
7928
+ defaultBlockVariants: {
7929
+ "block.faq": "split-heading-columns"
7930
+ },
7931
+ recommendedAppearancePresetIds: [
7932
+ "hero-split-editorial",
7933
+ "intro-organic-statement",
7934
+ "feature-cards-raised-rule",
7935
+ "media-text-quiet-story",
7936
+ "testimonials-brand-background-quotes",
7937
+ "faq-contained-help",
7938
+ "contact-form-panel"
7939
+ ],
7940
+ recommendedHeaderLookIds: [
7941
+ "centered-calm",
7942
+ "serif-line",
7943
+ "minimal-transparent"
7944
+ ],
7945
+ recommendedFooterLookIds: [
7946
+ "footer-muted-grounding",
7947
+ "site-footer-brand-two-band"
7948
+ ],
7949
+ buttonPersonalityChoices: [
7950
+ buttonChoice("soft-pill"),
7951
+ buttonChoice("pebble"),
7952
+ buttonChoice("editorial-link")
7953
+ ],
7954
+ paletteVariantChoices: [
7955
+ paletteChoice("brand-led-cool"),
7956
+ paletteChoice("soft-natural-watercolor"),
7957
+ paletteChoice("soft-natural-stone"),
7958
+ paletteChoice("warm-neutral-cream")
7959
+ ]
7960
+ }),
7807
7961
  defineCuratedSiteStyle({
7808
7962
  id: "site-style:personal-retreat-journal",
7809
7963
  name: "Personal Retreat Journal",
@@ -11279,47 +11433,48 @@ function validateFieldDefinitions(fields3, fragmentId) {
11279
11433
  function prefixFieldId(field, scope) {
11280
11434
  const cloned = cloneFieldDefinition2(field);
11281
11435
  cloned.id = `${scope}.${field.id}`;
11282
- cloned.defaultValue = cloneUnknown(cloned.defaultValue);
11436
+ const defaultValue = cloned.defaultValue;
11437
+ cloned.defaultValue = cloneUnknown(defaultValue);
11283
11438
  cloned.visibleRoles = cloned.visibleRoles ? [...cloned.visibleRoles] : void 0;
11284
11439
  cloned.ui = cloneUnknown(cloned.ui);
11285
11440
  return cloned;
11286
11441
  }
11287
11442
  function cloneFieldDefinition2(field) {
11288
- switch (field.type) {
11289
- case "repeater":
11290
- if (field.polymorphic && field.itemTypes) {
11291
- return {
11292
- ...field,
11293
- polymorphic: true,
11294
- itemTypes: Object.fromEntries(
11295
- Object.entries(field.itemTypes).map(([key, itemType]) => [
11296
- key,
11297
- {
11298
- ...itemType,
11299
- fields: itemType.fields.map(cloneFieldDefinition2)
11300
- }
11301
- ])
11302
- )
11303
- };
11304
- } else if (field.schema) {
11305
- return {
11306
- ...field,
11307
- schema: {
11308
- fields: field.schema.fields.map(cloneFieldDefinition2)
11309
- }
11310
- };
11311
- }
11312
- return { ...field };
11313
- case "group":
11443
+ if (field.type === "repeater") {
11444
+ if (field.polymorphic && field.itemTypes) {
11445
+ return {
11446
+ ...field,
11447
+ polymorphic: true,
11448
+ itemTypes: Object.fromEntries(
11449
+ Object.entries(field.itemTypes).map(([key, itemType]) => [
11450
+ key,
11451
+ {
11452
+ ...itemType,
11453
+ fields: itemType.fields.map(cloneFieldDefinition2)
11454
+ }
11455
+ ])
11456
+ )
11457
+ };
11458
+ }
11459
+ if (field.schema) {
11314
11460
  return {
11315
11461
  ...field,
11316
11462
  schema: {
11317
11463
  fields: field.schema.fields.map(cloneFieldDefinition2)
11318
11464
  }
11319
11465
  };
11320
- default:
11321
- return { ...field };
11466
+ }
11467
+ return { ...field };
11468
+ }
11469
+ if (field.type === "group") {
11470
+ return {
11471
+ ...field,
11472
+ schema: {
11473
+ fields: field.schema.fields.map(cloneFieldDefinition2)
11474
+ }
11475
+ };
11322
11476
  }
11477
+ return { ...field };
11323
11478
  }
11324
11479
  function cloneUnknown(value) {
11325
11480
  if (value == null || typeof value !== "object") {
@@ -12190,36 +12345,46 @@ function buildCarouselLayout() {
12190
12345
  [buildTestimonialCard(repeat("data.entries", "testimonial"))]
12191
12346
  );
12192
12347
  }
12348
+ function buildResponsiveGridCards() {
12349
+ return [
12350
+ // 2 columns
12351
+ grid(
12352
+ { gap: "lg", cols: { base: 1, sm: 2 } },
12353
+ [buildTestimonialCard(repeat("data.entries", "testimonial"))],
12354
+ when("gridColumns", { equals: "2" })
12355
+ ),
12356
+ // 3 columns (default when unset)
12357
+ grid(
12358
+ { gap: "lg", cols: { base: 1, sm: 2, lg: 3 } },
12359
+ [buildTestimonialCard(repeat("data.entries", "testimonial"))],
12360
+ when("gridColumns", { equals: "3" })
12361
+ ),
12362
+ // 4 columns
12363
+ grid(
12364
+ { gap: "lg", cols: { base: 1, sm: 2, lg: 3, xl: 4 } },
12365
+ [buildTestimonialCard(repeat("data.entries", "testimonial"))],
12366
+ when("gridColumns", { equals: "4" })
12367
+ ),
12368
+ // Fallback to 3 columns when gridColumns is not set
12369
+ grid(
12370
+ { gap: "lg", cols: { base: 1, sm: 2, lg: 3 } },
12371
+ [buildTestimonialCard(repeat("data.entries", "testimonial"))],
12372
+ when("gridColumns", { not: true })
12373
+ )
12374
+ ];
12375
+ }
12193
12376
  function buildGridLayout() {
12194
12377
  return el(
12195
12378
  "div",
12196
12379
  { className: "rb-mt-12 rb-testimonials-carousel" },
12197
- [
12198
- // 2 columns
12199
- grid(
12200
- { gap: "lg", cols: { base: 1, sm: 2 } },
12201
- [buildTestimonialCard(repeat("data.entries", "testimonial"))],
12202
- when("gridColumns", { equals: "2" })
12203
- ),
12204
- // 3 columns (default when unset)
12205
- grid(
12206
- { gap: "lg", cols: { base: 1, sm: 2, lg: 3 } },
12207
- [buildTestimonialCard(repeat("data.entries", "testimonial"))],
12208
- when("gridColumns", { equals: "3" })
12209
- ),
12210
- // 4 columns
12211
- grid(
12212
- { gap: "lg", cols: { base: 1, sm: 2, lg: 3, xl: 4 } },
12213
- [buildTestimonialCard(repeat("data.entries", "testimonial"))],
12214
- when("gridColumns", { equals: "4" })
12215
- ),
12216
- // Fallback to 3 columns when gridColumns is not set
12217
- grid(
12218
- { gap: "lg", cols: { base: 1, sm: 2, lg: 3 } },
12219
- [buildTestimonialCard(repeat("data.entries", "testimonial"))],
12220
- when("gridColumns", { not: true })
12221
- )
12222
- ]
12380
+ buildResponsiveGridCards()
12381
+ );
12382
+ }
12383
+ function buildGridCardsLayout(className) {
12384
+ return el(
12385
+ "div",
12386
+ { className },
12387
+ buildResponsiveGridCards()
12223
12388
  );
12224
12389
  }
12225
12390
  var grid, testimonialsCarouselFragment;
@@ -14247,7 +14412,8 @@ function createBlockManifestWithContentShape(config2, _contentShape) {
14247
14412
  return createBlockManifest(config2);
14248
14413
  }
14249
14414
  function normalizeBlockLayout(layout) {
14250
- return Array.isArray(layout) ? [...layout] : layout;
14415
+ const rawLayout = layout;
14416
+ return Array.isArray(rawLayout) ? rawLayout : rawLayout;
14251
14417
  }
14252
14418
  function deriveComponentName(id) {
14253
14419
  const base = id.replace(/^block\./, "");
@@ -14454,7 +14620,7 @@ var init_form_interactive = __esm({
14454
14620
  });
14455
14621
 
14456
14622
  // ../blocks/src/lib/typeGuards.ts
14457
- function isRecord2(value) {
14623
+ function isRecord3(value) {
14458
14624
  return typeof value === "object" && value !== null && !Array.isArray(value);
14459
14625
  }
14460
14626
  var init_typeGuards = __esm({
@@ -14974,10 +15140,10 @@ function normalizeEventCategoryIds(value) {
14974
15140
  if (Array.isArray(value)) {
14975
15141
  return normalizeIdList(
14976
15142
  value.filter((entry) => typeof entry === "string")
14977
- ).map(asEventCategoryId);
15143
+ ).map(unsafeAsEventCategoryId);
14978
15144
  }
14979
15145
  if (typeof value === "string") {
14980
- return normalizeIdList(value.split(",")).map(asEventCategoryId);
15146
+ return normalizeIdList(value.split(",")).map(unsafeAsEventCategoryId);
14981
15147
  }
14982
15148
  return [];
14983
15149
  }
@@ -14990,7 +15156,7 @@ function normalizeEventVenueId(value) {
14990
15156
  return null;
14991
15157
  }
14992
15158
  const trimmed = value.trim();
14993
- return trimmed ? asVenueId(trimmed) : null;
15159
+ return trimmed ? unsafeAsVenueId(trimmed) : null;
14994
15160
  }
14995
15161
  function normalizeEventStaffMemberId(value) {
14996
15162
  if (typeof value !== "string") {
@@ -14999,7 +15165,7 @@ function normalizeEventStaffMemberId(value) {
14999
15165
  const trimmed = value.trim();
15000
15166
  return trimmed ? trimmed : null;
15001
15167
  }
15002
- var eventBlockKindValues, eventSurfacePresetValues, eventSurfaceScopeValues, eventScheduleScopeValues, asEventCategoryId, asVenueId;
15168
+ var eventBlockKindValues, eventSurfacePresetValues, eventSurfaceScopeValues, eventScheduleScopeValues, unsafeAsEventCategoryId, unsafeAsVenueId;
15003
15169
  var init_filtering = __esm({
15004
15170
  "../blocks/src/system/blocks/events/shared/filtering.ts"() {
15005
15171
  init_normalizeIds();
@@ -15017,8 +15183,8 @@ var init_filtering = __esm({
15017
15183
  "custom"
15018
15184
  ];
15019
15185
  eventScheduleScopeValues = ["any", "recurring", "oneOff"];
15020
- asEventCategoryId = (value) => value;
15021
- asVenueId = (value) => value;
15186
+ unsafeAsEventCategoryId = (value) => value;
15187
+ unsafeAsVenueId = (value) => value;
15022
15188
  }
15023
15189
  });
15024
15190
 
@@ -18949,7 +19115,16 @@ var ENDPOINT_DEFINITIONS = {
18949
19115
  revalidate: 60,
18950
19116
  tags: ["site-{siteId}", "content-{siteId}-{type}"],
18951
19117
  auth: "user",
18952
- responseKind: "json"
19118
+ responseKind: "json",
19119
+ errors: ["validation:invalid_input", "resource:not_found", "resource:conflict", "server:internal_error"]
19120
+ },
19121
+ reorderContentEntries: {
19122
+ path: "/sites/{siteId}/content/{type}/order",
19123
+ method: "POST",
19124
+ tags: ["site-{siteId}", "content-{siteId}-{type}"],
19125
+ auth: "user",
19126
+ responseKind: "json",
19127
+ errors: ["validation:invalid_input", "resource:not_found", "resource:conflict", "server:internal_error"]
18953
19128
  },
18954
19129
  getContentTemplate: {
18955
19130
  path: "/sites/{siteId}/content/types/{type}/template",
@@ -19341,6 +19516,46 @@ var ENDPOINT_DEFINITIONS = {
19341
19516
  auth: "user",
19342
19517
  responseKind: "json"
19343
19518
  },
19519
+ getSiteIconStyleGuide: {
19520
+ path: "/sites/{siteId}/settings/icon-style-guide",
19521
+ method: "GET",
19522
+ revalidate: 120,
19523
+ tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings],
19524
+ auth: "user",
19525
+ responseKind: "json",
19526
+ errors: []
19527
+ },
19528
+ updateSiteIconStyleGuide: {
19529
+ path: "/sites/{siteId}/settings/icon-style-guide",
19530
+ method: "POST",
19531
+ tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings],
19532
+ auth: "user",
19533
+ responseKind: "json",
19534
+ errors: []
19535
+ },
19536
+ regenerateSiteIconStyleGuide: {
19537
+ path: "/sites/{siteId}/settings/icon-style-guide/regenerate",
19538
+ method: "POST",
19539
+ tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings],
19540
+ auth: "user",
19541
+ responseKind: "json",
19542
+ errors: []
19543
+ },
19544
+ generateGeneratedIconSet: {
19545
+ path: "/sites/{siteId}/ai/generated-icons/generate",
19546
+ method: "POST",
19547
+ auth: "user",
19548
+ responseKind: "json",
19549
+ errors: []
19550
+ },
19551
+ applyGeneratedIconSet: {
19552
+ path: "/sites/{siteId}/ai/generated-icons/apply",
19553
+ method: "POST",
19554
+ tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteSettings],
19555
+ auth: "user",
19556
+ responseKind: "json",
19557
+ errors: []
19558
+ },
19344
19559
  getSiteAiProfile: {
19345
19560
  path: "/sites/{siteId}/settings/ai-site-profile",
19346
19561
  method: "GET",
@@ -21116,6 +21331,14 @@ var ENDPOINT_DEFINITIONS = {
21116
21331
  auth: "public",
21117
21332
  responseKind: "json"
21118
21333
  },
21334
+ getGeneratedIconRenderAssets: {
21335
+ path: "/public/sites/{siteId}/generated-icon-assets",
21336
+ method: "POST",
21337
+ tags: [TAG_TEMPLATES.siteRoutableContent],
21338
+ auth: "public",
21339
+ responseKind: "json",
21340
+ errors: []
21341
+ },
21119
21342
  // Resolve entry subroute by kind and URL segment
21120
21343
  resolveEntrySubroute: {
21121
21344
  path: "/public/sites/{siteId}/routing/subroutes/resolve",
@@ -22820,6 +23043,13 @@ var ENDPOINT_DEFINITIONS = {
22820
23043
  auth: "service",
22821
23044
  responseKind: "json"
22822
23045
  },
23046
+ sdkDeleteNavigationMenu: {
23047
+ path: "/sdk/{siteId}/navigation/{menuId}",
23048
+ method: "DELETE",
23049
+ auth: "service",
23050
+ responseKind: "json",
23051
+ errors: ["resource:not_found", "server:internal_error"]
23052
+ },
22823
23053
  sdkUpsertTheme: {
22824
23054
  path: "/sdk/{siteId}/theme",
22825
23055
  method: "POST",
@@ -23587,6 +23817,370 @@ var linkSchema = z.union([
23587
23817
 
23588
23818
  // ../blocks/src/system/manifest/fieldValidation/index.ts
23589
23819
  init_schema2();
23820
+
23821
+ // ../blocks/src/system/icons/ids.ts
23822
+ var GENERATED_ICON_SET_ID_PATTERN = /^generated-icon-set:[a-z0-9][a-z0-9:_-]{0,107}$/u;
23823
+ var GENERATED_ICON_ASSET_ID_PATTERN = /^generated-icon-asset:[a-z0-9][a-z0-9:_-]{0,105}$/u;
23824
+ var SITE_ICON_STYLE_GUIDE_VERSION_ID_PATTERN = /^site-icon-style-guide:[a-f0-9]{16}$/u;
23825
+ function normalizeString(value) {
23826
+ if (typeof value !== "string") return null;
23827
+ const normalized = value.trim();
23828
+ return normalized.length > 0 ? normalized : null;
23829
+ }
23830
+ function unsafeAsGeneratedIconSetId(value) {
23831
+ return value;
23832
+ }
23833
+ function unsafeAsGeneratedIconAssetId(value) {
23834
+ return value;
23835
+ }
23836
+ function unsafeAsSiteIconStyleGuideVersionId(value) {
23837
+ return value;
23838
+ }
23839
+ function parseGeneratedIconSetId(value) {
23840
+ const normalized = normalizeString(value);
23841
+ return normalized !== null && GENERATED_ICON_SET_ID_PATTERN.test(normalized) ? unsafeAsGeneratedIconSetId(normalized) : null;
23842
+ }
23843
+ function parseGeneratedIconAssetId(value) {
23844
+ const normalized = normalizeString(value);
23845
+ return normalized !== null && GENERATED_ICON_ASSET_ID_PATTERN.test(normalized) ? unsafeAsGeneratedIconAssetId(normalized) : null;
23846
+ }
23847
+ function parseSiteIconStyleGuideVersionId(value) {
23848
+ if (typeof value !== "string") return null;
23849
+ const normalized = value.trim();
23850
+ return SITE_ICON_STYLE_GUIDE_VERSION_ID_PATTERN.test(normalized) ? unsafeAsSiteIconStyleGuideVersionId(normalized) : null;
23851
+ }
23852
+
23853
+ // ../blocks/src/system/icons/semantic.ts
23854
+ var SEMANTIC_ICON_IDS = [
23855
+ "protection-trust",
23856
+ "confidentiality",
23857
+ "care-support",
23858
+ "partnership",
23859
+ "warmth",
23860
+ "community",
23861
+ "personal-guidance",
23862
+ "conversation",
23863
+ "friendly-welcome",
23864
+ "insight-learning",
23865
+ "natural-wellbeing",
23866
+ "growth",
23867
+ "gentle-care",
23868
+ "special-touch",
23869
+ "ideas",
23870
+ "direction",
23871
+ "focus",
23872
+ "quality",
23873
+ "highlight",
23874
+ "verified-quality",
23875
+ "learning",
23876
+ "training",
23877
+ "programmes-dates",
23878
+ "place",
23879
+ "products",
23880
+ "packages",
23881
+ "time",
23882
+ "practical-service",
23883
+ "at-home",
23884
+ "worldwide",
23885
+ "professional-service"
23886
+ ];
23887
+ var featurePreset = ["feature"];
23888
+ var SEMANTIC_ICON_DEFINITIONS = [
23889
+ {
23890
+ id: "protection-trust",
23891
+ label: "Protection and trust",
23892
+ tags: ["safe", "safety", "security", "trust", "privacy", "confidence"],
23893
+ domains: ["wellbeing", "services", "technology"],
23894
+ tone: ["trustworthy", "practical"],
23895
+ presets: featurePreset
23896
+ },
23897
+ {
23898
+ id: "confidentiality",
23899
+ label: "Confidentiality",
23900
+ tags: ["confidential", "privacy", "secure", "protected", "private"],
23901
+ domains: ["wellbeing", "coaching", "services", "technology"],
23902
+ tone: ["trustworthy", "calm"],
23903
+ presets: featurePreset
23904
+ },
23905
+ {
23906
+ id: "care-support",
23907
+ label: "Care and support",
23908
+ tags: ["care", "support", "therapy", "kindness", "help", "compassion"],
23909
+ domains: ["wellbeing", "coaching", "community"],
23910
+ tone: ["warm", "human"],
23911
+ presets: featurePreset
23912
+ },
23913
+ {
23914
+ id: "partnership",
23915
+ label: "Partnership",
23916
+ tags: ["partnership", "together", "support", "relationship", "collaboration"],
23917
+ domains: ["coaching", "community", "services"],
23918
+ tone: ["warm", "human", "trustworthy"],
23919
+ presets: featurePreset
23920
+ },
23921
+ {
23922
+ id: "warmth",
23923
+ label: "Warmth",
23924
+ tags: ["heart", "warmth", "care", "love", "wellbeing", "personal"],
23925
+ domains: ["wellbeing", "community", "hospitality"],
23926
+ tone: ["warm", "human"],
23927
+ presets: featurePreset
23928
+ },
23929
+ {
23930
+ id: "community",
23931
+ label: "Community",
23932
+ tags: ["community", "group", "people", "team", "members", "belonging"],
23933
+ domains: ["community", "education", "events"],
23934
+ tone: ["human", "warm"],
23935
+ presets: featurePreset
23936
+ },
23937
+ {
23938
+ id: "personal-guidance",
23939
+ label: "Personal guidance",
23940
+ tags: ["guidance", "personal", "coach", "expert", "one to one", "trusted"],
23941
+ domains: ["coaching", "services", "education"],
23942
+ tone: ["trustworthy", "human"],
23943
+ presets: featurePreset
23944
+ },
23945
+ {
23946
+ id: "conversation",
23947
+ label: "Conversation",
23948
+ tags: ["conversation", "talk", "chat", "communication", "support"],
23949
+ domains: ["coaching", "community", "services"],
23950
+ tone: ["human", "warm"],
23951
+ presets: featurePreset
23952
+ },
23953
+ {
23954
+ id: "friendly-welcome",
23955
+ label: "Friendly welcome",
23956
+ tags: ["friendly", "welcome", "positive", "happy", "approachable"],
23957
+ domains: ["hospitality", "community", "services"],
23958
+ tone: ["warm", "playful", "human"],
23959
+ presets: featurePreset
23960
+ },
23961
+ {
23962
+ id: "insight-learning",
23963
+ label: "Insight and learning",
23964
+ tags: ["mind", "insight", "learning", "clarity", "thinking", "therapy"],
23965
+ domains: ["wellbeing", "coaching", "education"],
23966
+ tone: ["calm", "practical"],
23967
+ presets: featurePreset
23968
+ },
23969
+ {
23970
+ id: "natural-wellbeing",
23971
+ label: "Natural wellbeing",
23972
+ tags: ["natural", "wellbeing", "growth", "eco", "calm", "organic"],
23973
+ domains: ["wellbeing", "hospitality", "creative"],
23974
+ tone: ["calm", "warm"],
23975
+ presets: featurePreset
23976
+ },
23977
+ {
23978
+ id: "growth",
23979
+ label: "Growth",
23980
+ tags: ["growth", "new", "progress", "development", "nurture"],
23981
+ domains: ["wellbeing", "coaching", "education", "community"],
23982
+ tone: ["warm", "calm"],
23983
+ presets: featurePreset
23984
+ },
23985
+ {
23986
+ id: "gentle-care",
23987
+ label: "Gentle care",
23988
+ tags: ["gentle", "soft", "care", "wellbeing", "beauty", "calm"],
23989
+ domains: ["wellbeing", "creative", "hospitality"],
23990
+ tone: ["warm", "calm", "premium"],
23991
+ presets: featurePreset
23992
+ },
23993
+ {
23994
+ id: "special-touch",
23995
+ label: "Special touch",
23996
+ tags: ["special", "sparkle", "magic", "polish", "delight", "creative"],
23997
+ domains: ["creative", "commerce", "hospitality"],
23998
+ tone: ["playful", "premium"],
23999
+ presets: featurePreset
24000
+ },
24001
+ {
24002
+ id: "ideas",
24003
+ label: "Ideas",
24004
+ tags: ["idea", "innovation", "clarity", "creative", "strategy"],
24005
+ domains: ["coaching", "education", "creative", "technology"],
24006
+ tone: ["practical", "playful"],
24007
+ presets: featurePreset
24008
+ },
24009
+ {
24010
+ id: "direction",
24011
+ label: "Direction",
24012
+ tags: ["direction", "navigation", "path", "journey", "guidance"],
24013
+ domains: ["coaching", "education", "services"],
24014
+ tone: ["trustworthy", "practical"],
24015
+ presets: featurePreset
24016
+ },
24017
+ {
24018
+ id: "focus",
24019
+ label: "Focus",
24020
+ tags: ["focus", "goal", "outcome", "aim", "strategy"],
24021
+ domains: ["coaching", "services", "technology"],
24022
+ tone: ["practical"],
24023
+ presets: featurePreset
24024
+ },
24025
+ {
24026
+ id: "quality",
24027
+ label: "Quality",
24028
+ tags: ["quality", "award", "standard", "achievement", "premium"],
24029
+ domains: ["services", "education", "commerce"],
24030
+ tone: ["premium", "trustworthy"],
24031
+ presets: featurePreset
24032
+ },
24033
+ {
24034
+ id: "highlight",
24035
+ label: "Highlight",
24036
+ tags: ["highlight", "featured", "favorite", "quality", "special"],
24037
+ domains: ["creative", "commerce", "services"],
24038
+ tone: ["playful", "premium"],
24039
+ presets: featurePreset
24040
+ },
24041
+ {
24042
+ id: "verified-quality",
24043
+ label: "Verified quality",
24044
+ tags: ["verified", "quality", "approved", "trusted", "check"],
24045
+ domains: ["services", "commerce", "education"],
24046
+ tone: ["trustworthy", "practical"],
24047
+ presets: featurePreset
24048
+ },
24049
+ {
24050
+ id: "learning",
24051
+ label: "Learning",
24052
+ tags: ["learning", "book", "course", "knowledge", "education"],
24053
+ domains: ["education", "coaching", "community"],
24054
+ tone: ["calm", "practical"],
24055
+ presets: featurePreset
24056
+ },
24057
+ {
24058
+ id: "training",
24059
+ label: "Training",
24060
+ tags: ["training", "course", "qualification", "school", "education"],
24061
+ domains: ["education", "coaching"],
24062
+ tone: ["trustworthy", "practical"],
24063
+ presets: featurePreset
24064
+ },
24065
+ {
24066
+ id: "programmes-dates",
24067
+ label: "Programmes and dates",
24068
+ tags: ["calendar", "dates", "schedule", "events", "programme", "classes"],
24069
+ domains: ["events", "education", "community"],
24070
+ tone: ["practical"],
24071
+ presets: featurePreset
24072
+ },
24073
+ {
24074
+ id: "place",
24075
+ label: "Place",
24076
+ tags: ["place", "location", "local", "venue", "destination"],
24077
+ domains: ["events", "hospitality", "services"],
24078
+ tone: ["practical"],
24079
+ presets: featurePreset
24080
+ },
24081
+ {
24082
+ id: "products",
24083
+ label: "Products",
24084
+ tags: ["products", "shop", "store", "retail", "commerce"],
24085
+ domains: ["commerce"],
24086
+ tone: ["practical", "premium"],
24087
+ presets: featurePreset
24088
+ },
24089
+ {
24090
+ id: "packages",
24091
+ label: "Packages",
24092
+ tags: ["package", "bundle", "delivery", "offer", "product"],
24093
+ domains: ["commerce", "services"],
24094
+ tone: ["practical"],
24095
+ presets: featurePreset
24096
+ },
24097
+ {
24098
+ id: "time",
24099
+ label: "Time",
24100
+ tags: ["time", "duration", "schedule", "availability", "appointment"],
24101
+ domains: ["events", "services", "wellbeing"],
24102
+ tone: ["practical", "calm"],
24103
+ presets: featurePreset
24104
+ },
24105
+ {
24106
+ id: "practical-service",
24107
+ label: "Practical service",
24108
+ tags: ["service", "repair", "setup", "practical", "tools", "support"],
24109
+ domains: ["services", "technology"],
24110
+ tone: ["practical"],
24111
+ presets: featurePreset
24112
+ },
24113
+ {
24114
+ id: "at-home",
24115
+ label: "At home",
24116
+ tags: ["home", "domestic", "comfort", "local", "space"],
24117
+ domains: ["hospitality", "services", "community"],
24118
+ tone: ["warm", "calm"],
24119
+ presets: featurePreset
24120
+ },
24121
+ {
24122
+ id: "worldwide",
24123
+ label: "Worldwide",
24124
+ tags: ["global", "online", "worldwide", "remote", "international"],
24125
+ domains: ["technology", "education", "services"],
24126
+ tone: ["practical"],
24127
+ presets: featurePreset
24128
+ },
24129
+ {
24130
+ id: "professional-service",
24131
+ label: "Professional service",
24132
+ tags: ["business", "professional", "consulting", "service", "work"],
24133
+ domains: ["services", "technology", "coaching"],
24134
+ tone: ["practical", "trustworthy"],
24135
+ presets: featurePreset
24136
+ }
24137
+ ];
24138
+ SEMANTIC_ICON_DEFINITIONS.map(({ id, label }) => ({
24139
+ id,
24140
+ label
24141
+ }));
24142
+ function isSemanticIconId(value) {
24143
+ return typeof value === "string" && SEMANTIC_ICON_IDS.includes(value);
24144
+ }
24145
+
24146
+ // ../blocks/src/system/icons/value.ts
24147
+ var NO_BLOCK_ICON_VALUE = { kind: "none" };
24148
+ function isRecord(value) {
24149
+ return typeof value === "object" && value !== null && !Array.isArray(value);
24150
+ }
24151
+ function parseBlockIconValue(value) {
24152
+ if (isSemanticIconId(value)) {
24153
+ return { kind: "semantic", iconId: value };
24154
+ }
24155
+ if (!isRecord(value)) {
24156
+ return NO_BLOCK_ICON_VALUE;
24157
+ }
24158
+ switch (value.kind) {
24159
+ case "none":
24160
+ return NO_BLOCK_ICON_VALUE;
24161
+ case "semantic":
24162
+ return isSemanticIconId(value.iconId) ? { kind: "semantic", iconId: value.iconId } : NO_BLOCK_ICON_VALUE;
24163
+ case "generated": {
24164
+ const setId = parseGeneratedIconSetId(value.setId);
24165
+ const assetId = parseGeneratedIconAssetId(value.assetId);
24166
+ const styleGuideVersionId = parseSiteIconStyleGuideVersionId(value.styleGuideVersionId);
24167
+ if (setId !== null && assetId !== null && isSemanticIconId(value.semanticFallbackIconId) && styleGuideVersionId !== null) {
24168
+ return {
24169
+ kind: "generated",
24170
+ setId,
24171
+ assetId,
24172
+ semanticFallbackIconId: value.semanticFallbackIconId,
24173
+ styleGuideVersionId
24174
+ };
24175
+ }
24176
+ return NO_BLOCK_ICON_VALUE;
24177
+ }
24178
+ default:
24179
+ return NO_BLOCK_ICON_VALUE;
24180
+ }
24181
+ }
24182
+
24183
+ // ../blocks/src/system/manifest/fieldValidation/index.ts
23590
24184
  var TEL_RE = /^[+()0-9\s-]{3,}$/;
23591
24185
  var SLUG_PATTERN = /^(?:[a-z0-9]+(?:-[a-z0-9]+)*)(?:\/(?:[a-z0-9]+(?:-[a-z0-9]+)*))*$/;
23592
24186
  var ALLOWED_URL_PROTOCOLS = ["http:", "https:"];
@@ -23675,7 +24269,7 @@ function deriveFieldValidationPlan(field, path24 = [field.id]) {
23675
24269
  return makePlan("number", "number", field, path24, required, constraints2);
23676
24270
  }
23677
24271
  const constraints = commonConstraints(required, {
23678
- kind: "textType"
24272
+ kind: field.ui?.widget === "iconPicker" ? "blockIconValue" : "textType"
23679
24273
  });
23680
24274
  if (inputType === "email") constraints.push({ kind: "emailFormat" });
23681
24275
  if (inputType === "tel") constraints.push({ kind: "phoneFormat" });
@@ -23895,7 +24489,7 @@ function normalizeStoredObjectChildren(children, value, ctx) {
23895
24489
  return normalized;
23896
24490
  }
23897
24491
  function normalizeStoredRepeaterItems(plan, value, ctx) {
23898
- if (!Array.isArray(value)) {
24492
+ if (!isUnknownArray(value)) {
23899
24493
  return value;
23900
24494
  }
23901
24495
  return value.map((item) => {
@@ -23942,7 +24536,7 @@ function normalizeObjectChildren(children, value, ctx) {
23942
24536
  return normalized;
23943
24537
  }
23944
24538
  function normalizeRepeaterItems(plan, value, ctx) {
23945
- if (!Array.isArray(value)) return value;
24539
+ if (!isUnknownArray(value)) return value;
23946
24540
  return value.map((item) => {
23947
24541
  if (!item || typeof item !== "object" || Array.isArray(item)) return item;
23948
24542
  const itemRecord = item;
@@ -24008,39 +24602,52 @@ function isMissingForPlan(plan, value) {
24008
24602
  return false;
24009
24603
  }
24010
24604
  function validateStringPlan(plan, value) {
24605
+ if (plan.constraints.some((constraint) => constraint.kind === "blockIconValue")) {
24606
+ return plan.constraints.flatMap((constraint) => validateStringConstraint(plan, constraint, value));
24607
+ }
24011
24608
  if (typeof value !== "string") return [issue(plan, "wrongType", { expected: "text" })];
24012
24609
  return plan.constraints.flatMap((constraint) => validateStringConstraint(plan, constraint, value));
24013
24610
  }
24014
24611
  function validateStringConstraint(plan, constraint, value) {
24015
24612
  switch (constraint.kind) {
24016
24613
  case "required":
24614
+ return [];
24017
24615
  case "textType":
24018
24616
  case "referenceText":
24019
- return [];
24617
+ return typeof value === "string" ? [] : [issue(plan, "wrongType", { expected: "text" })];
24618
+ case "blockIconValue":
24619
+ return isValidIconPickerValue(value) ? [] : [issue(plan, "wrongType", { expected: "text or icon" })];
24020
24620
  case "maxLength":
24021
- return value.length > constraint.maximum ? [issue(plan, "tooLong", { maximum: constraint.maximum })] : [];
24621
+ return typeof value === "string" && value.length > constraint.maximum ? [issue(plan, "tooLong", { maximum: constraint.maximum })] : [];
24022
24622
  case "emailFormat":
24023
- return isCanonicalEmailValue(value) ? [] : [issue(plan, "invalidEmail")];
24623
+ return typeof value === "string" && isCanonicalEmailValue(value) ? [] : [issue(plan, "invalidEmail")];
24024
24624
  case "phoneFormat":
24025
- return isCanonicalPhoneValue(value) ? [] : [issue(plan, "invalidPhone")];
24625
+ return typeof value === "string" && isCanonicalPhoneValue(value) ? [] : [issue(plan, "invalidPhone")];
24026
24626
  case "patternFormat": {
24627
+ if (typeof value !== "string") return [issue(plan, "wrongType", { expected: "text" })];
24027
24628
  const re = compilePattern(constraint.pattern);
24028
24629
  return re && !re.test(value) ? [issue(plan, "invalidPattern")] : [];
24029
24630
  }
24030
24631
  case "urlFormat":
24031
- return isCanonicalUrlValue(value, { allowRelative: constraint.allowRelative }) ? [] : [issue(plan, "invalidUrl")];
24632
+ return typeof value === "string" && isCanonicalUrlValue(value, { allowRelative: constraint.allowRelative }) ? [] : [issue(plan, "invalidUrl")];
24032
24633
  case "dateFormat":
24033
- return isValidDateString(value) ? [] : [issue(plan, "invalidDate")];
24634
+ return typeof value === "string" && isValidDateString(value) ? [] : [issue(plan, "invalidDate")];
24034
24635
  case "timeFormat":
24035
- return isValidTimeString(value) ? [] : [issue(plan, "invalidTime")];
24636
+ return typeof value === "string" && isValidTimeString(value) ? [] : [issue(plan, "invalidTime")];
24036
24637
  case "datetimeFormat":
24037
- return isValidDateTimeInstantString(value) ? [] : [issue(plan, "invalidDateTime")];
24638
+ return typeof value === "string" && isValidDateTimeInstantString(value) ? [] : [issue(plan, "invalidDateTime")];
24038
24639
  case "slugFormat":
24039
- return SLUG_PATTERN.test(value) ? [] : [issue(plan, "invalidSlug")];
24640
+ return typeof value === "string" && SLUG_PATTERN.test(value) ? [] : [issue(plan, "invalidSlug")];
24040
24641
  default:
24041
24642
  return assertNever2(constraint);
24042
24643
  }
24043
24644
  }
24645
+ function isValidIconPickerValue(value) {
24646
+ if (typeof value === "string") return true;
24647
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
24648
+ if (value.kind === "none") return true;
24649
+ return parseBlockIconValue(value).kind !== "none";
24650
+ }
24044
24651
  function validateNumberPlan(plan, value) {
24045
24652
  if (!isValidNumber(value)) return [issue(plan, "invalidNumber")];
24046
24653
  return plan.constraints.flatMap((constraint) => validateNumberConstraint(plan, constraint, Number(value)));
@@ -24329,6 +24936,9 @@ function isEmptyValue(value) {
24329
24936
  function isPlainObject(value) {
24330
24937
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
24331
24938
  }
24939
+ function isUnknownArray(value) {
24940
+ return Array.isArray(value);
24941
+ }
24332
24942
  function isValidRichTextDoc(value) {
24333
24943
  const doc = richTextDoc(value);
24334
24944
  return Boolean(isPlainObject(doc) && doc.type === "doc");
@@ -25604,6 +26214,24 @@ var questionColumnsLayout = styledSection({
25604
26214
  }),
25605
26215
  baseClass: ""
25606
26216
  });
26217
+ var splitHeadingColumnsLayout = styledSection({
26218
+ children: styledContainer({
26219
+ baseClassName: "rb-relative rb-isolate",
26220
+ children: el(
26221
+ "div",
26222
+ {
26223
+ className: "rb-faq-split-heading-columns rb-grid rb-grid-cols-1 rb-gap-8 rb-lg-grid-cols-2 rb-lg-items-start"
26224
+ },
26225
+ [
26226
+ el("div", { className: "rb-faq-split-heading-columns-copy" }, [headingLayout]),
26227
+ el("div", { className: "rb-faq-split-heading-columns-accordion" }, [
26228
+ questionColumnsAccordionLayout
26229
+ ])
26230
+ ]
26231
+ )
26232
+ }),
26233
+ baseClass: ""
26234
+ });
25607
26235
  var faqManifest = createBlockManifest({
25608
26236
  id: "block.faq",
25609
26237
  title: "FAQ",
@@ -25624,7 +26252,8 @@ var faqManifest = createBlockManifest({
25624
26252
  variants: {
25625
26253
  default: defaultLayout,
25626
26254
  "two-column": twoColumnLayout,
25627
- "question-columns": questionColumnsLayout
26255
+ "question-columns": questionColumnsLayout,
26256
+ "split-heading-columns": splitHeadingColumnsLayout
25628
26257
  },
25629
26258
  defaultVariant: "default",
25630
26259
  variantOptions: {
@@ -25639,6 +26268,10 @@ var faqManifest = createBlockManifest({
25639
26268
  "question-columns": {
25640
26269
  label: "Question columns",
25641
26270
  description: "A full-width heading above FAQ items split into two columns."
26271
+ },
26272
+ "split-heading-columns": {
26273
+ label: "Split heading columns",
26274
+ description: "A left heading column with FAQ items split into two columns on the right."
25642
26275
  }
25643
26276
  },
25644
26277
  description: "Accordion of frequently asked questions and answers.",
@@ -25728,16 +26361,20 @@ var marqueeLoopTransform = {
25728
26361
  summary: "Repeat an array to a minimum length, then duplicate it for seamless marquee looping",
25729
26362
  schema: marqueeLoopOptionsSchema,
25730
26363
  run: (value, options) => {
25731
- if (!Array.isArray(value) || value.length === 0) return [];
26364
+ const items = toUnknownArray(value);
26365
+ if (items.length === 0) return [];
25732
26366
  const minItems = options?.minItems ?? 10;
25733
26367
  const base = [];
25734
26368
  while (base.length < minItems) {
25735
- base.push(...value);
26369
+ base.push(...items);
25736
26370
  if (base.length > 1e3) break;
25737
26371
  }
25738
26372
  return [...base, ...base];
25739
26373
  }
25740
26374
  };
26375
+ function toUnknownArray(value) {
26376
+ return Array.isArray(value) ? value : [];
26377
+ }
25741
26378
  var formattingTransforms = [
25742
26379
  uppercaseTransform,
25743
26380
  fallbackTransform,
@@ -26873,16 +27510,16 @@ var interpolateRichTextTokensOptionsSchema = z.object({
26873
27510
  var richTextTokenPattern = /\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g;
26874
27511
  function getSiteName(context) {
26875
27512
  const viewModel = context.viewModel;
26876
- if (!isRecord2(viewModel)) return null;
27513
+ if (!isRecord3(viewModel)) return null;
26877
27514
  const site = viewModel.site;
26878
- if (isRecord2(site) && typeof site.title === "string") {
27515
+ if (isRecord3(site) && typeof site.title === "string") {
26879
27516
  const title = site.title.trim();
26880
27517
  return title.length > 0 ? title : null;
26881
27518
  }
26882
27519
  const root = viewModel.$root;
26883
- if (isRecord2(root)) {
27520
+ if (isRecord3(root)) {
26884
27521
  const rootSite = root.site;
26885
- if (isRecord2(rootSite) && typeof rootSite.title === "string") {
27522
+ if (isRecord3(rootSite) && typeof rootSite.title === "string") {
26886
27523
  const title = rootSite.title.trim();
26887
27524
  if (title.length > 0) return title;
26888
27525
  }
@@ -26904,7 +27541,7 @@ function replaceTokenText(input, allowedTokens, tokenValues) {
26904
27541
  });
26905
27542
  }
26906
27543
  function visitRichTextNode(node, allowedTokens, tokenValues) {
26907
- if (!isRecord2(node)) return node;
27544
+ if (!isRecord3(node)) return node;
26908
27545
  let changed = false;
26909
27546
  const nextNode = { ...node };
26910
27547
  if (nextNode.type === "text" && typeof nextNode.text === "string") {
@@ -26930,13 +27567,13 @@ function visitRichTextNode(node, allowedTokens, tokenValues) {
26930
27567
  return changed ? nextNode : node;
26931
27568
  }
26932
27569
  function interpolateRichTextTokens(value, options, context) {
26933
- if (!isRecord2(value)) return value;
27570
+ if (!isRecord3(value)) return value;
26934
27571
  const allowedTokens = new Set(options.tokens);
26935
27572
  const tokenValues = {
26936
27573
  year: String((/* @__PURE__ */ new Date()).getFullYear()),
26937
27574
  site_name: getSiteName(context)
26938
27575
  };
26939
- if (isRecord2(value.doc)) {
27576
+ if (isRecord3(value.doc)) {
26940
27577
  const nextDoc = visitRichTextNode(value.doc, allowedTokens, tokenValues);
26941
27578
  if (nextDoc === value.doc) return value;
26942
27579
  return { ...value, doc: nextDoc };
@@ -27735,6 +28372,8 @@ init_boxStyles();
27735
28372
  init_defineBlock();
27736
28373
  init_builder();
27737
28374
  init_fragments2();
28375
+ init_colorStyles();
28376
+ var backgroundImageClassName = "rb-absolute rb-inset-0 rb-z-neg-10 rb-h-full rb-w-full rb-object-cover rb-opacity-50";
27738
28377
  var wrapVariant = (variantLayout) => styledSection({
27739
28378
  children: styledContainer({
27740
28379
  children: stack(
@@ -27748,10 +28387,53 @@ var wrapVariant = (variantLayout) => styledSection({
27748
28387
  // styledContainer (rb-container) already provides horizontal padding
27749
28388
  baseClass: "",
27750
28389
  spacing: "comfortable",
27751
- imageClassName: "rb-absolute rb-inset-0 rb-z-neg-10 rb-h-full rb-w-full rb-object-cover rb-opacity-50"
28390
+ imageClassName: backgroundImageClassName
27752
28391
  });
27753
28392
  var carouselLayout = wrapVariant(buildCarouselLayout());
27754
28393
  var gridLayout2 = wrapVariant(buildGridLayout());
28394
+ var splitHeading = stack(
28395
+ { gap: "md", className: "rb-testimonials-split-heading-copy rb-max-w-xl" },
28396
+ [
28397
+ text(
28398
+ { as: "h2" },
28399
+ when("content.heading"),
28400
+ bind("content.heading")
28401
+ ),
28402
+ headingDecoration({
28403
+ family: "short-center-rule",
28404
+ placement: "after-heading"
28405
+ }),
28406
+ text(
28407
+ {
28408
+ as: "p",
28409
+ className: "rb-prose",
28410
+ style: textColorStyle("mutedText")
28411
+ },
28412
+ when("content.subheading"),
28413
+ bind("content.subheading")
28414
+ )
28415
+ ]
28416
+ );
28417
+ var splitGridLayout = styledSection({
28418
+ children: styledContainer({
28419
+ baseClassName: "rb-relative rb-isolate",
28420
+ children: el(
28421
+ "div",
28422
+ {
28423
+ className: "rb-testimonials-split-grid rb-grid rb-grid-cols-1 rb-gap-8 rb-lg-grid-cols-2 rb-lg-items-start"
28424
+ },
28425
+ [
28426
+ el("div", { className: "rb-testimonials-split-grid-heading" }, [splitHeading]),
28427
+ el("div", { className: "rb-testimonials-split-grid-cards" }, [
28428
+ buildGridCardsLayout("rb-testimonials-split-grid-card-list")
28429
+ ])
28430
+ ]
28431
+ )
28432
+ }),
28433
+ baseClass: "",
28434
+ spacing: "comfortable",
28435
+ imageClassName: backgroundImageClassName
28436
+ });
27755
28437
  var additionalFields = parseFieldDefinitions([
27756
28438
  // Heading fields from fragment
27757
28439
  ...testimonialsHeadingFragment.fields,
@@ -27783,7 +28465,7 @@ var additionalFields = parseFieldDefinitions([
27783
28465
  ],
27784
28466
  ui: {
27785
28467
  intent: "display",
27786
- visibleWhen: { field: "variant", equals: "grid" }
28468
+ visibleWhen: { field: "variant", oneOf: ["grid", "split-grid"] }
27787
28469
  }
27788
28470
  },
27789
28471
  // Carousel-specific fields (from fragment)
@@ -27817,7 +28499,8 @@ var testimonialsManifest = createBlockManifest({
27817
28499
  // Variant system - enables the variant switcher control in the editor
27818
28500
  variants: {
27819
28501
  carousel: carouselLayout,
27820
- grid: gridLayout2
28502
+ grid: gridLayout2,
28503
+ "split-grid": splitGridLayout
27821
28504
  },
27822
28505
  defaultVariant: "carousel",
27823
28506
  variantOptions: {
@@ -27830,6 +28513,11 @@ var testimonialsManifest = createBlockManifest({
27830
28513
  label: "Grid",
27831
28514
  description: "Responsive grid layout",
27832
28515
  icon: "Grid"
28516
+ },
28517
+ "split-grid": {
28518
+ label: "Split grid",
28519
+ description: "Heading on the left with testimonial cards on the right",
28520
+ icon: "PanelLeft"
27833
28521
  }
27834
28522
  },
27835
28523
  // Fields (variant field is auto-generated by augmentManifest)
@@ -28244,6 +28932,15 @@ init_ctas();
28244
28932
  init_builder();
28245
28933
  init_fragments();
28246
28934
  init_colorStyles();
28935
+
28936
+ // ../blocks/src/system/blocks/feature-card-icons.ts
28937
+ var FEATURE_CARD_ICON_TREATMENTS = [
28938
+ "plain",
28939
+ "soft-badge",
28940
+ "utility-badge"
28941
+ ];
28942
+
28943
+ // ../blocks/src/system/blocks/feature-cards.ts
28247
28944
  function grid3(props2, children) {
28248
28945
  return el("grid", props2 ?? void 0, children ?? void 0);
28249
28946
  }
@@ -28285,6 +28982,15 @@ var featureCard = styledCard(
28285
28982
  bind("card.media")
28286
28983
  ),
28287
28984
  stack({ gap: "sm", className: "rb-feature-card-content rb-flex-1 rb-p-6" }, [
28985
+ el(
28986
+ "feature-card-icon",
28987
+ {
28988
+ treatment: { $bind: { from: "content._iconTreatment", fallback: "soft-badge" } },
28989
+ generatedAssets: { $bind: { from: "data.generatedIconAssets" } }
28990
+ },
28991
+ null,
28992
+ bind("card.icon")
28993
+ ),
28288
28994
  text(
28289
28995
  {
28290
28996
  as: "h3",
@@ -28406,6 +29112,16 @@ var featureCardsConfig = {
28406
29112
  defaultValue: "4/3",
28407
29113
  visibleWhen: { field: "media", notEquals: null }
28408
29114
  }),
29115
+ {
29116
+ id: "icon",
29117
+ type: "text",
29118
+ label: "Icon",
29119
+ required: false,
29120
+ ui: {
29121
+ widget: "iconPicker",
29122
+ iconPickerPreset: "feature"
29123
+ }
29124
+ },
28409
29125
  {
28410
29126
  id: "title",
28411
29127
  type: "text",
@@ -28441,6 +29157,19 @@ var featureCardsConfig = {
28441
29157
  ]
28442
29158
  }
28443
29159
  },
29160
+ {
29161
+ id: "_iconTreatment",
29162
+ type: "select",
29163
+ label: "Icon style",
29164
+ required: false,
29165
+ defaultValue: "soft-badge",
29166
+ multiple: false,
29167
+ options: FEATURE_CARD_ICON_TREATMENTS.map((value) => ({
29168
+ value,
29169
+ label: value === "plain" ? "Plain" : value === "soft-badge" ? "Soft badge" : "Utility badge"
29170
+ })),
29171
+ ui: { intent: "display" }
29172
+ },
28444
29173
  cardStylesField({
28445
29174
  id: "_cardStyles",
28446
29175
  label: "Card styles"
@@ -33779,7 +34508,8 @@ var systemBlockDefinitionsRaw = [
33779
34508
  layoutProfiles: [
33780
34509
  layoutProfile({ variantKey: "default", family: "stack", weight: "standard" }),
33781
34510
  layoutProfile({ variantKey: "two-column", family: "split", weight: "standard" }),
33782
- layoutProfile({ variantKey: "question-columns", family: "grid", weight: "standard" })
34511
+ layoutProfile({ variantKey: "question-columns", family: "grid", weight: "standard" }),
34512
+ layoutProfile({ variantKey: "split-heading-columns", family: "split", weight: "standard" })
33783
34513
  ]
33784
34514
  })),
33785
34515
  withDesignCapability("block.site-header", siteHeaderBlockDefinition, declareNoBlockDesignCapability("site-chrome"), defineBlockDesignMetadata({
@@ -33810,6 +34540,12 @@ var systemBlockDefinitionsRaw = [
33810
34540
  family: "grid",
33811
34541
  weight: "standard",
33812
34542
  bias: "soft"
34543
+ }),
34544
+ layoutProfile({
34545
+ variantKey: "split-grid",
34546
+ family: "split",
34547
+ weight: "featured",
34548
+ bias: "soft"
33813
34549
  })
33814
34550
  ]
33815
34551
  })),
@@ -36402,10 +37138,16 @@ var dashboardConfigSchema = z.object({
36402
37138
  }).strip();
36403
37139
  var fieldDefinitionInputSchema = unsafeRetypeZodSchema(fieldSchema);
36404
37140
  var sdkLoaderEndpointSchema = z.enum(SUPPORTED_LOADER_ENDPOINTS);
37141
+ var loaderFallbackScalarSchema = z.union([
37142
+ z.string(),
37143
+ z.number(),
37144
+ z.boolean(),
37145
+ z.null()
37146
+ ]);
36405
37147
  var loaderParamBindingSchema = z.object({
36406
37148
  $bind: z.object({
36407
37149
  from: z.string().min(1, "Binding path is required"),
36408
- fallback: z.string().optional()
37150
+ fallback: loaderFallbackScalarSchema.optional()
36409
37151
  })
36410
37152
  });
36411
37153
  var loaderParamValueSchema = z.union([
@@ -36551,9 +37293,13 @@ var sdkBlockFieldOptionsMapSchema = z.record(
36551
37293
  var sdkContentTypeTemplateConfigSchema = z.object({
36552
37294
  blocks: z.array(z.unknown())
36553
37295
  }).passthrough();
37296
+ var sdkContentTypeOrderingConfigSchema = z.object({
37297
+ mode: z.enum(["default", "manual"]).optional()
37298
+ }).optional();
36554
37299
  var sdkContentTypeConfigSchema = z.object({
36555
37300
  key: z.string().min(1),
36556
37301
  fields: z.array(z.unknown()),
37302
+ ordering: sdkContentTypeOrderingConfigSchema,
36557
37303
  template: sdkContentTypeTemplateConfigSchema.nullable().optional()
36558
37304
  }).passthrough();
36559
37305
  var sdkContentConfigSchema = z.object({
@@ -36659,9 +37405,9 @@ z.object({
36659
37405
 
36660
37406
  // ../api/src/sdkContracts.ts
36661
37407
  var ignoredDocumentSyncSectionWarnings = {
36662
- pages: "content.pages is ignored by push-config; use `riverbankcms push pages` to sync pages.",
36663
- entries: "content.entries is ignored by push-config; use `riverbankcms push entries` to sync content entries.",
36664
- navigationMenus: "content.navigationMenus is ignored by push-config; use `riverbankcms push navigation` to sync navigation menus."
37408
+ pages: "content.pages is ignored by push-config; put pages in content/pages/*.json and use `riverbankcms push pages` (or `riverbankcms push`) to sync them.",
37409
+ entries: "content.entries is ignored by push-config; put entries in content/entries/<type>/*.json and use `riverbankcms push entries` (or `riverbankcms push`) to sync them.",
37410
+ navigationMenus: "content.navigationMenus is ignored by push-config; put navigation in content/navigation.json and use `riverbankcms push navigation` (or `riverbankcms push`) to sync it."
36665
37411
  };
36666
37412
  function formatIgnoredDocumentSyncSectionWarning(section2) {
36667
37413
  return ignoredDocumentSyncSectionWarnings[section2];
@@ -36823,18 +37569,21 @@ function buildEndpointURL(baseURL, endpoint) {
36823
37569
  function isFormDataBody(value) {
36824
37570
  return typeof FormData !== "undefined" && value instanceof FormData;
36825
37571
  }
37572
+ function isUnknownArray2(value) {
37573
+ return Array.isArray(value);
37574
+ }
36826
37575
  function appendQueryParam(queryParams, key, value) {
36827
37576
  if (value === void 0 || value === null) {
36828
37577
  return;
36829
37578
  }
36830
- if (Array.isArray(value)) {
37579
+ if (isUnknownArray2(value)) {
36831
37580
  const stack2 = [...value].reverse();
36832
37581
  while (stack2.length > 0) {
36833
37582
  const item = stack2.pop();
36834
37583
  if (item === void 0 || item === null) {
36835
37584
  continue;
36836
37585
  }
36837
- if (Array.isArray(item)) {
37586
+ if (isUnknownArray2(item)) {
36838
37587
  stack2.push(...[...item].reverse());
36839
37588
  continue;
36840
37589
  }
@@ -36844,6 +37593,12 @@ function appendQueryParam(queryParams, key, value) {
36844
37593
  }
36845
37594
  queryParams.append(key, String(value));
36846
37595
  }
37596
+ function serializePathParam(endpoint, key, value) {
37597
+ if (typeof value === "string") {
37598
+ return value;
37599
+ }
37600
+ throw new Error(`Invalid path param for endpoint ${String(endpoint)}: ${key} must be a string`);
37601
+ }
36847
37602
  function invalidateCacheTags(tags2, params) {
36848
37603
  const resolved = getRevalidateTag();
36849
37604
  if (typeof window !== "undefined" || !resolved || !tags2) return;
@@ -36982,8 +37737,9 @@ function createRawCMSClient(headers = {}, baseUrl) {
36982
37737
  const bracePlaceholder = `{${key}}`;
36983
37738
  const colonPlaceholder = `:${key}`;
36984
37739
  if (originalPath.includes(bracePlaceholder) || originalPath.includes(colonPlaceholder)) {
36985
- url = url.replace(bracePlaceholder, value);
36986
- url = url.replace(colonPlaceholder, value);
37740
+ const stringValue = serializePathParam(endpoint, key, value);
37741
+ url = url.replace(bracePlaceholder, stringValue);
37742
+ url = url.replace(colonPlaceholder, stringValue);
36987
37743
  } else {
36988
37744
  unusedParams[key] = value;
36989
37745
  }
@@ -37333,7 +38089,7 @@ function preset(id, verticalId, canonicalBehaviour, label, pluralLabel, descript
37333
38089
  }
37334
38090
 
37335
38091
  // ../api/src/utils/isRecord.ts
37336
- function isRecord3(value) {
38092
+ function isRecord4(value) {
37337
38093
  return typeof value === "object" && value !== null && !Array.isArray(value);
37338
38094
  }
37339
38095
  var APPOINTMENT_SETUP_MAX_MINUTES = 1440;
@@ -37606,7 +38362,7 @@ function sanitizeMarks(marks) {
37606
38362
  if (mark.type === "bold" || mark.type === "strong" || mark.type === "italic" || mark.type === "em") {
37607
38363
  return [{ type: mark.type }];
37608
38364
  }
37609
- if (mark.type === "link" && isRecord3(mark.attrs) && typeof mark.attrs.href === "string") {
38365
+ if (mark.type === "link" && isRecord4(mark.attrs) && typeof mark.attrs.href === "string") {
37610
38366
  const attrs = { href: mark.attrs.href };
37611
38367
  if (typeof mark.attrs.target === "string" && mark.attrs.target.trim().length > 0) {
37612
38368
  attrs.target = mark.attrs.target;
@@ -37621,10 +38377,10 @@ function sanitizeMarks(marks) {
37621
38377
  return sanitized.length > 0 ? sanitized : void 0;
37622
38378
  }
37623
38379
  function unwrapRichTextValue(value) {
37624
- if (isRecord3(value) && isRecord3(value.doc)) {
38380
+ if (isRecord4(value) && isRecord4(value.doc)) {
37625
38381
  return unwrapRichTextValue(value.doc);
37626
38382
  }
37627
- if (isRecord3(value) && value.type === "doc") {
38383
+ if (isRecord4(value) && value.type === "doc") {
37628
38384
  return {
37629
38385
  type: "doc",
37630
38386
  content: Array.isArray(value.content) ? value.content.filter(isTipTapNodeLike).map(coerceTipTapNode) : []
@@ -37633,7 +38389,7 @@ function unwrapRichTextValue(value) {
37633
38389
  return EMPTY_SITE_BANNER_BODY;
37634
38390
  }
37635
38391
  function isTipTapNodeLike(value) {
37636
- return isRecord3(value) && typeof value.type === "string";
38392
+ return isRecord4(value) && typeof value.type === "string";
37637
38393
  }
37638
38394
  function coerceTipTapNode(value) {
37639
38395
  return {
@@ -37641,9 +38397,9 @@ function coerceTipTapNode(value) {
37641
38397
  ...Array.isArray(value.content) ? { content: value.content.filter(isTipTapNodeLike).map(coerceTipTapNode) } : {},
37642
38398
  ...typeof value.text === "string" ? { text: value.text } : {},
37643
38399
  ...Array.isArray(value.marks) ? {
37644
- marks: value.marks.filter((mark) => isRecord3(mark) && typeof mark.type === "string").map((mark) => ({
38400
+ marks: value.marks.filter((mark) => isRecord4(mark) && typeof mark.type === "string").map((mark) => ({
37645
38401
  type: mark.type,
37646
- ...isRecord3(mark.attrs) ? { attrs: mark.attrs } : {}
38402
+ ...isRecord4(mark.attrs) ? { attrs: mark.attrs } : {}
37647
38403
  }))
37648
38404
  } : {}
37649
38405
  };
@@ -37759,7 +38515,7 @@ function collectCartLinkStats(items, depth = 0) {
37759
38515
  return result;
37760
38516
  }
37761
38517
  function isNavigationMenuValidationItem(value) {
37762
- if (!isRecord3(value)) return false;
38518
+ if (!isRecord4(value)) return false;
37763
38519
  return typeof value.label === "string";
37764
38520
  }
37765
38521
 
@@ -37775,7 +38531,6 @@ var websiteSurfaceIds = [
37775
38531
  "site.footerBlocks",
37776
38532
  "site.navigation",
37777
38533
  "site.media",
37778
- "site.style",
37779
38534
  "site.performance"
37780
38535
  ];
37781
38536
  new Set(
@@ -37795,6 +38550,104 @@ var hiddenDemoSettingsNavSurfaceIds = [
37795
38550
  "settings.backup"
37796
38551
  ];
37797
38552
  new Set(hiddenDemoSettingsNavSurfaceIds);
38553
+
38554
+ // ../api/src/navigation/identity.ts
38555
+ init_src();
38556
+ function unsafeAsNavigationMenuIdentifier(identifier) {
38557
+ return identifier;
38558
+ }
38559
+ function unsafeAsNavigationMenuIdentity(identity) {
38560
+ return identity;
38561
+ }
38562
+ var MAIN_NAVIGATION_MENU_IDENTIFIER = unsafeAsNavigationMenuIdentifier("main");
38563
+ function parseNavigationMenuIdentifier(value) {
38564
+ if (typeof value !== "string") {
38565
+ return err({ kind: "not_string" });
38566
+ }
38567
+ const trimmed = value.trim();
38568
+ if (trimmed.length === 0) {
38569
+ return err({ kind: "empty_string" });
38570
+ }
38571
+ return ok(unsafeAsNavigationMenuIdentifier(trimmed));
38572
+ }
38573
+ function normalizeNavigationMenuIdentifier(identifier) {
38574
+ const parsed = parseNavigationMenuIdentifier(identifier);
38575
+ return parsed.ok ? parsed.value : null;
38576
+ }
38577
+ function navigationMenuIdentity(input) {
38578
+ return unsafeAsNavigationMenuIdentity(
38579
+ normalizeNavigationMenuIdentifier(input.identifier) ?? input.name
38580
+ );
38581
+ }
38582
+ function planNavigationMenuMatch(input, menus) {
38583
+ const identifier = normalizeNavigationMenuIdentifier(input.identifier);
38584
+ if (identifier) {
38585
+ const identifierMatches = menus.filter(
38586
+ (menu) => normalizeNavigationMenuIdentifier(menu.identifier) === identifier
38587
+ );
38588
+ const identifierMatch = identifierMatches[0];
38589
+ if (identifierMatches.length === 1 && identifierMatch) {
38590
+ return {
38591
+ type: "update",
38592
+ menuId: identifierMatch.id,
38593
+ identifier
38594
+ };
38595
+ }
38596
+ if (identifierMatches.length > 1) {
38597
+ return {
38598
+ type: "identifier_conflict",
38599
+ identifier,
38600
+ menuIds: identifierMatches.map((menu) => menu.id)
38601
+ };
38602
+ }
38603
+ if (identifier === MAIN_NAVIGATION_MENU_IDENTIFIER) {
38604
+ const legacyPrimaryMatches = menus.filter(
38605
+ (menu) => menu.isPrimary && normalizeNavigationMenuIdentifier(menu.identifier) === null
38606
+ );
38607
+ const legacyPrimaryMatch = legacyPrimaryMatches[0];
38608
+ if (legacyPrimaryMatches.length === 1 && legacyPrimaryMatch) {
38609
+ return {
38610
+ type: "adopt_legacy_primary",
38611
+ menuId: legacyPrimaryMatch.id,
38612
+ identifier
38613
+ };
38614
+ }
38615
+ if (legacyPrimaryMatches.length > 1) {
38616
+ return {
38617
+ type: "ambiguous_legacy_primary",
38618
+ identifier,
38619
+ menuIds: legacyPrimaryMatches.map((menu) => menu.id)
38620
+ };
38621
+ }
38622
+ }
38623
+ return { type: "create", identifier };
38624
+ }
38625
+ const nameMatches = menus.filter((menu) => menu.name === input.name);
38626
+ const nameMatch = nameMatches[0];
38627
+ if (nameMatches.length === 1 && nameMatch) {
38628
+ return { type: "update", menuId: nameMatch.id, identifier: null };
38629
+ }
38630
+ if (nameMatches.length > 1) {
38631
+ return {
38632
+ type: "ambiguous_name",
38633
+ name: input.name,
38634
+ menuIds: nameMatches.map((menu) => menu.id)
38635
+ };
38636
+ }
38637
+ return { type: "create", identifier: null };
38638
+ }
38639
+ function actionableNavigationMenuMatchPlan(plan) {
38640
+ switch (plan.type) {
38641
+ case "create":
38642
+ case "update":
38643
+ case "adopt_legacy_primary":
38644
+ return ok(plan);
38645
+ case "identifier_conflict":
38646
+ case "ambiguous_legacy_primary":
38647
+ case "ambiguous_name":
38648
+ return err(plan);
38649
+ }
38650
+ }
37798
38651
  var Rfc6902PatchOp = z.discriminatedUnion("op", [
37799
38652
  // Standard RFC-6902 operations
37800
38653
  z.object({
@@ -38029,6 +38882,9 @@ var templateConfigSchemaForward = z.object({
38029
38882
  })
38030
38883
  )
38031
38884
  }).optional();
38885
+ var contentTypeOrderingSchema = z.object({
38886
+ mode: z.enum(["default", "manual"]).optional()
38887
+ }).optional();
38032
38888
  var contentTypeConfigSchema = z.object({
38033
38889
  key: contentTypeKeySchema,
38034
38890
  name: z.string().min(1),
@@ -38038,6 +38894,7 @@ var contentTypeConfigSchema = z.object({
38038
38894
  // Fields are validated as unknown[] here - deep field validation happens in @riverbankcms/blocks
38039
38895
  fields: z.array(z.any()).min(1, "At least one field is required"),
38040
38896
  titleField: z.string().optional(),
38897
+ ordering: contentTypeOrderingSchema,
38041
38898
  isSingleton: z.boolean().optional().default(false),
38042
38899
  template: templateConfigSchemaForward
38043
38900
  }).refine(
@@ -38563,7 +39420,7 @@ var loaderParamBindingSchema2 = z.object({
38563
39420
  // Loader params are ultimately string-normalized for query strings, so fallbacks should
38564
39421
  // stay scalar. Use transforms (e.g. `value.jsonArray`) when you need to serialize
38565
39422
  // more complex values into a string.
38566
- fallback: z.union([z.string(), z.number(), z.boolean(), z.null()]).optional(),
39423
+ fallback: loaderFallbackScalarSchema.optional(),
38567
39424
  transforms: z.array(loaderTransformStepSchema).default([]),
38568
39425
  pick: z.enum(["value", "collection", "context"]).default("value"),
38569
39426
  coerce: z.enum(["number", "boolean", "string"]).optional()
@@ -38904,20 +39761,20 @@ var ManagementApiError = class extends Error {
38904
39761
  function is404Error(error) {
38905
39762
  return error instanceof ManagementApiError && error.statusCode === 404;
38906
39763
  }
38907
- function isRecord4(value) {
39764
+ function isRecord5(value) {
38908
39765
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
38909
39766
  }
38910
39767
  function isFieldError(value) {
38911
- return isRecord4(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string";
39768
+ return isRecord5(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string";
38912
39769
  }
38913
39770
  function parseApiResponse(value) {
38914
- if (!isRecord4(value)) return null;
39771
+ if (!isRecord5(value)) return null;
38915
39772
  if (value.success === true) {
38916
39773
  return { success: true, data: value.data };
38917
39774
  }
38918
39775
  if (value.success === false) {
38919
39776
  const error = value.error;
38920
- if (!isRecord4(error) || typeof error.code !== "string" || typeof error.message !== "string") {
39777
+ if (!isRecord5(error) || typeof error.code !== "string" || typeof error.message !== "string") {
38921
39778
  return { success: false, error: { code: "sdk:http-error", message: "Request failed", details: error } };
38922
39779
  }
38923
39780
  const fieldErrorsRaw = error.fieldErrors;
@@ -39261,9 +40118,10 @@ function createNavigationOperations(http) {
39261
40118
  async upsert(input) {
39262
40119
  const result = await http.post("/navigation", input);
39263
40120
  return mapPulledNavigationMenu({
39264
- ...result.menu,
39265
- identifier: null
39266
- });
40121
+ ...result.menu});
40122
+ },
40123
+ async delete(menuId) {
40124
+ await http.delete(`/navigation/${encodeURIComponent(menuId)}`);
39267
40125
  }
39268
40126
  };
39269
40127
  }
@@ -39627,6 +40485,7 @@ function createPullOperations(http) {
39627
40485
  meta: {
39628
40486
  pulledAt: (/* @__PURE__ */ new Date()).toISOString(),
39629
40487
  entries: entriesResult?.meta?.entries,
40488
+ settingsUpdatedAt: settingsResult?.meta?.updatedAt,
39630
40489
  truncated: entriesResult?.meta?.truncated,
39631
40490
  truncationMessage: entriesResult?.meta?.truncationMessage
39632
40491
  }
@@ -39807,7 +40666,11 @@ function getEnv(name, fallback) {
39807
40666
  function loadEnvironment(remote) {
39808
40667
  const target = remote ? "remote" : "local";
39809
40668
  const prefix = getEnvPrefix(target);
39810
- const siteId = asSiteId(requireEnv(`${prefix}_SITE_ID`));
40669
+ const rawSiteId = requireEnv(`${prefix}_SITE_ID`);
40670
+ const siteId = parseSiteId(rawSiteId);
40671
+ if (!siteId.ok) {
40672
+ throw new Error(`Invalid site ID for ${prefix}_SITE_ID. Expected a UUID.`);
40673
+ }
39811
40674
  const dashboardUrl = requireEnv(`${prefix}_DASHBOARD_URL`);
39812
40675
  const managementApiKey = requireEnv(`${prefix}_MGMT_API_KEY`);
39813
40676
  const apiKey = getEnv(`${prefix}_API_KEY`);
@@ -39834,7 +40697,7 @@ function loadEnvironment(remote) {
39834
40697
  }
39835
40698
  }
39836
40699
  return {
39837
- siteId,
40700
+ siteId: siteId.value,
39838
40701
  dashboardUrl,
39839
40702
  managementApiKey,
39840
40703
  apiKey,
@@ -40136,7 +40999,8 @@ function mapEntryForOutput(entry) {
40136
40999
  data: entry.data,
40137
41000
  status: entry.status,
40138
41001
  hasUnpublishedChanges: entry.hasUnpublishedChanges,
40139
- title: entry.title
41002
+ title: entry.title,
41003
+ manualOrder: entry.manualOrder
40140
41004
  };
40141
41005
  if (entry.slug !== void 0) {
40142
41006
  result.slug = entry.slug;
@@ -40427,7 +41291,7 @@ function createListCommand(config2) {
40427
41291
 
40428
41292
  // src/cli/push-config.ts
40429
41293
  var DEFAULT_CONFIG_PATH = "./riverbank.config.ts";
40430
- function isRecord5(value) {
41294
+ function isRecord6(value) {
40431
41295
  return typeof value === "object" && value !== null;
40432
41296
  }
40433
41297
  function parseErrorDetails(value) {
@@ -40435,10 +41299,10 @@ function parseErrorDetails(value) {
40435
41299
  if (typeof value === "string") {
40436
41300
  return { message: value };
40437
41301
  }
40438
- if (!isRecord5(value)) return {};
41302
+ if (!isRecord6(value)) return {};
40439
41303
  const message = typeof value.message === "string" ? value.message : void 0;
40440
41304
  const fieldErrorsRaw = value.fieldErrors;
40441
- const fieldErrors = Array.isArray(fieldErrorsRaw) ? fieldErrorsRaw.filter(isRecord5).map((d) => ({
41305
+ const fieldErrors = Array.isArray(fieldErrorsRaw) ? fieldErrorsRaw.filter(isRecord6).map((d) => ({
40442
41306
  field: typeof d.field === "string" ? d.field : "",
40443
41307
  message: typeof d.message === "string" ? d.message : ""
40444
41308
  })).filter((d) => d.field.length > 0 && d.message.length > 0) : void 0;
@@ -40450,12 +41314,12 @@ function formatFieldErrors(fieldErrors) {
40450
41314
  }
40451
41315
  function getDashboardErrorMessage(responseJson, fallback) {
40452
41316
  if (!responseJson) return fallback;
40453
- if (isRecord5(responseJson) && responseJson.success === false && "error" in responseJson) {
41317
+ if (isRecord6(responseJson) && responseJson.success === false && "error" in responseJson) {
40454
41318
  const parsed = parseErrorDetails(responseJson.error);
40455
41319
  const msg = parsed.message ?? fallback;
40456
41320
  return msg + formatFieldErrors(parsed.fieldErrors);
40457
41321
  }
40458
- if (isRecord5(responseJson) && "error" in responseJson) {
41322
+ if (isRecord6(responseJson) && "error" in responseJson) {
40459
41323
  const parsed = parseErrorDetails(responseJson.error);
40460
41324
  const msg = parsed.message ?? fallback;
40461
41325
  return msg + formatFieldErrors(parsed.fieldErrors);
@@ -40813,9 +41677,34 @@ function convertPulledFooterToLocal(remoteFooter) {
40813
41677
  return { bottomText: remoteFooter.bottomText };
40814
41678
  }
40815
41679
 
41680
+ // src/cli/navigationIdentity.ts
41681
+ init_src();
41682
+ var navigationIdentity = navigationMenuIdentity;
41683
+ function navigationIdentityMap(menus) {
41684
+ const byIdentity = /* @__PURE__ */ new Map();
41685
+ const menuNamesByIdentity = /* @__PURE__ */ new Map();
41686
+ for (const menu of menus) {
41687
+ const identity = navigationIdentity(menu);
41688
+ const existingNames = menuNamesByIdentity.get(identity);
41689
+ if (existingNames) {
41690
+ return err({
41691
+ code: "duplicate_navigation_identity",
41692
+ identity,
41693
+ menuNames: [...existingNames, menu.name]
41694
+ });
41695
+ }
41696
+ byIdentity.set(identity, menu);
41697
+ menuNamesByIdentity.set(identity, [menu.name]);
41698
+ }
41699
+ return ok(byIdentity);
41700
+ }
41701
+ function duplicateNavigationIdentityMessage(error) {
41702
+ return `Duplicate navigation menu identity '${error.identity}' for menus: ${error.menuNames.join(", ")}. Use unique navigation identifiers or names before syncing.`;
41703
+ }
41704
+
40816
41705
  // src/cli/media/portable.ts
40817
41706
  var ENV_SPECIFIC_MEDIA_KEYS = ["assetId", "storagePath", "storageBucket"];
40818
- var isRecord6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
41707
+ var isRecord7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
40819
41708
  var isMediaObject = (value) => value.type === "image" || value.type === "video";
40820
41709
  function stripEnvSpecificMediaFieldsInPlace(value) {
40821
41710
  if (value === null || value === void 0) return;
@@ -40825,7 +41714,7 @@ function stripEnvSpecificMediaFieldsInPlace(value) {
40825
41714
  }
40826
41715
  return;
40827
41716
  }
40828
- if (!isRecord6(value)) return;
41717
+ if (!isRecord7(value)) return;
40829
41718
  if (isMediaObject(value)) {
40830
41719
  const hasCmsRef = typeof value.identifier === "string" || typeof value.assetId === "string" || typeof value.storagePath === "string" || typeof value.storageBucket === "string";
40831
41720
  for (const key of ENV_SPECIFIC_MEDIA_KEYS) {
@@ -40836,7 +41725,7 @@ function stripEnvSpecificMediaFieldsInPlace(value) {
40836
41725
  }
40837
41726
  delete value.mimeType;
40838
41727
  }
40839
- if (value.type === "image" && isRecord6(value.attrs)) {
41728
+ if (value.type === "image" && isRecord7(value.attrs)) {
40840
41729
  const attrs = value.attrs;
40841
41730
  const hasIdentifier = typeof attrs.identifier === "string" && attrs.identifier.trim().length > 0;
40842
41731
  if (hasIdentifier) {
@@ -41007,6 +41896,15 @@ function entryFilePath(input) {
41007
41896
  }
41008
41897
 
41009
41898
  // src/cli/content/writer.ts
41899
+ function isRecord8(value) {
41900
+ return typeof value === "object" && value !== null && !Array.isArray(value);
41901
+ }
41902
+ function parseThemeMeta(value) {
41903
+ if (!isRecord8(value) || typeof value.pulledAt !== "string" || !isRecord8(value.themes)) {
41904
+ return null;
41905
+ }
41906
+ return { pulledAt: value.pulledAt, themes: value.themes };
41907
+ }
41010
41908
  async function writeEntries(contentDir, pulledEntries, options) {
41011
41909
  const entriesDir = path5.join(contentDir, "entries");
41012
41910
  const metaDir = path5.join(contentDir, ".meta");
@@ -41038,23 +41936,33 @@ async function writeEntries(contentDir, pulledEntries, options) {
41038
41936
  const metaPath = path5.join(metaDir, `${contentType}.json`);
41039
41937
  if (!options?.skipMeta) {
41040
41938
  await ensureDir(metaDir);
41939
+ const nextMeta = {
41940
+ ...meta,
41941
+ manualOrder: entries.slice().sort((left, right) => {
41942
+ const leftOrder = left.manualOrder ?? Number.MAX_SAFE_INTEGER;
41943
+ const rightOrder = right.manualOrder ?? Number.MAX_SAFE_INTEGER;
41944
+ if (leftOrder !== rightOrder) return leftOrder - rightOrder;
41945
+ return left.identifier.localeCompare(right.identifier);
41946
+ }).map((entry) => entry.identifier)
41947
+ };
41041
41948
  if (options?.cleanupMissing === false) {
41042
41949
  try {
41043
41950
  const existing = JSON.parse(await fs5.readFile(metaPath, "utf-8"));
41044
41951
  await writeJsonFile(metaPath, {
41045
41952
  ...existing,
41046
- pulledAt: meta.pulledAt,
41953
+ pulledAt: nextMeta.pulledAt,
41954
+ manualOrder: nextMeta.manualOrder,
41047
41955
  entries: {
41048
41956
  ...existing.entries,
41049
- ...meta.entries
41957
+ ...nextMeta.entries
41050
41958
  }
41051
41959
  });
41052
41960
  } catch (error) {
41053
41961
  if (error.code !== "ENOENT") throw error;
41054
- await writeJsonFile(metaPath, meta);
41962
+ await writeJsonFile(metaPath, nextMeta);
41055
41963
  }
41056
41964
  } else {
41057
- await writeJsonFile(metaPath, meta);
41965
+ await writeJsonFile(metaPath, nextMeta);
41058
41966
  }
41059
41967
  }
41060
41968
  if (!options?.skipMeta && options?.entryBaseSnapshot) {
@@ -41122,7 +42030,7 @@ async function writeNavigation(contentDir, pulledNavigation, options) {
41122
42030
  await writeJsonFile(filePath, localNavigation);
41123
42031
  const menusMeta = {};
41124
42032
  for (const menu of pulledNavigation.menus) {
41125
- menusMeta[menu.name] = {
42033
+ menusMeta[navigationIdentity(menu)] = {
41126
42034
  createdAt: menu.createdAt,
41127
42035
  updatedAt: menu.updatedAt
41128
42036
  };
@@ -41137,11 +42045,19 @@ async function writeNavigation(contentDir, pulledNavigation, options) {
41137
42045
  }
41138
42046
  return { filePath, metaPath };
41139
42047
  }
41140
- async function writeSettings(contentDir, pulledSettings) {
42048
+ async function writeSettings(contentDir, pulledSettings, options) {
41141
42049
  await ensureDir(contentDir);
41142
42050
  const filePath = path5.join(contentDir, "settings.json");
41143
42051
  stripEnvSpecificMediaFieldsInPlace(pulledSettings.settings);
41144
42052
  await writeJsonFile(filePath, pulledSettings.settings);
42053
+ if (!options?.skipMeta) {
42054
+ const metaDir = path5.join(contentDir, ".meta");
42055
+ await ensureDir(metaDir);
42056
+ await writeJsonFile(path5.join(metaDir, "settings.json"), {
42057
+ pulledAt: pulledSettings.meta.pulledAt,
42058
+ updatedAt: pulledSettings.meta.updatedAt ?? null
42059
+ });
42060
+ }
41145
42061
  return filePath;
41146
42062
  }
41147
42063
  async function writeForms(contentDir, pulledForms, options) {
@@ -41204,7 +42120,7 @@ async function writePulledTheme(contentDir, pulledTheme, themeName = "current",
41204
42120
  };
41205
42121
  try {
41206
42122
  const content = await fs5.readFile(metaPath, "utf-8");
41207
- existingMeta = JSON.parse(content);
42123
+ existingMeta = parseThemeMeta(JSON.parse(content)) ?? existingMeta;
41208
42124
  } catch {
41209
42125
  }
41210
42126
  existingMeta.pulledAt = pulledTheme.meta.pulledAt;
@@ -41423,7 +42339,7 @@ async function updateMetadataAfterPush(contentDir, remoteContent) {
41423
42339
  const metaPath = path5.join(metaDir, "navigation.json");
41424
42340
  const menusMeta = {};
41425
42341
  for (const menu of remoteContent.navigation) {
41426
- menusMeta[menu.name] = {
42342
+ menusMeta[navigationIdentity(menu)] = {
41427
42343
  createdAt: menu.createdAt,
41428
42344
  updatedAt: menu.updatedAt
41429
42345
  };
@@ -41433,6 +42349,12 @@ async function updateMetadataAfterPush(contentDir, remoteContent) {
41433
42349
  menus: menusMeta
41434
42350
  });
41435
42351
  }
42352
+ if (remoteContent.settingsUpdatedAt !== void 0) {
42353
+ await writeJsonFile(path5.join(metaDir, "settings.json"), {
42354
+ pulledAt: now,
42355
+ updatedAt: remoteContent.settingsUpdatedAt
42356
+ });
42357
+ }
41436
42358
  if (remoteContent.forms && remoteContent.forms.length > 0) {
41437
42359
  const metaPath = path5.join(metaDir, "forms.json");
41438
42360
  const formsMeta = {};
@@ -41591,6 +42513,7 @@ async function readEntries(contentDir, contentType) {
41591
42513
  for (const item of items) {
41592
42514
  if (item.isDirectory()) {
41593
42515
  const entries = await readEntriesFromDirectory(path5.join(entriesDir, item.name));
42516
+ await applyManualOrderMetadata(contentDir, item.name, entries);
41594
42517
  if (entries.length > 0) {
41595
42518
  result.set(item.name, entries);
41596
42519
  }
@@ -41602,6 +42525,24 @@ async function readEntries(contentDir, contentType) {
41602
42525
  }
41603
42526
  return result;
41604
42527
  }
42528
+ async function applyManualOrderMetadata(contentDir, contentType, entries) {
42529
+ const meta = await readEntriesMeta(contentDir, contentType);
42530
+ const order = meta?.manualOrder;
42531
+ if (!order?.length) return;
42532
+ const orderByIdentifier = new Map(order.map((identifier, index) => [identifier, index]));
42533
+ for (const entry of entries) {
42534
+ const manualOrder = orderByIdentifier.get(entry.identifier);
42535
+ if (manualOrder !== void 0) {
42536
+ entry.manualOrder = manualOrder;
42537
+ }
42538
+ }
42539
+ entries.sort((left, right) => {
42540
+ const leftOrder = left.manualOrder ?? Number.MAX_SAFE_INTEGER;
42541
+ const rightOrder = right.manualOrder ?? Number.MAX_SAFE_INTEGER;
42542
+ if (leftOrder !== rightOrder) return leftOrder - rightOrder;
42543
+ return left.identifier.localeCompare(right.identifier);
42544
+ });
42545
+ }
41605
42546
  async function readPages(contentDir) {
41606
42547
  const pagesDir = path5.join(contentDir, "pages");
41607
42548
  const pages = [];
@@ -41798,6 +42739,10 @@ async function getContentSummary(contentDir) {
41798
42739
  courseCount: content.courses.length
41799
42740
  };
41800
42741
  }
42742
+ var settingsMetadataSchema = z.object({
42743
+ pulledAt: z.string(),
42744
+ updatedAt: z.string().nullable()
42745
+ });
41801
42746
  async function readEntriesMeta(contentDir, contentType) {
41802
42747
  const metaPath = path5.join(contentDir, ".meta", `${contentType}.json`);
41803
42748
  try {
@@ -41818,6 +42763,7 @@ async function readAllMeta(contentDir) {
41818
42763
  const skipFiles = [
41819
42764
  "pages.json",
41820
42765
  "navigation.json",
42766
+ "settings.json",
41821
42767
  "forms.json",
41822
42768
  "themes.json",
41823
42769
  "footer.json",
@@ -41838,6 +42784,22 @@ async function readAllMeta(contentDir) {
41838
42784
  }
41839
42785
  return metaMap;
41840
42786
  }
42787
+ async function readSettingsMeta(contentDir) {
42788
+ const metaPath = path5.join(contentDir, ".meta", "settings.json");
42789
+ try {
42790
+ const content = await fs5.readFile(metaPath, "utf-8");
42791
+ const parsed = settingsMetadataSchema.safeParse(JSON.parse(content));
42792
+ if (!parsed.success) {
42793
+ throw new Error("Invalid settings metadata in .meta/settings.json");
42794
+ }
42795
+ return parsed.data;
42796
+ } catch (error) {
42797
+ if (error.code === "ENOENT") {
42798
+ return null;
42799
+ }
42800
+ throw error;
42801
+ }
42802
+ }
41841
42803
  async function readPagesMeta(contentDir) {
41842
42804
  const metaPath = path5.join(contentDir, ".meta", "pages.json");
41843
42805
  try {
@@ -42324,9 +43286,9 @@ async function localMediaFileExists(filePath) {
42324
43286
  }
42325
43287
 
42326
43288
  // src/cli/media/identifiers.ts
42327
- var isRecord7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
43289
+ var isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
42328
43290
  var isMediaValue = (value) => {
42329
- if (!isRecord7(value)) return false;
43291
+ if (!isRecord9(value)) return false;
42330
43292
  const type = value.type;
42331
43293
  if (type !== "image" && type !== "video" && type !== "audio" && type !== "document" && type !== "spreadsheet" && type !== "archive") return false;
42332
43294
  return typeof value.identifier === "string" || typeof value.assetId === "string" || typeof value.storagePath === "string" || typeof value.src === "string";
@@ -42341,7 +43303,7 @@ var walkMediaValues = (value, location2, handler) => {
42341
43303
  });
42342
43304
  return;
42343
43305
  }
42344
- if (isRecord7(value)) {
43306
+ if (isRecord9(value)) {
42345
43307
  Object.entries(value).forEach(([key, entry]) => {
42346
43308
  walkMediaValues(entry, location2 ? `${location2}.${key}` : key, handler);
42347
43309
  });
@@ -42449,7 +43411,7 @@ var normalizeMediaValueToIdentifierOnly = (value, identifier, asset) => {
42449
43411
  };
42450
43412
 
42451
43413
  // src/cli/media/rich-text.ts
42452
- var isRecord8 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
43414
+ var isRecord10 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
42453
43415
  function collectRichTextImageAttrs(value, out = [], location2 = "") {
42454
43416
  if (Array.isArray(value)) {
42455
43417
  value.forEach(
@@ -42457,8 +43419,8 @@ function collectRichTextImageAttrs(value, out = [], location2 = "") {
42457
43419
  );
42458
43420
  return out;
42459
43421
  }
42460
- if (!isRecord8(value)) return out;
42461
- if (value.type === "image" && isRecord8(value.attrs)) {
43422
+ if (!isRecord10(value)) return out;
43423
+ if (value.type === "image" && isRecord10(value.attrs)) {
42462
43424
  out.push({ attrs: value.attrs, location: location2 ? `${location2}.attrs` : "attrs" });
42463
43425
  }
42464
43426
  for (const [key, child] of Object.entries(value)) {
@@ -43311,15 +44273,78 @@ function determineStatusChange(localStatus, remoteStatus) {
43311
44273
  }
43312
44274
  return void 0;
43313
44275
  }
44276
+ function findRemoteNavigationMenuForLocal(localMenu, remoteNavigation) {
44277
+ const plan = actionableNavigationMenuMatchPlan(
44278
+ planNavigationMenuMatch(localMenu, remoteNavigationMatchCandidates(remoteNavigation))
44279
+ );
44280
+ const menuId = plan.ok ? matchedNavigationMenuId(plan.value) : void 0;
44281
+ if (!menuId) return void 0;
44282
+ return remoteNavigation.find((menu) => remoteNavigationCandidateId(menu) === menuId);
44283
+ }
44284
+ function findLocalNavigationMenuForRemote(remoteMenu, localNavigation) {
44285
+ const localMenus = localNavigation?.menus ?? [];
44286
+ const directPlan = actionableNavigationMenuMatchPlan(
44287
+ planNavigationMenuMatch(remoteMenu, localNavigationMatchCandidates(localMenus))
44288
+ );
44289
+ const directMenuId = directPlan.ok ? matchedNavigationMenuId(directPlan.value) : void 0;
44290
+ if (directMenuId) {
44291
+ return localMenus.find((menu) => navigationIdentity(menu) === directMenuId);
44292
+ }
44293
+ if (!remoteMenu.isPrimary || remoteMenu.identifier !== null) return void 0;
44294
+ const legacyMainPlan = actionableNavigationMenuMatchPlan(
44295
+ planNavigationMenuMatch(
44296
+ { identifier: "main", name: remoteMenu.name },
44297
+ localNavigationMatchCandidates(localMenus)
44298
+ )
44299
+ );
44300
+ const legacyMainMenuId = legacyMainPlan.ok ? matchedNavigationMenuId(legacyMainPlan.value) : void 0;
44301
+ if (!legacyMainMenuId) return void 0;
44302
+ return localMenus.find((menu) => navigationIdentity(menu) === legacyMainMenuId);
44303
+ }
44304
+ function matchedNavigationMenuId(plan) {
44305
+ switch (plan.type) {
44306
+ case "create":
44307
+ return void 0;
44308
+ case "update":
44309
+ case "adopt_legacy_primary":
44310
+ return plan.menuId;
44311
+ }
44312
+ }
44313
+ function localNavigationMatchCandidates(menus) {
44314
+ return menus.map((menu) => ({
44315
+ id: navigationIdentity(menu),
44316
+ identifier: menu.identifier,
44317
+ name: menu.name,
44318
+ isPrimary: menu.isPrimary ?? false
44319
+ }));
44320
+ }
44321
+ function remoteNavigationMatchCandidates(menus) {
44322
+ return menus.map((menu) => ({
44323
+ id: remoteNavigationCandidateId(menu),
44324
+ identifier: menu.identifier,
44325
+ name: menu.name,
44326
+ isPrimary: menu.isPrimary
44327
+ }));
44328
+ }
44329
+ function remoteNavigationCandidateId(menu) {
44330
+ return menu.id ?? navigationIdentity(menu);
44331
+ }
43314
44332
  function buildJsonDiff(diff, local, remote, mode) {
43315
44333
  const summary = { creates: 0, updates: 0, deletes: 0, publishes: 0, unpublishes: 0 };
43316
44334
  const changes = [];
44335
+ const warnings = [];
43317
44336
  const localPages = new Map(local.pages.map((page) => [page.identifier, page]));
43318
44337
  const remotePages = new Map(remote.pages.map((page) => [page.identifier, page]));
43319
44338
  const localEntries = local.entries;
43320
44339
  const remoteEntries = remote.entries;
43321
- const localMenus = new Map((local.navigation?.menus ?? []).map((menu) => [menu.name, menu]));
43322
- const remoteMenus = new Map(remote.navigation.map((menu) => [menu.name, menu]));
44340
+ const localMenus = navigationIdentityMap(local.navigation?.menus ?? []);
44341
+ const remoteMenus = navigationIdentityMap(remote.navigation);
44342
+ if (!localMenus.ok) {
44343
+ warnings.push(jsonDiffDuplicateNavigationIdentityWarning("local", localMenus.error));
44344
+ }
44345
+ if (!remoteMenus.ok) {
44346
+ warnings.push(jsonDiffDuplicateNavigationIdentityWarning("remote", remoteMenus.error));
44347
+ }
43323
44348
  const localForms = new Map(local.forms.map((form2) => [form2.slug, form2]));
43324
44349
  const remoteForms = new Map(remote.forms.map((form2) => [form2.slug, form2]));
43325
44350
  const addChange = (change) => {
@@ -43404,9 +44429,9 @@ function buildJsonDiff(diff, local, remote, mode) {
43404
44429
  for (const navDiff of diff.navigation) {
43405
44430
  if (navDiff.type === "unchanged") continue;
43406
44431
  if (navDiff.type !== "create" && navDiff.type !== "update") continue;
43407
- const identifier = navDiff.name;
43408
- const localMenu = localMenus.get(navDiff.name);
43409
- const remoteMenu = remoteMenus.get(navDiff.name);
44432
+ const identifier = navigationIdentity(navDiff);
44433
+ const localMenu = localMenus.ok ? localMenus.value.get(identifier) : void 0;
44434
+ const remoteMenu = localMenu ? findRemoteNavigationMenuForLocal(localMenu, remote.navigation) : remoteMenus.ok ? remoteMenus.value.get(identifier) : void 0;
43410
44435
  const change = {
43411
44436
  type: "navigation",
43412
44437
  identifier,
@@ -43450,7 +44475,20 @@ function buildJsonDiff(diff, local, remote, mode) {
43450
44475
  }
43451
44476
  addChange(change);
43452
44477
  }
43453
- return { summary, changes };
44478
+ return {
44479
+ summary,
44480
+ changes,
44481
+ ...warnings.length > 0 ? { warnings } : {}
44482
+ };
44483
+ }
44484
+ function jsonDiffDuplicateNavigationIdentityWarning(source, error) {
44485
+ return {
44486
+ type: "duplicate_navigation_identity",
44487
+ source,
44488
+ identity: error.identity,
44489
+ menuNames: error.menuNames,
44490
+ message: duplicateNavigationIdentityMessage(error)
44491
+ };
43454
44492
  }
43455
44493
  function calculateEntryDiffs(localEntries, remoteEntries, options) {
43456
44494
  const diffs = /* @__PURE__ */ new Map();
@@ -43462,7 +44500,8 @@ function calculateEntryDiffs(localEntries, remoteEntries, options) {
43462
44500
  for (const entry of entries) {
43463
44501
  typeMap.set(entry.identifier, {
43464
44502
  data: entry.data,
43465
- status: entry.status
44503
+ status: entry.status,
44504
+ manualOrder: entry.manualOrder
43466
44505
  });
43467
44506
  }
43468
44507
  remoteLookup.set(contentType, typeMap);
@@ -43501,6 +44540,9 @@ function calculateEntryDiffs(localEntries, remoteEntries, options) {
43501
44540
  remoteEntry.data
43502
44541
  ));
43503
44542
  }
44543
+ if (typeof localEntry.manualOrder === "number" && localEntry.manualOrder !== remoteEntry.manualOrder) {
44544
+ changes.push("manualOrder");
44545
+ }
43504
44546
  const statusChange2 = determineStatusChange(localEntry.status, remoteEntry.status);
43505
44547
  if (changes.length > 0) {
43506
44548
  typeDiffs.push({
@@ -43707,20 +44749,23 @@ function calculateNavigationDiffs(localNavigation, remoteNavigation) {
43707
44749
  if (!localNavigation || !localNavigation.menus) {
43708
44750
  return { diffs, summary };
43709
44751
  }
43710
- const remoteLookup = /* @__PURE__ */ new Map();
43711
- for (const menu of remoteNavigation) {
43712
- remoteLookup.set(menu.name, menu);
43713
- }
43714
44752
  for (const localMenu of localNavigation.menus) {
43715
- const remoteMenu = remoteLookup.get(localMenu.name);
44753
+ const remoteMenu = findRemoteNavigationMenuForLocal(
44754
+ localMenu,
44755
+ remoteNavigation
44756
+ );
43716
44757
  if (!remoteMenu) {
43717
44758
  diffs.push({
43718
44759
  type: "create",
44760
+ identifier: localMenu.identifier,
43719
44761
  name: localMenu.name
43720
44762
  });
43721
44763
  summary.create++;
43722
44764
  } else {
43723
44765
  const changes = [];
44766
+ if (localMenu.name !== remoteMenu.name) {
44767
+ changes.push("name");
44768
+ }
43724
44769
  if (!equal(localMenu.items, stripNavigationItemIds(remoteMenu.items))) {
43725
44770
  changes.push("items");
43726
44771
  }
@@ -43733,6 +44778,7 @@ function calculateNavigationDiffs(localNavigation, remoteNavigation) {
43733
44778
  if (changes.length > 0) {
43734
44779
  diffs.push({
43735
44780
  type: "update",
44781
+ identifier: localMenu.identifier,
43736
44782
  name: localMenu.name,
43737
44783
  changes
43738
44784
  });
@@ -43740,6 +44786,7 @@ function calculateNavigationDiffs(localNavigation, remoteNavigation) {
43740
44786
  } else {
43741
44787
  diffs.push({
43742
44788
  type: "unchanged",
44789
+ identifier: localMenu.identifier,
43743
44790
  name: localMenu.name
43744
44791
  });
43745
44792
  summary.unchanged++;
@@ -44124,19 +45171,23 @@ function calculatePullDiff(remote, local) {
44124
45171
  }
44125
45172
  const navDiffs = [];
44126
45173
  const navSummary = { create: 0, update: 0, unchanged: 0 };
44127
- const localNavLookup = /* @__PURE__ */ new Map();
44128
- if (local?.navigation?.menus) {
44129
- for (const menu of local.navigation.menus) {
44130
- localNavLookup.set(menu.name, menu);
44131
- }
44132
- }
44133
45174
  for (const remoteMenu of remote.navigation) {
44134
- const localMenu = localNavLookup.get(remoteMenu.name);
45175
+ const localMenu = findLocalNavigationMenuForRemote(
45176
+ remoteMenu,
45177
+ local?.navigation ?? null
45178
+ );
44135
45179
  if (!localMenu) {
44136
- navDiffs.push({ type: "create", name: remoteMenu.name });
45180
+ navDiffs.push({
45181
+ type: "create",
45182
+ identifier: remoteMenu.identifier,
45183
+ name: remoteMenu.name
45184
+ });
44137
45185
  navSummary.create++;
44138
45186
  } else {
44139
45187
  const changes = [];
45188
+ if (localMenu.name !== remoteMenu.name) {
45189
+ changes.push("name");
45190
+ }
44140
45191
  if (!equal(stripNavigationItemIds(remoteMenu.items), localMenu.items)) {
44141
45192
  changes.push("items");
44142
45193
  }
@@ -44147,10 +45198,19 @@ function calculatePullDiff(remote, local) {
44147
45198
  changes.push("isFooter");
44148
45199
  }
44149
45200
  if (changes.length > 0) {
44150
- navDiffs.push({ type: "update", name: remoteMenu.name, changes });
45201
+ navDiffs.push({
45202
+ type: "update",
45203
+ identifier: remoteMenu.identifier,
45204
+ name: remoteMenu.name,
45205
+ changes
45206
+ });
44151
45207
  navSummary.update++;
44152
45208
  } else {
44153
- navDiffs.push({ type: "unchanged", name: remoteMenu.name });
45209
+ navDiffs.push({
45210
+ type: "unchanged",
45211
+ identifier: remoteMenu.identifier,
45212
+ name: remoteMenu.name
45213
+ });
44154
45214
  navSummary.unchanged++;
44155
45215
  }
44156
45216
  }
@@ -45032,7 +46092,8 @@ async function fetchAllContentPaginated(client, contentTypes, output, baseConten
45032
46092
  ...baseContent?.courses ? { courses: baseContent.courses } : {},
45033
46093
  meta: {
45034
46094
  pulledAt: (/* @__PURE__ */ new Date()).toISOString(),
45035
- entries: allMeta
46095
+ entries: allMeta,
46096
+ settingsUpdatedAt: settingsResult.meta.updatedAt
45036
46097
  }
45037
46098
  };
45038
46099
  }
@@ -45087,12 +46148,17 @@ function buildPullJsonDiff(diff, remoteContent, localContent, mode) {
45087
46148
  }
45088
46149
  for (const navDiff of diff.navigation) {
45089
46150
  if (navDiff.type === "unchanged") continue;
45090
- const remoteMenu = remoteContent.navigation.find((m) => m.name === navDiff.name);
45091
- const localMenu = localContent?.navigation?.menus.find((m) => m.name === navDiff.name);
46151
+ const navIdentifier = navigationIdentity(navDiff);
46152
+ const remoteMenu = remoteContent.navigation.find(
46153
+ (m) => navigationIdentity(m) === navIdentifier
46154
+ );
46155
+ const localMenu = localContent?.navigation?.menus.find(
46156
+ (m) => navigationIdentity(m) === navIdentifier
46157
+ );
45092
46158
  changes.push({
45093
46159
  type: "navigation",
45094
46160
  operation: navDiff.type,
45095
- identifier: navDiff.name,
46161
+ identifier: navIdentifier,
45096
46162
  before: localMenu ?? null,
45097
46163
  after: remoteMenu ?? null
45098
46164
  });
@@ -45117,7 +46183,8 @@ function mapManagementEntryToPulledEntry(entry) {
45117
46183
  status: entry.status,
45118
46184
  hasUnpublishedChanges: entry.hasUnpublishedChanges,
45119
46185
  slug: entry.slug,
45120
- title: entry.title
46186
+ title: entry.title,
46187
+ manualOrder: entry.manualOrder
45121
46188
  };
45122
46189
  }
45123
46190
  async function pullSingleEntry(client, contentType, identifier) {
@@ -45793,7 +46860,7 @@ Media Sync:
45793
46860
  const mediaContent = createScopedPullContent(result.meta, { settings: result.settings });
45794
46861
  await applyMediaIdentifiers(mediaContent);
45795
46862
  await syncMediaIfRequested(mediaContent);
45796
- const filePath = await writeSettings(contentDir, result);
46863
+ const filePath = await writeSettings(contentDir, result, { skipMeta });
45797
46864
  output.success("Pulled site settings", { file: filePath });
45798
46865
  break;
45799
46866
  }
@@ -45900,7 +46967,17 @@ Media Sync:
45900
46967
  );
45901
46968
  await writePages(contentDir, { pages: result.pages, meta: result.meta }, { skipMeta });
45902
46969
  await writeNavigation(contentDir, { menus: result.navigation, meta: result.meta }, { skipMeta });
45903
- await writeSettings(contentDir, { settings: result.settings, meta: result.meta });
46970
+ await writeSettings(
46971
+ contentDir,
46972
+ {
46973
+ settings: result.settings,
46974
+ meta: {
46975
+ pulledAt: result.meta.pulledAt,
46976
+ updatedAt: result.meta.settingsUpdatedAt ?? null
46977
+ }
46978
+ },
46979
+ { skipMeta }
46980
+ );
45904
46981
  await writeForms(contentDir, { forms: result.forms, meta: result.meta }, { skipMeta });
45905
46982
  if (result.venues) {
45906
46983
  await writeVenues(contentDir, { venues: result.venues, meta: result.meta }, { skipMeta });
@@ -45981,6 +47058,7 @@ var VALID_PUSH_SCOPES = [
45981
47058
  "pages",
45982
47059
  "navigation",
45983
47060
  "forms",
47061
+ "settings",
45984
47062
  "theme",
45985
47063
  "footer",
45986
47064
  "venues",
@@ -46134,6 +47212,22 @@ function filterLocalContent(localContent, scope, contentType, identifier) {
46134
47212
  }
46135
47213
  };
46136
47214
  }
47215
+ if (scope === "settings") {
47216
+ return {
47217
+ content: {
47218
+ ...localContent,
47219
+ entries: /* @__PURE__ */ new Map(),
47220
+ pages: [],
47221
+ navigation: null,
47222
+ forms: [],
47223
+ footer: null,
47224
+ venues: [],
47225
+ eventCategories: [],
47226
+ events: [],
47227
+ courses: []
47228
+ }
47229
+ };
47230
+ }
46137
47231
  if (scope === "venues") {
46138
47232
  return {
46139
47233
  content: {
@@ -46207,12 +47301,14 @@ function calculateMetadataUpdates(result) {
46207
47301
  const willUpdatePages = result.pages.failed === 0 && result.pages.created + result.pages.updated > 0;
46208
47302
  const willUpdateNavigation = result.navigation.failed === 0 && result.navigation.created + result.navigation.updated > 0;
46209
47303
  const willUpdateForms = result.forms.failed === 0 && result.forms.created + result.forms.updated > 0;
46210
- const shouldUpdateMetadata = willUpdateEntries || willUpdatePages || willUpdateNavigation || willUpdateForms;
47304
+ const willUpdateSettings = result.settings.failed === 0 && result.settings.updated > 0;
47305
+ const shouldUpdateMetadata = willUpdateEntries || willUpdatePages || willUpdateNavigation || willUpdateForms || willUpdateSettings;
46211
47306
  return {
46212
47307
  willUpdateEntries,
46213
47308
  willUpdatePages,
46214
47309
  willUpdateNavigation,
46215
47310
  willUpdateForms,
47311
+ willUpdateSettings,
46216
47312
  shouldUpdateMetadata
46217
47313
  };
46218
47314
  }
@@ -46236,11 +47332,11 @@ function normalizeLocalContentShape(content) {
46236
47332
  function nullishToNull(value) {
46237
47333
  return value == null ? null : value;
46238
47334
  }
46239
- function isRecord9(value) {
47335
+ function isRecord11(value) {
46240
47336
  return typeof value === "object" && value !== null && !Array.isArray(value);
46241
47337
  }
46242
47338
  function normalizeVenueAddress(value) {
46243
- const obj = isRecord9(value) ? value : {};
47339
+ const obj = isRecord11(value) ? value : {};
46244
47340
  return {
46245
47341
  line1: nullishToNull(typeof obj.line1 === "string" ? obj.line1 : void 0),
46246
47342
  line2: nullishToNull(typeof obj.line2 === "string" ? obj.line2 : void 0),
@@ -46257,7 +47353,7 @@ function normalizeVenueAddress(value) {
46257
47353
  };
46258
47354
  }
46259
47355
  function normalizeVenueLocation(value) {
46260
- if (!isRecord9(value)) return null;
47356
+ if (!isRecord11(value)) return null;
46261
47357
  const obj = value;
46262
47358
  const lat = typeof obj.lat === "number" ? obj.lat : null;
46263
47359
  const lng = typeof obj.lng === "number" ? obj.lng : null;
@@ -46265,7 +47361,7 @@ function normalizeVenueLocation(value) {
46265
47361
  return { lat, lng };
46266
47362
  }
46267
47363
  function normalizeVenueForCompare(venue) {
46268
- const obj = isRecord9(venue) ? venue : {};
47364
+ const obj = isRecord11(venue) ? venue : {};
46269
47365
  return {
46270
47366
  slug: String(obj.slug),
46271
47367
  title: String(obj.title),
@@ -46278,7 +47374,7 @@ function normalizeVenueForCompare(venue) {
46278
47374
  };
46279
47375
  }
46280
47376
  function normalizeEventCategoryForCompare(category) {
46281
- const obj = isRecord9(category) ? category : {};
47377
+ const obj = isRecord11(category) ? category : {};
46282
47378
  return {
46283
47379
  identifier: String(obj.identifier),
46284
47380
  name: String(obj.name),
@@ -46288,9 +47384,9 @@ function normalizeEventCategoryForCompare(category) {
46288
47384
  };
46289
47385
  }
46290
47386
  function normalizeRemoteEventForCompare(event) {
46291
- const obj = isRecord9(event) ? event : {};
46292
- const schedule = isRecord9(obj.schedule) ? obj.schedule : {};
46293
- const pricing = isRecord9(obj.pricing) ? obj.pricing : {};
47387
+ const obj = isRecord11(event) ? event : {};
47388
+ const schedule = isRecord11(obj.schedule) ? obj.schedule : {};
47389
+ const pricing = isRecord11(obj.pricing) ? obj.pricing : {};
46294
47390
  return {
46295
47391
  identifier: String(obj.identifier),
46296
47392
  title: String(obj.title),
@@ -46323,14 +47419,14 @@ function normalizeRemoteEventForCompare(event) {
46323
47419
  venueRef: nullishToNull(typeof obj.venueRef === "string" ? obj.venueRef : void 0),
46324
47420
  categoryRef: nullishToNull(typeof obj.categoryRef === "string" ? obj.categoryRef : void 0),
46325
47421
  formRef: nullishToNull(typeof obj.formRef === "string" ? obj.formRef : void 0),
46326
- content: isRecord9(obj.content) ? obj.content : {},
46327
- settings: isRecord9(obj.settings) ? obj.settings : {},
46328
- presentation: isRecord9(obj.presentation) ? obj.presentation : null,
47422
+ content: isRecord11(obj.content) ? obj.content : {},
47423
+ settings: isRecord11(obj.settings) ? obj.settings : {},
47424
+ presentation: isRecord11(obj.presentation) ? obj.presentation : null,
46329
47425
  tags: Array.isArray(obj.tags) ? obj.tags : []
46330
47426
  };
46331
47427
  }
46332
47428
  function normalizeLocalEventAgainstRemoteForCompare(localEvent, remoteEvent) {
46333
- const local = isRecord9(localEvent) ? localEvent : {};
47429
+ const local = isRecord11(localEvent) ? localEvent : {};
46334
47430
  const base = remoteEvent ? normalizeRemoteEventForCompare(remoteEvent) : normalizeRemoteEventForCompare({
46335
47431
  identifier: local.identifier,
46336
47432
  title: local.title,
@@ -46348,8 +47444,8 @@ function normalizeLocalEventAgainstRemoteForCompare(localEvent, remoteEvent) {
46348
47444
  presentation: local.presentation ?? null,
46349
47445
  tags: local.tags ?? []
46350
47446
  });
46351
- const schedule = isRecord9(local.schedule) ? local.schedule : {};
46352
- const pricing = isRecord9(local.pricing) ? local.pricing : {};
47447
+ const schedule = isRecord11(local.schedule) ? local.schedule : {};
47448
+ const pricing = isRecord11(local.pricing) ? local.pricing : {};
46353
47449
  return {
46354
47450
  ...base,
46355
47451
  identifier: String(local.identifier ?? base.identifier),
@@ -46375,9 +47471,9 @@ function normalizeLocalEventAgainstRemoteForCompare(localEvent, remoteEvent) {
46375
47471
  venueRef: local.venueRef === void 0 ? base.venueRef : nullishToNull(typeof local.venueRef === "string" ? local.venueRef : void 0),
46376
47472
  categoryRef: local.categoryRef === void 0 ? base.categoryRef : nullishToNull(typeof local.categoryRef === "string" ? local.categoryRef : void 0),
46377
47473
  formRef: local.formRef === void 0 ? base.formRef : nullishToNull(typeof local.formRef === "string" ? local.formRef : void 0),
46378
- content: local.content === void 0 ? base.content : isRecord9(local.content) ? local.content : {},
46379
- settings: local.settings === void 0 ? base.settings : isRecord9(local.settings) ? local.settings : {},
46380
- presentation: local.presentation === void 0 ? base.presentation : isRecord9(local.presentation) ? local.presentation : null,
47474
+ content: local.content === void 0 ? base.content : isRecord11(local.content) ? local.content : {},
47475
+ settings: local.settings === void 0 ? base.settings : isRecord11(local.settings) ? local.settings : {},
47476
+ presentation: local.presentation === void 0 ? base.presentation : isRecord11(local.presentation) ? local.presentation : null,
46381
47477
  tags: local.tags === void 0 ? base.tags : Array.isArray(local.tags) ? local.tags : []
46382
47478
  };
46383
47479
  }
@@ -46389,7 +47485,7 @@ function toIsoStringOrOriginal(value) {
46389
47485
  function normalizeCourseSessions(value) {
46390
47486
  if (!Array.isArray(value)) return [];
46391
47487
  return value.map((session) => {
46392
- const obj = isRecord9(session) ? session : {};
47488
+ const obj = isRecord11(session) ? session : {};
46393
47489
  return {
46394
47490
  startsAt: toIsoStringOrOriginal(obj.startsAt),
46395
47491
  endsAt: toIsoStringOrOriginal(obj.endsAt)
@@ -46401,18 +47497,18 @@ function normalizeCourseSessions(value) {
46401
47497
  }
46402
47498
  function normalizeCourseProgram(value) {
46403
47499
  if (value == null) return null;
46404
- if (!isRecord9(value)) {
47500
+ if (!isRecord11(value)) {
46405
47501
  return { identifier: null, data: {} };
46406
47502
  }
46407
47503
  return {
46408
47504
  identifier: nullishToNull(
46409
47505
  typeof value.identifier === "string" ? value.identifier : void 0
46410
47506
  ),
46411
- data: isRecord9(value.data) ? value.data : {}
47507
+ data: isRecord11(value.data) ? value.data : {}
46412
47508
  };
46413
47509
  }
46414
47510
  function normalizeRemoteCourseForCompare(course) {
46415
- const obj = isRecord9(course) ? course : {};
47511
+ const obj = isRecord11(course) ? course : {};
46416
47512
  return {
46417
47513
  identifier: String(obj.identifier),
46418
47514
  title: String(obj.title),
@@ -46435,7 +47531,7 @@ function normalizeRemoteCourseForCompare(course) {
46435
47531
  };
46436
47532
  }
46437
47533
  function normalizeLocalCourseAgainstRemoteForCompare(localCourse, remoteCourse) {
46438
- const local = isRecord9(localCourse) ? localCourse : {};
47534
+ const local = isRecord11(localCourse) ? localCourse : {};
46439
47535
  const base = remoteCourse ? normalizeRemoteCourseForCompare(remoteCourse) : normalizeRemoteCourseForCompare({
46440
47536
  identifier: local.identifier,
46441
47537
  title: local.title,
@@ -46456,11 +47552,11 @@ function normalizeLocalCourseAgainstRemoteForCompare(localCourse, remoteCourse)
46456
47552
  });
46457
47553
  const status = local.status === void 0 ? base.status : local.status === "active" || local.status === "cancelled" || local.status === "completed" ? local.status : "draft";
46458
47554
  const visibility = local.visibility === void 0 ? base.visibility : local.visibility === "public" || local.visibility === "private" || local.visibility === "unlisted" ? local.visibility : "public";
46459
- const program2 = local.program === void 0 ? base.program : local.program === null ? null : isRecord9(local.program) ? {
47555
+ const program2 = local.program === void 0 ? base.program : local.program === null ? null : isRecord11(local.program) ? {
46460
47556
  identifier: local.program.identifier === void 0 ? base.program?.identifier ?? null : nullishToNull(
46461
47557
  typeof local.program.identifier === "string" ? local.program.identifier : void 0
46462
47558
  ),
46463
- data: isRecord9(local.program.data) ? local.program.data : base.program?.data ?? {}
47559
+ data: isRecord11(local.program.data) ? local.program.data : base.program?.data ?? {}
46464
47560
  } : base.program;
46465
47561
  return {
46466
47562
  ...base,
@@ -46630,7 +47726,7 @@ function calculatePushAllExtraChanges(local, remote, options) {
46630
47726
  }
46631
47727
 
46632
47728
  // src/cli/commands/push/stale.ts
46633
- function checkForStaleContent(localContent, localMeta, pagesMeta, navigationMeta, formsMeta, remoteContent) {
47729
+ function checkForStaleContent(localContent, localMeta, pagesMeta, navigationMeta, formsMeta, remoteContent, settingsMeta = null) {
46634
47730
  const staleItems = [];
46635
47731
  for (const [contentType, localEntries] of localContent.entries) {
46636
47732
  const meta = localMeta.get(contentType);
@@ -46689,6 +47785,17 @@ function checkForStaleContent(localContent, localMeta, pagesMeta, navigationMeta
46689
47785
  }
46690
47786
  });
46691
47787
  }
47788
+ if (localContent.settings && settingsMeta?.updatedAt && remoteContent.meta.settingsUpdatedAt) {
47789
+ const remoteTime = remoteContent.meta.settingsUpdatedAt;
47790
+ if (new Date(remoteTime) > new Date(settingsMeta.updatedAt)) {
47791
+ staleItems.push({
47792
+ scope: "settings",
47793
+ identifier: "site",
47794
+ remoteUpdatedAt: remoteTime,
47795
+ display: `Settings: site (Remote updated: ${remoteTime})`
47796
+ });
47797
+ }
47798
+ }
46692
47799
  if (formsMeta) {
46693
47800
  localContent.forms.forEach((localForm) => {
46694
47801
  const remoteForm = remoteContent.forms.find((f) => f.slug === localForm.slug);
@@ -47351,6 +48458,7 @@ var upsertNavigationMenuCommandSchema = z.object({
47351
48458
  type: z.literal("upsertNavigationMenu"),
47352
48459
  ref: navigationRefSchema,
47353
48460
  input: z.object({
48461
+ identifier: z.string().min(1).optional(),
47354
48462
  name: z.string().min(1).optional(),
47355
48463
  location: z.enum(navigationLocations).optional(),
47356
48464
  role: z.enum(navigationMenuRoles).optional(),
@@ -47408,6 +48516,7 @@ var upsertContentEntryCommandSchema = z.object({
47408
48516
  contentTypeKey: z.string().min(1),
47409
48517
  slug: z.string().min(1).optional(),
47410
48518
  title: z.string().min(1).optional(),
48519
+ manualOrder: z.number().int().min(0).optional(),
47411
48520
  data: unknownRecordSchema.optional(),
47412
48521
  linkedSubjectRef: contentEntryRefSchema.optional(),
47413
48522
  mediaRefs: z.array(mediaRefSchema).readonly().optional()
@@ -48625,19 +49734,17 @@ function getSiteCommandMetadata(type) {
48625
49734
  return siteCommandMetadata[type];
48626
49735
  }
48627
49736
  function getSiteCommandLifecycleIntent(command) {
48628
- switch (command.type) {
48629
- case "ensureTeamMemberProfile":
48630
- return command.input.publish ? "publish" : "mutation";
48631
- default:
48632
- return getSiteCommandMetadata(command.type).lifecycleIntent;
49737
+ if (command.type === "ensureTeamMemberProfile") {
49738
+ return command.input.publish ? "publish" : "mutation";
48633
49739
  }
49740
+ return getSiteCommandMetadata(command.type).lifecycleIntent;
48634
49741
  }
48635
49742
 
48636
49743
  // ../site-commands/src/planner.ts
48637
49744
  init_src();
48638
49745
 
48639
49746
  // ../site-commands/src/guards.ts
48640
- function isRecord10(value) {
49747
+ function isRecord12(value) {
48641
49748
  return typeof value === "object" && value !== null;
48642
49749
  }
48643
49750
 
@@ -48902,7 +50009,7 @@ function collectVenueRefsFromIntervals(intervals, path24) {
48902
50009
  }
48903
50010
  function collectNavigationRefs(items, path24) {
48904
50011
  return items.flatMap((item, index) => {
48905
- if (!isRecord10(item)) return [];
50012
+ if (!isRecord12(item)) return [];
48906
50013
  const itemPath = `${path24}[${index}]`;
48907
50014
  const refs = [];
48908
50015
  if (typeof item.pageRef === "string") {
@@ -48919,7 +50026,7 @@ function collectNavigationRefs(items, path24) {
48919
50026
  }
48920
50027
  function collectBlockRefs(blocks, path24) {
48921
50028
  return blocks.flatMap((block, index) => {
48922
- if (!isRecord10(block)) return [];
50029
+ if (!isRecord12(block)) return [];
48923
50030
  const blockPath = `${path24}[${index}]`;
48924
50031
  return [
48925
50032
  ...collectNestedRefs(block.props, `${blockPath}.props`),
@@ -48935,22 +50042,16 @@ function collectNestedRefs(value, path24) {
48935
50042
  if (Array.isArray(value)) {
48936
50043
  return value.flatMap((item, index) => collectNestedRefs(item, `${path24}[${index}]`));
48937
50044
  }
48938
- if (!isRecord10(value)) return [];
50045
+ if (!isRecord12(value)) return [];
48939
50046
  return Object.entries(value).flatMap(([key, child]) => collectNestedRefs(child, `${path24}.${key}`));
48940
50047
  }
48941
50048
 
48942
50049
  // ../site-commands/src/staticExecutionGaps.ts
48943
50050
  function staticExecutionGapsForCommand(command) {
48944
- switch (command.type) {
48945
- case "upsertEventSeries":
48946
- return eventSeriesStaticExecutionGaps(command);
48947
- case "upsertEventTicketType":
48948
- return eventTicketTypeStaticExecutionGaps(command);
48949
- case "upsertCourse":
48950
- return courseStaticExecutionGaps(command);
48951
- default:
48952
- return [];
48953
- }
50051
+ if (command.type === "upsertEventSeries") return eventSeriesStaticExecutionGaps(command);
50052
+ if (command.type === "upsertEventTicketType") return eventTicketTypeStaticExecutionGaps(command);
50053
+ if (command.type === "upsertCourse") return courseStaticExecutionGaps(command);
50054
+ return [];
48954
50055
  }
48955
50056
  function eventSeriesStaticExecutionGaps(command) {
48956
50057
  return [
@@ -49197,9 +50298,9 @@ function deriveIdempotencyKey(input) {
49197
50298
  ].join("|"));
49198
50299
  }
49199
50300
  function findUnknownCommandTypes(input) {
49200
- if (!isRecord10(input) || !Array.isArray(input.commands)) return [];
50301
+ if (!isRecord12(input) || !Array.isArray(input.commands)) return [];
49201
50302
  return input.commands.flatMap((command, commandIndex) => {
49202
- if (!isRecord10(command) || typeof command.type !== "string") return [];
50303
+ if (!isRecord12(command) || typeof command.type !== "string") return [];
49203
50304
  if (commandTypeSet.has(command.type)) return [];
49204
50305
  return [{
49205
50306
  code: "unknown_command_type",
@@ -49225,9 +50326,12 @@ function commandIndexForIssuePath(path24) {
49225
50326
  return path24[0] === "commands" && typeof path24[1] === "number" ? path24[1] : -1;
49226
50327
  }
49227
50328
  function commandTypeForIssue(input, commandIndex) {
49228
- if (!isRecord10(input) || !Array.isArray(input.commands)) return null;
50329
+ if (!isRecord12(input) || !isUnknownArray3(input.commands)) return null;
49229
50330
  const command = input.commands[commandIndex];
49230
- return isRecord10(command) && typeof command.type === "string" ? command.type : null;
50331
+ return isRecord12(command) && typeof command.type === "string" ? command.type : null;
50332
+ }
50333
+ function isUnknownArray3(value) {
50334
+ return Array.isArray(value);
49231
50335
  }
49232
50336
  function formatIssuePath(path24) {
49233
50337
  if (path24.length === 0) return "<root>";
@@ -49409,6 +50513,51 @@ function indexOfferingCommands(batch) {
49409
50513
  mutableTicketsByEventRef.set(command.input.eventRef, tickets);
49410
50514
  break;
49411
50515
  }
50516
+ case "configureSiteIdentity":
50517
+ case "configureBookingSettings":
50518
+ case "applySiteStyleSelection":
50519
+ case "upsertMediaAsset":
50520
+ case "upsertPage":
50521
+ case "upsertBlockTree":
50522
+ case "upsertPageBlock":
50523
+ case "patchPageBlockContent":
50524
+ case "deletePageBlock":
50525
+ case "reorderPageBlocks":
50526
+ case "upsertNavigationMenu":
50527
+ case "upsertForm":
50528
+ case "upsertFooterContent":
50529
+ case "upsertContentEntry":
50530
+ case "publishPage":
50531
+ case "unpublishPage":
50532
+ case "publishContentEntry":
50533
+ case "unpublishContentEntry":
50534
+ case "deleteContentEntry":
50535
+ case "upsertStaffMember":
50536
+ case "ensureTeamMemberProfile":
50537
+ case "upsertVenue":
50538
+ case "deleteVenue":
50539
+ case "upsertEventCategory":
50540
+ case "deleteEventCategory":
50541
+ case "deleteEventSeries":
50542
+ case "upsertCourse":
50543
+ case "deleteCourse":
50544
+ case "upsertBookingPassProduct":
50545
+ case "upsertBookingMembershipProduct":
50546
+ case "seedBookingCustomer":
50547
+ case "grantCustomerPass":
50548
+ case "grantCustomerMembership":
50549
+ case "seedAppointmentBooking":
50550
+ case "seedCourseEnrollment":
50551
+ case "seedEventRegistration":
50552
+ case "seedPassRedemption":
50553
+ case "seedPortalOrder":
50554
+ case "upsertAppointmentService":
50555
+ case "upsertBookableResource":
50556
+ case "assignAppointmentServiceResources":
50557
+ case "configureAppointmentAvailability":
50558
+ break;
50559
+ default:
50560
+ assertNeverCommand(command);
49412
50561
  }
49413
50562
  }
49414
50563
  const ticketsByEventRef = new Map(
@@ -49808,6 +50957,7 @@ function appliedSubjectFromOutcome(outcome) {
49808
50957
  case "failed":
49809
50958
  case "skipped_by_stop_policy":
49810
50959
  case "compile_failed":
50960
+ case "preflight_failed":
49811
50961
  return [];
49812
50962
  default:
49813
50963
  assertNever(outcome);
@@ -49817,6 +50967,7 @@ function failureFromOutcome(outcome) {
49817
50967
  switch (outcome.status) {
49818
50968
  case "failed":
49819
50969
  case "compile_failed":
50970
+ case "preflight_failed":
49820
50971
  return {
49821
50972
  identifier: outcome.identifier,
49822
50973
  message: outcome.message,
@@ -50199,8 +51350,8 @@ function eventContentInput(content) {
50199
51350
  if (!content) return void 0;
50200
51351
  return {
50201
51352
  ...content.summary ? { summary: content.summary } : {},
50202
- ...typeof content.body === "string" || isRecord11(content.body) ? { body: content.body } : {},
50203
- ...typeof content.image === "string" || isRecord11(content.image) ? { image: content.image } : {}
51353
+ ...typeof content.body === "string" || isRecord13(content.body) ? { body: content.body } : {},
51354
+ ...typeof content.image === "string" || isRecord13(content.image) ? { image: content.image } : {}
50204
51355
  };
50205
51356
  }
50206
51357
  function courseUpsertInput(command) {
@@ -50372,7 +51523,7 @@ function toUtcIso(date, time) {
50372
51523
  const normalizedTime = time.length === 5 ? `${time}:00` : time;
50373
51524
  return (/* @__PURE__ */ new Date(`${date}T${normalizedTime}Z`)).toISOString();
50374
51525
  }
50375
- function isRecord11(value) {
51526
+ function isRecord13(value) {
50376
51527
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
50377
51528
  }
50378
51529
  function unsupported(identifier, message) {
@@ -50393,12 +51544,12 @@ function courseSessionConflictMessage(error) {
50393
51544
  init_src();
50394
51545
 
50395
51546
  // src/cli/site-commands/commandKeys.ts
50396
- var asCliContentTypeKey = (value) => value;
50397
- var asCliEntryIdentifier = (value) => value;
50398
- var asCliPageIdentifier = (value) => value;
50399
- var asCliBlockIdentifier = (value) => value;
50400
- var asCliFormSlug = (value) => value;
50401
- var asCliNavigationMenuName = (value) => value;
51547
+ var unsafeAsCliContentTypeKey = (value) => value;
51548
+ var unsafeAsCliEntryIdentifier = (value) => value;
51549
+ var unsafeAsCliPageIdentifier = (value) => value;
51550
+ var unsafeAsCliBlockIdentifier = (value) => value;
51551
+ var unsafeAsCliFormSlug = (value) => value;
51552
+ var unsafeAsCliNavigationMenuName = (value) => value;
50402
51553
 
50403
51554
  // src/cli/site-commands/commandRuntimeCompat.ts
50404
51555
  init_src();
@@ -50411,6 +51562,7 @@ function commandReportToSyncResult(input) {
50411
51562
  break;
50412
51563
  case "failed":
50413
51564
  case "compile_failed":
51565
+ case "preflight_failed":
50414
51566
  input.recordFailure(
50415
51567
  result,
50416
51568
  outcome.identifier,
@@ -50448,12 +51600,12 @@ function compileEntryPushCommands(input) {
50448
51600
  const commandBindings = [];
50449
51601
  const localEntriesByType = new Map(
50450
51602
  [...input.local.entries.entries()].map(([contentType, entries]) => [
50451
- asCliContentTypeKey(contentType),
50452
- new Map(entries.map((entry) => [asCliEntryIdentifier(entry.identifier), entry]))
51603
+ unsafeAsCliContentTypeKey(contentType),
51604
+ new Map(entries.map((entry) => [unsafeAsCliEntryIdentifier(entry.identifier), entry]))
50453
51605
  ])
50454
51606
  );
50455
51607
  for (const [contentType, entryDiffs] of input.diff.entries) {
50456
- const contentTypeKey = asCliContentTypeKey(contentType);
51608
+ const contentTypeKey = unsafeAsCliContentTypeKey(contentType);
50457
51609
  for (const entryDiff of entryDiffs) {
50458
51610
  const commandResult = entryCommandsForDiff({
50459
51611
  contentType: contentTypeKey,
@@ -50483,7 +51635,8 @@ async function executeEntryCommandPlan(input) {
50483
51635
  identifier,
50484
51636
  contentType: command.input.contentTypeKey,
50485
51637
  data: command.input.data ?? {},
50486
- slug: command.input.slug
51638
+ slug: command.input.slug,
51639
+ manualOrder: command.input.manualOrder
50487
51640
  });
50488
51641
  return;
50489
51642
  }
@@ -50565,7 +51718,7 @@ function entryCommandsForDiff(input) {
50565
51718
  if (input.entryDiff.type === "unchanged" && !input.entryDiff.statusChange) {
50566
51719
  return ok([]);
50567
51720
  }
50568
- const entryIdentifier = asCliEntryIdentifier(input.entryDiff.identifier);
51721
+ const entryIdentifier = unsafeAsCliEntryIdentifier(input.entryDiff.identifier);
50569
51722
  const entryRef = createContentEntryRef([input.contentType, entryIdentifier]);
50570
51723
  const commandBindings = [];
50571
51724
  const upsertedInBatch = input.entryDiff.type !== "delete" && input.entryDiff.type !== "unchanged";
@@ -50597,7 +51750,7 @@ function entryCommandsForDiff(input) {
50597
51750
  message: `Missing local entry for ${input.contentType}/${input.entryDiff.identifier}.`
50598
51751
  });
50599
51752
  }
50600
- const localEntryIdentifier = asCliEntryIdentifier(localEntry.identifier);
51753
+ const localEntryIdentifier = unsafeAsCliEntryIdentifier(localEntry.identifier);
50601
51754
  if (input.entryDiff.type !== "unchanged") {
50602
51755
  const command = {
50603
51756
  type: "upsertContentEntry",
@@ -50606,6 +51759,7 @@ function entryCommandsForDiff(input) {
50606
51759
  identifier: localEntryIdentifier,
50607
51760
  contentTypeKey: input.contentType,
50608
51761
  ...localEntry.slug ? { slug: localEntry.slug } : {},
51762
+ ...typeof localEntry.manualOrder === "number" ? { manualOrder: localEntry.manualOrder } : {},
50609
51763
  ...optionalTitle(localEntry.data),
50610
51764
  data: localEntry.data
50611
51765
  }
@@ -50716,10 +51870,10 @@ var formSiteCommandTypes = [
50716
51870
  function compileFormPushCommands(input) {
50717
51871
  const commandBindings = [];
50718
51872
  const formsBySlug = new Map(
50719
- input.local.forms.map((form2) => [asCliFormSlug(form2.slug), form2])
51873
+ input.local.forms.map((form2) => [unsafeAsCliFormSlug(form2.slug), form2])
50720
51874
  );
50721
51875
  for (const formDiff of input.diff.forms) {
50722
- const formSlug = asCliFormSlug(formDiff.slug);
51876
+ const formSlug = unsafeAsCliFormSlug(formDiff.slug);
50723
51877
  const commandResult = formCommandForDiff({
50724
51878
  formDiff,
50725
51879
  slug: formSlug,
@@ -50799,7 +51953,7 @@ function formCommandForDiff(input) {
50799
51953
  message: `Missing local form: ${input.formDiff.slug}.`
50800
51954
  });
50801
51955
  }
50802
- const localFormSlug = asCliFormSlug(input.localForm.slug);
51956
+ const localFormSlug = unsafeAsCliFormSlug(input.localForm.slug);
50803
51957
  const formRef = createFormRef([input.slug]);
50804
51958
  return ok({
50805
51959
  command: {
@@ -50947,27 +52101,36 @@ var navigationSiteCommandTypes = [
50947
52101
  ];
50948
52102
  function compileNavigationPushCommands(input) {
50949
52103
  const commandBindings = [];
50950
- const menusByName = new Map(
50951
- (input.local.navigation?.menus ?? []).map((menu) => [asCliNavigationMenuName(menu.name), menu])
52104
+ const menusByIdentity = navigationIdentityMap(
52105
+ input.local.navigation?.menus ?? []
50952
52106
  );
52107
+ if (!menusByIdentity.ok) {
52108
+ return err({
52109
+ code: menusByIdentity.error.code,
52110
+ identity: menusByIdentity.error.identity,
52111
+ message: duplicateNavigationIdentityMessage(menusByIdentity.error)
52112
+ });
52113
+ }
50953
52114
  for (const navigationDiff of input.diff) {
50954
52115
  if (navigationDiff.type === "unchanged") continue;
50955
- const menuName = asCliNavigationMenuName(navigationDiff.name);
50956
- const menu = menusByName.get(menuName);
52116
+ const menuIdentity = navigationIdentity(navigationDiff);
52117
+ const menu = menusByIdentity.value.get(menuIdentity);
50957
52118
  if (!menu) {
52119
+ const menuName = unsafeAsCliNavigationMenuName(navigationDiff.name);
50958
52120
  return err({
50959
52121
  code: "missing_local_navigation_menu",
50960
52122
  name: menuName,
50961
52123
  message: `Missing local navigation menu: ${navigationDiff.name}.`
50962
52124
  });
50963
52125
  }
50964
- const localMenuName = asCliNavigationMenuName(menu.name);
52126
+ const localMenuName = unsafeAsCliNavigationMenuName(menu.name);
50965
52127
  const commandRef = createNavigationRef([localMenuName]);
50966
52128
  const role = navigationRole(menu);
50967
52129
  const command = {
50968
52130
  type: "upsertNavigationMenu",
50969
52131
  ref: commandRef,
50970
52132
  input: {
52133
+ ...menu.identifier ? { identifier: menu.identifier } : {},
50971
52134
  name: localMenuName,
50972
52135
  ...role ? { role } : {},
50973
52136
  items: menu.items.map(navigationItemForCommand)
@@ -50998,6 +52161,7 @@ async function executeNavigationCommandPlan(input) {
50998
52161
  case "upsertNavigationMenu": {
50999
52162
  const role = navigationCommandRole(command);
51000
52163
  await input.client.navigation.upsert({
52164
+ ...command.input.identifier ? { identifier: command.input.identifier } : {},
51001
52165
  name: navigationCommandMenuName(command),
51002
52166
  items: command.input.items.map(navigationItemInput),
51003
52167
  ...role === "primary" ? { isPrimary: true } : {},
@@ -51024,10 +52188,22 @@ function executeNavigationCommandPlanAsReport(input) {
51024
52188
  }
51025
52189
  function navigationCommandCompileErrorToReport(error) {
51026
52190
  return commandCompileFailureToReport({
51027
- identifier: error.code === "missing_local_navigation_menu" ? error.name : "command-validation",
52191
+ identifier: navigationCompileErrorIdentifier(error),
51028
52192
  message: error.message
51029
52193
  });
51030
52194
  }
52195
+ function navigationCompileErrorIdentifier(error) {
52196
+ switch (error.code) {
52197
+ case "missing_local_navigation_menu":
52198
+ return error.name;
52199
+ case "duplicate_navigation_identity":
52200
+ return error.identity;
52201
+ case "command_validation_failed":
52202
+ return "command-validation";
52203
+ default:
52204
+ return assertNever(error);
52205
+ }
52206
+ }
51031
52207
  function navigationCommandExecutionToReport(input) {
51032
52208
  return commandExecutionToReport({
51033
52209
  execution: input.execution,
@@ -51109,6 +52285,9 @@ function recordNavigationFailure(result, identifier, message) {
51109
52285
 
51110
52286
  // src/cli/site-commands/pageCommands.ts
51111
52287
  init_src();
52288
+ function assertNeverField(field) {
52289
+ throw new Error(`Unhandled field type while extracting field ids: ${JSON.stringify(field)}`);
52290
+ }
51112
52291
  function extractFieldIds(fields3) {
51113
52292
  const ids = /* @__PURE__ */ new Set();
51114
52293
  function processField(field) {
@@ -51116,24 +52295,19 @@ function extractFieldIds(fields3) {
51116
52295
  switch (field.type) {
51117
52296
  case "group":
51118
52297
  case "modal":
51119
- if (field.schema?.fields) {
51120
- for (const nestedField of field.schema.fields) {
51121
- processField(nestedField);
51122
- }
52298
+ for (const nestedField of field.schema?.fields ?? []) {
52299
+ processField(nestedField);
51123
52300
  }
51124
52301
  break;
51125
52302
  case "repeater":
51126
- if (field.schema?.fields) {
51127
- for (const nestedField of field.schema.fields) {
51128
- processField(nestedField);
51129
- }
52303
+ for (const nestedField of field.schema?.fields ?? []) {
52304
+ processField(nestedField);
51130
52305
  }
51131
52306
  if ("itemTypes" in field && field.itemTypes) {
51132
52307
  for (const itemType of Object.values(field.itemTypes)) {
51133
- if (itemType.fields) {
51134
- for (const nestedField of itemType.fields) {
51135
- processField(nestedField);
51136
- }
52308
+ if (!itemType.fields) continue;
52309
+ for (const nestedField of itemType.fields) {
52310
+ processField(nestedField);
51137
52311
  }
51138
52312
  }
51139
52313
  }
@@ -51141,14 +52315,33 @@ function extractFieldIds(fields3) {
51141
52315
  case "tabGroup":
51142
52316
  if ("tabs" in field && field.tabs) {
51143
52317
  for (const tab of field.tabs) {
51144
- if (tab.fields) {
51145
- for (const nestedField of tab.fields) {
51146
- processField(nestedField);
51147
- }
52318
+ if (!tab.fields) continue;
52319
+ for (const nestedField of tab.fields) {
52320
+ processField(nestedField);
51148
52321
  }
51149
52322
  }
51150
52323
  }
51151
52324
  break;
52325
+ case "text":
52326
+ case "richText":
52327
+ case "media":
52328
+ case "file":
52329
+ case "boolean":
52330
+ case "number":
52331
+ case "date":
52332
+ case "time":
52333
+ case "datetime":
52334
+ case "slug":
52335
+ case "url":
52336
+ case "link":
52337
+ case "select":
52338
+ case "reference":
52339
+ case "presetOrCustom":
52340
+ case "contentTypeSelect":
52341
+ case "entryPicker":
52342
+ break;
52343
+ default:
52344
+ assertNeverField(field);
51152
52345
  }
51153
52346
  }
51154
52347
  for (const field of fields3) {
@@ -51253,10 +52446,10 @@ function compilePagePushCommands(input) {
51253
52446
  const commandBindings = [];
51254
52447
  const warnings = [];
51255
52448
  const pagesByIdentifier = new Map(
51256
- input.local.pages.map((page) => [asCliPageIdentifier(page.identifier), page])
52449
+ input.local.pages.map((page) => [unsafeAsCliPageIdentifier(page.identifier), page])
51257
52450
  );
51258
52451
  for (const pageDiff of input.diff.pages) {
51259
- const pageIdentifier = asCliPageIdentifier(pageDiff.identifier);
52452
+ const pageIdentifier = unsafeAsCliPageIdentifier(pageDiff.identifier);
51260
52453
  const commandResult = pageCommandsForDiff({
51261
52454
  pageDiff,
51262
52455
  pageIdentifier,
@@ -51366,6 +52559,76 @@ function pageCommandExecutionToReport(input) {
51366
52559
  includeFailureSubject: true
51367
52560
  });
51368
52561
  }
52562
+ function preflightPageCommandPlanAsReport(input) {
52563
+ const outcomes = [];
52564
+ const warnings = [];
52565
+ const subjectByCommandRef = new Map(
52566
+ input.compiledPlan.reportedCommands.map((reportedCommand) => [
52567
+ reportedCommand.plannedCommand.command.ref,
52568
+ reportedCommand.reportSubject
52569
+ ])
52570
+ );
52571
+ for (const plannedCommand of input.compiledPlan.plan.commands) {
52572
+ const command = plannedCommand.command;
52573
+ if (command.type !== "upsertPageBlock") continue;
52574
+ const validation = validateLocalBlock({
52575
+ pageIdentifier: unsafeAsCliPageIdentifier(pageIdentifierForBlockCommand(command)),
52576
+ blockIdentifier: unsafeAsCliBlockIdentifier(blockIdentifierForCommand(command)),
52577
+ kind: command.input.type,
52578
+ data: command.input.props ?? {},
52579
+ blockFieldExtensions: input.blockFieldExtensions,
52580
+ invalidContentAsError: true
52581
+ });
52582
+ if (validation.ok) {
52583
+ warnings.push(...validation.value);
52584
+ continue;
52585
+ }
52586
+ const failure = preflightFailureFromPageCompileError({
52587
+ error: validation.error,
52588
+ subject: subjectByCommandRef.get(command.ref)
52589
+ });
52590
+ outcomes.push(failure.outcome);
52591
+ warnings.push(...failure.warnings);
52592
+ }
52593
+ return reportFromOutcomes({ outcomes, warnings });
52594
+ }
52595
+ function preflightFailureFromPageCompileError(input) {
52596
+ switch (input.error.code) {
52597
+ case "missing_local_page":
52598
+ return {
52599
+ outcome: {
52600
+ status: "preflight_failed",
52601
+ identifier: input.error.identifier,
52602
+ message: input.error.message,
52603
+ subject: input.subject
52604
+ },
52605
+ warnings: []
52606
+ };
52607
+ case "missing_local_block":
52608
+ case "invalid_page_block":
52609
+ return {
52610
+ outcome: {
52611
+ status: "preflight_failed",
52612
+ identifier: input.error.identifier,
52613
+ message: input.error.message,
52614
+ subject: input.subject
52615
+ },
52616
+ warnings: input.error.code === "invalid_page_block" ? input.error.warnings : []
52617
+ };
52618
+ case "command_validation_failed":
52619
+ return {
52620
+ outcome: {
52621
+ status: "preflight_failed",
52622
+ identifier: "command-validation",
52623
+ message: input.error.message,
52624
+ subject: input.subject
52625
+ },
52626
+ warnings: []
52627
+ };
52628
+ default:
52629
+ assertNever(input.error);
52630
+ }
52631
+ }
51369
52632
  function pageCommandReportToSyncResult(report) {
51370
52633
  return commandReportToSyncResult({
51371
52634
  report,
@@ -51395,7 +52658,7 @@ function pageCommandsForDiff(input) {
51395
52658
  const commandBindings = [];
51396
52659
  const warnings = [];
51397
52660
  const upsertedInBatch = input.pageDiff.type !== "unchanged";
51398
- const localPageIdentifier = asCliPageIdentifier(input.localPage.identifier);
52661
+ const localPageIdentifier = unsafeAsCliPageIdentifier(input.localPage.identifier);
51399
52662
  if (input.pageDiff.type !== "unchanged") {
51400
52663
  const command = {
51401
52664
  type: "upsertPage",
@@ -51474,14 +52737,14 @@ function blockCommandsForDiff(input) {
51474
52737
  if (changedBlockDiffs.length === 0) return ok(emptyPageCommandCompileFragment());
51475
52738
  const localBlocks = input.localPage.blocks ?? [];
51476
52739
  const blockLookup = new Map(
51477
- localBlocks.map((block) => [asCliBlockIdentifier(block.identifier), block])
52740
+ localBlocks.map((block) => [unsafeAsCliBlockIdentifier(block.identifier), block])
51478
52741
  );
51479
52742
  const commandBindings = [];
51480
52743
  const warnings = [];
51481
52744
  const pageDependency = input.includePageRefDependency ? { pageRef: input.pageRef } : {};
51482
52745
  for (const blockDiff of changedBlockDiffs) {
51483
52746
  if (blockDiff.type === "reorder") continue;
51484
- const blockIdentifier = asCliBlockIdentifier(blockDiff.identifier);
52747
+ const blockIdentifier = unsafeAsCliBlockIdentifier(blockDiff.identifier);
51485
52748
  const blockRef = createBlockRef([input.pageIdentifier, blockIdentifier]);
51486
52749
  if (blockDiff.type === "delete") {
51487
52750
  const command2 = {
@@ -51512,7 +52775,7 @@ function blockCommandsForDiff(input) {
51512
52775
  message: `Missing local block: ${input.localPage.identifier}/${blockDiff.identifier}.`
51513
52776
  });
51514
52777
  }
51515
- const localBlockIdentifier = asCliBlockIdentifier(localBlock.identifier);
52778
+ const localBlockIdentifier = unsafeAsCliBlockIdentifier(localBlock.identifier);
51516
52779
  const validation = validateLocalBlock({
51517
52780
  pageIdentifier: input.pageIdentifier,
51518
52781
  blockIdentifier: localBlockIdentifier,
@@ -51520,8 +52783,9 @@ function blockCommandsForDiff(input) {
51520
52783
  data: localBlock.data,
51521
52784
  blockFieldExtensions: input.blockFieldExtensions
51522
52785
  });
51523
- if (!validation.ok) return validation;
51524
- warnings.push(...validation.value);
52786
+ if (validation.ok) {
52787
+ warnings.push(...validation.value);
52788
+ }
51525
52789
  const command = {
51526
52790
  type: "upsertPageBlock",
51527
52791
  ref: blockRef,
@@ -51550,8 +52814,8 @@ function blockCommandsForDiff(input) {
51550
52814
  pageIdentifier: input.pageIdentifier,
51551
52815
  ...pageDependency,
51552
52816
  blocks: localBlocks.map((block) => ({
51553
- blockRef: createBlockRef([input.pageIdentifier, asCliBlockIdentifier(block.identifier)]),
51554
- identifier: asCliBlockIdentifier(block.identifier)
52817
+ blockRef: createBlockRef([input.pageIdentifier, unsafeAsCliBlockIdentifier(block.identifier)]),
52818
+ identifier: unsafeAsCliBlockIdentifier(block.identifier)
51555
52819
  }))
51556
52820
  }
51557
52821
  };
@@ -51568,21 +52832,39 @@ function blockCommandsForDiff(input) {
51568
52832
  }
51569
52833
  function validateLocalBlock(input) {
51570
52834
  const blockDefinition = getBlockDefinition(input.kind);
51571
- if (!blockDefinition) return ok([]);
51572
52835
  const customFields = customBlockFields(input.blockFieldExtensions, input.kind);
51573
- const validation = validateBlockData(input.data, blockDefinition.manifest, customFields);
52836
+ if (!blockDefinition && !customFields) {
52837
+ if (input.kind.startsWith("custom.")) {
52838
+ return err({
52839
+ code: "invalid_page_block",
52840
+ identifier: pageBlockIdentifier(input.pageIdentifier, input.blockIdentifier),
52841
+ warnings: [],
52842
+ message: `Unknown custom block kind: ${input.kind}`
52843
+ });
52844
+ }
52845
+ return ok([]);
52846
+ }
52847
+ const validation = validateBlockData(
52848
+ input.data,
52849
+ blockDefinition?.manifest ?? { fields: customFields ?? [] },
52850
+ blockDefinition ? customFields : void 0
52851
+ );
51574
52852
  const warnings = formatValidationResult(
51575
52853
  input.pageIdentifier,
51576
52854
  input.blockIdentifier,
51577
52855
  input.kind,
51578
52856
  validation
51579
52857
  );
51580
- if (validation.valid) return ok(warnings);
52858
+ const blockingIssues = [
52859
+ ...validation.errors,
52860
+ ...input.invalidContentAsError ? validation.warnings.filter((warning) => warning.type === "invalid_content") : []
52861
+ ];
52862
+ if (blockingIssues.length === 0) return ok(warnings);
51581
52863
  return err({
51582
52864
  code: "invalid_page_block",
51583
52865
  identifier: pageBlockIdentifier(input.pageIdentifier, input.blockIdentifier),
51584
52866
  warnings,
51585
- message: validation.errors.map((error) => error.message).join("; ")
52867
+ message: blockingIssues.map((error) => error.message).join("; ")
51586
52868
  });
51587
52869
  }
51588
52870
  function emptyPageCommandCompileFragment() {
@@ -51683,10 +52965,10 @@ function pageBlockIdentifier(pageIdentifier, blockIdentifier) {
51683
52965
  return `${pageIdentifier}/${blockIdentifier}`;
51684
52966
  }
51685
52967
  function pageIdentifierFromPageBlockIdentifier(identifier) {
51686
- return asCliPageIdentifier(identifier.split("/")[0] ?? identifier);
52968
+ return unsafeAsCliPageIdentifier(identifier.split("/")[0] ?? identifier);
51687
52969
  }
51688
52970
  function blockIdentifierFromPageBlockIdentifier(identifier) {
51689
- return asCliBlockIdentifier(identifier.split("/")[1] ?? identifier);
52971
+ return unsafeAsCliBlockIdentifier(identifier.split("/")[1] ?? identifier);
51690
52972
  }
51691
52973
 
51692
52974
  // src/cli/site-commands/pushExecution.ts
@@ -51721,6 +53003,23 @@ function compileContentPushExecutionPlan(plan, input, dependencies = {}) {
51721
53003
  steps
51722
53004
  });
51723
53005
  }
53006
+ function preflightContentPushExecutionPlan(steps, input, dependencies = {}) {
53007
+ const commandReports = steps.flatMap((step) => {
53008
+ if (step.kind !== "command-surface") return [];
53009
+ const report = (dependencies.preflightCommandSurfaceAsReport ?? preflightCommandSurfaceAsReport)(
53010
+ step.surface,
53011
+ input
53012
+ );
53013
+ return commandSurfaceReportHasFailures(report) ? [report] : [];
53014
+ });
53015
+ return {
53016
+ commandReports,
53017
+ residualSyncResults: []
53018
+ };
53019
+ }
53020
+ function contentPushExecutionReportHasFailures(report) {
53021
+ return report.commandReports.some(commandSurfaceReportHasFailures) || report.residualSyncResults.some((result) => result.errors.length > 0);
53022
+ }
51724
53023
  async function executeCommandSurfaceAsReport(surface, input) {
51725
53024
  switch (surface.surface) {
51726
53025
  case "entry":
@@ -51763,6 +53062,26 @@ async function executeCommandSurfaceAsReport(surface, input) {
51763
53062
  assertNever(surface);
51764
53063
  }
51765
53064
  }
53065
+ function preflightCommandSurfaceAsReport(surface, input) {
53066
+ switch (surface.surface) {
53067
+ case "entry":
53068
+ return { surface: "entry", report: reportFromOutcomes({ outcomes: [] }) };
53069
+ case "page":
53070
+ return {
53071
+ surface: "page",
53072
+ report: preflightPageCommandPlanAsReport({
53073
+ compiledPlan: surface.compileValue,
53074
+ blockFieldExtensions: input.blockFieldExtensions
53075
+ })
53076
+ };
53077
+ case "form":
53078
+ return { surface: "form", report: reportFromOutcomes({ outcomes: [] }) };
53079
+ case "navigation":
53080
+ return { surface: "navigation", report: reportFromOutcomes({ outcomes: [] }) };
53081
+ default:
53082
+ assertNever(surface);
53083
+ }
53084
+ }
51766
53085
  function skippedRemainingCommandReports(steps) {
51767
53086
  return steps.flatMap((step) => step.kind === "command-surface" ? [skippedCommandSurfaceReport(step.surface)] : []);
51768
53087
  }
@@ -51780,6 +53099,9 @@ function commandSurfaceReportToSyncResult(report) {
51780
53099
  assertNever(report);
51781
53100
  }
51782
53101
  }
53102
+ function commandSurfaceReportHasFailures(report) {
53103
+ return commandReportHasFailures(report.report);
53104
+ }
51783
53105
  function compileCommandSurface(surface, input) {
51784
53106
  switch (surface) {
51785
53107
  case "entry":
@@ -52047,6 +53369,8 @@ function planContentPushExecution(input) {
52047
53369
  return syncPlanWithSteps([commandSurfaceStep("navigation", "continue")]);
52048
53370
  case "pages":
52049
53371
  return pageCommandRouting(input.diff).kind === "command_backed" ? syncPlanWithSteps([commandSurfaceStep("page", "continue")]) : syncPlanWithResidualOnly(input);
53372
+ case "settings":
53373
+ return syncPlanWithResidualOnly(input);
52050
53374
  case "all":
52051
53375
  return pushAllExecutionPlan(input);
52052
53376
  default:
@@ -52127,14 +53451,29 @@ async function executeContentPushPlan(input) {
52127
53451
  return contentPushExecutionReportToSyncResult(report);
52128
53452
  }
52129
53453
  async function executeContentPushPlanAsCommandReport(input, dependencies = {}) {
53454
+ const preflight = preflightContentPushPlanAsCommandReport(input, dependencies);
53455
+ if (!preflight.ok) return preflight.report;
53456
+ return executePushExecutionSteps(preflight.compiled.steps, input, dependencies);
53457
+ }
53458
+ function preflightContentPushPlanAsCommandReport(input, dependencies = {}) {
52130
53459
  const executionPlan = planContentPushExecution({
52131
53460
  pushScope: input.pushScope,
52132
53461
  diff: input.diff,
52133
53462
  local: input.local
52134
53463
  });
52135
53464
  const compiled = compileContentPushExecutionPlan(executionPlan, input, dependencies);
52136
- if (!compiled.ok) return compiled.error;
52137
- return executePushExecutionSteps(compiled.value.steps, input, dependencies);
53465
+ if (!compiled.ok) {
53466
+ return { ok: false, report: compiled.error };
53467
+ }
53468
+ const preflightReport = preflightContentPushExecutionPlan(
53469
+ compiled.value.steps,
53470
+ input,
53471
+ dependencies
53472
+ );
53473
+ if (contentPushExecutionReportHasFailures(preflightReport)) {
53474
+ return { ok: false, report: preflightReport };
53475
+ }
53476
+ return { ok: true, compiled: compiled.value, report: preflightReport };
52138
53477
  }
52139
53478
  async function executePushExecutionSteps(steps, input, dependencies) {
52140
53479
  const commandReports = [];
@@ -53111,6 +54450,8 @@ function scalarEntryChanges(changes) {
53111
54450
  function setEntryPath(entry, pathParts, value) {
53112
54451
  const [head, ...rest] = pathParts;
53113
54452
  switch (head) {
54453
+ case void 0:
54454
+ throw new Error("Cannot set an empty entry merge path.");
53114
54455
  case "identifier":
53115
54456
  entry.identifier = expectStringValue(head, value);
53116
54457
  return;
@@ -53747,6 +55088,21 @@ async function executeScopedPush(output, isRemote, options, globalOpts, scopeLab
53747
55088
  }
53748
55089
  return { success: true };
53749
55090
  }
55091
+ function noContentFoundWarningDetails(contentDir) {
55092
+ return {
55093
+ contentDir,
55094
+ expectedFiles: [
55095
+ "content/pages/*.json",
55096
+ "content/entries/<type>/*.json",
55097
+ "content/navigation.json",
55098
+ "content/settings.json"
55099
+ ],
55100
+ suggestion: "Document content is read from content/**. Add file-based pages, entries, navigation, or settings, then run `riverbankcms push` again. Use `riverbankcms push-config` for schema/config only."
55101
+ };
55102
+ }
55103
+ function contentSummaryHasPushableContent(summary) {
55104
+ return summary.totalEntries > 0 || summary.pageCount > 0 || summary.hasNavigation || summary.hasSettings || summary.hasForms || summary.hasVenues || summary.hasEventCategories || summary.hasEvents || summary.hasCourses;
55105
+ }
53750
55106
  function validateMergeRemoteEntryPushOptions(input) {
53751
55107
  if (input.target !== "remote") {
53752
55108
  return {
@@ -54028,8 +55384,8 @@ ${errors}`
54028
55384
  });
54029
55385
  }
54030
55386
  const summary = await getContentSummary(contentDir);
54031
- if (summary.totalEntries === 0 && summary.pageCount === 0 && !summary.hasNavigation && !summary.hasForms && !summary.hasVenues && !summary.hasEventCategories && !summary.hasEvents && !summary.hasCourses) {
54032
- output.warn("No content found to push");
55387
+ if (!contentSummaryHasPushableContent(summary)) {
55388
+ output.warn("No content found to push", noContentFoundWarningDetails(contentDir));
54033
55389
  return { success: true };
54034
55390
  }
54035
55391
  const env = loadEnvironment(isRemote);
@@ -54137,10 +55493,11 @@ ${errors}`
54137
55493
  }
54138
55494
  if (!options.force) {
54139
55495
  output.info("Checking for stale content...");
54140
- const [localMeta, pagesMeta, navigationMeta, formsMeta] = await Promise.all([
55496
+ const [localMeta, pagesMeta, navigationMeta, settingsMeta, formsMeta] = await Promise.all([
54141
55497
  readAllMeta(contentDir),
54142
55498
  readPagesMeta(contentDir),
54143
55499
  readNavigationMeta(contentDir),
55500
+ readSettingsMeta(contentDir),
54144
55501
  readFormsMeta(contentDir)
54145
55502
  ]);
54146
55503
  const staleItems = checkForStaleContent(
@@ -54149,7 +55506,8 @@ ${errors}`
54149
55506
  pagesMeta,
54150
55507
  navigationMeta,
54151
55508
  formsMeta,
54152
- remoteContent
55509
+ remoteContent,
55510
+ settingsMeta
54153
55511
  );
54154
55512
  if (staleItems.length > 0) {
54155
55513
  output.warn(
@@ -54275,6 +55633,22 @@ ${errors}`
54275
55633
  humanDiff
54276
55634
  });
54277
55635
  if (dryRun) {
55636
+ const preflight = preflightContentPushPlanAsCommandReport({
55637
+ pushScope,
55638
+ siteId: env.siteId,
55639
+ target,
55640
+ diff,
55641
+ local: filteredLocal,
55642
+ client,
55643
+ blockFieldExtensions: cliConfig.blockFieldExtensions,
55644
+ output
55645
+ });
55646
+ const preflightResult = contentPushExecutionReportToSyncResult(preflight.report);
55647
+ if (preflightResult.errors.length > 0) {
55648
+ reportSyncResults({ output, result: preflightResult, hasErrors: true });
55649
+ process.exitCode = 1;
55650
+ return { success: false };
55651
+ }
54278
55652
  if (pushScope === "all") {
54279
55653
  if (pushAllExtraChanges?.venues.toPush.size) {
54280
55654
  output.info(
@@ -54415,6 +55789,7 @@ ${errors}`
54415
55789
  createdAt: n.createdAt
54416
55790
  })
54417
55791
  ),
55792
+ settingsUpdatedAt: metadataFlags.willUpdateSettings ? freshRemote.meta.settingsUpdatedAt ?? null : void 0,
54418
55793
  forms: mapIfUpdating(metadataFlags.willUpdateForms, freshRemote.forms, (f) => ({
54419
55794
  slug: f.slug,
54420
55795
  updatedAt: f.updatedAt,
@@ -54604,8 +55979,8 @@ Pushing ${label.toLowerCase()}...`);
54604
55979
  // src/cli/commands/push.ts
54605
55980
  var pushCommand = new Command("push").description("Push content to CMS").argument(
54606
55981
  "[scope]",
54607
- "What to push: entries, pages, navigation, forms, footer, theme, venues, event-categories, events, courses, or all (default)"
54608
- ).argument("[type]", "Content type (entries), page identifier (pages), or theme name (theme)").argument("[identifier]", 'Entry identifier (when scope is "entries" and type is set)').option("--content-dir <dir>", "Content directory (overrides config)").option("--dry-run", "Show what would be pushed without making changes").option("--yes", "Skip confirmation prompt (required for --env=remote or --env=both)").option("--force", "Push even if remote content is newer (skip stale check)").option("--force-update-asset", "Replace CMS media when identifiers conflict (local media sync only)").option("--allow-truncated", "Push even if remote content was truncated (may cause incomplete sync)").option("--json-diff [mode]", "Output JSON diff (summary or full)", "summary").option("--with-config", "Also push SDK config after content").option("--with-theme", "Also push theme when pushing all content").option("--sync-media", "Sync media files from local to remote environment").option("--overwrite-media", "When using --sync-media, overwrite target media on checksum mismatch").option(
55982
+ "What to push: entries, pages, navigation, forms, settings, footer, theme, venues, event-categories, events, courses, or all (default)"
55983
+ ).argument("[type]", "Content type (entries), page identifier (pages), or theme name (theme)").argument("[identifier]", 'Entry identifier (when scope is "entries" and type is set)').option("--content-dir <dir>", "Content directory (overrides config)").option("--dry-run", "Show what would be pushed without making changes").option("--yes", "Skip confirmation prompt (required for --env=remote or --env=both)").option("--force", "Push even if remote content is newer (skip stale check)").option("--force-update-asset", "Replace CMS media when identifiers conflict (local media sync only)").option("--allow-truncated", "Push even if remote content was truncated (may cause incomplete sync)").option("--json-diff [mode]", "Output JSON diff (summary or full)", "summary").option("--with-config", "Also push SDK schema/config after file content").option("--with-theme", "Also push theme when pushing all content").option("--sync-media", "Sync media files from local to remote environment").option("--overwrite-media", "When using --sync-media, overwrite target media on checksum mismatch").option(
54609
55984
  "--delete-missing",
54610
55985
  "[Deprecated: use --delete-orphaned] Delete CMS entries not in local file (single content type only)"
54611
55986
  ).option("--delete-orphaned", "Delete remote items not present in local files (entries, events, courses, venues, event-categories)").option("--auto-pull-stale", "Automatically pull stale content and retry push").option("--merge-remote", "Plan an entries-only three-way merge that preserves remote edits").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(
@@ -54616,7 +55991,7 @@ Examples:
54616
55991
  $ riverbankcms push --env=remote --yes # Push to production
54617
55992
  $ riverbankcms push --env=both --yes # Push to both environments
54618
55993
  $ riverbankcms push --dry-run # Preview changes
54619
- $ riverbankcms push --with-config # Push content and config together
55994
+ $ riverbankcms push --with-config # Push file content and schema/config together
54620
55995
  $ riverbankcms push --with-theme # Push content and theme together
54621
55996
  $ riverbankcms push entries # Push all entries
54622
55997
  $ riverbankcms push entries blog-post # Push specific content type
@@ -54624,6 +55999,8 @@ Examples:
54624
55999
  $ riverbankcms push pages # Push pages with blocks
54625
56000
  $ riverbankcms push pages home # Push specific page with blocks
54626
56001
  $ riverbankcms push navigation # Push navigation menus
56002
+ $ riverbankcms push settings # Push site settings
56003
+ $ riverbankcms push settings --sync-media # Push site settings and sync referenced branding media
54627
56004
  $ riverbankcms push forms # Push forms
54628
56005
  $ riverbankcms push venues # Push venues
54629
56006
  $ riverbankcms push event-categories # Push event categories
@@ -54648,11 +56025,16 @@ Sync Behavior:
54648
56025
  - Status (draft/published) is synced based on local file status
54649
56026
 
54650
56027
  Safety:
56028
+ - Preflight validation: deterministic content issues are checked before mutations
56029
+ and reported together when possible.
54651
56030
  - Stale detection: aborts if remote content is newer than last pull (use --force to override)
54652
56031
  - Truncation: aborts if remote has >100 entries per type (use --allow-truncated to override)
54653
56032
  - Remote environment (--env=remote): defaults to dry-run, requires --yes to execute
54654
56033
  - Remote-aware merge: entries-only v1 for --env=remote; run a dry-run first, then add --yes
54655
56034
  - Theme: not pushed by default (use "push theme" or --with-theme)
56035
+ - Boundaries: media uploads/storage writes and multi-endpoint CMS mutations are
56036
+ not globally transactional; preflight prevents deterministic validation failures
56037
+ before apply, but runtime/network/storage failures can still stop a push mid-run.
54656
56038
 
54657
56039
  Media Sync:
54658
56040
  Local media sync is enabled by default for push.
@@ -55105,6 +56487,7 @@ async function applyOneOffPageCommandReturningBlock(command, client) {
55105
56487
  async function applyOneOffNavigationCommand(command, client) {
55106
56488
  const role = navigationCommandRole2(command);
55107
56489
  return client.navigation.upsert({
56490
+ ...command.input.identifier ? { identifier: command.input.identifier } : {},
55108
56491
  name: navigationCommandMenuName2(command),
55109
56492
  items: command.input.items.map(navigationItemInput2),
55110
56493
  ...role === "primary" ? { isPrimary: true } : {},
@@ -55112,8 +56495,8 @@ async function applyOneOffNavigationCommand(command, client) {
55112
56495
  });
55113
56496
  }
55114
56497
  function oneOffEntryCommandBinding(mutation) {
55115
- const contentType = asCliContentTypeKey(mutation.contentType);
55116
- const identifier = asCliEntryIdentifier(mutation.identifier);
56498
+ const contentType = unsafeAsCliContentTypeKey(mutation.contentType);
56499
+ const identifier = unsafeAsCliEntryIdentifier(mutation.identifier);
55117
56500
  switch (mutation.kind) {
55118
56501
  case "upsert": {
55119
56502
  const title = titleFromEntryData(mutation.data);
@@ -55160,7 +56543,7 @@ function oneOffEntryCommandBinding(mutation) {
55160
56543
  }
55161
56544
  }
55162
56545
  function oneOffPageCommandBinding(mutation) {
55163
- const identifier = asCliPageIdentifier(mutation.identifier);
56546
+ const identifier = unsafeAsCliPageIdentifier(mutation.identifier);
55164
56547
  switch (mutation.kind) {
55165
56548
  case "upsert": {
55166
56549
  const command = {
@@ -55207,10 +56590,10 @@ function oneOffPageCommandBinding(mutation) {
55207
56590
  }
55208
56591
  }
55209
56592
  function oneOffBlockCommandBinding(mutation) {
55210
- const pageIdentifier = asCliPageIdentifier(mutation.pageIdentifier);
56593
+ const pageIdentifier = unsafeAsCliPageIdentifier(mutation.pageIdentifier);
55211
56594
  switch (mutation.kind) {
55212
56595
  case "upsert": {
55213
- const identifier = asCliBlockIdentifier(mutation.blockIdentifier);
56596
+ const identifier = unsafeAsCliBlockIdentifier(mutation.blockIdentifier);
55214
56597
  const command = {
55215
56598
  type: "upsertPageBlock",
55216
56599
  ref: createBlockRef([pageIdentifier, identifier]),
@@ -55232,7 +56615,7 @@ function oneOffBlockCommandBinding(mutation) {
55232
56615
  };
55233
56616
  }
55234
56617
  case "reorder": {
55235
- const identifiers = mutation.blockIdentifiers.map(asCliBlockIdentifier);
56618
+ const identifiers = mutation.blockIdentifiers.map(unsafeAsCliBlockIdentifier);
55236
56619
  const command = {
55237
56620
  type: "reorderPageBlocks",
55238
56621
  ref: createBlocksRef([pageIdentifier]),
@@ -55259,11 +56642,12 @@ function oneOffBlockCommandBinding(mutation) {
55259
56642
  }
55260
56643
  }
55261
56644
  function oneOffNavigationCommandBinding(mutation) {
55262
- const name = asCliNavigationMenuName(mutation.menuName);
56645
+ const name = unsafeAsCliNavigationMenuName(mutation.menuName);
55263
56646
  const command = {
55264
56647
  type: "upsertNavigationMenu",
55265
56648
  ref: createNavigationRef([name]),
55266
56649
  input: {
56650
+ ...mutation.identifier ? { identifier: mutation.identifier } : {},
55267
56651
  name,
55268
56652
  items: mutation.items.map(navigationItemForCommand2)
55269
56653
  }
@@ -56023,7 +57407,7 @@ function countItems(items) {
56023
57407
  }
56024
57408
  return count;
56025
57409
  }
56026
- var upsertCommand4 = new Command("upsert").description("Create or update a navigation menu").argument("<menu-name>", "Navigation menu name").option("--file <path>", "Path to JSON file with menu items").option("--data <json>", "Menu items as JSON string").action(
57410
+ var upsertCommand4 = new Command("upsert").description("Create or update a navigation menu").argument("<menu-name>", "Navigation menu name").option("--identifier <identifier>", "Stable SDK identifier for this menu").option("--file <path>", "Path to JSON file with menu items").option("--data <json>", "Menu items as JSON string").action(
56027
57411
  withCommandContext(async (ctx, menuName, options) => {
56028
57412
  const { output, client, siteId, targetEnv } = ctx;
56029
57413
  const items = await parseJsonArray(options);
@@ -56032,7 +57416,12 @@ var upsertCommand4 = new Command("upsert").description("Create or update a navig
56032
57416
  source: "one_off_navigation",
56033
57417
  siteId,
56034
57418
  targetEnv,
56035
- mutation: { kind: "upsert", menuName, items }
57419
+ mutation: {
57420
+ kind: "upsert",
57421
+ ...options.identifier ? { identifier: options.identifier } : {},
57422
+ menuName,
57423
+ items
57424
+ }
56036
57425
  });
56037
57426
  if (!compiled.ok) {
56038
57427
  return output.error(compiled.error.message);
@@ -56070,10 +57459,58 @@ var listCommand4 = createListCommand({
56070
57459
  tableHeaders: ["Name", "Items", "Updated"],
56071
57460
  formatRow: formatMenuRow
56072
57461
  });
57462
+ function resolveNavigationMenuForDelete(menus, selector) {
57463
+ const idMatch = menus.find((menu) => menu.id === selector);
57464
+ if (idMatch) return idMatch;
57465
+ const nameMatches = menus.filter((menu) => menu.name === selector);
57466
+ const onlyNameMatch = nameMatches[0];
57467
+ if (nameMatches.length === 1 && onlyNameMatch) {
57468
+ return onlyNameMatch;
57469
+ }
57470
+ if (nameMatches.length > 1) {
57471
+ throw new Error(
57472
+ `Multiple navigation menus are named "${selector}". Delete by ID instead: ${nameMatches.map((menu) => menu.id).join(", ")}`
57473
+ );
57474
+ }
57475
+ throw new Error(`Navigation menu not found by ID or exact name: ${selector}`);
57476
+ }
57477
+ var deleteCommand = new Command("delete").description("Delete a navigation menu by ID or exact unique name").argument("<menu-id-or-name>", "Navigation menu ID, or exact name when unique").option("--yes", "Skip confirmation prompt (required for --env=remote)").action(
57478
+ withCommandContext(async (ctx, selector, options) => {
57479
+ const { client, isRemote, output, targetEnv } = ctx;
57480
+ const menu = resolveNavigationMenuForDelete(await client.navigation.list(), selector);
57481
+ const itemCount = countItems(menu.items);
57482
+ const flags = [
57483
+ menu.isPrimary ? "primary" : null,
57484
+ menu.isFooter ? "footer" : null
57485
+ ].filter((flag) => Boolean(flag));
57486
+ const flagText = flags.length > 0 ? flags.join(", ") : "none";
57487
+ const confirmed = await confirmAction(
57488
+ `Delete navigation menu "${menu.name}" (${menu.id}) from ${targetEnv}? flags: ${flagText}; items: ${itemCount}`,
57489
+ options,
57490
+ isRemote
57491
+ );
57492
+ if (!confirmed) {
57493
+ output.info("Operation cancelled");
57494
+ return;
57495
+ }
57496
+ output.info(`Deleting navigation menu: ${menu.name}`);
57497
+ await client.navigation.delete(menu.id);
57498
+ output.success(`Navigation menu deleted: ${menu.name}`, {
57499
+ id: menu.id,
57500
+ name: menu.name,
57501
+ identifier: menu.identifier,
57502
+ isPrimary: menu.isPrimary,
57503
+ isFooter: menu.isFooter,
57504
+ itemCount,
57505
+ environment: targetEnv
57506
+ });
57507
+ })
57508
+ );
56073
57509
  var navigationCommand = new Command("navigation").description("Manage navigation menus").addHelpText("after", `
56074
57510
  Examples:
56075
57511
  $ riverbankcms navigation upsert main --file ./main-nav.json
56076
57512
  $ riverbankcms navigation upsert footer --data '[{"label": "Home", "url": "/"}]'
57513
+ $ riverbankcms navigation delete "Primary navigation" --yes
56077
57514
  $ riverbankcms navigation get main
56078
57515
  $ riverbankcms navigation list
56079
57516
 
@@ -56086,7 +57523,7 @@ JSON file format:
56086
57523
  ]}
56087
57524
  ]
56088
57525
  }
56089
- `).addCommand(upsertCommand4).addCommand(getCommand4).addCommand(listCommand4);
57526
+ `).addCommand(upsertCommand4).addCommand(deleteCommand).addCommand(getCommand4).addCommand(listCommand4);
56090
57527
  var deleteEntryCommand = new Command("entry").description("Delete a content entry").argument("<type>", "Content type").argument("<identifier>", "Entry identifier").option("--yes", "Skip confirmation prompt (required for --env=remote)").action(
56091
57528
  withConfirmation(
56092
57529
  (type, identifier) => `Delete entry "${type}/${identifier}"?`,
@@ -56107,7 +57544,7 @@ var deleteBlockCommand = new Command("block").description("Delete a block from a
56107
57544
  }
56108
57545
  )
56109
57546
  );
56110
- var deleteCommand = new Command("delete").description("Delete content from CMS").addHelpText("after", `
57547
+ var deleteCommand2 = new Command("delete").description("Delete content from CMS").addHelpText("after", `
56111
57548
  Examples:
56112
57549
  $ riverbankcms delete entry blog-post my-post
56113
57550
  $ riverbankcms delete entry blog-post my-post --yes
@@ -56137,7 +57574,7 @@ var THEME_FIELD_CATEGORY_MAP = {
56137
57574
  };
56138
57575
 
56139
57576
  // src/cli/init-docs/zod-to-markdown.ts
56140
- function isRecord12(value) {
57577
+ function isRecord14(value) {
56141
57578
  return typeof value === "object" && value !== null && !Array.isArray(value);
56142
57579
  }
56143
57580
  function isZodTypeAny(value) {
@@ -56224,6 +57661,8 @@ function unwrapSchema(schema) {
56224
57661
  function zodTypeToString(schema) {
56225
57662
  const typeName = getTypeName(schema);
56226
57663
  switch (typeName) {
57664
+ case void 0:
57665
+ return "unknown";
56227
57666
  case ZodTypeName.ZodString:
56228
57667
  return "string";
56229
57668
  case ZodTypeName.ZodNumber:
@@ -56263,7 +57702,7 @@ function extractLiteralValue(schema) {
56263
57702
  const typeName = getTypeName(schema);
56264
57703
  if (typeName !== ZodTypeName.ZodLiteral) return void 0;
56265
57704
  const def = schema._def;
56266
- if (!isRecord12(def)) return void 0;
57705
+ if (!isRecord14(def)) return void 0;
56267
57706
  return String(def.value);
56268
57707
  }
56269
57708
  function extractSchemaInfo(schema, skipFields = []) {
@@ -56333,7 +57772,7 @@ function extractFieldInfo(name, schema) {
56333
57772
  }
56334
57773
  if (typeName === ZodTypeName.ZodRecord) {
56335
57774
  const def = inner._def;
56336
- const valueSchema = isRecord12(def) ? def.valueType : void 0;
57775
+ const valueSchema = isRecord14(def) ? def.valueType : void 0;
56337
57776
  if (!isZodTypeAny(valueSchema)) {
56338
57777
  info.recordValueType = "unknown";
56339
57778
  return info;
@@ -56348,7 +57787,7 @@ function extractFieldInfo(name, schema) {
56348
57787
  }
56349
57788
  } else if (getTypeName(valueInner) === ZodTypeName.ZodRecord) {
56350
57789
  const nestedDef = valueInner._def;
56351
- const nestedValueSchema = isRecord12(nestedDef) ? nestedDef.valueType : void 0;
57790
+ const nestedValueSchema = isRecord14(nestedDef) ? nestedDef.valueType : void 0;
56352
57791
  if (!isZodTypeAny(nestedValueSchema)) {
56353
57792
  info.recordValueType = "record<string, unknown>";
56354
57793
  return info;
@@ -56359,7 +57798,7 @@ function extractFieldInfo(name, schema) {
56359
57798
  }
56360
57799
  if (typeName === ZodTypeName.ZodUnion || typeName === ZodTypeName.ZodDiscriminatedUnion) {
56361
57800
  const def = inner._def;
56362
- const optionsValue = isRecord12(def) ? def.options : void 0;
57801
+ const optionsValue = isRecord14(def) ? def.options : void 0;
56363
57802
  const options = Array.isArray(optionsValue) ? optionsValue.filter(isZodTypeAny) : [];
56364
57803
  const optionTypes = options.map((opt) => {
56365
57804
  const { inner: optInner } = unwrapSchema(opt);
@@ -56748,7 +58187,7 @@ function renderConfigGuideSection() {
56748
58187
  " navigation: {",
56749
58188
  " siteNav: {",
56750
58189
  " // mode: 'augment' | 'restrict'",
56751
- " // allowIds: ['site.style']",
58190
+ " // allowIds: ['site.performance']",
56752
58191
  " // denyIds: ['site.performance', 'site.newsletter']",
56753
58192
  " roles: {",
56754
58193
  " editor: { mode: 'restrict', allowIds: ['site.overview', 'site.content', 'site.media', 'site.bookings'] },",
@@ -56769,7 +58208,7 @@ function renderConfigGuideSection() {
56769
58208
  "Navigation IDs:",
56770
58209
  "",
56771
58210
  "- Top nav (`dashboard.navigation.siteNav`):",
56772
- " - `site.overview`, `site.content`, `site.media`, `site.bookings`, `site.newsletter`, `site.style`, `site.performance`, `site.settings`",
58211
+ " - `site.overview`, `site.content`, `site.media`, `site.bookings`, `site.newsletter`, `site.performance`, `site.settings`",
56773
58212
  "- Settings sidebar (`dashboard.navigation.settingsNav`):",
56774
58213
  " - `settings.general`, `settings.domains`, `settings.fonts`, `settings.navigation`, `settings.redirects`, `settings.emails`",
56775
58214
  " - `settings.ai.siteProfile`, `settings.ai.brandGuidelines`",
@@ -57071,14 +58510,14 @@ function renderFieldList(fields3, depth, skipPatternCheck = false) {
57071
58510
  );
57072
58511
  }
57073
58512
  }
57074
- if ("fields" in field && Array.isArray(field.fields)) {
58513
+ if ("fields" in field && isFieldDefinitionArray(field.fields)) {
57075
58514
  lines.push(...renderFieldList(field.fields, depth + 1));
57076
58515
  }
57077
58516
  if ("schema" in field) {
57078
58517
  const schema = field.schema;
57079
58518
  if (schema && typeof schema === "object" && "fields" in schema) {
57080
58519
  const fields4 = schema.fields;
57081
- if (Array.isArray(fields4)) {
58520
+ if (isFieldDefinitionArray(fields4)) {
57082
58521
  lines.push(...renderFieldList(fields4, depth + 1));
57083
58522
  }
57084
58523
  }
@@ -57101,6 +58540,9 @@ function renderFieldList(fields3, depth, skipPatternCheck = false) {
57101
58540
  }
57102
58541
  return lines;
57103
58542
  }
58543
+ function isFieldDefinitionArray(value) {
58544
+ return Array.isArray(value);
58545
+ }
57104
58546
  function renderOptionsList(options, depth) {
57105
58547
  const indent = " ".repeat(depth);
57106
58548
  return options.map((option) => {
@@ -57191,7 +58633,8 @@ async function initDocs(options) {
57191
58633
  { filename: "templates.md", template: "workflow-templates" },
57192
58634
  { filename: "cmsify-page.md", template: "workflow-cmsify-page" },
57193
58635
  { filename: "editor-workflows.md", template: "workflow-editor-workflows" },
57194
- { filename: "preview-mode.md", template: "workflow-preview-mode" }
58636
+ { filename: "preview-mode.md", template: "workflow-preview-mode" },
58637
+ { filename: "isr-revalidation.md", template: "workflow-isr-revalidation" }
57195
58638
  ];
57196
58639
  await Promise.all(
57197
58640
  coreWorkflows.map(
@@ -57516,7 +58959,7 @@ var SimpleCache = class {
57516
58959
  };
57517
58960
 
57518
58961
  // src/version.ts
57519
- var SDK_VERSION = "0.78.0";
58962
+ var SDK_VERSION = "0.79.0";
57520
58963
 
57521
58964
  // src/client/error.ts
57522
58965
  var RiverbankApiError = class _RiverbankApiError extends Error {
@@ -57929,9 +59372,10 @@ var CircuitOpenError = class extends Error {
57929
59372
  var prebuildModule = null;
57930
59373
  function tryRequire(modulePath) {
57931
59374
  try {
57932
- const req = Function(
59375
+ const getRequire = new Function(
57933
59376
  'return typeof require === "function" ? require : null'
57934
- )();
59377
+ );
59378
+ const req = getRequire();
57935
59379
  return req ? req(modulePath) : null;
57936
59380
  } catch {
57937
59381
  return null;
@@ -58444,8 +59888,7 @@ function createRiverbankClient(config2) {
58444
59888
  async (sig) => {
58445
59889
  return await apiClient({
58446
59890
  endpoint: "getContentByPath",
58447
- params: { siteId },
58448
- body: { path: path24, preview },
59891
+ params: { siteId, path: path24, preview: String(preview) },
58449
59892
  options: { signal: sig }
58450
59893
  });
58451
59894
  },
@@ -58495,6 +59938,8 @@ function createRiverbankClient(config2) {
58495
59938
  orderParam = "published_at.asc";
58496
59939
  } else if (order === "title") {
58497
59940
  orderParam = "title.asc";
59941
+ } else if (order === "manual") {
59942
+ orderParam = "manual.asc";
58498
59943
  }
58499
59944
  const apiParams = {
58500
59945
  siteId,
@@ -61672,11 +63117,14 @@ function collectFieldIds(fields3) {
61672
63117
  for (const field of fieldList) {
61673
63118
  ids.add(field.id);
61674
63119
  if (field.schema && typeof field.schema === "object" && "fields" in field.schema) {
61675
- collect(field.schema.fields);
63120
+ const nestedFields = field.schema.fields;
63121
+ if (isFieldIdRecordArray(nestedFields)) {
63122
+ collect(nestedFields);
63123
+ }
61676
63124
  }
61677
- if (field.tabs && Array.isArray(field.tabs)) {
63125
+ if (isRecordArray(field.tabs)) {
61678
63126
  for (const tab of field.tabs) {
61679
- if (tab.fields && Array.isArray(tab.fields)) {
63127
+ if (isFieldIdRecordArray(tab.fields)) {
61680
63128
  collect(tab.fields);
61681
63129
  }
61682
63130
  }
@@ -61693,6 +63141,12 @@ function collectFieldIds(fields3) {
61693
63141
  collect(fields3);
61694
63142
  return ids;
61695
63143
  }
63144
+ function isRecordArray(value) {
63145
+ return Array.isArray(value);
63146
+ }
63147
+ function isFieldIdRecordArray(value) {
63148
+ return Array.isArray(value) && value.every((item) => typeof item === "object" && item !== null && typeof item.id === "string");
63149
+ }
61696
63150
  var CONTENT_NODE_TYPES = ["text", "richText", "media", "button", "link"];
61697
63151
  function collectFieldInfo(fields3) {
61698
63152
  const topLevelFieldIds = /* @__PURE__ */ new Set();
@@ -64097,7 +65551,7 @@ var listCommand6 = createListCommand({
64097
65551
  tableHeaders: ["Identifier", "Status", "Visibility", "Updated"],
64098
65552
  formatRow: formatEventRow
64099
65553
  });
64100
- var deleteCommand2 = new Command("delete").description("Delete an event series").argument("<identifier>", "Event identifier").option("--yes", "Skip confirmation prompt (required for --env=remote)").action(
65554
+ var deleteCommand3 = new Command("delete").description("Delete an event series").argument("<identifier>", "Event identifier").option("--yes", "Skip confirmation prompt (required for --env=remote)").action(
64101
65555
  withConfirmation(
64102
65556
  (identifier) => `Delete event "${identifier}"?`,
64103
65557
  async (ctx, identifier) => {
@@ -64144,7 +65598,7 @@ Examples:
64144
65598
  $ riverbankcms event cancel summer-fest
64145
65599
  $ riverbankcms event delete summer-fest --yes
64146
65600
  `
64147
- ).addCommand(listCommand6).addCommand(getCommand5).addCommand(upsertCommand5).addCommand(cancelCommand).addCommand(deleteCommand2);
65601
+ ).addCommand(listCommand6).addCommand(getCommand5).addCommand(upsertCommand5).addCommand(cancelCommand).addCommand(deleteCommand3);
64148
65602
  var courseUpsertInputSchema = z.object({
64149
65603
  identifier: z.string().min(1).optional(),
64150
65604
  title: z.string().min(1, "title is required"),
@@ -64266,7 +65720,7 @@ var listCommand7 = createListCommand({
64266
65720
  tableHeaders: ["Identifier", "Status", "Visibility", "Updated"],
64267
65721
  formatRow: formatCourseRow
64268
65722
  });
64269
- var deleteCommand3 = new Command("delete").description("Delete a course run").argument("<identifier>", "Course identifier").option("--yes", "Skip confirmation prompt (required for --env=remote)").action(
65723
+ var deleteCommand4 = new Command("delete").description("Delete a course run").argument("<identifier>", "Course identifier").option("--yes", "Skip confirmation prompt (required for --env=remote)").action(
64270
65724
  withConfirmation(
64271
65725
  (identifier) => `Delete course "${identifier}"?`,
64272
65726
  async (ctx, identifier) => {
@@ -64317,7 +65771,7 @@ Examples:
64317
65771
  $ riverbankcms course cancel beginner-yoga
64318
65772
  $ riverbankcms course delete beginner-yoga --yes
64319
65773
  `
64320
- ).addCommand(listCommand7).addCommand(getCommand6).addCommand(upsertCommand6).addCommand(cancelCommand2).addCommand(deleteCommand3);
65774
+ ).addCommand(listCommand7).addCommand(getCommand6).addCommand(upsertCommand6).addCommand(cancelCommand2).addCommand(deleteCommand4);
64321
65775
  function isPlainObject3(value) {
64322
65776
  return !!value && typeof value === "object" && !Array.isArray(value);
64323
65777
  }
@@ -64714,7 +66168,7 @@ program.addCommand(entryCommand);
64714
66168
  program.addCommand(pageCommand);
64715
66169
  program.addCommand(blockCommand);
64716
66170
  program.addCommand(navigationCommand);
64717
- program.addCommand(deleteCommand);
66171
+ program.addCommand(deleteCommand2);
64718
66172
  program.addCommand(initDocsCommand);
64719
66173
  program.addCommand(identifiersCommand);
64720
66174
  program.addCommand(deployCommand);