@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
@@ -1765,12 +1765,14 @@ const unsafeAsSiteId = (id) => id;
1765
1765
  const unsafeAsApiKeyId = (id) => id;
1766
1766
  const unsafeAsEventOfferingId = (id) => id;
1767
1767
  const unsafeAsEventSeriesId = (id) => id;
1768
+ const unsafeAsMediaAssetId = (id) => id;
1768
1769
  const unsafeAsUserId = (id) => id;
1769
1770
  const unsafeAsContentVersionId = (id) => id;
1770
1771
  const parseSiteId = (value) => parseUuidBrand(value, unsafeAsSiteId);
1771
1772
  const parseApiKeyId = (value) => parseUuidBrand(value, unsafeAsApiKeyId);
1772
1773
  const parseEventOfferingId = (value) => parseUuidBrand(value, unsafeAsEventOfferingId);
1773
1774
  const parseUserId = (value) => parseUuidBrand(value, unsafeAsUserId);
1775
+ const parseMediaAssetId = (value) => parseUuidBrand(value, unsafeAsMediaAssetId);
1774
1776
  const parseContentVersionId = (value) => parseUuidBrand(value, unsafeAsContentVersionId);
1775
1777
  const parseEventSeriesId = (value) => parseUuidBrand(value, unsafeAsEventSeriesId);
1776
1778
  //#endregion
@@ -2441,7 +2443,7 @@ function parsePositiveInteger(value) {
2441
2443
  return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : null;
2442
2444
  }
2443
2445
  function parseNewsletterListId(value) {
2444
- return parseTrimmedMatchingString(value, UUID_PATTERN);
2446
+ return parseTrimmedMatchingString(typeof value === "string" ? value.toLowerCase() : value, UUID_PATTERN);
2445
2447
  }
2446
2448
  function parseMailchimpAccountId(value) {
2447
2449
  return parseTrimmedMatchingString(value, OPAQUE_ID_PATTERN);
@@ -2483,8 +2485,15 @@ function parseMailingListProviderScope(value) {
2483
2485
  }
2484
2486
  return err$1("invalid_mailing_list_provider_scope");
2485
2487
  }
2486
- //#endregion
2487
- //#region ../core/src/mailing-list-setup-parser.ts
2488
+ z.unknown().transform((value, ctx) => {
2489
+ const parsed = parseNewsletterAudience(value);
2490
+ if (parsed.ok) return parsed.value;
2491
+ ctx.addIssue({
2492
+ code: "custom",
2493
+ message: "Choose a valid newsletter audience."
2494
+ });
2495
+ return z.NEVER;
2496
+ });
2488
2497
  function parseMailingListGlobalForm(value) {
2489
2498
  if (!isRecord$16(value)) return formError("shape");
2490
2499
  const fields = parseGlobalFields(value.fields);
@@ -2504,6 +2513,16 @@ function parseMailingListGlobalForm(value) {
2504
2513
  privacyNote
2505
2514
  });
2506
2515
  }
2516
+ function parseNewsletterAudience(value) {
2517
+ if (!isRecord$16(value)) return err$1("invalid_newsletter_audience");
2518
+ if (value.kind === "general" && Object.keys(value).length === 1) return ok$1({ kind: "general" });
2519
+ if (value.kind !== "topic" || Object.keys(value).some((key) => key !== "kind" && key !== "topicId")) return err$1("invalid_newsletter_audience");
2520
+ const topicId = parseNewsletterListId(value.topicId);
2521
+ return topicId === null ? err$1("invalid_newsletter_audience") : ok$1({
2522
+ kind: "topic",
2523
+ topicId
2524
+ });
2525
+ }
2507
2526
  function parseGlobalFields(value) {
2508
2527
  if (!isRecord$16(value) || typeof value.preset !== "string") return null;
2509
2528
  switch (value.preset) {
@@ -2556,54 +2575,49 @@ function formError(field) {
2556
2575
  const DEFAULT_MAILING_LIST_TARGETING = { mode: "default" };
2557
2576
  function mailingListTargetingChoiceIds(targeting) {
2558
2577
  switch (targeting.provider) {
2559
- case "native": return targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds;
2578
+ case "native": return targeting.selection.tag === "general" ? [] : targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds;
2560
2579
  case "brevo": return targeting.selection.tag === "fixed" ? targeting.selection.listIds : targeting.selection.offeredListIds;
2561
2580
  case "mailchimp": return targeting.selection.tag === "fixed" ? targeting.selection.interestIds : targeting.selection.offeredInterestIds;
2562
2581
  }
2563
2582
  }
2564
2583
  function planMailingListChoicePresentation(targeting) {
2565
- if (targeting.mode === "default" || targeting.selection.tag === "fixed") return { tag: "hidden" };
2584
+ if (targeting.mode === "default" || targeting.selection.tag === "fixed" || targeting.selection.tag === "general") return { tag: "hidden" };
2566
2585
  switch (targeting.provider) {
2567
- case "native": return targeting.selection.offeredTopicIds.length === 1 ? {
2568
- tag: "automatic",
2569
- selection: {
2570
- provider: "native",
2571
- topicIds: targeting.selection.offeredTopicIds
2572
- }
2573
- } : {
2574
- tag: "visitor_choice",
2586
+ case "native": return presentVisitorSelection({
2575
2587
  provider: "native",
2576
- optionCount: targeting.selection.offeredTopicIds.length
2577
- };
2578
- case "brevo": return targeting.selection.offeredListIds.length === 1 ? {
2579
- tag: "automatic",
2580
- selection: {
2581
- provider: "brevo",
2582
- listIds: targeting.selection.offeredListIds
2583
- }
2584
- } : {
2585
- tag: "visitor_choice",
2588
+ topicIds: targeting.selection.offeredTopicIds
2589
+ }, targeting.selection.offeredTopicIds.length);
2590
+ case "brevo": return presentVisitorSelection({
2586
2591
  provider: "brevo",
2587
- optionCount: targeting.selection.offeredListIds.length
2588
- };
2589
- case "mailchimp": return targeting.selection.offeredInterestIds.length === 1 ? {
2590
- tag: "automatic",
2591
- selection: {
2592
- provider: "mailchimp",
2593
- interestIds: targeting.selection.offeredInterestIds
2594
- }
2595
- } : {
2596
- tag: "visitor_choice",
2592
+ listIds: targeting.selection.offeredListIds
2593
+ }, targeting.selection.offeredListIds.length);
2594
+ case "mailchimp": return presentVisitorSelection({
2597
2595
  provider: "mailchimp",
2598
- optionCount: targeting.selection.offeredInterestIds.length
2599
- };
2596
+ interestIds: targeting.selection.offeredInterestIds
2597
+ }, targeting.selection.offeredInterestIds.length);
2600
2598
  }
2601
2599
  }
2600
+ function presentVisitorSelection(selection, optionCount) {
2601
+ return optionCount === 1 ? {
2602
+ tag: "automatic",
2603
+ selection
2604
+ } : {
2605
+ tag: "visitor_choice",
2606
+ provider: selection.provider,
2607
+ optionCount
2608
+ };
2609
+ }
2602
2610
  //#endregion
2603
2611
  //#region ../core/src/mailing-list-targeting-availability.ts
2604
2612
  function resolveMailingListDefaultDestination(provider) {
2605
2613
  switch (provider.provider) {
2606
- case "native": return provider.topics.find((item) => item.id === provider.defaultTopicId) ?? null;
2614
+ case "native": {
2615
+ const audience = provider.defaultAudience;
2616
+ return audience.kind === "general" ? {
2617
+ id: "general",
2618
+ name: "General mailing list"
2619
+ } : provider.topics.find((item) => item.id === audience.topicId) ?? null;
2620
+ }
2607
2621
  case "brevo": return provider.lists.find((item) => item.id === provider.defaultListId) ?? null;
2608
2622
  case "mailchimp": return provider.audiences.find((item) => item.id === provider.defaultAudienceId) ?? null;
2609
2623
  }
@@ -2741,11 +2755,12 @@ function parseRuntimeProvider(value) {
2741
2755
  }
2742
2756
  }
2743
2757
  function parseNativeRuntimeProvider(value) {
2744
- const defaultTopicId = parseNewsletterListId(value.defaultTopicId);
2758
+ if ("defaultTopicId" in value) return null;
2759
+ const defaultAudience = parseNewsletterAudience(value.defaultAudience);
2745
2760
  const topics = parseNamedItems(value.topics, parseNewsletterListId);
2746
- return defaultTopicId !== null && topics !== null ? {
2761
+ return defaultAudience.ok && topics !== null ? {
2747
2762
  provider: "native",
2748
- defaultTopicId,
2763
+ defaultAudience: defaultAudience.value,
2749
2764
  topics
2750
2765
  } : null;
2751
2766
  }
@@ -2830,6 +2845,11 @@ function parseMailingListPlacementTargeting(value) {
2830
2845
  }
2831
2846
  }
2832
2847
  function parseNativeTargeting(selection) {
2848
+ if (selection.tag === "general") return Object.keys(selection).length === 1 ? ok$1({
2849
+ mode: "custom",
2850
+ provider: "native",
2851
+ selection: { tag: "general" }
2852
+ }) : targetingError("selection");
2833
2853
  if (selection.tag === "fixed") {
2834
2854
  const topicIds = parseNonEmptyUniqueIds(selection.topicIds, parseNewsletterListId);
2835
2855
  return topicIds.ok ? ok$1({
@@ -10553,7 +10573,7 @@ var SimpleCache = class {
10553
10573
  * 1. This constant
10554
10574
  * 2. The "version" field in package.json
10555
10575
  */
10556
- const SDK_VERSION = "0.152.0";
10576
+ const SDK_VERSION = "0.153.0";
10557
10577
  //#endregion
10558
10578
  //#region src/client/error.ts
10559
10579
  let _Symbol$for;
@@ -15858,7 +15878,96 @@ Object.keys(legacyItemSurfaceCardRoles);
15858
15878
  */
15859
15879
  const cardRoleWithLegacyAliasSchema = z.preprocess((value) => normalizeCardRole(value) ?? (typeof value === "string" && Object.prototype.hasOwnProperty.call(legacyItemSurfaceCardRoles, value) ? legacyItemSurfaceCardRoles[value] : value), cardRoleSchema);
15860
15880
  //#endregion
15861
- //#region ../theme-core/src/lib/media.ts
15881
+ //#region ../media-core/src/identifiers.ts
15882
+ function slugifyMediaIdentifier(value) {
15883
+ return value.toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
15884
+ }
15885
+ function parseMediaIdentifier(value) {
15886
+ if (typeof value !== "string") return err$1({ kind: "not_string" });
15887
+ const trimmed = value.trim();
15888
+ if (trimmed.length === 0) return err$1({ kind: "empty_identifier" });
15889
+ const normalized = slugifyMediaIdentifier(trimmed);
15890
+ if (normalized.length === 0) return err$1({
15891
+ kind: "empty_after_normalization",
15892
+ value
15893
+ });
15894
+ return ok$1(normalized);
15895
+ }
15896
+ /**
15897
+ * Admits identifiers read from trusted persistence without repairing dirty data in memory.
15898
+ * User input should use parseMediaIdentifier, which intentionally canonicalizes it.
15899
+ */
15900
+ function parseCanonicalMediaIdentifier(value) {
15901
+ if (typeof value !== "string") return err$1({ kind: "not_string" });
15902
+ const parsed = parseMediaIdentifier(value);
15903
+ if (!parsed.ok) return parsed;
15904
+ if (value !== parsed.value) return err$1({
15905
+ kind: "non_canonical_identifier",
15906
+ value,
15907
+ canonical: parsed.value
15908
+ });
15909
+ return parsed;
15910
+ }
15911
+ //#endregion
15912
+ //#region ../media-core/src/mediaIdentifierSchema.ts
15913
+ /** Strict stored-reference admission delegates the canonical identifier decision. */
15914
+ const mediaIdentifierSchema = z.string().transform((value, context) => {
15915
+ const parsed = parseCanonicalMediaIdentifier(value);
15916
+ if (parsed.ok) return parsed.value;
15917
+ context.addIssue({
15918
+ code: "custom",
15919
+ message: "Expected a canonical media identifier"
15920
+ });
15921
+ return z.NEVER;
15922
+ });
15923
+ //#endregion
15924
+ //#region ../media-core/src/mediaKinds.ts
15925
+ const mediaTypeDiscriminants = [
15926
+ "image",
15927
+ "video",
15928
+ "audio",
15929
+ "document",
15930
+ "spreadsheet",
15931
+ "archive"
15932
+ ];
15933
+ //#endregion
15934
+ //#region ../media-core/src/renderableMediaAsset.ts
15935
+ /** A portable reference never uses an incidental UUID, URL or storage snapshot for identity. */
15936
+ function resolveManagedMediaReference(reference, index) {
15937
+ const asset = index?.byIdentifier.get(reference.identifier);
15938
+ return asset ? {
15939
+ kind: "resolved",
15940
+ reference,
15941
+ asset
15942
+ } : {
15943
+ kind: "missing",
15944
+ reference
15945
+ };
15946
+ }
15947
+ //#endregion
15948
+ //#region ../media-core/src/renderableMediaAssetAdmission.ts
15949
+ const mediaAssetIdSchema = z.string().transform((value, context) => {
15950
+ const parsed = parseMediaAssetId(value);
15951
+ if (parsed.ok) return parsed.value;
15952
+ context.addIssue({
15953
+ code: "custom",
15954
+ message: "Expected a media asset ID"
15955
+ });
15956
+ return z.NEVER;
15957
+ });
15958
+ const nonemptyStorageValue = z.string().refine((value) => value.trim().length > 0);
15959
+ const renderableMediaAssetSchema = z.object({
15960
+ id: mediaAssetIdSchema,
15961
+ identifier: mediaIdentifierSchema,
15962
+ storageBucket: nonemptyStorageValue,
15963
+ storagePath: nonemptyStorageValue,
15964
+ mimeType: nonemptyStorageValue,
15965
+ filename: z.string().optional(),
15966
+ width: z.number().positive().nullable(),
15967
+ height: z.number().positive().nullable()
15968
+ });
15969
+ //#endregion
15970
+ //#region ../media-core/src/media.ts
15862
15971
  const hotspotSchema = z.object({
15863
15972
  x: z.number().min(0).max(1),
15864
15973
  y: z.number().min(0).max(1),
@@ -15892,56 +16001,185 @@ const transformSchema = z.object({
15892
16001
  rotation: rotationSchema.optional()
15893
16002
  });
15894
16003
  const mediaPosterSchema = z.discriminatedUnion("tag", [z.object({
15895
- tag: z.literal("storage"),
15896
- assetId: z.string().optional(),
15897
- storageBucket: z.string().min(1),
15898
- storagePath: z.string().min(1)
15899
- }), z.object({
16004
+ tag: z.literal("media"),
16005
+ identifier: mediaIdentifierSchema
16006
+ }).strict(), z.object({
15900
16007
  tag: z.literal("external-src"),
15901
- assetId: z.string().optional(),
15902
16008
  src: z.string().url()
15903
- })]);
15904
- const mediaBaseSchema = z.object({
16009
+ }).strict()]);
16010
+ const mediaUsageShape = {
15905
16011
  purpose: z.string().optional(),
15906
16012
  placeholder: z.boolean().default(true).optional(),
15907
- assetId: z.string().optional(),
15908
- identifier: z.string().optional(),
15909
- src: z.string().optional(),
15910
16013
  alt: z.string().optional(),
15911
16014
  filename: z.string().optional(),
15912
- mimeType: z.string().optional(),
15913
16015
  width: z.number().optional(),
15914
16016
  height: z.number().optional(),
15915
- storageBucket: z.string().optional(),
15916
- storagePath: z.string().optional(),
15917
16017
  poster: mediaPosterSchema.optional(),
15918
16018
  transform: transformSchema.optional()
15919
- });
15920
- const mediaIdentifierSchema = z.string().trim().min(1).brand();
16019
+ };
16020
+ const environmentExclusions = {
16021
+ assetId: z.never().optional(),
16022
+ id: z.never().optional(),
16023
+ src: z.never().optional(),
16024
+ storageBucket: z.never().optional(),
16025
+ storagePath: z.never().optional(),
16026
+ mimeType: z.never().optional()
16027
+ };
16028
+ const mediaBaseSchema = z.object({
16029
+ ...mediaUsageShape,
16030
+ ...environmentExclusions,
16031
+ identifier: mediaIdentifierSchema
16032
+ }).strict();
15921
16033
  const imageMediaSchema = mediaBaseSchema.extend({ type: z.literal("image") });
15922
16034
  const videoMediaSchema = mediaBaseSchema.extend({ type: z.literal("video") });
15923
- const audioMediaSchema = mediaBaseSchema.extend({ type: z.literal("audio") });
15924
- const documentMediaSchema = mediaBaseSchema.extend({ type: z.literal("document") });
15925
- const spreadsheetMediaSchema = mediaBaseSchema.extend({ type: z.literal("spreadsheet") });
15926
- const archiveMediaSchema = mediaBaseSchema.extend({ type: z.literal("archive") });
15927
- const mediaSchema = z.discriminatedUnion("type", [
15928
- imageMediaSchema,
15929
- videoMediaSchema,
15930
- audioMediaSchema,
15931
- documentMediaSchema,
15932
- spreadsheetMediaSchema,
15933
- archiveMediaSchema
15934
- ]);
15935
- const persistableMediaBaseSchema = mediaBaseSchema.extend({ identifier: mediaIdentifierSchema });
15936
- z.discriminatedUnion("type", [
15937
- persistableMediaBaseSchema.extend({ type: z.literal("image") }),
15938
- persistableMediaBaseSchema.extend({ type: z.literal("video") }),
15939
- persistableMediaBaseSchema.extend({ type: z.literal("audio") }),
15940
- persistableMediaBaseSchema.extend({ type: z.literal("document") }),
15941
- persistableMediaBaseSchema.extend({ type: z.literal("spreadsheet") }),
15942
- persistableMediaBaseSchema.extend({ type: z.literal("archive") })
16035
+ const mediaSchema = mediaBaseSchema.extend({ type: z.enum(mediaTypeDiscriminants) });
16036
+ const externalMediaSchema = z.object({
16037
+ ...mediaUsageShape,
16038
+ ...environmentExclusions,
16039
+ type: z.enum(mediaTypeDiscriminants),
16040
+ src: z.string().min(1),
16041
+ identifier: z.never().optional()
16042
+ }).strict();
16043
+ const assetMediaSchema = z.object({
16044
+ ...mediaUsageShape,
16045
+ ...environmentExclusions,
16046
+ type: z.enum(mediaTypeDiscriminants),
16047
+ asset: renderableMediaAssetSchema,
16048
+ identifier: z.never().optional()
16049
+ }).strict();
16050
+ const runtimeMediaSchema = z.union([
16051
+ mediaSchema,
16052
+ externalMediaSchema,
16053
+ assetMediaSchema
15943
16054
  ]);
15944
16055
  //#endregion
16056
+ //#region ../media-core/src/typeGuards.ts
16057
+ function isRecord$12(value) {
16058
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
16059
+ }
16060
+ //#endregion
16061
+ //#region ../media-core/src/transformRect.ts
16062
+ function isValidTransformRectStructure(rect) {
16063
+ if (!Array.isArray(rect) || rect.length !== 4) return false;
16064
+ const [left, top, width, height] = rect;
16065
+ return Number.isFinite(left) && Number.isFinite(top) && Number.isFinite(width) && Number.isFinite(height) && left >= 0 && top >= 0 && width > 0 && height > 0;
16066
+ }
16067
+ //#endregion
16068
+ //#region ../media-core/src/aspectTransforms.ts
16069
+ const DEFAULT_RECT_EPSILON = .5;
16070
+ function parseAspectRatioValue(value) {
16071
+ if (typeof value === "number") return Number.isFinite(value) && value > 0 ? value : void 0;
16072
+ if (typeof value !== "string") return void 0;
16073
+ const normalized = value.trim();
16074
+ if (!normalized) return void 0;
16075
+ if (normalized === "auto") return void 0;
16076
+ if (normalized.includes(":") || normalized.includes("/")) {
16077
+ const delimiter = normalized.includes(":") ? ":" : "/";
16078
+ const [wRaw, hRaw] = normalized.split(delimiter);
16079
+ const width = Number(wRaw?.trim());
16080
+ const height = Number(hRaw?.trim());
16081
+ if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return;
16082
+ return width / height;
16083
+ }
16084
+ const numeric = Number(normalized);
16085
+ if (!Number.isFinite(numeric) || numeric <= 0) return void 0;
16086
+ return numeric;
16087
+ }
16088
+ const MAX_ASPECT_DISTANCE = .25;
16089
+ function resolveMediaTransformForAspect(transform, targetAspect) {
16090
+ if (!transform) return {};
16091
+ const base = {
16092
+ rect: transform.rect,
16093
+ hotspot: transform.hotspot,
16094
+ rotation: transform.rotation
16095
+ };
16096
+ const target = parseAspectRatioValue(targetAspect);
16097
+ const crops = transform.aspectCrops;
16098
+ if (!target || !crops || Object.keys(crops).length === 0) return base;
16099
+ let best = null;
16100
+ let bestDistance = Number.POSITIVE_INFINITY;
16101
+ for (const [key, candidate] of Object.entries(crops)) {
16102
+ const candidateAspect = parseAspectRatioValue(candidate.aspect ?? key);
16103
+ if (!candidateAspect) continue;
16104
+ const distance = Math.abs(Math.log(candidateAspect / target));
16105
+ if (distance < bestDistance) {
16106
+ best = candidate;
16107
+ bestDistance = distance;
16108
+ }
16109
+ }
16110
+ if (!best) return base;
16111
+ if (bestDistance > MAX_ASPECT_DISTANCE) return base;
16112
+ return {
16113
+ rect: best.rect ?? base.rect,
16114
+ hotspot: best.hotspot ?? base.hotspot,
16115
+ rotation: best.rotation ?? base.rotation
16116
+ };
16117
+ }
16118
+ function isValidTransformRect(rect) {
16119
+ return isValidTransformRectStructure(rect);
16120
+ }
16121
+ function isExplicitRectCrop(rect, sourceWidth, sourceHeight, epsilon = DEFAULT_RECT_EPSILON) {
16122
+ if (!isValidTransformRect(rect)) return false;
16123
+ if (!(typeof sourceWidth === "number" && Number.isFinite(sourceWidth) && sourceWidth > 0 && typeof sourceHeight === "number" && Number.isFinite(sourceHeight) && sourceHeight > 0)) return true;
16124
+ const [x, y, width, height] = rect;
16125
+ return !(Math.abs(x) <= epsilon && Math.abs(y) <= epsilon && Math.abs(width - sourceWidth) <= epsilon && Math.abs(height - sourceHeight) <= epsilon);
16126
+ }
16127
+ //#endregion
16128
+ //#region ../media-core/src/rotation.ts
16129
+ function rotateNormalizedPoint(point, rotation) {
16130
+ const x = point.x;
16131
+ const y = point.y;
16132
+ switch (rotation) {
16133
+ case 0: return {
16134
+ x,
16135
+ y
16136
+ };
16137
+ case 90: return {
16138
+ x: 1 - y,
16139
+ y: x
16140
+ };
16141
+ case 180: return {
16142
+ x: 1 - x,
16143
+ y: 1 - y
16144
+ };
16145
+ case 270: return {
16146
+ x: y,
16147
+ y: 1 - x
16148
+ };
16149
+ }
16150
+ }
16151
+ //#endregion
16152
+ //#region ../media-core/src/mediaRefNormalizer.ts
16153
+ function looksLikeUuid(value) {
16154
+ return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
16155
+ }
16156
+ /**
16157
+ * Strip environment-specific keys from a CMS media object.
16158
+ * @mutates Mutates the passed object in-place.
16159
+ */
16160
+ function deleteEnvSpecificKeys(obj) {
16161
+ delete obj.assetId;
16162
+ delete obj.storageBucket;
16163
+ delete obj.storagePath;
16164
+ delete obj.src;
16165
+ delete obj.mimeType;
16166
+ delete obj.id;
16167
+ }
16168
+ //#endregion
16169
+ //#region ../media-core/src/richTextImageCollector.ts
16170
+ function walkAndCollectImageAttrs(value, out, location = "") {
16171
+ if (Array.isArray(value)) {
16172
+ value.forEach((item, index) => walkAndCollectImageAttrs(item, out, `${location}[${index}]`));
16173
+ return;
16174
+ }
16175
+ if (!isRecord$12(value)) return;
16176
+ if (value.type === "image" && isRecord$12(value.attrs)) out.push({
16177
+ attrs: value.attrs,
16178
+ location: location ? `${location}.attrs` : "attrs"
16179
+ });
16180
+ for (const [key, child] of Object.entries(value)) walkAndCollectImageAttrs(child, out, location ? `${location}.${key}` : key);
16181
+ }
16182
+ //#endregion
15945
16183
  //#region ../theme-core/src/site-styles/rawStyleFields.ts
15946
16184
  const themeV2RuntimeStyleFieldNames = [
15947
16185
  "_frameStyles",
@@ -16029,8 +16267,23 @@ const boxBackgroundSchema = z.discriminatedUnion("type", [
16029
16267
  showVideoOnMobile: z.boolean().nullable().optional()
16030
16268
  })
16031
16269
  ]);
16270
+ /** Application rendering sources are admitted separately from saved references. */
16271
+ const runtimeBoxBackgroundSchema = z.discriminatedUnion("type", [
16272
+ boxBackgroundSchema.options[0],
16273
+ boxBackgroundSchema.options[1],
16274
+ boxBackgroundSchema.options[2].extend({ image: z.union([
16275
+ imageMediaSchema,
16276
+ externalMediaSchema.extend({ type: z.literal("image") }),
16277
+ assetMediaSchema.extend({ type: z.literal("image") })
16278
+ ]).nullable().optional() }),
16279
+ boxBackgroundSchema.options[3].extend({ image: z.union([
16280
+ videoMediaSchema,
16281
+ externalMediaSchema.extend({ type: z.literal("video") }),
16282
+ assetMediaSchema.extend({ type: z.literal("video") })
16283
+ ]).nullable().optional() })
16284
+ ]);
16032
16285
  function normalizeAuthoringOpacity(value) {
16033
- if (!isRecord$12(value)) return value;
16286
+ if (!isRecord$11(value)) return value;
16034
16287
  return {
16035
16288
  ...value,
16036
16289
  opacity: normalizeOpacity(value.opacity)
@@ -16039,7 +16292,7 @@ function normalizeAuthoringOpacity(value) {
16039
16292
  function normalizeOpacity(value) {
16040
16293
  return typeof value === "number" && value > 1 && value <= 100 ? value / 100 : value;
16041
16294
  }
16042
- function isRecord$12(value) {
16295
+ function isRecord$11(value) {
16043
16296
  return typeof value === "object" && value !== null && !Array.isArray(value);
16044
16297
  }
16045
16298
  //#endregion
@@ -30619,133 +30872,6 @@ const linkSchema = z.union([
30619
30872
  entryLinkSchema$1
30620
30873
  ]);
30621
30874
  //#endregion
30622
- //#region ../media-core/src/typeGuards.ts
30623
- function isRecord$11(value) {
30624
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
30625
- }
30626
- //#endregion
30627
- //#region ../media-core/src/transformRect.ts
30628
- function isValidTransformRectStructure(rect) {
30629
- if (!Array.isArray(rect) || rect.length !== 4) return false;
30630
- const [left, top, width, height] = rect;
30631
- return Number.isFinite(left) && Number.isFinite(top) && Number.isFinite(width) && Number.isFinite(height) && left >= 0 && top >= 0 && width > 0 && height > 0;
30632
- }
30633
- //#endregion
30634
- //#region ../media-core/src/aspectTransforms.ts
30635
- const DEFAULT_RECT_EPSILON = .5;
30636
- function parseAspectRatioValue(value) {
30637
- if (typeof value === "number") return Number.isFinite(value) && value > 0 ? value : void 0;
30638
- if (typeof value !== "string") return void 0;
30639
- const normalized = value.trim();
30640
- if (!normalized) return void 0;
30641
- if (normalized === "auto") return void 0;
30642
- if (normalized.includes(":") || normalized.includes("/")) {
30643
- const delimiter = normalized.includes(":") ? ":" : "/";
30644
- const [wRaw, hRaw] = normalized.split(delimiter);
30645
- const width = Number(wRaw?.trim());
30646
- const height = Number(hRaw?.trim());
30647
- if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return;
30648
- return width / height;
30649
- }
30650
- const numeric = Number(normalized);
30651
- if (!Number.isFinite(numeric) || numeric <= 0) return void 0;
30652
- return numeric;
30653
- }
30654
- const MAX_ASPECT_DISTANCE = .25;
30655
- function resolveMediaTransformForAspect(transform, targetAspect) {
30656
- if (!transform) return {};
30657
- const base = {
30658
- rect: transform.rect,
30659
- hotspot: transform.hotspot,
30660
- rotation: transform.rotation
30661
- };
30662
- const target = parseAspectRatioValue(targetAspect);
30663
- const crops = transform.aspectCrops;
30664
- if (!target || !crops || Object.keys(crops).length === 0) return base;
30665
- let best = null;
30666
- let bestDistance = Number.POSITIVE_INFINITY;
30667
- for (const [key, candidate] of Object.entries(crops)) {
30668
- const candidateAspect = parseAspectRatioValue(candidate.aspect ?? key);
30669
- if (!candidateAspect) continue;
30670
- const distance = Math.abs(Math.log(candidateAspect / target));
30671
- if (distance < bestDistance) {
30672
- best = candidate;
30673
- bestDistance = distance;
30674
- }
30675
- }
30676
- if (!best) return base;
30677
- if (bestDistance > MAX_ASPECT_DISTANCE) return base;
30678
- return {
30679
- rect: best.rect ?? base.rect,
30680
- hotspot: best.hotspot ?? base.hotspot,
30681
- rotation: best.rotation ?? base.rotation
30682
- };
30683
- }
30684
- function isValidTransformRect(rect) {
30685
- return isValidTransformRectStructure(rect);
30686
- }
30687
- function isExplicitRectCrop(rect, sourceWidth, sourceHeight, epsilon = DEFAULT_RECT_EPSILON) {
30688
- if (!isValidTransformRect(rect)) return false;
30689
- if (!(typeof sourceWidth === "number" && Number.isFinite(sourceWidth) && sourceWidth > 0 && typeof sourceHeight === "number" && Number.isFinite(sourceHeight) && sourceHeight > 0)) return true;
30690
- const [x, y, width, height] = rect;
30691
- return !(Math.abs(x) <= epsilon && Math.abs(y) <= epsilon && Math.abs(width - sourceWidth) <= epsilon && Math.abs(height - sourceHeight) <= epsilon);
30692
- }
30693
- //#endregion
30694
- //#region ../media-core/src/rotation.ts
30695
- function rotateNormalizedPoint(point, rotation) {
30696
- const x = point.x;
30697
- const y = point.y;
30698
- switch (rotation) {
30699
- case 0: return {
30700
- x,
30701
- y
30702
- };
30703
- case 90: return {
30704
- x: 1 - y,
30705
- y: x
30706
- };
30707
- case 180: return {
30708
- x: 1 - x,
30709
- y: 1 - y
30710
- };
30711
- case 270: return {
30712
- x: y,
30713
- y: 1 - x
30714
- };
30715
- }
30716
- }
30717
- //#endregion
30718
- //#region ../media-core/src/mediaRefNormalizer.ts
30719
- function looksLikeUuid(value) {
30720
- return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
30721
- }
30722
- /**
30723
- * Strip environment-specific keys from a CMS media object.
30724
- * @mutates Mutates the passed object in-place.
30725
- */
30726
- function deleteEnvSpecificKeys(obj) {
30727
- delete obj.assetId;
30728
- delete obj.storageBucket;
30729
- delete obj.storagePath;
30730
- delete obj.src;
30731
- delete obj.mimeType;
30732
- if (looksLikeUuid(obj.id)) delete obj.id;
30733
- }
30734
- //#endregion
30735
- //#region ../media-core/src/richTextImageCollector.ts
30736
- function walkAndCollectImageAttrs(value, out, location = "") {
30737
- if (Array.isArray(value)) {
30738
- value.forEach((item, index) => walkAndCollectImageAttrs(item, out, `${location}[${index}]`));
30739
- return;
30740
- }
30741
- if (!isRecord$11(value)) return;
30742
- if (value.type === "image" && isRecord$11(value.attrs)) out.push({
30743
- attrs: value.attrs,
30744
- location: location ? `${location}.attrs` : "attrs"
30745
- });
30746
- for (const [key, child] of Object.entries(value)) walkAndCollectImageAttrs(child, out, location ? `${location}.${key}` : key);
30747
- }
30748
- //#endregion
30749
30875
  //#region ../blocks/src/system/node/schema.ts
30750
30876
  const transformStepSchema = z.object({
30751
30877
  id: z.string().min(1, "Transform requires an identifier"),
@@ -32443,7 +32569,8 @@ function validationContext(options = {}) {
32443
32569
  const isDraft = options.mode === "draft";
32444
32570
  return {
32445
32571
  allowNull: options.allowNull ?? true,
32446
- allowIncomplete: isDraft || (options.allowIncomplete ?? false)
32572
+ allowIncomplete: isDraft || (options.allowIncomplete ?? false),
32573
+ mode: options.mode ?? "strict"
32447
32574
  };
32448
32575
  }
32449
32576
  function strictValidationContext(options = {}) {
@@ -32817,7 +32944,7 @@ function validateNormalizedFieldValue(plan, value, ctx) {
32817
32944
  case "select": return validateSelectPlan(plan, value);
32818
32945
  case "richText": return isValidRichTextDoc(value) ? [] : [issue(plan, "invalidRichText")];
32819
32946
  case "inlineText": return validateInlineTextPlan(plan, value);
32820
- case "media": return isPlainObject$2(value) && mediaIdentifierSchema.safeParse(value.identifier).success && (value.type === void 0 || typeof value.type === "string" && plan.allowedMediaTypes.includes(value.type)) ? [] : [issue(plan, "invalidMedia")];
32947
+ case "media": return validateMediaPlan(plan, value, ctx);
32821
32948
  case "link": return linkSchema.safeParse(value).success ? [] : [issue(plan, "invalidLink")];
32822
32949
  case "repeater": return validateRepeaterPlan(plan, value, ctx);
32823
32950
  case "group": return validateGroupPlan(plan, value, ctx);
@@ -32825,6 +32952,15 @@ function validateNormalizedFieldValue(plan, value, ctx) {
32825
32952
  default: return assertNever$4(plan);
32826
32953
  }
32827
32954
  }
32955
+ function validateMediaPlan(plan, value, ctx) {
32956
+ if (!isPlainObject$2(value)) return [issue(plan, "invalidMedia")];
32957
+ const allowedKind = value.type === void 0 || typeof value.type === "string" && plan.allowedMediaTypes.includes(value.type);
32958
+ const admitted = ctx.mode === "render" ? runtimeMediaSchema.safeParse({
32959
+ ...value,
32960
+ type: value.type ?? plan.allowedMediaTypes[0]
32961
+ }).success : mediaIdentifierSchema.safeParse(value.identifier).success;
32962
+ return allowedKind && admitted ? [] : [issue(plan, "invalidMedia")];
32963
+ }
32828
32964
  function shouldRequireValue(plan, value, ctx) {
32829
32965
  if (!plan.required || ctx.allowIncomplete) return false;
32830
32966
  if (value === null && ctx.allowNull) return false;
@@ -32949,7 +33085,7 @@ function validateGroupPlan(plan, value, ctx) {
32949
33085
  const childCtx = childValidationContext(plan, ctx);
32950
33086
  const childIssues = selectedGroupChildPlans(plan, value).flatMap((childPlan) => validateNormalizedFieldValue(childPlan, value[childPlan.fieldId], childCtx));
32951
33087
  if (childIssues.length > 0) return childIssues;
32952
- if (plan.valueContract === "boxBackground" && !boxBackgroundSchema.safeParse(value).success) return [issue(plan, "invalidBoxBackground")];
33088
+ if (plan.valueContract === "boxBackground" && !(ctx.mode === "render" ? runtimeBoxBackgroundSchema : boxBackgroundSchema).safeParse(value).success) return [issue(plan, "invalidBoxBackground")];
32953
33089
  return [];
32954
33090
  }
32955
33091
  function childValidationContext(plan, ctx) {
@@ -33049,11 +33185,16 @@ function fieldPlanToObjectPropertyZod(plan, options = {}) {
33049
33185
  default: return assertNever$4(presence);
33050
33186
  }
33051
33187
  }
33052
- /** Validate stored field values without applying editor/write normalization. */
33053
- function fieldPlanToStoredObjectPropertyZod(plan) {
33054
- const ctx = strictValidationContext({ allowNull: false });
33188
+ /** Validate stored or runtime fields without applying editor/write normalization. */
33189
+ function fieldPlanToStrictObjectPropertyZod(plan, mode = "strict") {
33190
+ const ctx = strictValidationContext({
33191
+ allowNull: false,
33192
+ mode
33193
+ });
33055
33194
  const schema = z.any().superRefine((value, zodCtx) => {
33056
- for (const validationIssue of validateNormalizedFieldValue(plan, value, ctx)) addFieldIssueToZodContext(zodCtx, validationIssue, plan.path);
33195
+ validateNormalizedFieldValue(plan, value, ctx).forEach((validationIssue) => {
33196
+ addFieldIssueToZodContext(zodCtx, validationIssue, plan.path);
33197
+ });
33057
33198
  });
33058
33199
  return plan.required ? schema : schema.optional();
33059
33200
  }
@@ -33256,7 +33397,7 @@ function preprocessEmptyValues(content) {
33256
33397
  function compileManifestContentContract(manifestOrFields) {
33257
33398
  const plans = derivePlansFromManifestOrFields(manifestOrFields);
33258
33399
  const strictOptions = { allowNull: false };
33259
- const strictStoredSchema = deriveStrictStoredZodFromPlans(plans);
33400
+ const strictStoredSchema = deriveStrictContentZodFromPlans(plans);
33260
33401
  return Object.freeze({ [compiledManifestContentContract]: Object.freeze({
33261
33402
  plans,
33262
33403
  strictStoredSchema,
@@ -33266,7 +33407,7 @@ function compileManifestContentContract(manifestOrFields) {
33266
33407
  allowIncomplete: true,
33267
33408
  mode: "draft"
33268
33409
  }, normalizeStoredContentValues),
33269
- renderSchema: strictStoredSchema,
33410
+ renderSchema: deriveStrictContentZodFromPlans(plans, "render"),
33270
33411
  findNonPortableMediaPaths: (content) => findNonPortableMediaPaths(plans, content)
33271
33412
  }) });
33272
33413
  }
@@ -33296,9 +33437,8 @@ function deriveContentZodFromPlans(plans, options) {
33296
33437
  for (const plan of plans) shape[plan.fieldId] = fieldPlanToObjectPropertyZod(plan, options);
33297
33438
  return z.object(shape).catchall(z.unknown()).passthrough();
33298
33439
  }
33299
- function deriveStrictStoredZodFromPlans(plans) {
33300
- const shape = {};
33301
- for (const plan of plans) shape[plan.fieldId] = fieldPlanToStoredObjectPropertyZod(plan);
33440
+ function deriveStrictContentZodFromPlans(plans, mode = "strict") {
33441
+ const shape = Object.fromEntries(plans.map((plan) => [plan.fieldId, fieldPlanToStrictObjectPropertyZod(plan, mode)]));
33302
33442
  return z.object(shape).catchall(z.unknown()).passthrough();
33303
33443
  }
33304
33444
  function derivePlansFromManifestOrFields(manifestOrFields) {
@@ -33322,41 +33462,51 @@ function findNonPortableMediaPaths(plans, content) {
33322
33462
  collectNonPortablePlannedMedia(plans, content, [], paths);
33323
33463
  return [...paths].sort();
33324
33464
  }
33325
- function collectNonPortablePlannedMedia(plans, content, parentPath, paths) {
33465
+ /** One descriptor walker covers references and stored portability, including inactive retained fields. */
33466
+ function visitPlannedMedia(plans, content, parentPath, visit) {
33326
33467
  if (!isPlainRecord(content)) return;
33327
- for (const plan of plans) {
33328
- if (!(plan.fieldId in content)) continue;
33468
+ plans.forEach((plan) => {
33469
+ if (!(plan.fieldId in content)) return;
33329
33470
  const value = content[plan.fieldId];
33330
33471
  const path = [...parentPath, plan.fieldId];
33331
33472
  switch (plan.kind) {
33332
33473
  case "media":
33333
- if (isPlainRecord(value) && hasEnvironmentSpecificMediaField(value)) paths.add(formatFieldPath(path));
33334
- break;
33474
+ visit(isPlainRecord(value) ? {
33475
+ ...value,
33476
+ type: value.type ?? plan.allowedMediaTypes[0]
33477
+ } : value, path, "media");
33478
+ return;
33335
33479
  case "richText":
33336
- collectNonPortableRichTextImages(value, path, paths);
33337
- break;
33480
+ visit(value, path, "richText");
33481
+ return;
33338
33482
  case "group":
33339
- collectNonPortablePlannedMedia(selectedGroupChildPlans(plan, value), value, path, paths);
33340
- break;
33483
+ visitPlannedMedia(allGroupChildPlans(plan), value, path, visit);
33484
+ return;
33341
33485
  case "repeater":
33342
- collectNonPortableRepeaterMedia(plan, value, path, paths);
33343
- break;
33344
- case "string":
33345
- case "number":
33486
+ visitRepeatedMedia(plan, value, path, visit);
33487
+ return;
33346
33488
  case "boolean":
33347
33489
  case "inlineText":
33348
33490
  case "link":
33491
+ case "number":
33492
+ case "passthrough":
33349
33493
  case "select":
33350
- case "passthrough": break;
33494
+ case "string": return;
33351
33495
  }
33352
- }
33496
+ });
33353
33497
  }
33354
- function collectNonPortableRepeaterMedia(plan, value, path, paths) {
33498
+ function visitRepeatedMedia(plan, value, path, visit) {
33355
33499
  if (!Array.isArray(value)) return;
33356
33500
  value.forEach((item, index) => {
33357
33501
  if (!isPlainRecord(item)) return;
33358
- const childPlans = plan.repeatedItemVariants ? plan.repeatedItemVariants.find((variant) => variant.typeId === item._type)?.fields : plan.repeatedItemPlan;
33359
- if (childPlans) collectNonPortablePlannedMedia(childPlans, item, [...path, index], paths);
33502
+ const fields = plan.repeatedItemVariants ? plan.repeatedItemVariants.find((variant) => variant.typeId === item._type)?.fields : plan.repeatedItemPlan;
33503
+ if (fields) visitPlannedMedia(fields, item, [...path, index], visit);
33504
+ });
33505
+ }
33506
+ function collectNonPortablePlannedMedia(plans, content, parentPath, paths) {
33507
+ visitPlannedMedia(plans, content, parentPath, (value, path, kind) => {
33508
+ if (kind === "richText") collectNonPortableRichTextImages(value, path, paths);
33509
+ else if (isPlainRecord(value) && (hasEnvironmentSpecificMediaField(value) || hasNonPortablePoster(value))) paths.add(formatFieldPath(path));
33360
33510
  });
33361
33511
  }
33362
33512
  function collectNonPortableRichTextImages(value, path, paths) {
@@ -33371,6 +33521,10 @@ function isPlainRecord(value) {
33371
33521
  function hasEnvironmentSpecificMediaField(value) {
33372
33522
  return "assetId" in value || "storageBucket" in value || "storagePath" in value || "src" in value || "mimeType" in value || looksLikeUuid(value.id);
33373
33523
  }
33524
+ function hasNonPortablePoster(value) {
33525
+ if (value.poster === void 0) return false;
33526
+ return !mediaPosterSchema.safeParse(value.poster).success;
33527
+ }
33374
33528
  //#endregion
33375
33529
  //#region ../blocks/src/system/designCapabilities.ts
33376
33530
  function declareBlockDesignCapability(capability) {
@@ -35356,6 +35510,12 @@ function parseBackgroundOverlay(value) {
35356
35510
  const result = boxBackgroundOverlaySchema.safeParse(value);
35357
35511
  return result.success ? result.data : void 0;
35358
35512
  }
35513
+ /** Rendering accepts explicit application sources separately from stored references. */
35514
+ const runtimeBackgroundContentSchema = runtimeBoxBackgroundSchema;
35515
+ function parseRuntimeBackgroundContent(value) {
35516
+ const result = runtimeBackgroundContentSchema.safeParse(value);
35517
+ return result.success ? result.data : null;
35518
+ }
35359
35519
  //#endregion
35360
35520
  //#region ../blocks/src/system/transforms/registry/_utils/themeColorResolution.ts
35361
35521
  function resolveBackgroundColorValue(value, context) {
@@ -44330,7 +44490,7 @@ const publicEventBaseSchema = z.object({
44330
44490
  content: z.object({ body: RichTextDocSchema.nullable().optional() }).optional(),
44331
44491
  presentation: z.object({
44332
44492
  summary: z.string().nullable().optional(),
44333
- image: mediaSchema.nullable().optional()
44493
+ image: runtimeMediaSchema.nullable().optional()
44334
44494
  }).optional(),
44335
44495
  slug: z.string(),
44336
44496
  path: z.string().nullable(),
@@ -53597,7 +53757,7 @@ const memberPhotoClassName = (baseClass) => cardRoleChildClass({
53597
53757
  baseClass,
53598
53758
  stylesFrom: "content._cardStyles"
53599
53759
  });
53600
- const teamMemberPhotoSchema = mediaSchema.refine((media) => media.type === "image", { message: "Team member photos must be image media" }).nullable();
53760
+ const teamMemberPhotoSchema = runtimeMediaSchema.refine((media) => media.type === "image", { message: "Team member photos must be image media" }).nullable();
53601
53761
  const teamMemberDataSchema = z.object({
53602
53762
  _type: z.literal("teamMember"),
53603
53763
  id: z.string(),
@@ -55139,11 +55299,14 @@ const offeringsPreviewDatesReadEnabled = {
55139
55299
  //#endregion
55140
55300
  //#region ../blocks/src/system/helpers/backgroundMedia.ts
55141
55301
  function resolveBackgroundMedia(input) {
55142
- const parsedMedia = mediaSchema.safeParse(input.image);
55302
+ const parsedMedia = runtimeMediaSchema.safeParse(input.image);
55143
55303
  if (!parsedMedia.success) return null;
55144
55304
  switch (parsedMedia.data.type) {
55145
55305
  case "image":
55146
- case "video": return parsedMedia.data;
55306
+ case "video": return {
55307
+ ...parsedMedia.data,
55308
+ type: parsedMedia.data.type
55309
+ };
55147
55310
  case "audio":
55148
55311
  case "document":
55149
55312
  case "spreadsheet":
@@ -55155,6 +55318,75 @@ function backgroundVideoMobileClassNames(input) {
55155
55318
  return input.showVideoOnMobile === true ? "" : "rb-hidden rb-md-block";
55156
55319
  }
55157
55320
  //#endregion
55321
+ //#region ../blocks/src/system/runtime/nodes/mediaContext.ts
55322
+ /**
55323
+ * Server-side: AsyncLocalStorage for request isolation.
55324
+ * Prevents race conditions when multiple requests are processed concurrently.
55325
+ *
55326
+ * Lazy initialization to avoid issues in environments that don't support async_hooks.
55327
+ */
55328
+ const serverStorageState = {
55329
+ storage: null,
55330
+ checked: false
55331
+ };
55332
+ function getServerStorage() {
55333
+ if (typeof window !== "undefined") return null;
55334
+ if (serverStorageState.checked) return serverStorageState.storage;
55335
+ serverStorageState.checked = true;
55336
+ try {
55337
+ const globalWithNonWebpackRequire = globalThis;
55338
+ const AsyncLocalStorage = (typeof globalWithNonWebpackRequire.__non_webpack_require__ === "function" ? globalWithNonWebpackRequire.__non_webpack_require__ : new Function("id", "return require(id)"))("async_hooks").AsyncLocalStorage;
55339
+ if (AsyncLocalStorage) {
55340
+ serverStorageState.storage = new AsyncLocalStorage();
55341
+ return serverStorageState.storage;
55342
+ }
55343
+ return null;
55344
+ } catch {
55345
+ if (process.env.NODE_ENV !== "production") console.warn("[blocks] AsyncLocalStorage not available - using module-level state");
55346
+ return null;
55347
+ }
55348
+ }
55349
+ /**
55350
+ * Client-side context storage.
55351
+ * Safe because browsers are single-threaded per tab.
55352
+ *
55353
+ * IMPORTANT: This must be shared across bundles.
55354
+ * SDK preview mode can load multiple independently-bundled entrypoints
55355
+ * (e.g. `@riverbankcms/sdk/rendering` + `@riverbankcms/sdk/preview-next/client`),
55356
+ * which can otherwise each get their own module-scoped singleton.
55357
+ */
55358
+ const RB_MEDIA_CONTEXT_KEY = Symbol.for("riverbankcms.blocks.mediaContext");
55359
+ function getClientContextStore() {
55360
+ const g = globalThis;
55361
+ const existing = g[RB_MEDIA_CONTEXT_KEY];
55362
+ if (existing && typeof existing === "object") return existing;
55363
+ const next = {};
55364
+ g[RB_MEDIA_CONTEXT_KEY] = next;
55365
+ return next;
55366
+ }
55367
+ /**
55368
+ * Get the current media context.
55369
+ * Server-side: Uses AsyncLocalStorage for request isolation.
55370
+ * Client-side: Uses module-level state (safe in single-threaded browser).
55371
+ */
55372
+ function getMediaContext() {
55373
+ const storage = getServerStorage();
55374
+ if (storage) return storage.getStore() ?? {};
55375
+ return getClientContextStore();
55376
+ }
55377
+ function getCurrentResolveImageUrlContext() {
55378
+ const context = getMediaContext();
55379
+ if (!context.supabaseUrl && !context.siteId && !context.mediaAssetIndex) return;
55380
+ return {
55381
+ supabaseUrl: context.supabaseUrl,
55382
+ siteId: context.siteId,
55383
+ mediaAssetIndex: context.mediaAssetIndex
55384
+ };
55385
+ }
55386
+ function getMediaAssetIndex(context) {
55387
+ return context?.mediaAssetIndex ?? getMediaContext().mediaAssetIndex;
55388
+ }
55389
+ //#endregion
55158
55390
  //#region ../blocks/src/system/runtime/nodes/media.tsx
55159
55391
  function getValidSourceDimension(value) {
55160
55392
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
@@ -55190,41 +55422,72 @@ function applyRectTransform(existingStyle, patch) {
55190
55422
  if (patch.transform) next.transform = appendTransform(existingStyle?.transform, patch.transform);
55191
55423
  return next;
55192
55424
  }
55193
- function computeMediaTransformStyle(value, style, targetAspectRatio, options) {
55425
+ /** Resolve portable content without exposing runtime metadata as saved values. */
55426
+ function resolveMediaWithContext(reference, context) {
55427
+ return resolveManagedMediaReference(reference, getMediaAssetIndex(context ?? void 0));
55428
+ }
55429
+ function sourceFromAsset(value, asset) {
55430
+ return {
55431
+ type: value.type,
55432
+ alt: value.alt,
55433
+ filename: value.filename,
55434
+ purpose: value.purpose,
55435
+ placeholder: value.placeholder,
55436
+ transform: value.transform,
55437
+ poster: value.poster,
55438
+ identifier: asset.identifier,
55439
+ assetId: asset.id,
55440
+ storageBucket: asset.storageBucket,
55441
+ storagePath: asset.storagePath,
55442
+ mimeType: asset.mimeType,
55443
+ width: asset.width,
55444
+ height: asset.height
55445
+ };
55446
+ }
55447
+ function resolveRuntimeMedia(value, context) {
55448
+ if ("asset" in value && value.asset) return sourceFromAsset(value, value.asset);
55449
+ if ("src" in value && value.src) return value;
55450
+ if (!value.identifier) return void 0;
55451
+ const resolved = resolveMediaWithContext(value, context);
55452
+ return resolved.kind === "resolved" ? sourceFromAsset(resolved.reference, resolved.asset) : void 0;
55453
+ }
55454
+ function usesProxyFraming(source, transform) {
55455
+ if (!source?.assetId || !isExplicitCropProxyEnabled()) return false;
55456
+ return Boolean(transform.rotation) || isExplicitRectCrop(transform.rect, getValidSourceDimension(source.width), getValidSourceDimension(source.height));
55457
+ }
55458
+ function rectFramingPatch(source, rect, proxy, style) {
55459
+ if (!source || !rect || proxy) return {};
55460
+ const patch = buildCssRectStylePatch(source, rect);
55461
+ return patch ? applyRectTransform(style, patch) : {};
55462
+ }
55463
+ function hotspotFramingPatch(transform, proxy, rectPatch, style) {
55464
+ if (!transform.hotspot || rectPatch.objectPosition !== void 0) return {};
55465
+ const fit = style?.objectFit;
55466
+ if (fit && fit !== "cover" && fit !== "contain") return {};
55467
+ const point = proxy && transform.rotation ? rotateNormalizedPoint(transform.hotspot, transform.rotation) : transform.hotspot;
55468
+ return { objectPosition: `${point.x * 100}% ${point.y * 100}%` };
55469
+ }
55470
+ function rotationFramingPatch(rotation, proxy, rectPatch, style) {
55471
+ if (!rotation || proxy) return {};
55472
+ return {
55473
+ transform: appendTransform(rectPatch.transform ?? style?.transform, `rotate(${rotation}deg)`),
55474
+ transformOrigin: rectPatch.transformOrigin ?? "center"
55475
+ };
55476
+ }
55477
+ /** CSS framing is a pure projection of the resolved source and per-use transform. */
55478
+ function deriveMediaFramingStyle(source, transform, proxy, style) {
55479
+ if (!transform.rect && !transform.hotspot && !transform.rotation) return style;
55480
+ const rectPatch = rectFramingPatch(source, transform.rect, proxy, style);
55481
+ return mergeStyles(style, {
55482
+ ...rectPatch,
55483
+ ...hotspotFramingPatch(transform, proxy, rectPatch, style),
55484
+ ...rotationFramingPatch(transform.rotation, proxy, rectPatch, style)
55485
+ });
55486
+ }
55487
+ function computeMediaTransformStyle(value, style, targetAspectRatio, options, context) {
55488
+ const source = resolveRuntimeMedia(value, context ?? getCurrentResolveImageUrlContext());
55194
55489
  const transform = options?.resolvedTransform ?? resolveMediaTransformForAspect(value.transform, targetAspectRatio);
55195
- const rect = transform.rect;
55196
- const hotspot = transform.hotspot;
55197
- const rotation = transform.rotation;
55198
- if (!rect && !hotspot && !rotation) return style;
55199
- const stylePatch = {};
55200
- const heuristicSuppressCss = Boolean(isExplicitCropProxyEnabled() && value.assetId && (typeof rotation === "number" && rotation !== 0 || isExplicitRectCrop(rect, getValidSourceDimension(value.width), getValidSourceDimension(value.height))));
55201
- const shouldSuppressCss = options?.isProxy ?? heuristicSuppressCss;
55202
- if (rect && !shouldSuppressCss) {
55203
- const rectPatch = buildCssRectStylePatch(value, rect);
55204
- if (rectPatch) {
55205
- const mergedRect = applyRectTransform(style, rectPatch);
55206
- Object.assign(stylePatch, mergedRect);
55207
- }
55208
- }
55209
- if (hotspot) {
55210
- const effectiveObjectFit = stylePatch.objectFit ?? style?.objectFit;
55211
- if ((!effectiveObjectFit || effectiveObjectFit === "cover" || effectiveObjectFit === "contain") && stylePatch.objectPosition === void 0) {
55212
- const resolved = shouldSuppressCss && rotation ? rotateNormalizedPoint({
55213
- x: hotspot.x,
55214
- y: hotspot.y
55215
- }, rotation) : {
55216
- x: hotspot.x,
55217
- y: hotspot.y
55218
- };
55219
- stylePatch.objectPosition = `${resolved.x * 100}% ${resolved.y * 100}%`;
55220
- }
55221
- }
55222
- if (rotation && !shouldSuppressCss) {
55223
- const existingTransform = stylePatch.transform ?? style?.transform;
55224
- stylePatch.transform = existingTransform ? `${existingTransform} rotate(${rotation}deg)` : `rotate(${rotation}deg)`;
55225
- if (!stylePatch.transformOrigin) stylePatch.transformOrigin = "center";
55226
- }
55227
- return mergeStyles(style, stylePatch);
55490
+ return deriveMediaFramingStyle(source, transform, options?.isProxy ?? usesProxyFraming(source, transform), style);
55228
55491
  }
55229
55492
  //#endregion
55230
55493
  //#region ../blocks/src/system/transforms/registry/background.ts
@@ -55373,11 +55636,11 @@ const backgroundTransforms = [
55373
55636
  }
55374
55637
  ];
55375
55638
  function parseMediaBackground(value) {
55376
- const background = parseBackgroundContent(value);
55639
+ const background = parseRuntimeBackgroundContent(value);
55377
55640
  return background?.type === "image" || background?.type === "video" ? background : null;
55378
55641
  }
55379
55642
  function resolveBackgroundLayerStyle(value, fallbackToken, context) {
55380
- const background = parseBackgroundContent(value);
55643
+ const background = parseRuntimeBackgroundContent(value);
55381
55644
  const style = {};
55382
55645
  const gradient = background?.type === "gradient" ? isString(background.gradient) ? background.gradient.trim() : gradientPresetCss(background.gradientPresetId) : null;
55383
55646
  const color = background?.type === "color" && isString(background.color) ? background.color.trim() : null;