@riverbankcms/sdk 0.152.0 → 0.153.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 (178) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/{EventEmbeddedCheckoutStep-DVQXWFm6.mjs → EventEmbeddedCheckoutStep-veN-QiAE.mjs} +1 -1
  3. package/dist/{PreviewEditorSidebar-Dr4NJi3Q.mjs → PreviewEditorSidebar-jI_4DTZY.mjs} +4 -4
  4. package/dist/{PreviewEditorUI-DSZXQbyh.mjs → PreviewEditorUI-ORkVZhfu.mjs} +3 -3
  5. package/dist/{SdkPreviewModeRuntime-Dl4GyMc3.mjs → SdkPreviewModeRuntime-DaNqevI1.mjs} +221 -115
  6. package/dist/{SiteChromeCustomizeContext-DgBe-FlM.mjs → SiteChromeCustomizeContext-CgNuBHC0.mjs} +1798 -2024
  7. package/dist/{ThemedButton-B8ViBnLK.mjs → ThemedButton-X2UxhW6F.mjs} +213 -38
  8. package/dist/_dts/ai/src/contracts/proposals.d.ts +52 -52
  9. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +2357 -7859
  10. package/dist/_dts/api/src/communications.d.ts +19 -5
  11. package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -1
  12. package/dist/_dts/api/src/sdkThemeWire.d.ts +186 -1434
  13. package/dist/_dts/api/src/shared-contracts.d.ts +10 -0
  14. package/dist/_dts/api/src/siteInfrastructure.d.ts +2 -1
  15. package/dist/_dts/api/src/teamMembers.d.ts +2 -27
  16. package/dist/_dts/block-form/src/widgets/RepeaterField/components/layoutGridDomain.d.ts +3 -13
  17. package/dist/_dts/blocks/src/contracts/index.d.ts +1 -0
  18. package/dist/_dts/blocks/src/index.d.ts +1 -0
  19. package/dist/_dts/blocks/src/lib/media.d.ts +1 -0
  20. package/dist/_dts/blocks/src/lib/picsum.d.ts +2 -2
  21. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +2 -1
  22. package/dist/_dts/blocks/src/system/blocks/events/eventSelectionFields.d.ts +1 -1
  23. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +196 -804
  24. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +2 -2
  25. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +1 -1
  26. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +45 -45
  27. package/dist/_dts/blocks/src/system/blocks/shared/teamMembers.d.ts +4 -7
  28. package/dist/_dts/blocks/src/system/blocks/team-members.d.ts +2 -2
  29. package/dist/_dts/blocks/src/system/customize/backgrounds.d.ts +6 -6
  30. package/dist/_dts/blocks/src/system/fields/backgroundContent.d.ts +377 -1
  31. package/dist/_dts/blocks/src/system/helpers/backgroundMedia.d.ts +6 -2
  32. package/dist/_dts/blocks/src/system/helpers/resolveBackground.d.ts +3 -3
  33. package/dist/_dts/blocks/src/system/layout/repeaterGrid.d.ts +12 -5
  34. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +3 -3
  35. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +24 -24
  36. package/dist/_dts/blocks/src/system/manifest/validation.d.ts +2 -0
  37. package/dist/_dts/blocks/src/system/node/fragments/lookSlot.d.ts +1 -1
  38. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingFlowController.d.ts +1 -1
  39. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.d.ts +2 -0
  40. package/dist/_dts/blocks/src/system/runtime/lookSurfaces.d.ts +2 -2
  41. package/dist/_dts/blocks/src/system/runtime/nodes/ImageResolveContext.d.ts +1 -1
  42. package/dist/_dts/blocks/src/system/runtime/nodes/appointment-services.d.ts +50 -202
  43. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +28 -1
  44. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/lookPresentation.d.ts +2 -2
  45. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/presentation.d.ts +1 -1
  46. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/CardListItem.d.ts +1 -1
  47. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +276 -884
  48. package/dist/_dts/blocks/src/system/runtime/nodes/file-download.d.ts +3 -2
  49. package/dist/_dts/blocks/src/system/runtime/nodes/media.d.ts +22 -90
  50. package/dist/_dts/blocks/src/system/runtime/nodes/mediaContext.d.ts +69 -0
  51. package/dist/_dts/blocks/src/system/transforms/registry/index.d.ts +1 -0
  52. package/dist/_dts/blocks/src/system/transforms/registry/links.d.ts +3 -3
  53. package/dist/_dts/content-model/src/content-types/schema.d.ts +3 -3
  54. package/dist/_dts/core/src/mailing-list-runtime.d.ts +2 -2
  55. package/dist/_dts/core/src/mailing-list-setup-parser.d.ts +9 -1
  56. package/dist/_dts/core/src/mailing-list-setup.d.ts +9 -1
  57. package/dist/_dts/core/src/mailing-list-submission.d.ts +1 -1
  58. package/dist/_dts/core/src/mailing-list-targeting.d.ts +9 -1
  59. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +55 -4
  60. package/dist/_dts/editor-blocks/src/index.d.ts +1 -0
  61. package/dist/_dts/editor-blocks/src/media/MediaField.d.ts +2 -2
  62. package/dist/_dts/editor-blocks/src/media/admitEditorMediaField.d.ts +4 -0
  63. package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/targetingState.d.ts +2 -2
  64. package/dist/_dts/media-core/src/assetsInUseSummary.d.ts +6 -0
  65. package/dist/_dts/media-core/src/contentMediaAudit.d.ts +3 -2
  66. package/dist/_dts/media-core/src/index.d.ts +4 -0
  67. package/dist/_dts/media-core/src/media.d.ts +406 -0
  68. package/dist/_dts/media-core/src/mediaIdentifierSchema.d.ts +3 -0
  69. package/dist/_dts/media-core/src/mediaKinds.d.ts +2 -0
  70. package/dist/_dts/media-core/src/mediaUsageProjection.d.ts +13 -1
  71. package/dist/_dts/media-core/src/mediaWriteNormalizer.d.ts +2 -6
  72. package/dist/_dts/media-core/src/portableMediaReferences.d.ts +8 -21
  73. package/dist/_dts/media-core/src/renderableMediaAsset.d.ts +28 -14
  74. package/dist/_dts/media-core/src/renderableMediaAssetAdmission.d.ts +15 -0
  75. package/dist/_dts/media-editor/src/CropDialog.d.ts +6 -3
  76. package/dist/_dts/media-editor/src/MediaEditor.d.ts +2 -1
  77. package/dist/_dts/media-editor/src/MediaPreview.d.ts +3 -3
  78. package/dist/_dts/media-editor/src/cropEditorSource.d.ts +5 -7
  79. package/dist/_dts/media-editor/src/editorMediaState.d.ts +29 -0
  80. package/dist/_dts/media-editor/src/mediaSelection.d.ts +1 -2
  81. package/dist/_dts/media-editor/src/runtimeMediaAssetState.d.ts +4 -5
  82. package/dist/_dts/media-editor/src/types.d.ts +1 -1
  83. package/dist/_dts/media-editor/src/utils.d.ts +0 -1
  84. package/dist/_dts/media-react/src/components/cropChangePolicy.d.ts +4 -1
  85. package/dist/_dts/media-react/src/components/cropGeometry.d.ts +1 -0
  86. package/dist/_dts/media-react/src/components/useImageCropperController.d.ts +1 -0
  87. package/dist/_dts/preview-next/src/client/blocks/BlockBackgroundChooser.d.ts +2 -1
  88. package/dist/_dts/preview-next/src/client/blocks/previewCustomizeSelectedMedia.d.ts +11 -12
  89. package/dist/_dts/sdk/src/contracts/content.d.ts +2 -45
  90. package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
  91. package/dist/_dts/sdk/src/contracts/rendering.d.ts +3 -3
  92. package/dist/_dts/sdk/src/index.d.ts +1 -0
  93. package/dist/_dts/sdk/src/rendering/image.d.ts +5 -5
  94. package/dist/_dts/sdk/src/rendering/index.d.ts +2 -1
  95. package/dist/_dts/sdk/src/rendering/link.d.ts +3 -7
  96. package/dist/_dts/sdk/src/rendering/mediaAssets.d.ts +2 -4
  97. package/dist/_dts/sdk/src/version.d.ts +1 -1
  98. package/dist/_dts/theme-core/src/accordions/types.d.ts +1 -1
  99. package/dist/_dts/theme-core/src/boxBackgroundSchema.d.ts +397 -26
  100. package/dist/_dts/theme-core/src/buttons/types.d.ts +21 -21
  101. package/dist/_dts/theme-core/src/cards/types.d.ts +34 -34
  102. package/dist/_dts/theme-core/src/inputs/types.d.ts +3 -3
  103. package/dist/_dts/theme-core/src/lib/media.d.ts +2 -616
  104. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +261 -2619
  105. package/dist/_dts/theme-core/src/palette/curated/types.d.ts +1 -1
  106. package/dist/_dts/theme-core/src/schema.d.ts +548 -3187
  107. package/dist/_dts/theme-core/src/site-styles/backgroundAppearance.d.ts +2 -2
  108. package/dist/_dts/theme-core/src/site-styles/runtimeBackgroundResolution.d.ts +9 -9
  109. package/dist/_dts/theme-core/src/site-styles/styleTags.d.ts +1 -1
  110. package/dist/_dts/theme-core/src/site-styles/tokenRecipes.d.ts +1 -1
  111. package/dist/_dts/theme-core/src/styles/skinTokens.d.ts +2 -2
  112. package/dist/_dts/theme-core/src/typography/schema.d.ts +2 -2
  113. package/dist/client/{BookingMailingListNote-CBuMKN0w.mjs → BookingMailingListNote-DrchYW1m.mjs} +2 -2
  114. package/dist/client/{CardListItem-Dc9XTXhB.mjs → CardListItem-CC_GVmF6.mjs} +5 -4
  115. package/dist/client/{CheckboxChoice-CIqx_o0E.mjs → CheckboxChoice-Dq30m3DO.mjs} +1 -1
  116. package/dist/client/{DemoBookingPortalAccess-D3VQ_kLj.mjs → DemoBookingPortalAccess-ojwbVUmx.mjs} +2 -2
  117. package/dist/client/{EventCombined.client-BHGEKise.mjs → EventCombined.client-DyN0v0Xk.mjs} +5 -6
  118. package/dist/client/{EventEmbeddedCheckoutStep-Bo1Cm23R.mjs → EventEmbeddedCheckoutStep-CgfpKc3n.mjs} +2 -2
  119. package/dist/client/{EventListing.client-D5OQgVPr.mjs → EventListing.client-CuOuvYMz.mjs} +2 -2
  120. package/dist/client/{LeafletStaticMap-CLL5cWrr.mjs → LeafletStaticMap-B0WhRr3j.mjs} +1 -1
  121. package/dist/client/{RichText-BoDmnopf.mjs → RichText-C1fIXBzA.mjs} +45 -32
  122. package/dist/client/{ThemedButton-Ciltp0IK.mjs → ThemedButton-B7HFqFBg.mjs} +1 -2
  123. package/dist/client/{accordion-DOkRS64-.mjs → accordion-DCDVWSye.mjs} +1 -1
  124. package/dist/client/{bookingForm-wlMVwo9h.mjs → bookingForm-BJ3C4GlM.mjs} +42 -15
  125. package/dist/client/bookings.mjs +116989 -22191
  126. package/dist/client/{carousel-CGWk-Z0u.mjs → carousel-BSCBhfHY.mjs} +2 -2
  127. package/dist/client/{carousel.client-kX5mN1Eg.mjs → carousel.client-GEtOGsxo.mjs} +1 -1
  128. package/dist/client/{cart-OBBPlaH4.mjs → cart-Yv-aAtck.mjs} +3 -3
  129. package/dist/client/{checkout-Bmw2WjQX.mjs → checkout-B9xDkl30.mjs} +3 -3
  130. package/dist/client/client.mjs +17577 -17361
  131. package/dist/client/{context-BI77UFAn.mjs → context-BOGe3rIA.mjs} +1 -1
  132. package/dist/client/{eventCalendar-qkej2Edn.mjs → eventCalendar-D6M0T9hs.mjs} +8 -9
  133. package/dist/client/{eventCombined-DApKHvat.mjs → eventCombined-NM4UFBq8.mjs} +4 -4
  134. package/dist/client/{eventDetails-BQyUDPH0.mjs → eventDetails-f_FhV4O8.mjs} +3 -3
  135. package/dist/client/{eventListing-CeAnshlZ.mjs → eventListing-WLkfAROh.mjs} +4 -4
  136. package/dist/client/{eventRegistration-C3A3NyBO.mjs → eventRegistration-D3ejfLvW.mjs} +10 -10
  137. package/dist/client/{form-DW8rU7jO.mjs → form-D5Or2Jyu.mjs} +4 -5
  138. package/dist/client/{headerSection-CkIhsoNm.mjs → headerSection-hWgnv27V.mjs} +3 -3
  139. package/dist/client/hooks.mjs +16014 -15751
  140. package/dist/client/{locationMap-D4O8wbli.mjs → locationMap-Di1K0O2S.mjs} +3 -4
  141. package/dist/client/{media-C5K_0xPd.mjs → media-D29-F1u_.mjs} +183 -362
  142. package/dist/client/mediaContext-CwbbimYB.mjs +135 -0
  143. package/dist/client/{newsletterForm-B7IxSPuz.mjs → newsletterForm-CwxcwTNO.mjs} +4 -4
  144. package/dist/client/{productDetail-Bqxpwy5N.mjs → productDetail-BLSnhPdA.mjs} +3 -3
  145. package/dist/client/{productList-u9Lz8V15.mjs → productList-oGytONOX.mjs} +3 -3
  146. package/dist/client/{propsDecoder-Bf1jucUp.mjs → propsDecoder-lf_dTeZS.mjs} +1467 -125
  147. package/dist/client/renderableMediaAssetAdmission-CHkXYDC_.mjs +143 -0
  148. package/dist/client/rendering/client.mjs +10855 -10689
  149. package/dist/client/rendering/islands.mjs +20 -23
  150. package/dist/client/rendering.mjs +18411 -18181
  151. package/dist/client/{routeIslandApiConfig-BgP-aPMl.mjs → routeIslandApiConfig-Bc_WVPS8.mjs} +1 -1
  152. package/dist/client/{shop-B_eykR-_.mjs → shop-BQ3bR7fA.mjs} +7 -7
  153. package/dist/client/{shop-commerce-CT0APkFV.mjs → shop-commerce-DDPll6ZC.mjs} +8 -8
  154. package/dist/client/{shop-commerce-store-DcvZxdEK.mjs → shop-commerce-store-DO-e1pTe.mjs} +1 -1
  155. package/dist/client/{shopShared-BVJOiUiJ.mjs → shopShared-BylM9jh1.mjs} +5 -5
  156. package/dist/client/{useDiscountCodeUi-DPmYDunz.mjs → useDiscountCodeUi-B1Puub2v.mjs} +1 -1
  157. package/dist/client/{useEventPagination-8-U55vH5.mjs → useEventPagination-BBhkmQaT.mjs} +6 -7
  158. package/dist/preview-next/before-render.mjs +89 -4
  159. package/dist/preview-next/client/runtime.mjs +3 -3
  160. package/dist/{sdk-runtime-C5jPdSrk.mjs → sdk-runtime-DWCvhJGu.mjs} +1 -1
  161. package/dist/server/components.mjs +18663 -18510
  162. package/dist/server/config-validation.mjs +450 -215
  163. package/dist/server/config.mjs +450 -215
  164. package/dist/server/data.mjs +15940 -15705
  165. package/dist/server/index.mjs +227 -2
  166. package/dist/server/next.mjs +18643 -18490
  167. package/dist/server/page-converter.mjs +12588 -12477
  168. package/dist/server/prebuild.mjs +1 -1
  169. package/dist/server/rendering/server.mjs +18007 -17855
  170. package/dist/server/rendering.mjs +18677 -18516
  171. package/dist/server/routing.mjs +17747 -17469
  172. package/dist/server/server.mjs +539 -276
  173. package/dist/server/theme-bridge.mjs +154 -37
  174. package/dist/server/theme.mjs +154 -37
  175. package/dist/{spinner-B-ab2rJp.mjs → spinner-BYM-Y81w.mjs} +1 -1
  176. package/package.json +1 -1
  177. package/dist/client/aspectTransforms-D-TnDdq4.mjs +0 -93
  178. package/dist/client/colorStyles-ECDNPE_P.mjs +0 -1253
@@ -1776,12 +1776,14 @@ const unsafeAsSiteId = (id) => id;
1776
1776
  const unsafeAsApiKeyId = (id) => id;
1777
1777
  const unsafeAsEventOfferingId = (id) => id;
1778
1778
  const unsafeAsEventSeriesId = (id) => id;
1779
+ const unsafeAsMediaAssetId = (id) => id;
1779
1780
  const unsafeAsUserId = (id) => id;
1780
1781
  const unsafeAsContentVersionId = (id) => id;
1781
1782
  const parseSiteId = (value) => parseUuidBrand(value, unsafeAsSiteId);
1782
1783
  const parseApiKeyId = (value) => parseUuidBrand(value, unsafeAsApiKeyId);
1783
1784
  const parseEventOfferingId = (value) => parseUuidBrand(value, unsafeAsEventOfferingId);
1784
1785
  const parseUserId = (value) => parseUuidBrand(value, unsafeAsUserId);
1786
+ const parseMediaAssetId = (value) => parseUuidBrand(value, unsafeAsMediaAssetId);
1785
1787
  const parseContentVersionId = (value) => parseUuidBrand(value, unsafeAsContentVersionId);
1786
1788
  const parseEventSeriesId = (value) => parseUuidBrand(value, unsafeAsEventSeriesId);
1787
1789
  //#endregion
@@ -2464,7 +2466,7 @@ function parsePositiveInteger(value) {
2464
2466
  return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : null;
2465
2467
  }
2466
2468
  function parseNewsletterListId(value) {
2467
- return parseTrimmedMatchingString(value, UUID_PATTERN);
2469
+ return parseTrimmedMatchingString(typeof value === "string" ? value.toLowerCase() : value, UUID_PATTERN);
2468
2470
  }
2469
2471
  function parseMailchimpAccountId(value) {
2470
2472
  return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
@@ -2506,8 +2508,15 @@ function parseMailingListProviderScope(value) {
2506
2508
  }
2507
2509
  return err("invalid_mailing_list_provider_scope");
2508
2510
  }
2509
- //#endregion
2510
- //#region ../core/src/mailing-list-setup-parser.ts
2511
+ z.unknown().transform((value, ctx) => {
2512
+ const parsed = parseNewsletterAudience(value);
2513
+ if (parsed.ok) return parsed.value;
2514
+ ctx.addIssue({
2515
+ code: "custom",
2516
+ message: "Choose a valid newsletter audience."
2517
+ });
2518
+ return z.NEVER;
2519
+ });
2511
2520
  function parseMailingListGlobalForm(value) {
2512
2521
  if (!isRecord$9(value)) return formError("shape");
2513
2522
  const fields = parseGlobalFields(value.fields);
@@ -2527,6 +2536,16 @@ function parseMailingListGlobalForm(value) {
2527
2536
  privacyNote
2528
2537
  });
2529
2538
  }
2539
+ function parseNewsletterAudience(value) {
2540
+ if (!isRecord$9(value)) return err("invalid_newsletter_audience");
2541
+ if (value.kind === "general" && Object.keys(value).length === 1) return ok({ kind: "general" });
2542
+ if (value.kind !== "topic" || Object.keys(value).some((key) => key !== "kind" && key !== "topicId")) return err("invalid_newsletter_audience");
2543
+ const topicId = parseNewsletterListId(value.topicId);
2544
+ return topicId === null ? err("invalid_newsletter_audience") : ok({
2545
+ kind: "topic",
2546
+ topicId
2547
+ });
2548
+ }
2530
2549
  function parseGlobalFields(value) {
2531
2550
  if (!isRecord$9(value) || typeof value.preset !== "string") return null;
2532
2551
  switch (value.preset) {
@@ -2579,54 +2598,49 @@ function formError(field) {
2579
2598
  const DEFAULT_MAILING_LIST_TARGETING = { mode: "default" };
2580
2599
  function mailingListTargetingChoiceIds(targeting) {
2581
2600
  switch (targeting.provider) {
2582
- case "native": return targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds;
2601
+ case "native": return targeting.selection.tag === "general" ? [] : targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds;
2583
2602
  case "brevo": return targeting.selection.tag === "fixed" ? targeting.selection.listIds : targeting.selection.offeredListIds;
2584
2603
  case "mailchimp": return targeting.selection.tag === "fixed" ? targeting.selection.interestIds : targeting.selection.offeredInterestIds;
2585
2604
  }
2586
2605
  }
2587
2606
  function planMailingListChoicePresentation(targeting) {
2588
- if (targeting.mode === "default" || targeting.selection.tag === "fixed") return { tag: "hidden" };
2607
+ if (targeting.mode === "default" || targeting.selection.tag === "fixed" || targeting.selection.tag === "general") return { tag: "hidden" };
2589
2608
  switch (targeting.provider) {
2590
- case "native": return targeting.selection.offeredTopicIds.length === 1 ? {
2591
- tag: "automatic",
2592
- selection: {
2593
- provider: "native",
2594
- topicIds: targeting.selection.offeredTopicIds
2595
- }
2596
- } : {
2597
- tag: "visitor_choice",
2609
+ case "native": return presentVisitorSelection({
2598
2610
  provider: "native",
2599
- optionCount: targeting.selection.offeredTopicIds.length
2600
- };
2601
- case "brevo": return targeting.selection.offeredListIds.length === 1 ? {
2602
- tag: "automatic",
2603
- selection: {
2604
- provider: "brevo",
2605
- listIds: targeting.selection.offeredListIds
2606
- }
2607
- } : {
2608
- tag: "visitor_choice",
2611
+ topicIds: targeting.selection.offeredTopicIds
2612
+ }, targeting.selection.offeredTopicIds.length);
2613
+ case "brevo": return presentVisitorSelection({
2609
2614
  provider: "brevo",
2610
- optionCount: targeting.selection.offeredListIds.length
2611
- };
2612
- case "mailchimp": return targeting.selection.offeredInterestIds.length === 1 ? {
2613
- tag: "automatic",
2614
- selection: {
2615
- provider: "mailchimp",
2616
- interestIds: targeting.selection.offeredInterestIds
2617
- }
2618
- } : {
2619
- tag: "visitor_choice",
2615
+ listIds: targeting.selection.offeredListIds
2616
+ }, targeting.selection.offeredListIds.length);
2617
+ case "mailchimp": return presentVisitorSelection({
2620
2618
  provider: "mailchimp",
2621
- optionCount: targeting.selection.offeredInterestIds.length
2622
- };
2619
+ interestIds: targeting.selection.offeredInterestIds
2620
+ }, targeting.selection.offeredInterestIds.length);
2623
2621
  }
2624
2622
  }
2623
+ function presentVisitorSelection(selection, optionCount) {
2624
+ return optionCount === 1 ? {
2625
+ tag: "automatic",
2626
+ selection
2627
+ } : {
2628
+ tag: "visitor_choice",
2629
+ provider: selection.provider,
2630
+ optionCount
2631
+ };
2632
+ }
2625
2633
  //#endregion
2626
2634
  //#region ../core/src/mailing-list-targeting-availability.ts
2627
2635
  function resolveMailingListDefaultDestination(provider) {
2628
2636
  switch (provider.provider) {
2629
- case "native": return provider.topics.find((item) => item.id === provider.defaultTopicId) ?? null;
2637
+ case "native": {
2638
+ const audience = provider.defaultAudience;
2639
+ return audience.kind === "general" ? {
2640
+ id: "general",
2641
+ name: "General mailing list"
2642
+ } : provider.topics.find((item) => item.id === audience.topicId) ?? null;
2643
+ }
2630
2644
  case "brevo": return provider.lists.find((item) => item.id === provider.defaultListId) ?? null;
2631
2645
  case "mailchimp": return provider.audiences.find((item) => item.id === provider.defaultAudienceId) ?? null;
2632
2646
  }
@@ -2764,11 +2778,12 @@ function parseRuntimeProvider(value) {
2764
2778
  }
2765
2779
  }
2766
2780
  function parseNativeRuntimeProvider(value) {
2767
- const defaultTopicId = parseNewsletterListId(value.defaultTopicId);
2781
+ if ("defaultTopicId" in value) return null;
2782
+ const defaultAudience = parseNewsletterAudience(value.defaultAudience);
2768
2783
  const topics = parseNamedItems(value.topics, parseNewsletterListId);
2769
- return defaultTopicId !== null && topics !== null ? {
2784
+ return defaultAudience.ok && topics !== null ? {
2770
2785
  provider: "native",
2771
- defaultTopicId,
2786
+ defaultAudience: defaultAudience.value,
2772
2787
  topics
2773
2788
  } : null;
2774
2789
  }
@@ -2853,6 +2868,11 @@ function parseMailingListPlacementTargeting(value) {
2853
2868
  }
2854
2869
  }
2855
2870
  function parseNativeTargeting(selection) {
2871
+ if (selection.tag === "general") return Object.keys(selection).length === 1 ? ok({
2872
+ mode: "custom",
2873
+ provider: "native",
2874
+ selection: { tag: "general" }
2875
+ }) : targetingError("selection");
2856
2876
  if (selection.tag === "fixed") {
2857
2877
  const topicIds = parseNonEmptyUniqueIds(selection.topicIds, parseNewsletterListId);
2858
2878
  return topicIds.ok ? ok({
@@ -7937,7 +7957,96 @@ const themeLookMetadataSchema = z.object({
7937
7957
  skinMarks: skinMarksSchema.optional()
7938
7958
  });
7939
7959
  //#endregion
7940
- //#region ../theme-core/src/lib/media.ts
7960
+ //#region ../media-core/src/identifiers.ts
7961
+ function slugifyMediaIdentifier(value) {
7962
+ return value.toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
7963
+ }
7964
+ function parseMediaIdentifier(value) {
7965
+ if (typeof value !== "string") return err({ kind: "not_string" });
7966
+ const trimmed = value.trim();
7967
+ if (trimmed.length === 0) return err({ kind: "empty_identifier" });
7968
+ const normalized = slugifyMediaIdentifier(trimmed);
7969
+ if (normalized.length === 0) return err({
7970
+ kind: "empty_after_normalization",
7971
+ value
7972
+ });
7973
+ return ok(normalized);
7974
+ }
7975
+ /**
7976
+ * Admits identifiers read from trusted persistence without repairing dirty data in memory.
7977
+ * User input should use parseMediaIdentifier, which intentionally canonicalizes it.
7978
+ */
7979
+ function parseCanonicalMediaIdentifier(value) {
7980
+ if (typeof value !== "string") return err({ kind: "not_string" });
7981
+ const parsed = parseMediaIdentifier(value);
7982
+ if (!parsed.ok) return parsed;
7983
+ if (value !== parsed.value) return err({
7984
+ kind: "non_canonical_identifier",
7985
+ value,
7986
+ canonical: parsed.value
7987
+ });
7988
+ return parsed;
7989
+ }
7990
+ //#endregion
7991
+ //#region ../media-core/src/mediaIdentifierSchema.ts
7992
+ /** Strict stored-reference admission delegates the canonical identifier decision. */
7993
+ const mediaIdentifierSchema = z.string().transform((value, context) => {
7994
+ const parsed = parseCanonicalMediaIdentifier(value);
7995
+ if (parsed.ok) return parsed.value;
7996
+ context.addIssue({
7997
+ code: "custom",
7998
+ message: "Expected a canonical media identifier"
7999
+ });
8000
+ return z.NEVER;
8001
+ });
8002
+ //#endregion
8003
+ //#region ../media-core/src/mediaKinds.ts
8004
+ const mediaTypeDiscriminants = [
8005
+ "image",
8006
+ "video",
8007
+ "audio",
8008
+ "document",
8009
+ "spreadsheet",
8010
+ "archive"
8011
+ ];
8012
+ //#endregion
8013
+ //#region ../media-core/src/renderableMediaAsset.ts
8014
+ /** A portable reference never uses an incidental UUID, URL or storage snapshot for identity. */
8015
+ function resolveManagedMediaReference(reference, index) {
8016
+ const asset = index?.byIdentifier.get(reference.identifier);
8017
+ return asset ? {
8018
+ kind: "resolved",
8019
+ reference,
8020
+ asset
8021
+ } : {
8022
+ kind: "missing",
8023
+ reference
8024
+ };
8025
+ }
8026
+ //#endregion
8027
+ //#region ../media-core/src/renderableMediaAssetAdmission.ts
8028
+ const mediaAssetIdSchema = z.string().transform((value, context) => {
8029
+ const parsed = parseMediaAssetId(value);
8030
+ if (parsed.ok) return parsed.value;
8031
+ context.addIssue({
8032
+ code: "custom",
8033
+ message: "Expected a media asset ID"
8034
+ });
8035
+ return z.NEVER;
8036
+ });
8037
+ const nonemptyStorageValue = z.string().refine((value) => value.trim().length > 0);
8038
+ const renderableMediaAssetSchema = z.object({
8039
+ id: mediaAssetIdSchema,
8040
+ identifier: mediaIdentifierSchema,
8041
+ storageBucket: nonemptyStorageValue,
8042
+ storagePath: nonemptyStorageValue,
8043
+ mimeType: nonemptyStorageValue,
8044
+ filename: z.string().optional(),
8045
+ width: z.number().positive().nullable(),
8046
+ height: z.number().positive().nullable()
8047
+ });
8048
+ //#endregion
8049
+ //#region ../media-core/src/media.ts
7941
8050
  const hotspotSchema = z.object({
7942
8051
  x: z.number().min(0).max(1),
7943
8052
  y: z.number().min(0).max(1),
@@ -7971,56 +8080,149 @@ const transformSchema = z.object({
7971
8080
  rotation: rotationSchema.optional()
7972
8081
  });
7973
8082
  const mediaPosterSchema = z.discriminatedUnion("tag", [z.object({
7974
- tag: z.literal("storage"),
7975
- assetId: z.string().optional(),
7976
- storageBucket: z.string().min(1),
7977
- storagePath: z.string().min(1)
7978
- }), z.object({
8083
+ tag: z.literal("media"),
8084
+ identifier: mediaIdentifierSchema
8085
+ }).strict(), z.object({
7979
8086
  tag: z.literal("external-src"),
7980
- assetId: z.string().optional(),
7981
8087
  src: z.string().url()
7982
- })]);
7983
- const mediaBaseSchema = z.object({
8088
+ }).strict()]);
8089
+ const mediaUsageShape = {
7984
8090
  purpose: z.string().optional(),
7985
8091
  placeholder: z.boolean().default(true).optional(),
7986
- assetId: z.string().optional(),
7987
- identifier: z.string().optional(),
7988
- src: z.string().optional(),
7989
8092
  alt: z.string().optional(),
7990
8093
  filename: z.string().optional(),
7991
- mimeType: z.string().optional(),
7992
8094
  width: z.number().optional(),
7993
8095
  height: z.number().optional(),
7994
- storageBucket: z.string().optional(),
7995
- storagePath: z.string().optional(),
7996
8096
  poster: mediaPosterSchema.optional(),
7997
8097
  transform: transformSchema.optional()
7998
- });
7999
- const mediaIdentifierSchema = z.string().trim().min(1).brand();
8098
+ };
8099
+ const environmentExclusions = {
8100
+ assetId: z.never().optional(),
8101
+ id: z.never().optional(),
8102
+ src: z.never().optional(),
8103
+ storageBucket: z.never().optional(),
8104
+ storagePath: z.never().optional(),
8105
+ mimeType: z.never().optional()
8106
+ };
8107
+ const mediaBaseSchema = z.object({
8108
+ ...mediaUsageShape,
8109
+ ...environmentExclusions,
8110
+ identifier: mediaIdentifierSchema
8111
+ }).strict();
8000
8112
  const imageMediaSchema = mediaBaseSchema.extend({ type: z.literal("image") });
8001
8113
  const videoMediaSchema = mediaBaseSchema.extend({ type: z.literal("video") });
8002
- const audioMediaSchema = mediaBaseSchema.extend({ type: z.literal("audio") });
8003
- const documentMediaSchema = mediaBaseSchema.extend({ type: z.literal("document") });
8004
- const spreadsheetMediaSchema = mediaBaseSchema.extend({ type: z.literal("spreadsheet") });
8005
- const archiveMediaSchema = mediaBaseSchema.extend({ type: z.literal("archive") });
8006
- const mediaSchema = z.discriminatedUnion("type", [
8007
- imageMediaSchema,
8008
- videoMediaSchema,
8009
- audioMediaSchema,
8010
- documentMediaSchema,
8011
- spreadsheetMediaSchema,
8012
- archiveMediaSchema
8013
- ]);
8014
- const persistableMediaBaseSchema = mediaBaseSchema.extend({ identifier: mediaIdentifierSchema });
8015
- z.discriminatedUnion("type", [
8016
- persistableMediaBaseSchema.extend({ type: z.literal("image") }),
8017
- persistableMediaBaseSchema.extend({ type: z.literal("video") }),
8018
- persistableMediaBaseSchema.extend({ type: z.literal("audio") }),
8019
- persistableMediaBaseSchema.extend({ type: z.literal("document") }),
8020
- persistableMediaBaseSchema.extend({ type: z.literal("spreadsheet") }),
8021
- persistableMediaBaseSchema.extend({ type: z.literal("archive") })
8114
+ const mediaSchema = mediaBaseSchema.extend({ type: z.enum(mediaTypeDiscriminants) });
8115
+ const externalMediaSchema = z.object({
8116
+ ...mediaUsageShape,
8117
+ ...environmentExclusions,
8118
+ type: z.enum(mediaTypeDiscriminants),
8119
+ src: z.string().min(1),
8120
+ identifier: z.never().optional()
8121
+ }).strict();
8122
+ const assetMediaSchema = z.object({
8123
+ ...mediaUsageShape,
8124
+ ...environmentExclusions,
8125
+ type: z.enum(mediaTypeDiscriminants),
8126
+ asset: renderableMediaAssetSchema,
8127
+ identifier: z.never().optional()
8128
+ }).strict();
8129
+ const runtimeMediaSchema = z.union([
8130
+ mediaSchema,
8131
+ externalMediaSchema,
8132
+ assetMediaSchema
8022
8133
  ]);
8023
8134
  //#endregion
8135
+ //#region ../media-core/src/transformRect.ts
8136
+ function isValidTransformRectStructure(rect) {
8137
+ if (!Array.isArray(rect) || rect.length !== 4) return false;
8138
+ const [left, top, width, height] = rect;
8139
+ return Number.isFinite(left) && Number.isFinite(top) && Number.isFinite(width) && Number.isFinite(height) && left >= 0 && top >= 0 && width > 0 && height > 0;
8140
+ }
8141
+ //#endregion
8142
+ //#region ../media-core/src/aspectTransforms.ts
8143
+ const DEFAULT_RECT_EPSILON = .5;
8144
+ function parseAspectRatioValue(value) {
8145
+ if (typeof value === "number") return Number.isFinite(value) && value > 0 ? value : void 0;
8146
+ if (typeof value !== "string") return void 0;
8147
+ const normalized = value.trim();
8148
+ if (!normalized) return void 0;
8149
+ if (normalized === "auto") return void 0;
8150
+ if (normalized.includes(":") || normalized.includes("/")) {
8151
+ const delimiter = normalized.includes(":") ? ":" : "/";
8152
+ const [wRaw, hRaw] = normalized.split(delimiter);
8153
+ const width = Number(wRaw?.trim());
8154
+ const height = Number(hRaw?.trim());
8155
+ if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return;
8156
+ return width / height;
8157
+ }
8158
+ const numeric = Number(normalized);
8159
+ if (!Number.isFinite(numeric) || numeric <= 0) return void 0;
8160
+ return numeric;
8161
+ }
8162
+ const MAX_ASPECT_DISTANCE = .25;
8163
+ function resolveMediaTransformForAspect(transform, targetAspect) {
8164
+ if (!transform) return {};
8165
+ const base = {
8166
+ rect: transform.rect,
8167
+ hotspot: transform.hotspot,
8168
+ rotation: transform.rotation
8169
+ };
8170
+ const target = parseAspectRatioValue(targetAspect);
8171
+ const crops = transform.aspectCrops;
8172
+ if (!target || !crops || Object.keys(crops).length === 0) return base;
8173
+ let best = null;
8174
+ let bestDistance = Number.POSITIVE_INFINITY;
8175
+ for (const [key, candidate] of Object.entries(crops)) {
8176
+ const candidateAspect = parseAspectRatioValue(candidate.aspect ?? key);
8177
+ if (!candidateAspect) continue;
8178
+ const distance = Math.abs(Math.log(candidateAspect / target));
8179
+ if (distance < bestDistance) {
8180
+ best = candidate;
8181
+ bestDistance = distance;
8182
+ }
8183
+ }
8184
+ if (!best) return base;
8185
+ if (bestDistance > MAX_ASPECT_DISTANCE) return base;
8186
+ return {
8187
+ rect: best.rect ?? base.rect,
8188
+ hotspot: best.hotspot ?? base.hotspot,
8189
+ rotation: best.rotation ?? base.rotation
8190
+ };
8191
+ }
8192
+ function isValidTransformRect(rect) {
8193
+ return isValidTransformRectStructure(rect);
8194
+ }
8195
+ function isExplicitRectCrop(rect, sourceWidth, sourceHeight, epsilon = DEFAULT_RECT_EPSILON) {
8196
+ if (!isValidTransformRect(rect)) return false;
8197
+ if (!(typeof sourceWidth === "number" && Number.isFinite(sourceWidth) && sourceWidth > 0 && typeof sourceHeight === "number" && Number.isFinite(sourceHeight) && sourceHeight > 0)) return true;
8198
+ const [x, y, width, height] = rect;
8199
+ return !(Math.abs(x) <= epsilon && Math.abs(y) <= epsilon && Math.abs(width - sourceWidth) <= epsilon && Math.abs(height - sourceHeight) <= epsilon);
8200
+ }
8201
+ //#endregion
8202
+ //#region ../media-core/src/rotation.ts
8203
+ function rotateNormalizedPoint(point, rotation) {
8204
+ const x = point.x;
8205
+ const y = point.y;
8206
+ switch (rotation) {
8207
+ case 0: return {
8208
+ x,
8209
+ y
8210
+ };
8211
+ case 90: return {
8212
+ x: 1 - y,
8213
+ y: x
8214
+ };
8215
+ case 180: return {
8216
+ x: 1 - x,
8217
+ y: 1 - y
8218
+ };
8219
+ case 270: return {
8220
+ x: y,
8221
+ y: 1 - x
8222
+ };
8223
+ }
8224
+ }
8225
+ //#endregion
8024
8226
  //#region ../theme-core/src/palette/schema.ts
8025
8227
  const colourHexString = z.string().regex(/^#([0-9A-Fa-f]{3}){1,2}$/);
8026
8228
  const paletteColorSchema = z.object({
@@ -16569,6 +16771,21 @@ const boxBackgroundSchema = z.discriminatedUnion("type", [
16569
16771
  showVideoOnMobile: z.boolean().nullable().optional()
16570
16772
  })
16571
16773
  ]);
16774
+ /** Application rendering sources are admitted separately from saved references. */
16775
+ const runtimeBoxBackgroundSchema = z.discriminatedUnion("type", [
16776
+ boxBackgroundSchema.options[0],
16777
+ boxBackgroundSchema.options[1],
16778
+ boxBackgroundSchema.options[2].extend({ image: z.union([
16779
+ imageMediaSchema,
16780
+ externalMediaSchema.extend({ type: z.literal("image") }),
16781
+ assetMediaSchema.extend({ type: z.literal("image") })
16782
+ ]).nullable().optional() }),
16783
+ boxBackgroundSchema.options[3].extend({ image: z.union([
16784
+ videoMediaSchema,
16785
+ externalMediaSchema.extend({ type: z.literal("video") }),
16786
+ assetMediaSchema.extend({ type: z.literal("video") })
16787
+ ]).nullable().optional() })
16788
+ ]);
16572
16789
  function normalizeAuthoringOpacity(value) {
16573
16790
  if (!isRecord$6(value)) return value;
16574
16791
  return {
@@ -23418,97 +23635,6 @@ function registerManifest(manifest) {
23418
23635
  return manifest;
23419
23636
  }
23420
23637
  //#endregion
23421
- //#region ../media-core/src/transformRect.ts
23422
- function isValidTransformRectStructure(rect) {
23423
- if (!Array.isArray(rect) || rect.length !== 4) return false;
23424
- const [left, top, width, height] = rect;
23425
- return Number.isFinite(left) && Number.isFinite(top) && Number.isFinite(width) && Number.isFinite(height) && left >= 0 && top >= 0 && width > 0 && height > 0;
23426
- }
23427
- //#endregion
23428
- //#region ../media-core/src/aspectTransforms.ts
23429
- const DEFAULT_RECT_EPSILON = .5;
23430
- function parseAspectRatioValue(value) {
23431
- if (typeof value === "number") return Number.isFinite(value) && value > 0 ? value : void 0;
23432
- if (typeof value !== "string") return void 0;
23433
- const normalized = value.trim();
23434
- if (!normalized) return void 0;
23435
- if (normalized === "auto") return void 0;
23436
- if (normalized.includes(":") || normalized.includes("/")) {
23437
- const delimiter = normalized.includes(":") ? ":" : "/";
23438
- const [wRaw, hRaw] = normalized.split(delimiter);
23439
- const width = Number(wRaw?.trim());
23440
- const height = Number(hRaw?.trim());
23441
- if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return;
23442
- return width / height;
23443
- }
23444
- const numeric = Number(normalized);
23445
- if (!Number.isFinite(numeric) || numeric <= 0) return void 0;
23446
- return numeric;
23447
- }
23448
- const MAX_ASPECT_DISTANCE = .25;
23449
- function resolveMediaTransformForAspect(transform, targetAspect) {
23450
- if (!transform) return {};
23451
- const base = {
23452
- rect: transform.rect,
23453
- hotspot: transform.hotspot,
23454
- rotation: transform.rotation
23455
- };
23456
- const target = parseAspectRatioValue(targetAspect);
23457
- const crops = transform.aspectCrops;
23458
- if (!target || !crops || Object.keys(crops).length === 0) return base;
23459
- let best = null;
23460
- let bestDistance = Number.POSITIVE_INFINITY;
23461
- for (const [key, candidate] of Object.entries(crops)) {
23462
- const candidateAspect = parseAspectRatioValue(candidate.aspect ?? key);
23463
- if (!candidateAspect) continue;
23464
- const distance = Math.abs(Math.log(candidateAspect / target));
23465
- if (distance < bestDistance) {
23466
- best = candidate;
23467
- bestDistance = distance;
23468
- }
23469
- }
23470
- if (!best) return base;
23471
- if (bestDistance > MAX_ASPECT_DISTANCE) return base;
23472
- return {
23473
- rect: best.rect ?? base.rect,
23474
- hotspot: best.hotspot ?? base.hotspot,
23475
- rotation: best.rotation ?? base.rotation
23476
- };
23477
- }
23478
- function isValidTransformRect(rect) {
23479
- return isValidTransformRectStructure(rect);
23480
- }
23481
- function isExplicitRectCrop(rect, sourceWidth, sourceHeight, epsilon = DEFAULT_RECT_EPSILON) {
23482
- if (!isValidTransformRect(rect)) return false;
23483
- if (!(typeof sourceWidth === "number" && Number.isFinite(sourceWidth) && sourceWidth > 0 && typeof sourceHeight === "number" && Number.isFinite(sourceHeight) && sourceHeight > 0)) return true;
23484
- const [x, y, width, height] = rect;
23485
- return !(Math.abs(x) <= epsilon && Math.abs(y) <= epsilon && Math.abs(width - sourceWidth) <= epsilon && Math.abs(height - sourceHeight) <= epsilon);
23486
- }
23487
- //#endregion
23488
- //#region ../media-core/src/rotation.ts
23489
- function rotateNormalizedPoint(point, rotation) {
23490
- const x = point.x;
23491
- const y = point.y;
23492
- switch (rotation) {
23493
- case 0: return {
23494
- x,
23495
- y
23496
- };
23497
- case 90: return {
23498
- x: 1 - y,
23499
- y: x
23500
- };
23501
- case 180: return {
23502
- x: 1 - x,
23503
- y: 1 - y
23504
- };
23505
- case 270: return {
23506
- x: y,
23507
- y: 1 - x
23508
- };
23509
- }
23510
- }
23511
- //#endregion
23512
23638
  //#region ../blocks/src/system/node/schema.ts
23513
23639
  const transformStepSchema = z.object({
23514
23640
  id: z.string().min(1, "Transform requires an identifier"),
@@ -26434,6 +26560,12 @@ function parseBackgroundOverlay(value) {
26434
26560
  const result = boxBackgroundOverlaySchema.safeParse(value);
26435
26561
  return result.success ? result.data : void 0;
26436
26562
  }
26563
+ /** Rendering accepts explicit application sources separately from stored references. */
26564
+ const runtimeBackgroundContentSchema = runtimeBoxBackgroundSchema;
26565
+ function parseRuntimeBackgroundContent(value) {
26566
+ const result = runtimeBackgroundContentSchema.safeParse(value);
26567
+ return result.success ? result.data : null;
26568
+ }
26437
26569
  //#endregion
26438
26570
  //#region ../blocks/src/system/transforms/registry/_utils/themeColorResolution.ts
26439
26571
  function resolveBackgroundColorValue(value, context) {
@@ -35692,14 +35824,6 @@ const weeklySlotAvailabilityBlockDefinition = {
35692
35824
  } }
35693
35825
  };
35694
35826
  //#endregion
35695
- //#region ../blocks/src/lib/media.ts
35696
- const PUBLIC_DOWNLOAD_MEDIA_TYPES = [
35697
- "document",
35698
- "spreadsheet",
35699
- "archive",
35700
- "audio"
35701
- ];
35702
- //#endregion
35703
35827
  //#region ../blocks/src/system/manifest/richTextSchema.ts
35704
35828
  /**
35705
35829
  * Shared Rich Text Schema
@@ -36135,7 +36259,7 @@ const publicEventBaseSchema = z.object({
36135
36259
  content: z.object({ body: RichTextDocSchema.nullable().optional() }).optional(),
36136
36260
  presentation: z.object({
36137
36261
  summary: z.string().nullable().optional(),
36138
- image: mediaSchema.nullable().optional()
36262
+ image: runtimeMediaSchema.nullable().optional()
36139
36263
  }).optional(),
36140
36264
  slug: z.string(),
36141
36265
  path: z.string().nullable(),
@@ -43026,6 +43150,14 @@ const audioPlayerBlockDefinition = { manifest: createBlockManifest({
43026
43150
  }
43027
43151
  }) };
43028
43152
  //#endregion
43153
+ //#region ../blocks/src/lib/media.ts
43154
+ const PUBLIC_DOWNLOAD_MEDIA_TYPES = [
43155
+ "document",
43156
+ "spreadsheet",
43157
+ "archive",
43158
+ "audio"
43159
+ ];
43160
+ //#endregion
43029
43161
  //#region ../blocks/src/system/blocks/file-download.ts
43030
43162
  const bound = (from) => ({ $bind: { from } });
43031
43163
  const fileDownloadLayout = styledSection({
@@ -45271,7 +45403,7 @@ const memberPhotoClassName = (baseClass) => cardRoleChildClass({
45271
45403
  baseClass,
45272
45404
  stylesFrom: "content._cardStyles"
45273
45405
  });
45274
- const teamMemberPhotoSchema = mediaSchema.refine((media) => media.type === "image", { message: "Team member photos must be image media" }).nullable();
45406
+ const teamMemberPhotoSchema = runtimeMediaSchema.refine((media) => media.type === "image", { message: "Team member photos must be image media" }).nullable();
45275
45407
  const teamMemberDataSchema = z.object({
45276
45408
  _type: z.literal("teamMember"),
45277
45409
  id: z.string(),
@@ -46813,11 +46945,14 @@ const offeringsPreviewDatesReadEnabled = {
46813
46945
  //#endregion
46814
46946
  //#region ../blocks/src/system/helpers/backgroundMedia.ts
46815
46947
  function resolveBackgroundMedia(input) {
46816
- const parsedMedia = mediaSchema.safeParse(input.image);
46948
+ const parsedMedia = runtimeMediaSchema.safeParse(input.image);
46817
46949
  if (!parsedMedia.success) return null;
46818
46950
  switch (parsedMedia.data.type) {
46819
46951
  case "image":
46820
- case "video": return parsedMedia.data;
46952
+ case "video": return {
46953
+ ...parsedMedia.data,
46954
+ type: parsedMedia.data.type
46955
+ };
46821
46956
  case "audio":
46822
46957
  case "document":
46823
46958
  case "spreadsheet":
@@ -46829,6 +46964,75 @@ function backgroundVideoMobileClassNames(input) {
46829
46964
  return input.showVideoOnMobile === true ? "" : "rb-hidden rb-md-block";
46830
46965
  }
46831
46966
  //#endregion
46967
+ //#region ../blocks/src/system/runtime/nodes/mediaContext.ts
46968
+ /**
46969
+ * Server-side: AsyncLocalStorage for request isolation.
46970
+ * Prevents race conditions when multiple requests are processed concurrently.
46971
+ *
46972
+ * Lazy initialization to avoid issues in environments that don't support async_hooks.
46973
+ */
46974
+ const serverStorageState = {
46975
+ storage: null,
46976
+ checked: false
46977
+ };
46978
+ function getServerStorage() {
46979
+ if (typeof window !== "undefined") return null;
46980
+ if (serverStorageState.checked) return serverStorageState.storage;
46981
+ serverStorageState.checked = true;
46982
+ try {
46983
+ const globalWithNonWebpackRequire = globalThis;
46984
+ const AsyncLocalStorage = (typeof globalWithNonWebpackRequire.__non_webpack_require__ === "function" ? globalWithNonWebpackRequire.__non_webpack_require__ : new Function("id", "return require(id)"))("async_hooks").AsyncLocalStorage;
46985
+ if (AsyncLocalStorage) {
46986
+ serverStorageState.storage = new AsyncLocalStorage();
46987
+ return serverStorageState.storage;
46988
+ }
46989
+ return null;
46990
+ } catch {
46991
+ if (process.env.NODE_ENV !== "production") console.warn("[blocks] AsyncLocalStorage not available - using module-level state");
46992
+ return null;
46993
+ }
46994
+ }
46995
+ /**
46996
+ * Client-side context storage.
46997
+ * Safe because browsers are single-threaded per tab.
46998
+ *
46999
+ * IMPORTANT: This must be shared across bundles.
47000
+ * SDK preview mode can load multiple independently-bundled entrypoints
47001
+ * (e.g. `@riverbankcms/sdk/rendering` + `@riverbankcms/sdk/preview-next/client`),
47002
+ * which can otherwise each get their own module-scoped singleton.
47003
+ */
47004
+ const RB_MEDIA_CONTEXT_KEY = Symbol.for("riverbankcms.blocks.mediaContext");
47005
+ function getClientContextStore() {
47006
+ const g = globalThis;
47007
+ const existing = g[RB_MEDIA_CONTEXT_KEY];
47008
+ if (existing && typeof existing === "object") return existing;
47009
+ const next = {};
47010
+ g[RB_MEDIA_CONTEXT_KEY] = next;
47011
+ return next;
47012
+ }
47013
+ /**
47014
+ * Get the current media context.
47015
+ * Server-side: Uses AsyncLocalStorage for request isolation.
47016
+ * Client-side: Uses module-level state (safe in single-threaded browser).
47017
+ */
47018
+ function getMediaContext() {
47019
+ const storage = getServerStorage();
47020
+ if (storage) return storage.getStore() ?? {};
47021
+ return getClientContextStore();
47022
+ }
47023
+ function getCurrentResolveImageUrlContext() {
47024
+ const context = getMediaContext();
47025
+ if (!context.supabaseUrl && !context.siteId && !context.mediaAssetIndex) return;
47026
+ return {
47027
+ supabaseUrl: context.supabaseUrl,
47028
+ siteId: context.siteId,
47029
+ mediaAssetIndex: context.mediaAssetIndex
47030
+ };
47031
+ }
47032
+ function getMediaAssetIndex(context) {
47033
+ return context?.mediaAssetIndex ?? getMediaContext().mediaAssetIndex;
47034
+ }
47035
+ //#endregion
46832
47036
  //#region ../blocks/src/system/runtime/nodes/media.tsx
46833
47037
  function getValidSourceDimension(value) {
46834
47038
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
@@ -46864,41 +47068,72 @@ function applyRectTransform(existingStyle, patch) {
46864
47068
  if (patch.transform) next.transform = appendTransform(existingStyle?.transform, patch.transform);
46865
47069
  return next;
46866
47070
  }
46867
- function computeMediaTransformStyle(value, style, targetAspectRatio, options) {
47071
+ /** Resolve portable content without exposing runtime metadata as saved values. */
47072
+ function resolveMediaWithContext(reference, context) {
47073
+ return resolveManagedMediaReference(reference, getMediaAssetIndex(context ?? void 0));
47074
+ }
47075
+ function sourceFromAsset(value, asset) {
47076
+ return {
47077
+ type: value.type,
47078
+ alt: value.alt,
47079
+ filename: value.filename,
47080
+ purpose: value.purpose,
47081
+ placeholder: value.placeholder,
47082
+ transform: value.transform,
47083
+ poster: value.poster,
47084
+ identifier: asset.identifier,
47085
+ assetId: asset.id,
47086
+ storageBucket: asset.storageBucket,
47087
+ storagePath: asset.storagePath,
47088
+ mimeType: asset.mimeType,
47089
+ width: asset.width,
47090
+ height: asset.height
47091
+ };
47092
+ }
47093
+ function resolveRuntimeMedia(value, context) {
47094
+ if ("asset" in value && value.asset) return sourceFromAsset(value, value.asset);
47095
+ if ("src" in value && value.src) return value;
47096
+ if (!value.identifier) return void 0;
47097
+ const resolved = resolveMediaWithContext(value, context);
47098
+ return resolved.kind === "resolved" ? sourceFromAsset(resolved.reference, resolved.asset) : void 0;
47099
+ }
47100
+ function usesProxyFraming(source, transform) {
47101
+ if (!source?.assetId || !isExplicitCropProxyEnabled()) return false;
47102
+ return Boolean(transform.rotation) || isExplicitRectCrop(transform.rect, getValidSourceDimension(source.width), getValidSourceDimension(source.height));
47103
+ }
47104
+ function rectFramingPatch(source, rect, proxy, style) {
47105
+ if (!source || !rect || proxy) return {};
47106
+ const patch = buildCssRectStylePatch(source, rect);
47107
+ return patch ? applyRectTransform(style, patch) : {};
47108
+ }
47109
+ function hotspotFramingPatch(transform, proxy, rectPatch, style) {
47110
+ if (!transform.hotspot || rectPatch.objectPosition !== void 0) return {};
47111
+ const fit = style?.objectFit;
47112
+ if (fit && fit !== "cover" && fit !== "contain") return {};
47113
+ const point = proxy && transform.rotation ? rotateNormalizedPoint(transform.hotspot, transform.rotation) : transform.hotspot;
47114
+ return { objectPosition: `${point.x * 100}% ${point.y * 100}%` };
47115
+ }
47116
+ function rotationFramingPatch(rotation, proxy, rectPatch, style) {
47117
+ if (!rotation || proxy) return {};
47118
+ return {
47119
+ transform: appendTransform(rectPatch.transform ?? style?.transform, `rotate(${rotation}deg)`),
47120
+ transformOrigin: rectPatch.transformOrigin ?? "center"
47121
+ };
47122
+ }
47123
+ /** CSS framing is a pure projection of the resolved source and per-use transform. */
47124
+ function deriveMediaFramingStyle(source, transform, proxy, style) {
47125
+ if (!transform.rect && !transform.hotspot && !transform.rotation) return style;
47126
+ const rectPatch = rectFramingPatch(source, transform.rect, proxy, style);
47127
+ return mergeStyles(style, {
47128
+ ...rectPatch,
47129
+ ...hotspotFramingPatch(transform, proxy, rectPatch, style),
47130
+ ...rotationFramingPatch(transform.rotation, proxy, rectPatch, style)
47131
+ });
47132
+ }
47133
+ function computeMediaTransformStyle(value, style, targetAspectRatio, options, context) {
47134
+ const source = resolveRuntimeMedia(value, context ?? getCurrentResolveImageUrlContext());
46868
47135
  const transform = options?.resolvedTransform ?? resolveMediaTransformForAspect(value.transform, targetAspectRatio);
46869
- const rect = transform.rect;
46870
- const hotspot = transform.hotspot;
46871
- const rotation = transform.rotation;
46872
- if (!rect && !hotspot && !rotation) return style;
46873
- const stylePatch = {};
46874
- const heuristicSuppressCss = Boolean(isExplicitCropProxyEnabled() && value.assetId && (typeof rotation === "number" && rotation !== 0 || isExplicitRectCrop(rect, getValidSourceDimension(value.width), getValidSourceDimension(value.height))));
46875
- const shouldSuppressCss = options?.isProxy ?? heuristicSuppressCss;
46876
- if (rect && !shouldSuppressCss) {
46877
- const rectPatch = buildCssRectStylePatch(value, rect);
46878
- if (rectPatch) {
46879
- const mergedRect = applyRectTransform(style, rectPatch);
46880
- Object.assign(stylePatch, mergedRect);
46881
- }
46882
- }
46883
- if (hotspot) {
46884
- const effectiveObjectFit = stylePatch.objectFit ?? style?.objectFit;
46885
- if ((!effectiveObjectFit || effectiveObjectFit === "cover" || effectiveObjectFit === "contain") && stylePatch.objectPosition === void 0) {
46886
- const resolved = shouldSuppressCss && rotation ? rotateNormalizedPoint({
46887
- x: hotspot.x,
46888
- y: hotspot.y
46889
- }, rotation) : {
46890
- x: hotspot.x,
46891
- y: hotspot.y
46892
- };
46893
- stylePatch.objectPosition = `${resolved.x * 100}% ${resolved.y * 100}%`;
46894
- }
46895
- }
46896
- if (rotation && !shouldSuppressCss) {
46897
- const existingTransform = stylePatch.transform ?? style?.transform;
46898
- stylePatch.transform = existingTransform ? `${existingTransform} rotate(${rotation}deg)` : `rotate(${rotation}deg)`;
46899
- if (!stylePatch.transformOrigin) stylePatch.transformOrigin = "center";
46900
- }
46901
- return mergeStyles(style, stylePatch);
47136
+ return deriveMediaFramingStyle(source, transform, options?.isProxy ?? usesProxyFraming(source, transform), style);
46902
47137
  }
46903
47138
  //#endregion
46904
47139
  //#region ../blocks/src/system/transforms/registry/background.ts
@@ -47047,11 +47282,11 @@ const backgroundTransforms = [
47047
47282
  }
47048
47283
  ];
47049
47284
  function parseMediaBackground(value) {
47050
- const background = parseBackgroundContent(value);
47285
+ const background = parseRuntimeBackgroundContent(value);
47051
47286
  return background?.type === "image" || background?.type === "video" ? background : null;
47052
47287
  }
47053
47288
  function resolveBackgroundLayerStyle(value, fallbackToken, context) {
47054
- const background = parseBackgroundContent(value);
47289
+ const background = parseRuntimeBackgroundContent(value);
47055
47290
  const style = {};
47056
47291
  const gradient = background?.type === "gradient" ? isString(background.gradient) ? background.gradient.trim() : gradientPresetCss(background.gradientPresetId) : null;
47057
47292
  const color = background?.type === "color" && isString(background.color) ? background.color.trim() : null;