@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
@@ -1731,12 +1731,14 @@ const unsafeAsSiteId = (id) => id;
1731
1731
  const unsafeAsApiKeyId = (id) => id;
1732
1732
  const unsafeAsEventOfferingId = (id) => id;
1733
1733
  const unsafeAsEventSeriesId = (id) => id;
1734
+ const unsafeAsMediaAssetId = (id) => id;
1734
1735
  const unsafeAsUserId = (id) => id;
1735
1736
  const unsafeAsContentVersionId = (id) => id;
1736
1737
  const parseSiteId = (value) => parseUuidBrand(value, unsafeAsSiteId);
1737
1738
  const parseApiKeyId = (value) => parseUuidBrand(value, unsafeAsApiKeyId);
1738
1739
  const parseEventOfferingId = (value) => parseUuidBrand(value, unsafeAsEventOfferingId);
1739
1740
  const parseUserId = (value) => parseUuidBrand(value, unsafeAsUserId);
1741
+ const parseMediaAssetId = (value) => parseUuidBrand(value, unsafeAsMediaAssetId);
1740
1742
  const parseContentVersionId = (value) => parseUuidBrand(value, unsafeAsContentVersionId);
1741
1743
  const parseEventSeriesId = (value) => parseUuidBrand(value, unsafeAsEventSeriesId);
1742
1744
  //#endregion
@@ -2387,7 +2389,7 @@ function parsePositiveInteger(value) {
2387
2389
  return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : null;
2388
2390
  }
2389
2391
  function parseNewsletterListId(value) {
2390
- return parseTrimmedMatchingString(value, UUID_PATTERN);
2392
+ return parseTrimmedMatchingString(typeof value === "string" ? value.toLowerCase() : value, UUID_PATTERN);
2391
2393
  }
2392
2394
  function parseMailchimpAccountId(value) {
2393
2395
  return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
@@ -2429,8 +2431,15 @@ function parseMailingListProviderScope(value) {
2429
2431
  }
2430
2432
  return err("invalid_mailing_list_provider_scope");
2431
2433
  }
2432
- //#endregion
2433
- //#region ../core/src/mailing-list-setup-parser.ts
2434
+ z.unknown().transform((value, ctx) => {
2435
+ const parsed = parseNewsletterAudience(value);
2436
+ if (parsed.ok) return parsed.value;
2437
+ ctx.addIssue({
2438
+ code: "custom",
2439
+ message: "Choose a valid newsletter audience."
2440
+ });
2441
+ return z.NEVER;
2442
+ });
2434
2443
  function parseMailingListGlobalForm(value) {
2435
2444
  if (!isRecord$9(value)) return formError("shape");
2436
2445
  const fields = parseGlobalFields(value.fields);
@@ -2450,6 +2459,16 @@ function parseMailingListGlobalForm(value) {
2450
2459
  privacyNote
2451
2460
  });
2452
2461
  }
2462
+ function parseNewsletterAudience(value) {
2463
+ if (!isRecord$9(value)) return err("invalid_newsletter_audience");
2464
+ if (value.kind === "general" && Object.keys(value).length === 1) return ok({ kind: "general" });
2465
+ if (value.kind !== "topic" || Object.keys(value).some((key) => key !== "kind" && key !== "topicId")) return err("invalid_newsletter_audience");
2466
+ const topicId = parseNewsletterListId(value.topicId);
2467
+ return topicId === null ? err("invalid_newsletter_audience") : ok({
2468
+ kind: "topic",
2469
+ topicId
2470
+ });
2471
+ }
2453
2472
  function parseGlobalFields(value) {
2454
2473
  if (!isRecord$9(value) || typeof value.preset !== "string") return null;
2455
2474
  switch (value.preset) {
@@ -2502,54 +2521,49 @@ function formError(field) {
2502
2521
  const DEFAULT_MAILING_LIST_TARGETING = { mode: "default" };
2503
2522
  function mailingListTargetingChoiceIds(targeting) {
2504
2523
  switch (targeting.provider) {
2505
- case "native": return targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds;
2524
+ case "native": return targeting.selection.tag === "general" ? [] : targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds;
2506
2525
  case "brevo": return targeting.selection.tag === "fixed" ? targeting.selection.listIds : targeting.selection.offeredListIds;
2507
2526
  case "mailchimp": return targeting.selection.tag === "fixed" ? targeting.selection.interestIds : targeting.selection.offeredInterestIds;
2508
2527
  }
2509
2528
  }
2510
2529
  function planMailingListChoicePresentation(targeting) {
2511
- if (targeting.mode === "default" || targeting.selection.tag === "fixed") return { tag: "hidden" };
2530
+ if (targeting.mode === "default" || targeting.selection.tag === "fixed" || targeting.selection.tag === "general") return { tag: "hidden" };
2512
2531
  switch (targeting.provider) {
2513
- case "native": return targeting.selection.offeredTopicIds.length === 1 ? {
2514
- tag: "automatic",
2515
- selection: {
2516
- provider: "native",
2517
- topicIds: targeting.selection.offeredTopicIds
2518
- }
2519
- } : {
2520
- tag: "visitor_choice",
2532
+ case "native": return presentVisitorSelection({
2521
2533
  provider: "native",
2522
- optionCount: targeting.selection.offeredTopicIds.length
2523
- };
2524
- case "brevo": return targeting.selection.offeredListIds.length === 1 ? {
2525
- tag: "automatic",
2526
- selection: {
2527
- provider: "brevo",
2528
- listIds: targeting.selection.offeredListIds
2529
- }
2530
- } : {
2531
- tag: "visitor_choice",
2534
+ topicIds: targeting.selection.offeredTopicIds
2535
+ }, targeting.selection.offeredTopicIds.length);
2536
+ case "brevo": return presentVisitorSelection({
2532
2537
  provider: "brevo",
2533
- optionCount: targeting.selection.offeredListIds.length
2534
- };
2535
- case "mailchimp": return targeting.selection.offeredInterestIds.length === 1 ? {
2536
- tag: "automatic",
2537
- selection: {
2538
- provider: "mailchimp",
2539
- interestIds: targeting.selection.offeredInterestIds
2540
- }
2541
- } : {
2542
- tag: "visitor_choice",
2538
+ listIds: targeting.selection.offeredListIds
2539
+ }, targeting.selection.offeredListIds.length);
2540
+ case "mailchimp": return presentVisitorSelection({
2543
2541
  provider: "mailchimp",
2544
- optionCount: targeting.selection.offeredInterestIds.length
2545
- };
2542
+ interestIds: targeting.selection.offeredInterestIds
2543
+ }, targeting.selection.offeredInterestIds.length);
2546
2544
  }
2547
2545
  }
2546
+ function presentVisitorSelection(selection, optionCount) {
2547
+ return optionCount === 1 ? {
2548
+ tag: "automatic",
2549
+ selection
2550
+ } : {
2551
+ tag: "visitor_choice",
2552
+ provider: selection.provider,
2553
+ optionCount
2554
+ };
2555
+ }
2548
2556
  //#endregion
2549
2557
  //#region ../core/src/mailing-list-targeting-availability.ts
2550
2558
  function resolveMailingListDefaultDestination(provider) {
2551
2559
  switch (provider.provider) {
2552
- case "native": return provider.topics.find((item) => item.id === provider.defaultTopicId) ?? null;
2560
+ case "native": {
2561
+ const audience = provider.defaultAudience;
2562
+ return audience.kind === "general" ? {
2563
+ id: "general",
2564
+ name: "General mailing list"
2565
+ } : provider.topics.find((item) => item.id === audience.topicId) ?? null;
2566
+ }
2553
2567
  case "brevo": return provider.lists.find((item) => item.id === provider.defaultListId) ?? null;
2554
2568
  case "mailchimp": return provider.audiences.find((item) => item.id === provider.defaultAudienceId) ?? null;
2555
2569
  }
@@ -2687,11 +2701,12 @@ function parseRuntimeProvider(value) {
2687
2701
  }
2688
2702
  }
2689
2703
  function parseNativeRuntimeProvider(value) {
2690
- const defaultTopicId = parseNewsletterListId(value.defaultTopicId);
2704
+ if ("defaultTopicId" in value) return null;
2705
+ const defaultAudience = parseNewsletterAudience(value.defaultAudience);
2691
2706
  const topics = parseNamedItems(value.topics, parseNewsletterListId);
2692
- return defaultTopicId !== null && topics !== null ? {
2707
+ return defaultAudience.ok && topics !== null ? {
2693
2708
  provider: "native",
2694
- defaultTopicId,
2709
+ defaultAudience: defaultAudience.value,
2695
2710
  topics
2696
2711
  } : null;
2697
2712
  }
@@ -2776,6 +2791,11 @@ function parseMailingListPlacementTargeting(value) {
2776
2791
  }
2777
2792
  }
2778
2793
  function parseNativeTargeting(selection) {
2794
+ if (selection.tag === "general") return Object.keys(selection).length === 1 ? ok({
2795
+ mode: "custom",
2796
+ provider: "native",
2797
+ selection: { tag: "general" }
2798
+ }) : targetingError("selection");
2779
2799
  if (selection.tag === "fixed") {
2780
2800
  const topicIds = parseNonEmptyUniqueIds(selection.topicIds, parseNewsletterListId);
2781
2801
  return topicIds.ok ? ok({
@@ -7860,7 +7880,96 @@ const themeLookMetadataSchema = z.object({
7860
7880
  skinMarks: skinMarksSchema.optional()
7861
7881
  });
7862
7882
  //#endregion
7863
- //#region ../theme-core/src/lib/media.ts
7883
+ //#region ../media-core/src/identifiers.ts
7884
+ function slugifyMediaIdentifier(value) {
7885
+ return value.toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
7886
+ }
7887
+ function parseMediaIdentifier(value) {
7888
+ if (typeof value !== "string") return err({ kind: "not_string" });
7889
+ const trimmed = value.trim();
7890
+ if (trimmed.length === 0) return err({ kind: "empty_identifier" });
7891
+ const normalized = slugifyMediaIdentifier(trimmed);
7892
+ if (normalized.length === 0) return err({
7893
+ kind: "empty_after_normalization",
7894
+ value
7895
+ });
7896
+ return ok(normalized);
7897
+ }
7898
+ /**
7899
+ * Admits identifiers read from trusted persistence without repairing dirty data in memory.
7900
+ * User input should use parseMediaIdentifier, which intentionally canonicalizes it.
7901
+ */
7902
+ function parseCanonicalMediaIdentifier(value) {
7903
+ if (typeof value !== "string") return err({ kind: "not_string" });
7904
+ const parsed = parseMediaIdentifier(value);
7905
+ if (!parsed.ok) return parsed;
7906
+ if (value !== parsed.value) return err({
7907
+ kind: "non_canonical_identifier",
7908
+ value,
7909
+ canonical: parsed.value
7910
+ });
7911
+ return parsed;
7912
+ }
7913
+ //#endregion
7914
+ //#region ../media-core/src/mediaIdentifierSchema.ts
7915
+ /** Strict stored-reference admission delegates the canonical identifier decision. */
7916
+ const mediaIdentifierSchema = z.string().transform((value, context) => {
7917
+ const parsed = parseCanonicalMediaIdentifier(value);
7918
+ if (parsed.ok) return parsed.value;
7919
+ context.addIssue({
7920
+ code: "custom",
7921
+ message: "Expected a canonical media identifier"
7922
+ });
7923
+ return z.NEVER;
7924
+ });
7925
+ //#endregion
7926
+ //#region ../media-core/src/mediaKinds.ts
7927
+ const mediaTypeDiscriminants = [
7928
+ "image",
7929
+ "video",
7930
+ "audio",
7931
+ "document",
7932
+ "spreadsheet",
7933
+ "archive"
7934
+ ];
7935
+ //#endregion
7936
+ //#region ../media-core/src/renderableMediaAsset.ts
7937
+ /** A portable reference never uses an incidental UUID, URL or storage snapshot for identity. */
7938
+ function resolveManagedMediaReference(reference, index) {
7939
+ const asset = index?.byIdentifier.get(reference.identifier);
7940
+ return asset ? {
7941
+ kind: "resolved",
7942
+ reference,
7943
+ asset
7944
+ } : {
7945
+ kind: "missing",
7946
+ reference
7947
+ };
7948
+ }
7949
+ //#endregion
7950
+ //#region ../media-core/src/renderableMediaAssetAdmission.ts
7951
+ const mediaAssetIdSchema = z.string().transform((value, context) => {
7952
+ const parsed = parseMediaAssetId(value);
7953
+ if (parsed.ok) return parsed.value;
7954
+ context.addIssue({
7955
+ code: "custom",
7956
+ message: "Expected a media asset ID"
7957
+ });
7958
+ return z.NEVER;
7959
+ });
7960
+ const nonemptyStorageValue = z.string().refine((value) => value.trim().length > 0);
7961
+ const renderableMediaAssetSchema = z.object({
7962
+ id: mediaAssetIdSchema,
7963
+ identifier: mediaIdentifierSchema,
7964
+ storageBucket: nonemptyStorageValue,
7965
+ storagePath: nonemptyStorageValue,
7966
+ mimeType: nonemptyStorageValue,
7967
+ filename: z.string().optional(),
7968
+ width: z.number().positive().nullable(),
7969
+ height: z.number().positive().nullable()
7970
+ });
7971
+ //#endregion
7972
+ //#region ../media-core/src/media.ts
7864
7973
  const hotspotSchema = z.object({
7865
7974
  x: z.number().min(0).max(1),
7866
7975
  y: z.number().min(0).max(1),
@@ -7894,56 +8003,149 @@ const transformSchema = z.object({
7894
8003
  rotation: rotationSchema.optional()
7895
8004
  });
7896
8005
  const mediaPosterSchema = z.discriminatedUnion("tag", [z.object({
7897
- tag: z.literal("storage"),
7898
- assetId: z.string().optional(),
7899
- storageBucket: z.string().min(1),
7900
- storagePath: z.string().min(1)
7901
- }), z.object({
8006
+ tag: z.literal("media"),
8007
+ identifier: mediaIdentifierSchema
8008
+ }).strict(), z.object({
7902
8009
  tag: z.literal("external-src"),
7903
- assetId: z.string().optional(),
7904
8010
  src: z.string().url()
7905
- })]);
7906
- const mediaBaseSchema = z.object({
8011
+ }).strict()]);
8012
+ const mediaUsageShape = {
7907
8013
  purpose: z.string().optional(),
7908
8014
  placeholder: z.boolean().default(true).optional(),
7909
- assetId: z.string().optional(),
7910
- identifier: z.string().optional(),
7911
- src: z.string().optional(),
7912
8015
  alt: z.string().optional(),
7913
8016
  filename: z.string().optional(),
7914
- mimeType: z.string().optional(),
7915
8017
  width: z.number().optional(),
7916
8018
  height: z.number().optional(),
7917
- storageBucket: z.string().optional(),
7918
- storagePath: z.string().optional(),
7919
8019
  poster: mediaPosterSchema.optional(),
7920
8020
  transform: transformSchema.optional()
7921
- });
7922
- const mediaIdentifierSchema = z.string().trim().min(1).brand();
8021
+ };
8022
+ const environmentExclusions = {
8023
+ assetId: z.never().optional(),
8024
+ id: z.never().optional(),
8025
+ src: z.never().optional(),
8026
+ storageBucket: z.never().optional(),
8027
+ storagePath: z.never().optional(),
8028
+ mimeType: z.never().optional()
8029
+ };
8030
+ const mediaBaseSchema = z.object({
8031
+ ...mediaUsageShape,
8032
+ ...environmentExclusions,
8033
+ identifier: mediaIdentifierSchema
8034
+ }).strict();
7923
8035
  const imageMediaSchema = mediaBaseSchema.extend({ type: z.literal("image") });
7924
8036
  const videoMediaSchema = mediaBaseSchema.extend({ type: z.literal("video") });
7925
- const audioMediaSchema = mediaBaseSchema.extend({ type: z.literal("audio") });
7926
- const documentMediaSchema = mediaBaseSchema.extend({ type: z.literal("document") });
7927
- const spreadsheetMediaSchema = mediaBaseSchema.extend({ type: z.literal("spreadsheet") });
7928
- const archiveMediaSchema = mediaBaseSchema.extend({ type: z.literal("archive") });
7929
- const mediaSchema = z.discriminatedUnion("type", [
7930
- imageMediaSchema,
7931
- videoMediaSchema,
7932
- audioMediaSchema,
7933
- documentMediaSchema,
7934
- spreadsheetMediaSchema,
7935
- archiveMediaSchema
7936
- ]);
7937
- const persistableMediaBaseSchema = mediaBaseSchema.extend({ identifier: mediaIdentifierSchema });
7938
- z.discriminatedUnion("type", [
7939
- persistableMediaBaseSchema.extend({ type: z.literal("image") }),
7940
- persistableMediaBaseSchema.extend({ type: z.literal("video") }),
7941
- persistableMediaBaseSchema.extend({ type: z.literal("audio") }),
7942
- persistableMediaBaseSchema.extend({ type: z.literal("document") }),
7943
- persistableMediaBaseSchema.extend({ type: z.literal("spreadsheet") }),
7944
- persistableMediaBaseSchema.extend({ type: z.literal("archive") })
8037
+ const mediaSchema = mediaBaseSchema.extend({ type: z.enum(mediaTypeDiscriminants) });
8038
+ const externalMediaSchema = z.object({
8039
+ ...mediaUsageShape,
8040
+ ...environmentExclusions,
8041
+ type: z.enum(mediaTypeDiscriminants),
8042
+ src: z.string().min(1),
8043
+ identifier: z.never().optional()
8044
+ }).strict();
8045
+ const assetMediaSchema = z.object({
8046
+ ...mediaUsageShape,
8047
+ ...environmentExclusions,
8048
+ type: z.enum(mediaTypeDiscriminants),
8049
+ asset: renderableMediaAssetSchema,
8050
+ identifier: z.never().optional()
8051
+ }).strict();
8052
+ const runtimeMediaSchema = z.union([
8053
+ mediaSchema,
8054
+ externalMediaSchema,
8055
+ assetMediaSchema
7945
8056
  ]);
7946
8057
  //#endregion
8058
+ //#region ../media-core/src/transformRect.ts
8059
+ function isValidTransformRectStructure(rect) {
8060
+ if (!Array.isArray(rect) || rect.length !== 4) return false;
8061
+ const [left, top, width, height] = rect;
8062
+ return Number.isFinite(left) && Number.isFinite(top) && Number.isFinite(width) && Number.isFinite(height) && left >= 0 && top >= 0 && width > 0 && height > 0;
8063
+ }
8064
+ //#endregion
8065
+ //#region ../media-core/src/aspectTransforms.ts
8066
+ const DEFAULT_RECT_EPSILON = .5;
8067
+ function parseAspectRatioValue(value) {
8068
+ if (typeof value === "number") return Number.isFinite(value) && value > 0 ? value : void 0;
8069
+ if (typeof value !== "string") return void 0;
8070
+ const normalized = value.trim();
8071
+ if (!normalized) return void 0;
8072
+ if (normalized === "auto") return void 0;
8073
+ if (normalized.includes(":") || normalized.includes("/")) {
8074
+ const delimiter = normalized.includes(":") ? ":" : "/";
8075
+ const [wRaw, hRaw] = normalized.split(delimiter);
8076
+ const width = Number(wRaw?.trim());
8077
+ const height = Number(hRaw?.trim());
8078
+ if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return;
8079
+ return width / height;
8080
+ }
8081
+ const numeric = Number(normalized);
8082
+ if (!Number.isFinite(numeric) || numeric <= 0) return void 0;
8083
+ return numeric;
8084
+ }
8085
+ const MAX_ASPECT_DISTANCE = .25;
8086
+ function resolveMediaTransformForAspect(transform, targetAspect) {
8087
+ if (!transform) return {};
8088
+ const base = {
8089
+ rect: transform.rect,
8090
+ hotspot: transform.hotspot,
8091
+ rotation: transform.rotation
8092
+ };
8093
+ const target = parseAspectRatioValue(targetAspect);
8094
+ const crops = transform.aspectCrops;
8095
+ if (!target || !crops || Object.keys(crops).length === 0) return base;
8096
+ let best = null;
8097
+ let bestDistance = Number.POSITIVE_INFINITY;
8098
+ for (const [key, candidate] of Object.entries(crops)) {
8099
+ const candidateAspect = parseAspectRatioValue(candidate.aspect ?? key);
8100
+ if (!candidateAspect) continue;
8101
+ const distance = Math.abs(Math.log(candidateAspect / target));
8102
+ if (distance < bestDistance) {
8103
+ best = candidate;
8104
+ bestDistance = distance;
8105
+ }
8106
+ }
8107
+ if (!best) return base;
8108
+ if (bestDistance > MAX_ASPECT_DISTANCE) return base;
8109
+ return {
8110
+ rect: best.rect ?? base.rect,
8111
+ hotspot: best.hotspot ?? base.hotspot,
8112
+ rotation: best.rotation ?? base.rotation
8113
+ };
8114
+ }
8115
+ function isValidTransformRect(rect) {
8116
+ return isValidTransformRectStructure(rect);
8117
+ }
8118
+ function isExplicitRectCrop(rect, sourceWidth, sourceHeight, epsilon = DEFAULT_RECT_EPSILON) {
8119
+ if (!isValidTransformRect(rect)) return false;
8120
+ if (!(typeof sourceWidth === "number" && Number.isFinite(sourceWidth) && sourceWidth > 0 && typeof sourceHeight === "number" && Number.isFinite(sourceHeight) && sourceHeight > 0)) return true;
8121
+ const [x, y, width, height] = rect;
8122
+ return !(Math.abs(x) <= epsilon && Math.abs(y) <= epsilon && Math.abs(width - sourceWidth) <= epsilon && Math.abs(height - sourceHeight) <= epsilon);
8123
+ }
8124
+ //#endregion
8125
+ //#region ../media-core/src/rotation.ts
8126
+ function rotateNormalizedPoint(point, rotation) {
8127
+ const x = point.x;
8128
+ const y = point.y;
8129
+ switch (rotation) {
8130
+ case 0: return {
8131
+ x,
8132
+ y
8133
+ };
8134
+ case 90: return {
8135
+ x: 1 - y,
8136
+ y: x
8137
+ };
8138
+ case 180: return {
8139
+ x: 1 - x,
8140
+ y: 1 - y
8141
+ };
8142
+ case 270: return {
8143
+ x: y,
8144
+ y: 1 - x
8145
+ };
8146
+ }
8147
+ }
8148
+ //#endregion
7947
8149
  //#region ../theme-core/src/palette/schema.ts
7948
8150
  const colourHexString = z.string().regex(/^#([0-9A-Fa-f]{3}){1,2}$/);
7949
8151
  const paletteColorSchema = z.object({
@@ -16492,6 +16694,21 @@ const boxBackgroundSchema = z.discriminatedUnion("type", [
16492
16694
  showVideoOnMobile: z.boolean().nullable().optional()
16493
16695
  })
16494
16696
  ]);
16697
+ /** Application rendering sources are admitted separately from saved references. */
16698
+ const runtimeBoxBackgroundSchema = z.discriminatedUnion("type", [
16699
+ boxBackgroundSchema.options[0],
16700
+ boxBackgroundSchema.options[1],
16701
+ boxBackgroundSchema.options[2].extend({ image: z.union([
16702
+ imageMediaSchema,
16703
+ externalMediaSchema.extend({ type: z.literal("image") }),
16704
+ assetMediaSchema.extend({ type: z.literal("image") })
16705
+ ]).nullable().optional() }),
16706
+ boxBackgroundSchema.options[3].extend({ image: z.union([
16707
+ videoMediaSchema,
16708
+ externalMediaSchema.extend({ type: z.literal("video") }),
16709
+ assetMediaSchema.extend({ type: z.literal("video") })
16710
+ ]).nullable().optional() })
16711
+ ]);
16495
16712
  function normalizeAuthoringOpacity(value) {
16496
16713
  if (!isRecord$6(value)) return value;
16497
16714
  return {
@@ -23341,97 +23558,6 @@ function registerManifest(manifest) {
23341
23558
  return manifest;
23342
23559
  }
23343
23560
  //#endregion
23344
- //#region ../media-core/src/transformRect.ts
23345
- function isValidTransformRectStructure(rect) {
23346
- if (!Array.isArray(rect) || rect.length !== 4) return false;
23347
- const [left, top, width, height] = rect;
23348
- return Number.isFinite(left) && Number.isFinite(top) && Number.isFinite(width) && Number.isFinite(height) && left >= 0 && top >= 0 && width > 0 && height > 0;
23349
- }
23350
- //#endregion
23351
- //#region ../media-core/src/aspectTransforms.ts
23352
- const DEFAULT_RECT_EPSILON = .5;
23353
- function parseAspectRatioValue(value) {
23354
- if (typeof value === "number") return Number.isFinite(value) && value > 0 ? value : void 0;
23355
- if (typeof value !== "string") return void 0;
23356
- const normalized = value.trim();
23357
- if (!normalized) return void 0;
23358
- if (normalized === "auto") return void 0;
23359
- if (normalized.includes(":") || normalized.includes("/")) {
23360
- const delimiter = normalized.includes(":") ? ":" : "/";
23361
- const [wRaw, hRaw] = normalized.split(delimiter);
23362
- const width = Number(wRaw?.trim());
23363
- const height = Number(hRaw?.trim());
23364
- if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return;
23365
- return width / height;
23366
- }
23367
- const numeric = Number(normalized);
23368
- if (!Number.isFinite(numeric) || numeric <= 0) return void 0;
23369
- return numeric;
23370
- }
23371
- const MAX_ASPECT_DISTANCE = .25;
23372
- function resolveMediaTransformForAspect(transform, targetAspect) {
23373
- if (!transform) return {};
23374
- const base = {
23375
- rect: transform.rect,
23376
- hotspot: transform.hotspot,
23377
- rotation: transform.rotation
23378
- };
23379
- const target = parseAspectRatioValue(targetAspect);
23380
- const crops = transform.aspectCrops;
23381
- if (!target || !crops || Object.keys(crops).length === 0) return base;
23382
- let best = null;
23383
- let bestDistance = Number.POSITIVE_INFINITY;
23384
- for (const [key, candidate] of Object.entries(crops)) {
23385
- const candidateAspect = parseAspectRatioValue(candidate.aspect ?? key);
23386
- if (!candidateAspect) continue;
23387
- const distance = Math.abs(Math.log(candidateAspect / target));
23388
- if (distance < bestDistance) {
23389
- best = candidate;
23390
- bestDistance = distance;
23391
- }
23392
- }
23393
- if (!best) return base;
23394
- if (bestDistance > MAX_ASPECT_DISTANCE) return base;
23395
- return {
23396
- rect: best.rect ?? base.rect,
23397
- hotspot: best.hotspot ?? base.hotspot,
23398
- rotation: best.rotation ?? base.rotation
23399
- };
23400
- }
23401
- function isValidTransformRect(rect) {
23402
- return isValidTransformRectStructure(rect);
23403
- }
23404
- function isExplicitRectCrop(rect, sourceWidth, sourceHeight, epsilon = DEFAULT_RECT_EPSILON) {
23405
- if (!isValidTransformRect(rect)) return false;
23406
- if (!(typeof sourceWidth === "number" && Number.isFinite(sourceWidth) && sourceWidth > 0 && typeof sourceHeight === "number" && Number.isFinite(sourceHeight) && sourceHeight > 0)) return true;
23407
- const [x, y, width, height] = rect;
23408
- return !(Math.abs(x) <= epsilon && Math.abs(y) <= epsilon && Math.abs(width - sourceWidth) <= epsilon && Math.abs(height - sourceHeight) <= epsilon);
23409
- }
23410
- //#endregion
23411
- //#region ../media-core/src/rotation.ts
23412
- function rotateNormalizedPoint(point, rotation) {
23413
- const x = point.x;
23414
- const y = point.y;
23415
- switch (rotation) {
23416
- case 0: return {
23417
- x,
23418
- y
23419
- };
23420
- case 90: return {
23421
- x: 1 - y,
23422
- y: x
23423
- };
23424
- case 180: return {
23425
- x: 1 - x,
23426
- y: 1 - y
23427
- };
23428
- case 270: return {
23429
- x: y,
23430
- y: 1 - x
23431
- };
23432
- }
23433
- }
23434
- //#endregion
23435
23561
  //#region ../blocks/src/system/node/schema.ts
23436
23562
  const transformStepSchema = z.object({
23437
23563
  id: z.string().min(1, "Transform requires an identifier"),
@@ -26357,6 +26483,12 @@ function parseBackgroundOverlay(value) {
26357
26483
  const result = boxBackgroundOverlaySchema.safeParse(value);
26358
26484
  return result.success ? result.data : void 0;
26359
26485
  }
26486
+ /** Rendering accepts explicit application sources separately from stored references. */
26487
+ const runtimeBackgroundContentSchema = runtimeBoxBackgroundSchema;
26488
+ function parseRuntimeBackgroundContent(value) {
26489
+ const result = runtimeBackgroundContentSchema.safeParse(value);
26490
+ return result.success ? result.data : null;
26491
+ }
26360
26492
  //#endregion
26361
26493
  //#region ../blocks/src/system/transforms/registry/_utils/themeColorResolution.ts
26362
26494
  function resolveBackgroundColorValue(value, context) {
@@ -35615,14 +35747,6 @@ const weeklySlotAvailabilityBlockDefinition = {
35615
35747
  } }
35616
35748
  };
35617
35749
  //#endregion
35618
- //#region ../blocks/src/lib/media.ts
35619
- const PUBLIC_DOWNLOAD_MEDIA_TYPES = [
35620
- "document",
35621
- "spreadsheet",
35622
- "archive",
35623
- "audio"
35624
- ];
35625
- //#endregion
35626
35750
  //#region ../blocks/src/system/manifest/richTextSchema.ts
35627
35751
  /**
35628
35752
  * Shared Rich Text Schema
@@ -36058,7 +36182,7 @@ const publicEventBaseSchema = z.object({
36058
36182
  content: z.object({ body: RichTextDocSchema.nullable().optional() }).optional(),
36059
36183
  presentation: z.object({
36060
36184
  summary: z.string().nullable().optional(),
36061
- image: mediaSchema.nullable().optional()
36185
+ image: runtimeMediaSchema.nullable().optional()
36062
36186
  }).optional(),
36063
36187
  slug: z.string(),
36064
36188
  path: z.string().nullable(),
@@ -42949,6 +43073,14 @@ const audioPlayerBlockDefinition = { manifest: createBlockManifest({
42949
43073
  }
42950
43074
  }) };
42951
43075
  //#endregion
43076
+ //#region ../blocks/src/lib/media.ts
43077
+ const PUBLIC_DOWNLOAD_MEDIA_TYPES = [
43078
+ "document",
43079
+ "spreadsheet",
43080
+ "archive",
43081
+ "audio"
43082
+ ];
43083
+ //#endregion
42952
43084
  //#region ../blocks/src/system/blocks/file-download.ts
42953
43085
  const bound = (from) => ({ $bind: { from } });
42954
43086
  const fileDownloadLayout = styledSection({
@@ -45194,7 +45326,7 @@ const memberPhotoClassName = (baseClass) => cardRoleChildClass({
45194
45326
  baseClass,
45195
45327
  stylesFrom: "content._cardStyles"
45196
45328
  });
45197
- const teamMemberPhotoSchema = mediaSchema.refine((media) => media.type === "image", { message: "Team member photos must be image media" }).nullable();
45329
+ const teamMemberPhotoSchema = runtimeMediaSchema.refine((media) => media.type === "image", { message: "Team member photos must be image media" }).nullable();
45198
45330
  const teamMemberDataSchema = z.object({
45199
45331
  _type: z.literal("teamMember"),
45200
45332
  id: z.string(),
@@ -46736,11 +46868,14 @@ const offeringsPreviewDatesReadEnabled = {
46736
46868
  //#endregion
46737
46869
  //#region ../blocks/src/system/helpers/backgroundMedia.ts
46738
46870
  function resolveBackgroundMedia(input) {
46739
- const parsedMedia = mediaSchema.safeParse(input.image);
46871
+ const parsedMedia = runtimeMediaSchema.safeParse(input.image);
46740
46872
  if (!parsedMedia.success) return null;
46741
46873
  switch (parsedMedia.data.type) {
46742
46874
  case "image":
46743
- case "video": return parsedMedia.data;
46875
+ case "video": return {
46876
+ ...parsedMedia.data,
46877
+ type: parsedMedia.data.type
46878
+ };
46744
46879
  case "audio":
46745
46880
  case "document":
46746
46881
  case "spreadsheet":
@@ -46752,6 +46887,75 @@ function backgroundVideoMobileClassNames(input) {
46752
46887
  return input.showVideoOnMobile === true ? "" : "rb-hidden rb-md-block";
46753
46888
  }
46754
46889
  //#endregion
46890
+ //#region ../blocks/src/system/runtime/nodes/mediaContext.ts
46891
+ /**
46892
+ * Server-side: AsyncLocalStorage for request isolation.
46893
+ * Prevents race conditions when multiple requests are processed concurrently.
46894
+ *
46895
+ * Lazy initialization to avoid issues in environments that don't support async_hooks.
46896
+ */
46897
+ const serverStorageState = {
46898
+ storage: null,
46899
+ checked: false
46900
+ };
46901
+ function getServerStorage() {
46902
+ if (typeof window !== "undefined") return null;
46903
+ if (serverStorageState.checked) return serverStorageState.storage;
46904
+ serverStorageState.checked = true;
46905
+ try {
46906
+ const globalWithNonWebpackRequire = globalThis;
46907
+ const AsyncLocalStorage = (typeof globalWithNonWebpackRequire.__non_webpack_require__ === "function" ? globalWithNonWebpackRequire.__non_webpack_require__ : new Function("id", "return require(id)"))("async_hooks").AsyncLocalStorage;
46908
+ if (AsyncLocalStorage) {
46909
+ serverStorageState.storage = new AsyncLocalStorage();
46910
+ return serverStorageState.storage;
46911
+ }
46912
+ return null;
46913
+ } catch {
46914
+ if (process.env.NODE_ENV !== "production") console.warn("[blocks] AsyncLocalStorage not available - using module-level state");
46915
+ return null;
46916
+ }
46917
+ }
46918
+ /**
46919
+ * Client-side context storage.
46920
+ * Safe because browsers are single-threaded per tab.
46921
+ *
46922
+ * IMPORTANT: This must be shared across bundles.
46923
+ * SDK preview mode can load multiple independently-bundled entrypoints
46924
+ * (e.g. `@riverbankcms/sdk/rendering` + `@riverbankcms/sdk/preview-next/client`),
46925
+ * which can otherwise each get their own module-scoped singleton.
46926
+ */
46927
+ const RB_MEDIA_CONTEXT_KEY = Symbol.for("riverbankcms.blocks.mediaContext");
46928
+ function getClientContextStore() {
46929
+ const g = globalThis;
46930
+ const existing = g[RB_MEDIA_CONTEXT_KEY];
46931
+ if (existing && typeof existing === "object") return existing;
46932
+ const next = {};
46933
+ g[RB_MEDIA_CONTEXT_KEY] = next;
46934
+ return next;
46935
+ }
46936
+ /**
46937
+ * Get the current media context.
46938
+ * Server-side: Uses AsyncLocalStorage for request isolation.
46939
+ * Client-side: Uses module-level state (safe in single-threaded browser).
46940
+ */
46941
+ function getMediaContext() {
46942
+ const storage = getServerStorage();
46943
+ if (storage) return storage.getStore() ?? {};
46944
+ return getClientContextStore();
46945
+ }
46946
+ function getCurrentResolveImageUrlContext() {
46947
+ const context = getMediaContext();
46948
+ if (!context.supabaseUrl && !context.siteId && !context.mediaAssetIndex) return;
46949
+ return {
46950
+ supabaseUrl: context.supabaseUrl,
46951
+ siteId: context.siteId,
46952
+ mediaAssetIndex: context.mediaAssetIndex
46953
+ };
46954
+ }
46955
+ function getMediaAssetIndex(context) {
46956
+ return context?.mediaAssetIndex ?? getMediaContext().mediaAssetIndex;
46957
+ }
46958
+ //#endregion
46755
46959
  //#region ../blocks/src/system/runtime/nodes/media.tsx
46756
46960
  function getValidSourceDimension(value) {
46757
46961
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
@@ -46787,41 +46991,72 @@ function applyRectTransform(existingStyle, patch) {
46787
46991
  if (patch.transform) next.transform = appendTransform(existingStyle?.transform, patch.transform);
46788
46992
  return next;
46789
46993
  }
46790
- function computeMediaTransformStyle(value, style, targetAspectRatio, options) {
46994
+ /** Resolve portable content without exposing runtime metadata as saved values. */
46995
+ function resolveMediaWithContext(reference, context) {
46996
+ return resolveManagedMediaReference(reference, getMediaAssetIndex(context ?? void 0));
46997
+ }
46998
+ function sourceFromAsset(value, asset) {
46999
+ return {
47000
+ type: value.type,
47001
+ alt: value.alt,
47002
+ filename: value.filename,
47003
+ purpose: value.purpose,
47004
+ placeholder: value.placeholder,
47005
+ transform: value.transform,
47006
+ poster: value.poster,
47007
+ identifier: asset.identifier,
47008
+ assetId: asset.id,
47009
+ storageBucket: asset.storageBucket,
47010
+ storagePath: asset.storagePath,
47011
+ mimeType: asset.mimeType,
47012
+ width: asset.width,
47013
+ height: asset.height
47014
+ };
47015
+ }
47016
+ function resolveRuntimeMedia(value, context) {
47017
+ if ("asset" in value && value.asset) return sourceFromAsset(value, value.asset);
47018
+ if ("src" in value && value.src) return value;
47019
+ if (!value.identifier) return void 0;
47020
+ const resolved = resolveMediaWithContext(value, context);
47021
+ return resolved.kind === "resolved" ? sourceFromAsset(resolved.reference, resolved.asset) : void 0;
47022
+ }
47023
+ function usesProxyFraming(source, transform) {
47024
+ if (!source?.assetId || !isExplicitCropProxyEnabled()) return false;
47025
+ return Boolean(transform.rotation) || isExplicitRectCrop(transform.rect, getValidSourceDimension(source.width), getValidSourceDimension(source.height));
47026
+ }
47027
+ function rectFramingPatch(source, rect, proxy, style) {
47028
+ if (!source || !rect || proxy) return {};
47029
+ const patch = buildCssRectStylePatch(source, rect);
47030
+ return patch ? applyRectTransform(style, patch) : {};
47031
+ }
47032
+ function hotspotFramingPatch(transform, proxy, rectPatch, style) {
47033
+ if (!transform.hotspot || rectPatch.objectPosition !== void 0) return {};
47034
+ const fit = style?.objectFit;
47035
+ if (fit && fit !== "cover" && fit !== "contain") return {};
47036
+ const point = proxy && transform.rotation ? rotateNormalizedPoint(transform.hotspot, transform.rotation) : transform.hotspot;
47037
+ return { objectPosition: `${point.x * 100}% ${point.y * 100}%` };
47038
+ }
47039
+ function rotationFramingPatch(rotation, proxy, rectPatch, style) {
47040
+ if (!rotation || proxy) return {};
47041
+ return {
47042
+ transform: appendTransform(rectPatch.transform ?? style?.transform, `rotate(${rotation}deg)`),
47043
+ transformOrigin: rectPatch.transformOrigin ?? "center"
47044
+ };
47045
+ }
47046
+ /** CSS framing is a pure projection of the resolved source and per-use transform. */
47047
+ function deriveMediaFramingStyle(source, transform, proxy, style) {
47048
+ if (!transform.rect && !transform.hotspot && !transform.rotation) return style;
47049
+ const rectPatch = rectFramingPatch(source, transform.rect, proxy, style);
47050
+ return mergeStyles(style, {
47051
+ ...rectPatch,
47052
+ ...hotspotFramingPatch(transform, proxy, rectPatch, style),
47053
+ ...rotationFramingPatch(transform.rotation, proxy, rectPatch, style)
47054
+ });
47055
+ }
47056
+ function computeMediaTransformStyle(value, style, targetAspectRatio, options, context) {
47057
+ const source = resolveRuntimeMedia(value, context ?? getCurrentResolveImageUrlContext());
46791
47058
  const transform = options?.resolvedTransform ?? resolveMediaTransformForAspect(value.transform, targetAspectRatio);
46792
- const rect = transform.rect;
46793
- const hotspot = transform.hotspot;
46794
- const rotation = transform.rotation;
46795
- if (!rect && !hotspot && !rotation) return style;
46796
- const stylePatch = {};
46797
- const heuristicSuppressCss = Boolean(isExplicitCropProxyEnabled() && value.assetId && (typeof rotation === "number" && rotation !== 0 || isExplicitRectCrop(rect, getValidSourceDimension(value.width), getValidSourceDimension(value.height))));
46798
- const shouldSuppressCss = options?.isProxy ?? heuristicSuppressCss;
46799
- if (rect && !shouldSuppressCss) {
46800
- const rectPatch = buildCssRectStylePatch(value, rect);
46801
- if (rectPatch) {
46802
- const mergedRect = applyRectTransform(style, rectPatch);
46803
- Object.assign(stylePatch, mergedRect);
46804
- }
46805
- }
46806
- if (hotspot) {
46807
- const effectiveObjectFit = stylePatch.objectFit ?? style?.objectFit;
46808
- if ((!effectiveObjectFit || effectiveObjectFit === "cover" || effectiveObjectFit === "contain") && stylePatch.objectPosition === void 0) {
46809
- const resolved = shouldSuppressCss && rotation ? rotateNormalizedPoint({
46810
- x: hotspot.x,
46811
- y: hotspot.y
46812
- }, rotation) : {
46813
- x: hotspot.x,
46814
- y: hotspot.y
46815
- };
46816
- stylePatch.objectPosition = `${resolved.x * 100}% ${resolved.y * 100}%`;
46817
- }
46818
- }
46819
- if (rotation && !shouldSuppressCss) {
46820
- const existingTransform = stylePatch.transform ?? style?.transform;
46821
- stylePatch.transform = existingTransform ? `${existingTransform} rotate(${rotation}deg)` : `rotate(${rotation}deg)`;
46822
- if (!stylePatch.transformOrigin) stylePatch.transformOrigin = "center";
46823
- }
46824
- return mergeStyles(style, stylePatch);
47059
+ return deriveMediaFramingStyle(source, transform, options?.isProxy ?? usesProxyFraming(source, transform), style);
46825
47060
  }
46826
47061
  //#endregion
46827
47062
  //#region ../blocks/src/system/transforms/registry/background.ts
@@ -46970,11 +47205,11 @@ const backgroundTransforms = [
46970
47205
  }
46971
47206
  ];
46972
47207
  function parseMediaBackground(value) {
46973
- const background = parseBackgroundContent(value);
47208
+ const background = parseRuntimeBackgroundContent(value);
46974
47209
  return background?.type === "image" || background?.type === "video" ? background : null;
46975
47210
  }
46976
47211
  function resolveBackgroundLayerStyle(value, fallbackToken, context) {
46977
- const background = parseBackgroundContent(value);
47212
+ const background = parseRuntimeBackgroundContent(value);
46978
47213
  const style = {};
46979
47214
  const gradient = background?.type === "gradient" ? isString(background.gradient) ? background.gradient.trim() : gradientPresetCss(background.gradientPresetId) : null;
46980
47215
  const color = background?.type === "color" && isString(background.color) ? background.color.trim() : null;