@riverbankcms/sdk 0.127.0 → 0.128.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 (152) hide show
  1. package/dist/{PreviewEditorSidebar-BXtfF7tp.mjs → PreviewEditorSidebar-Dbvb7GIr.mjs} +9 -33
  2. package/dist/{PreviewEditorUI-Dou73Q0K.mjs → PreviewEditorUI-e9O9l20X.mjs} +3 -3
  3. package/dist/{PreviewQueryProvider-DgFDIwvK.mjs → PreviewQueryProvider-B1kbhaJD.mjs} +1 -1
  4. package/dist/SdkPreviewModeRuntime-BZHt6e9w.mjs +11006 -0
  5. package/dist/{SiteChromeCustomizeContext-DZiDBAYu.mjs → SiteChromeCustomizeContext-CvuGbHJX.mjs} +31619 -1483
  6. package/dist/_dts/ai/src/contracts/proposals.d.ts +288 -36
  7. package/dist/_dts/api/src/bookingClosures.d.ts +19 -3
  8. package/dist/_dts/api/src/bookingManagementEndpoints.d.ts +4 -3
  9. package/dist/_dts/api/src/bookingRecords.d.ts +0 -13
  10. package/dist/_dts/api/src/commercePortalEndpoints.d.ts +2 -2
  11. package/dist/_dts/api/src/communications.d.ts +2 -1
  12. package/dist/_dts/api/src/contactFormSummary.d.ts +15 -0
  13. package/dist/_dts/api/src/contentRuntime.d.ts +2 -5
  14. package/dist/_dts/api/src/endpoints.d.ts +1 -1
  15. package/dist/_dts/api/src/footerSettings.d.ts +11 -0
  16. package/dist/_dts/api/src/index.d.ts +2 -1
  17. package/dist/_dts/api/src/occurrenceScheduling.d.ts +48 -0
  18. package/dist/_dts/api/src/participantMessaging.d.ts +5 -3
  19. package/dist/_dts/api/src/publicExperience/siteEndpoints.d.ts +7 -0
  20. package/dist/_dts/api/src/sdkContracts.d.ts +7 -5
  21. package/dist/_dts/api/src/siteOperations.d.ts +12 -3
  22. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +3 -2
  23. package/dist/_dts/blocks/src/client/form.d.ts +1 -0
  24. package/dist/_dts/blocks/src/client/newsletter-form.d.ts +1 -0
  25. package/dist/_dts/blocks/src/client/site-chrome.d.ts +1 -0
  26. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +4 -8
  27. package/dist/_dts/blocks/src/rendering/server.d.ts +1 -1
  28. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +41 -0
  29. package/dist/_dts/blocks/src/system/blocks/newsletter-signup-destination.d.ts +14 -23
  30. package/dist/_dts/blocks/src/system/blocks/newsletter-signup.d.ts +1 -1
  31. package/dist/_dts/blocks/src/system/blocks/site-footer-runtime.d.ts +109 -23
  32. package/dist/_dts/blocks/src/system/data/loaderEndpoints.d.ts +1 -1
  33. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +42 -108
  34. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +21 -54
  35. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/logic.d.ts +1 -1
  36. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationSurface.d.ts +26 -0
  37. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +8 -0
  38. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +21 -0
  39. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +29 -78
  40. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.server.d.ts +1 -1
  41. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.submission.d.ts +3 -6
  42. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +27 -8
  43. package/dist/_dts/content-editor/src/FooterComposerOverview.d.ts +21 -0
  44. package/dist/_dts/content-editor/src/FooterComposerPanel.d.ts +3 -1
  45. package/dist/_dts/content-editor/src/FooterEngagementEditorFields.d.ts +31 -0
  46. package/dist/_dts/content-editor/src/FooterEngagementEditorPanel.d.ts +17 -0
  47. package/dist/_dts/content-editor/src/footerComposer.d.ts +3 -0
  48. package/dist/_dts/content-editor/src/footerEngagementDraft.d.ts +57 -0
  49. package/dist/_dts/content-editor/src/footerEngagementEditor.d.ts +11 -0
  50. package/dist/_dts/content-editor/src/footerPreviewRuntime.d.ts +13 -0
  51. package/dist/_dts/content-editor/src/index.d.ts +1 -0
  52. package/dist/_dts/content-editor/src/useFooterComposerState.d.ts +35 -0
  53. package/dist/_dts/core/src/footer-arrangement.d.ts +2 -0
  54. package/dist/_dts/core/src/footer-composition-types.d.ts +118 -0
  55. package/dist/_dts/core/src/footer-composition.d.ts +7 -116
  56. package/dist/_dts/core/src/footer-engagement.d.ts +30 -0
  57. package/dist/_dts/core/src/index.d.ts +4 -0
  58. package/dist/_dts/core/src/newsletter-signup-destination.d.ts +38 -0
  59. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +59 -6
  60. package/dist/_dts/db/src/index.d.ts +1 -0
  61. package/dist/_dts/db/src/schemas/forms.d.ts +72 -2
  62. package/dist/_dts/db/src/schemas/standard-contact.d.ts +114 -0
  63. package/dist/_dts/preview-next/src/client/blocks/previewBatchLoaderParams.d.ts +6 -0
  64. package/dist/_dts/preview-next/src/client/preview/EntryEditorPanel.d.ts +2 -5
  65. package/dist/_dts/preview-next/src/client/preview/EntrySlotBlockEditorPanel.d.ts +2 -5
  66. package/dist/_dts/preview-next/src/client/preview/PageBlockEditorPanel.d.ts +2 -5
  67. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +2 -4
  68. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +1 -1
  69. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +2 -4
  70. package/dist/_dts/preview-next/src/client/widgets/widgetOverrides.d.ts +6 -5
  71. package/dist/_dts/sdk/src/cli/commands/push/execute/footer.d.ts +9 -0
  72. package/dist/_dts/sdk/src/cli/content/footerFile.d.ts +10 -0
  73. package/dist/_dts/sdk/src/cli/content/reader.d.ts +3 -5
  74. package/dist/_dts/sdk/src/cli/site-commands/footerCommands.d.ts +15 -3
  75. package/dist/_dts/sdk/src/client/combineAbortSignals.d.ts +2 -0
  76. package/dist/_dts/sdk/src/client/management/types.d.ts +6 -15
  77. package/dist/_dts/sdk/src/client/types.d.ts +10 -2
  78. package/dist/_dts/sdk/src/client/wholeSeriesReadOperations.d.ts +11 -0
  79. package/dist/_dts/sdk/src/config/types.d.ts +1 -1
  80. package/dist/_dts/sdk/src/config/validation.d.ts +3 -0
  81. package/dist/_dts/sdk/src/contracts/event-registration-content.d.ts +16 -0
  82. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +4 -15
  83. package/dist/_dts/sdk/src/public-api/contracts.d.ts +4 -18
  84. package/dist/_dts/sdk/src/public-api/teamMemberContracts.d.ts +17 -0
  85. package/dist/_dts/sdk/src/public-api/wholeSeriesContracts.d.ts +2 -0
  86. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +7 -0
  87. package/dist/_dts/sdk/src/rendering/index.d.ts +5 -3
  88. package/dist/_dts/sdk/src/rendering/mediaAssets.d.ts +8 -2
  89. package/dist/_dts/sdk/src/version.d.ts +1 -1
  90. package/dist/_dts/site-commands/src/commandContract.d.ts +8 -1
  91. package/dist/_dts/site-commands/src/commands.d.ts +16 -2
  92. package/dist/_dts/theme-core/src/header/paintTargets.d.ts +10 -4
  93. package/dist/_dts/theme-core/src/header/surfaceRules.d.ts +2 -3
  94. package/dist/cli/index.mjs +5302 -4628
  95. package/dist/client/{courseRegistration-DTEYWL6Z.mjs → CourseRegistrationWizard-xRmA7REV.mjs} +329 -49
  96. package/dist/client/{DiscountCodeDisclosure-BDFRp8Y7.mjs → DiscountCodeDisclosure-B9vriL5C.mjs} +1 -1
  97. package/dist/client/{EventCombined.client-DJgF1_lf.mjs → EventCombined.client-BgVnVTlz.mjs} +2 -2
  98. package/dist/client/{EventListing.client-CnWGNjOr.mjs → EventListing.client-CqdsO7jO.mjs} +2 -2
  99. package/dist/client/{LeafletStaticMap-BISs9Bl7.mjs → LeafletStaticMap-CKPxot9M.mjs} +1 -1
  100. package/dist/client/{StepIndicator-D8gVYkK-.mjs → StepIndicator-DGCYuBJ1.mjs} +2 -2
  101. package/dist/client/{accordion-DFDajgDz.mjs → accordion-BfN5Eqd-.mjs} +1 -1
  102. package/dist/client/{bookingForm-Bdqj9-52.mjs → bookingForm-DOvCpBFP.mjs} +5 -5
  103. package/dist/client/{carousel-Cvqf-kN8.mjs → carousel-DPNmiH0f.mjs} +1 -1
  104. package/dist/client/{cart-CuH2TJXP.mjs → cart--egVXlrR.mjs} +3 -3
  105. package/dist/client/{checkout-CMNPpejZ.mjs → checkout-DywWtMcq.mjs} +3 -3
  106. package/dist/client/client.mjs +4912 -4613
  107. package/dist/client/courseRegistration-Dk9qFVwt.mjs +46 -0
  108. package/dist/client/{eventCalendar-BW-XoxZ0.mjs → eventCalendar-Bkz2HjlS.mjs} +4 -4
  109. package/dist/client/{eventCombined-Bpn7s0y9.mjs → eventCombined-D4kipYWg.mjs} +2 -2
  110. package/dist/client/{eventDetails-D2uUSTMH.mjs → eventDetails-Dz_5ix2Q.mjs} +56 -35
  111. package/dist/client/{eventListing-CVr1c094.mjs → eventListing-D0vm-zST.mjs} +2 -2
  112. package/dist/client/{eventRegistration-Dv4AvkMw.mjs → eventRegistration-Cw1E4Q4p.mjs} +58 -6
  113. package/dist/client/{form-DxdKf9fs.mjs → form-C2Zf1n3K.mjs} +1 -1
  114. package/dist/client/{headerSection-BaXI5Sro.mjs → headerSection-CP05gzdc.mjs} +2 -2
  115. package/dist/client/hooks.mjs +212 -61
  116. package/dist/client/{locationMap-BEtW2fKz.mjs → locationMap-Cl3x9PYJ.mjs} +2 -2
  117. package/dist/client/{newsletterForm-BKKs0S4R.mjs → newsletterForm-DyEJoClm.mjs} +26 -20
  118. package/dist/client/{pricing-ClkqcElA.mjs → pricing-DGuNR1W4.mjs} +1 -1
  119. package/dist/client/{productDetail-H-ru8dyy.mjs → productDetail-Cq-HrGew.mjs} +3 -3
  120. package/dist/client/{productList-Buyi5c0C.mjs → productList-DbB3jwqd.mjs} +3 -3
  121. package/dist/client/{propsDecoder-BF7i6Ijg.mjs → propsDecoder-CiTuhUwY.mjs} +130 -87
  122. package/dist/client/rendering/client.mjs +416 -208
  123. package/dist/client/rendering/islands.mjs +18 -18
  124. package/dist/client/rendering.mjs +5522 -5237
  125. package/dist/client/{scrollToBlock-D_7t8yWb.mjs → scrollToBlock-CShkRqab.mjs} +1 -1
  126. package/dist/client/{shop-CF7SZQNX.mjs → shop-Cu4Ib-ZA.mjs} +5 -5
  127. package/dist/client/{shop-commerce-DA7_Rq5p.mjs → shop-commerce-BzpsOdh7.mjs} +4 -4
  128. package/dist/client/{shop-commerce-store-BmLqW7Gh.mjs → shop-commerce-store-DaE7Fhj8.mjs} +1 -1
  129. package/dist/client/{shopShared-WL-E1znM.mjs → shopShared-cF0c20vB.mjs} +2 -2
  130. package/dist/client/{useEventFilters-rc8VLeLV.mjs → useEventFilters-QZ3HMgaJ.mjs} +2 -2
  131. package/dist/client/{usePolling-1ncrfd4S.mjs → usePolling-BKf0GcE-.mjs} +2 -2
  132. package/dist/preview-next/before-render.mjs +1 -1
  133. package/dist/preview-next/client/runtime.mjs +4 -4
  134. package/dist/preview-next/middleware.mjs +1 -1
  135. package/dist/{previewAuthStore-Dev9CdG9.mjs → previewAuthStore-BesgU5Xu.mjs} +1 -1
  136. package/dist/{sdk-runtime-BnrCCFJq.mjs → sdk-runtime-Cn_QSCOg.mjs} +2 -2
  137. package/dist/{separator-CFvBx2yl.mjs → separator-CEoGABRc.mjs} +1 -1
  138. package/dist/server/components.mjs +473 -289
  139. package/dist/server/config-validation.mjs +209 -61
  140. package/dist/server/config.mjs +209 -61
  141. package/dist/server/data.mjs +212 -61
  142. package/dist/server/index.mjs +40 -16
  143. package/dist/server/next.mjs +513 -307
  144. package/dist/server/page-converter.mjs +211 -64
  145. package/dist/server/prebuild.mjs +1 -1
  146. package/dist/server/rendering/server.mjs +475 -282
  147. package/dist/server/rendering.mjs +482 -290
  148. package/dist/server/routing.mjs +254 -80
  149. package/dist/server/server.mjs +252 -77
  150. package/package.json +1 -1
  151. package/dist/SdkPreviewModeRuntime-B0HPXr-l.mjs +0 -39546
  152. package/dist/client/MagicLinkForm-b5E_HoG9.mjs +0 -327
@@ -4,6 +4,8 @@ export type FooterEditorTarget = Readonly<{
4
4
  }> | Readonly<{
5
5
  kind: 'module';
6
6
  moduleId: FooterModuleId;
7
+ }> | Readonly<{
8
+ kind: 'engagement';
7
9
  }> | Readonly<{
8
10
  kind: 'shared-profile';
9
11
  section: 'contact' | 'opening-hours' | 'social-links';
@@ -48,6 +50,7 @@ type FooterEditorViewPlanInput = Readonly<{
48
50
  hasLogo?: boolean;
49
51
  hasMainNavigation?: boolean;
50
52
  hasLegalPolicyNavigation?: boolean;
53
+ hasEngagementSource?: boolean;
51
54
  canEdit: boolean;
52
55
  legalRegion?: 'integrated' | 'separate';
53
56
  }>;
@@ -0,0 +1,57 @@
1
+ import { type FooterEngagementSection, type Result } from '../../core/src/index';
2
+ type FooterEngagementDraftBase = Readonly<{
3
+ treatment: FooterEngagementSection['treatment'];
4
+ heading: string;
5
+ intro: string;
6
+ }>;
7
+ type FooterMailingCopyDraft = Readonly<{
8
+ buttonLabel: string;
9
+ successMessage: string;
10
+ privacyNote: string;
11
+ }>;
12
+ export type FooterEngagementDraft = (FooterEngagementDraftBase & Readonly<{
13
+ kind: 'standard-contact';
14
+ formId: string;
15
+ }>) | (FooterEngagementDraftBase & FooterMailingCopyDraft & Readonly<{
16
+ kind: 'mailing-list';
17
+ destination: Readonly<{
18
+ provider: 'riverbank';
19
+ listId: string;
20
+ }> | Readonly<{
21
+ provider: 'mailchimp';
22
+ audienceId: string;
23
+ }>;
24
+ }>);
25
+ export type FooterEngagementDraftEvent = Readonly<{
26
+ type: 'select-kind';
27
+ kind: FooterEngagementDraft['kind'];
28
+ }> | Readonly<{
29
+ type: 'set-treatment';
30
+ treatment: FooterEngagementDraft['treatment'];
31
+ }> | Readonly<{
32
+ type: 'set-heading';
33
+ heading: string;
34
+ }> | Readonly<{
35
+ type: 'set-intro';
36
+ intro: string;
37
+ }> | Readonly<{
38
+ type: 'set-form';
39
+ formId: string;
40
+ }> | Readonly<{
41
+ type: 'select-mailing-provider';
42
+ provider: 'riverbank' | 'mailchimp';
43
+ }> | Readonly<{
44
+ type: 'set-mailing-destination';
45
+ id: string;
46
+ }> | Readonly<{
47
+ type: 'set-mailing-copy';
48
+ field: keyof FooterMailingCopyDraft;
49
+ value: string;
50
+ }>;
51
+ export declare function reduceFooterEngagementDraft(draft: FooterEngagementDraft, event: FooterEngagementDraftEvent): FooterEngagementDraft;
52
+ export declare function createFooterEngagementDraft(section: FooterEngagementSection | null): FooterEngagementDraft;
53
+ type DraftParseError = Readonly<{
54
+ message: string;
55
+ }>;
56
+ export declare function parseFooterEngagementDraft(draft: FooterEngagementDraft, currentId: string, mailchimpConnectionId: string): Result<FooterEngagementSection, DraftParseError>;
57
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { FooterEngagementSection } from '../../core/src/index';
2
+ import type { FooterEngagementAuthoringOptions } from '../../api/src/footer-settings';
3
+ import type { FooterResolvedEngagement } from '../../blocks/src/client/site-chrome';
4
+ export type FooterEngagementReadiness = Readonly<{
5
+ kind: 'ready';
6
+ }> | Readonly<{
7
+ kind: 'needs-repair';
8
+ message: string;
9
+ }>;
10
+ export declare function resolveFooterEngagementAuthoringState(section: FooterEngagementSection | null, options: FooterEngagementAuthoringOptions): FooterEngagementReadiness;
11
+ export declare function resolveFooterEngagementPreview(section: FooterEngagementSection | null, options: FooterEngagementAuthoringOptions): FooterResolvedEngagement;
@@ -0,0 +1,13 @@
1
+ import { type FooterResolvedEngagement, type FooterRuntimeViewModel } from '../../blocks/src/client/site-chrome';
2
+ import type { FooterCompositionV1, PublicProfile } from '../../core/src/index';
3
+ export type FooterPreviewRuntimeInput = Readonly<{
4
+ composition: FooterCompositionV1;
5
+ publicProfile: PublicProfile;
6
+ hasBusinessAddress: boolean;
7
+ hasLogo: boolean;
8
+ hasMainNavigation: boolean;
9
+ hasLegalPolicyNavigation: boolean;
10
+ legalRegion: 'integrated' | 'separate';
11
+ engagement: FooterResolvedEngagement;
12
+ }>;
13
+ export declare function buildFooterPreviewRuntime(input: FooterPreviewRuntimeInput): FooterRuntimeViewModel;
@@ -25,6 +25,7 @@ export { PreviewRichTextEditor } from './primitives/PreviewRichTextEditor';
25
25
  export { recordsEqual as editorValuesEqual } from './ui/stores/utils';
26
26
  export { footerModuleLabel, planFooterEditorView, type FooterEditorSectionPlan, type FooterEditorSource, type FooterEditorTarget, type FooterEditorViewPlan, } from './footerComposer';
27
27
  export { FooterComposerPanel } from './FooterComposerPanel';
28
+ export { resolveFooterEngagementAuthoringState, type FooterEngagementReadiness, } from './footerEngagementEditor';
28
29
  export { useStoreBinding, parseEditorPath } from './primitives/shared';
29
30
  export type { PathInfo } from './primitives/shared';
30
31
  export * from './ai/overlayHelpers';
@@ -0,0 +1,35 @@
1
+ import { type FooterCompositionSnapshot, type PublicProfileSnapshot } from '../../api/src/footer-settings';
2
+ import type { ApiClient } from '../../api/src/request';
3
+ import { type FooterCompositionV1, type PublicProfile } from '../../core/src/index';
4
+ import type { FooterEditorTarget } from './footerComposer';
5
+ export type SaveState = 'idle' | 'saving' | 'saved' | 'conflict' | 'failed';
6
+ export type CompositionSaveOutcome = 'saved' | 'conflict' | 'failed';
7
+ type FooterComposerStateOptions = Readonly<{
8
+ apiClient: ApiClient;
9
+ canEdit: boolean;
10
+ initialTarget?: FooterEditorTarget;
11
+ onSaved?: () => void;
12
+ rawSiteId: string;
13
+ }>;
14
+ export declare function useFooterComposerState({ apiClient, canEdit, initialTarget, onSaved, rawSiteId, }: FooterComposerStateOptions): {
15
+ message: string | null;
16
+ saveComposition: (next: FooterCompositionV1, optimistic?: boolean) => Promise<CompositionSaveOutcome>;
17
+ saveProfile: (next: PublicProfile) => Promise<void>;
18
+ saveState: SaveState;
19
+ siteId: import("../../core/src/index").SiteId;
20
+ target: FooterEditorTarget;
21
+ setTarget: import("react").Dispatch<import("react").SetStateAction<FooterEditorTarget>>;
22
+ compositionSnapshot: FooterCompositionSnapshot | null;
23
+ engagementOptions: Readonly<{
24
+ forms: readonly import("../../api/src/footerSettings").FooterFormSummary[];
25
+ newsletterLists: readonly import("../../api/src/index").NewsletterListRecord[];
26
+ mailchimp: import("../../api/src/index").ListMailchimpAudiencesResponse;
27
+ }> | null;
28
+ load: () => Promise<void>;
29
+ loadError: string | null;
30
+ navigationMenus: import("../../api/src/index").NavigationMenuWithItems[] | null;
31
+ profileSnapshot: PublicProfileSnapshot | null;
32
+ setCompositionSnapshot: import("react").Dispatch<import("react").SetStateAction<FooterCompositionSnapshot | null>>;
33
+ setProfileSnapshot: import("react").Dispatch<import("react").SetStateAction<PublicProfileSnapshot | null>>;
34
+ };
35
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { FooterArrangementPlan, FooterLookPolicy, RenderableFooterSection } from './footer-composition-types';
2
+ export declare function planFooterArrangement(renderableSections: readonly RenderableFooterSection[], policy: FooterLookPolicy): FooterArrangementPlan;
@@ -0,0 +1,118 @@
1
+ import type { Brand } from './branded';
2
+ import type { FooterEngagementSection, FooterEngagementSource } from './footer-engagement';
3
+ import type { RichTextDoc } from './rich-text';
4
+ export type FooterModuleId = Brand<string, 'FooterModuleId'>;
5
+ export type FooterMembershipKey = Brand<string, 'FooterMembershipKey'>;
6
+ export type FooterRichText = RichTextDoc;
7
+ export type FooterNavigationRole = 'main' | 'legal-policy';
8
+ type FooterSectionBase<TKind extends string> = Readonly<{
9
+ id: FooterModuleId;
10
+ kind: TKind;
11
+ heading: string | null;
12
+ selected: boolean;
13
+ }>;
14
+ export type FooterSection = (FooterSectionBase<'brand'> & Readonly<{
15
+ showLogo: boolean;
16
+ showTitle: boolean;
17
+ }>) | (FooterSectionBase<'navigation'> & Readonly<{
18
+ source: Readonly<{
19
+ kind: 'menu-role';
20
+ role: 'main';
21
+ }>;
22
+ }>) | (FooterSectionBase<'legal-navigation'> & Readonly<{
23
+ source: Readonly<{
24
+ kind: 'menu-role';
25
+ role: 'legal-policy';
26
+ }>;
27
+ }>) | (FooterSectionBase<'business-address'> & Readonly<{
28
+ source: Readonly<{
29
+ kind: 'business-address';
30
+ }>;
31
+ }>) | (FooterSectionBase<'contact'> & Readonly<{
32
+ source: Readonly<{
33
+ kind: 'public-profile';
34
+ }>;
35
+ }>) | (FooterSectionBase<'opening-hours'> & Readonly<{
36
+ source: Readonly<{
37
+ kind: 'public-profile';
38
+ }>;
39
+ }>) | (FooterSectionBase<'social-links'> & Readonly<{
40
+ source: Readonly<{
41
+ kind: 'public-profile';
42
+ }>;
43
+ }>) | (FooterSectionBase<'supporting-text'> & Readonly<{
44
+ content: FooterRichText | null;
45
+ }>) | (FooterSectionBase<'legal'> & Readonly<{
46
+ content: FooterRichText | null;
47
+ }>) | FooterEngagementSection;
48
+ export type FooterSectionKind = FooterSection['kind'];
49
+ export type FooterCompositionV1 = Readonly<{
50
+ schemaVersion: 1;
51
+ sections: readonly FooterSection[];
52
+ }>;
53
+ export type FooterCompositionError = Readonly<{
54
+ code: 'invalid_shape' | 'unsupported_schema_version' | 'invalid_section' | 'duplicate_section_id' | 'duplicate_section_kind' | 'unknown_section';
55
+ path: string;
56
+ message: string;
57
+ }>;
58
+ export type FooterLookPolicy = Readonly<{
59
+ kind: 'integrated-legal';
60
+ }> | Readonly<{
61
+ kind: 'separate-legal-region';
62
+ }>;
63
+ export type FooterVisualGroupKind = 'identity' | 'main-navigation' | 'visit' | 'engagement' | 'legal-ending';
64
+ export type FooterColumnCount = 1 | 2 | 3 | 4 | 5;
65
+ export type FooterVisualGroup = Readonly<{
66
+ kind: FooterVisualGroupKind;
67
+ sections: readonly FooterSection[];
68
+ span: 1;
69
+ }>;
70
+ export type FooterRenderRegion = Readonly<{
71
+ kind: 'engagement-row' | 'main' | 'bottom';
72
+ columns: FooterColumnCount;
73
+ groups: readonly FooterVisualGroup[];
74
+ }>;
75
+ export type FooterArrangementPlan = Readonly<{
76
+ membershipKey: FooterMembershipKey;
77
+ regions: readonly FooterRenderRegion[];
78
+ mobileGroups: readonly FooterVisualGroup[];
79
+ }>;
80
+ export type FooterRepairTarget = Readonly<{
81
+ kind: 'site-identity';
82
+ }> | Readonly<{
83
+ kind: 'navigation';
84
+ role: FooterNavigationRole;
85
+ }> | Readonly<{
86
+ kind: 'business-address';
87
+ }> | Readonly<{
88
+ kind: 'engagement-source';
89
+ source: FooterEngagementSource['kind'];
90
+ }> | Readonly<{
91
+ kind: 'public-profile';
92
+ section: 'contact' | 'opening-hours' | 'social-links';
93
+ }> | Readonly<{
94
+ kind: 'footer-section';
95
+ sectionId: FooterModuleId;
96
+ }>;
97
+ export type ResolvedFooterSection = Readonly<{
98
+ kind: 'renderable';
99
+ section: FooterSection;
100
+ }> | Readonly<{
101
+ kind: 'missing-source';
102
+ section: FooterSection;
103
+ repairTarget: FooterRepairTarget;
104
+ }>;
105
+ export type RenderableFooterSection = Extract<ResolvedFooterSection, {
106
+ kind: 'renderable';
107
+ }>;
108
+ export type FooterSourceAvailability = Readonly<{
109
+ hasLogo: boolean;
110
+ hasMainNavigation: boolean;
111
+ hasLegalPolicyNavigation: boolean;
112
+ hasBusinessAddress: boolean;
113
+ hasContact: boolean;
114
+ hasOpeningHours: boolean;
115
+ hasSocialLinks: boolean;
116
+ hasEngagementSource: boolean;
117
+ }>;
118
+ export {};
@@ -1,118 +1,8 @@
1
- import type { Brand } from './branded';
2
- import { type RichTextDoc } from './rich-text';
1
+ import type { FooterCompositionError, FooterCompositionV1, FooterModuleId, FooterSection, FooterSourceAvailability, ResolvedFooterSection } from './footer-composition-types';
2
+ import { type FooterEngagementSection } from './footer-engagement';
3
3
  import { type Result } from './result';
4
- export type FooterModuleId = Brand<string, 'FooterModuleId'>;
5
- export type FooterMembershipKey = Brand<string, 'FooterMembershipKey'>;
6
- export type FooterRichText = RichTextDoc;
7
- export type FooterNavigationRole = 'main' | 'legal-policy';
8
- type FooterSectionBase<TKind extends string> = Readonly<{
9
- id: FooterModuleId;
10
- kind: TKind;
11
- heading: string | null;
12
- selected: boolean;
13
- }>;
14
- export type FooterSection = (FooterSectionBase<'brand'> & Readonly<{
15
- showLogo: boolean;
16
- showTitle: boolean;
17
- }>) | (FooterSectionBase<'navigation'> & Readonly<{
18
- source: Readonly<{
19
- kind: 'menu-role';
20
- role: 'main';
21
- }>;
22
- }>) | (FooterSectionBase<'legal-navigation'> & Readonly<{
23
- source: Readonly<{
24
- kind: 'menu-role';
25
- role: 'legal-policy';
26
- }>;
27
- }>) | (FooterSectionBase<'business-address'> & Readonly<{
28
- source: Readonly<{
29
- kind: 'business-address';
30
- }>;
31
- }>) | (FooterSectionBase<'contact'> & Readonly<{
32
- source: Readonly<{
33
- kind: 'public-profile';
34
- }>;
35
- }>) | (FooterSectionBase<'opening-hours'> & Readonly<{
36
- source: Readonly<{
37
- kind: 'public-profile';
38
- }>;
39
- }>) | (FooterSectionBase<'social-links'> & Readonly<{
40
- source: Readonly<{
41
- kind: 'public-profile';
42
- }>;
43
- }>) | (FooterSectionBase<'supporting-text'> & Readonly<{
44
- content: FooterRichText | null;
45
- }>) | (FooterSectionBase<'legal'> & Readonly<{
46
- content: FooterRichText | null;
47
- }>);
48
- /** Retained as a source-compatible name while callers move from modules to sections. */
49
- export type FooterModule = FooterSection;
50
- export type FooterModuleKind = FooterSection['kind'];
51
- export type FooterCompositionV1 = Readonly<{
52
- schemaVersion: 1;
53
- sections: readonly FooterSection[];
54
- }>;
55
- export type FooterCompositionError = Readonly<{
56
- code: 'invalid_shape' | 'unsupported_schema_version' | 'invalid_section' | 'duplicate_section_id' | 'duplicate_section_kind' | 'unknown_section';
57
- path: string;
58
- message: string;
59
- }>;
60
- export type FooterLookPolicy = Readonly<{
61
- kind: 'integrated-legal';
62
- }> | Readonly<{
63
- kind: 'separate-legal-region';
64
- }>;
65
- export type FooterVisualGroupKind = 'identity' | 'main-navigation' | 'visit' | 'legal-ending';
66
- export type FooterColumnCount = 1 | 2 | 3 | 4;
67
- export type FooterVisualGroup = Readonly<{
68
- kind: FooterVisualGroupKind;
69
- sections: readonly FooterSection[];
70
- span: 1;
71
- }>;
72
- export type FooterRenderRegion = Readonly<{
73
- kind: 'main' | 'bottom';
74
- columns: FooterColumnCount;
75
- groups: readonly FooterVisualGroup[];
76
- }>;
77
- export type FooterArrangementPlan = Readonly<{
78
- membershipKey: FooterMembershipKey;
79
- regions: readonly FooterRenderRegion[];
80
- mobileGroups: readonly FooterVisualGroup[];
81
- }>;
82
- export type FooterRepairTarget = Readonly<{
83
- kind: 'site-identity';
84
- }> | Readonly<{
85
- kind: 'navigation';
86
- role: FooterNavigationRole;
87
- }> | Readonly<{
88
- kind: 'business-address';
89
- }> | Readonly<{
90
- kind: 'public-profile';
91
- section: 'contact' | 'opening-hours' | 'social-links';
92
- }> | Readonly<{
93
- kind: 'footer-section';
94
- sectionId: FooterModuleId;
95
- }>;
96
- export type ResolvedFooterSection = Readonly<{
97
- kind: 'renderable';
98
- section: FooterSection;
99
- }> | Readonly<{
100
- kind: 'missing-source';
101
- section: FooterSection;
102
- repairTarget: FooterRepairTarget;
103
- }>;
104
- export type RenderableFooterSection = Extract<ResolvedFooterSection, {
105
- kind: 'renderable';
106
- }>;
107
- export type FooterSourceAvailability = Readonly<{
108
- hasLogo: boolean;
109
- hasMainNavigation: boolean;
110
- hasLegalPolicyNavigation: boolean;
111
- hasBusinessAddress: boolean;
112
- hasContact: boolean;
113
- hasOpeningHours: boolean;
114
- hasSocialLinks: boolean;
115
- }>;
4
+ export { planFooterArrangement } from './footer-arrangement';
5
+ export type * from './footer-composition-types';
116
6
  export declare function unsafeAsFooterModuleId(value: string): FooterModuleId;
117
7
  export declare function parseFooterModuleId(value: unknown): Result<FooterModuleId, FooterCompositionError>;
118
8
  export declare function validateFooterComposition(composition: FooterCompositionV1): Result<FooterCompositionV1, FooterCompositionError>;
@@ -123,8 +13,10 @@ export declare function parseFooterCompositionV1(value: unknown): Result<FooterC
123
13
  */
124
14
  export declare function upgradePlacementFooterCompositionV1(value: unknown): Result<FooterCompositionV1, FooterCompositionError>;
125
15
  export declare function setFooterSectionSelected(composition: FooterCompositionV1, sectionId: FooterModuleId, selected: boolean): Result<FooterCompositionV1, FooterCompositionError>;
16
+ export declare function parseFooterEngagementSection(value: unknown): Result<FooterEngagementSection, FooterCompositionError>;
17
+ export declare function upsertFooterEngagementSection(composition: FooterCompositionV1, section: FooterEngagementSection): Result<FooterCompositionV1, FooterCompositionError>;
18
+ export declare function removeFooterEngagementSection(composition: FooterCompositionV1): FooterCompositionV1;
126
19
  export declare function resolveFooterSections(composition: FooterCompositionV1, availability: FooterSourceAvailability): readonly ResolvedFooterSection[];
127
- export declare function planFooterArrangement(renderableSections: readonly RenderableFooterSection[], policy: FooterLookPolicy): FooterArrangementPlan;
128
20
  export type FooterEditorOverviewItem = Readonly<{
129
21
  section: FooterSection;
130
22
  status: 'selected' | 'available';
@@ -141,4 +33,3 @@ type LegacyFooterNormalizationOptions = Readonly<{
141
33
  footerVisible?: boolean;
142
34
  }>;
143
35
  export declare function normalizeLegacyFooterContentToV1(value: unknown, options?: LegacyFooterNormalizationOptions): Result<FooterCompositionV1, FooterCompositionError>;
144
- export {};
@@ -0,0 +1,30 @@
1
+ import { type FormId } from './branded';
2
+ import { type NewsletterSignupAuthoringDestination } from './newsletter-signup-destination';
3
+ import { type Result } from './result';
4
+ import type { FooterCompositionError, FooterModuleId } from './footer-composition-types';
5
+ export type FooterEngagementTreatment = 'integrated' | 'separate-row';
6
+ export type FooterEngagementSource = Readonly<{
7
+ kind: 'standard-contact';
8
+ formId: FormId;
9
+ intro: string | null;
10
+ }> | Readonly<{
11
+ kind: 'mailing-list';
12
+ destination: NewsletterSignupAuthoringDestination;
13
+ intro: string | null;
14
+ buttonLabel: string;
15
+ successMessage: string;
16
+ privacyNote: string | null;
17
+ fieldPreset: 'emailOnly';
18
+ }>;
19
+ export type FooterEngagementSection = Readonly<{
20
+ id: FooterModuleId;
21
+ kind: 'engagement';
22
+ heading: string;
23
+ selected: boolean;
24
+ treatment: FooterEngagementTreatment;
25
+ source: FooterEngagementSource;
26
+ }>;
27
+ export declare function parseFooterEngagementSectionValue(value: Readonly<Record<string, unknown>>, sectionBase: Readonly<{
28
+ id: FooterModuleId;
29
+ selected: boolean;
30
+ }>, path: string): Result<FooterEngagementSection, FooterCompositionError>;
@@ -32,6 +32,10 @@ export * from './public-url-validation';
32
32
  export * from './public-profile';
33
33
  export * from './rich-text';
34
34
  export * from './footer-composition';
35
+ export * from './footer-arrangement';
36
+ export * from './footer-composition-types';
37
+ export * from './footer-engagement';
38
+ export * from './newsletter-signup-destination';
35
39
  export * from './number-input';
36
40
  export * from './field-errors';
37
41
  export * from './form-submission-preview';
@@ -0,0 +1,38 @@
1
+ import type { Brand } from './branded';
2
+ import { type Result } from './result';
3
+ export type NewsletterListId = Brand<string, 'NewsletterListId'>;
4
+ export type MailchimpConnectionId = Brand<string, 'MailchimpConnectionId'>;
5
+ export type MailchimpAudienceId = Brand<string, 'MailchimpAudienceId'>;
6
+ export type MailchimpTagName = Brand<string, 'MailchimpTagName'>;
7
+ export type NewsletterSignupDestinationProvider = 'riverbank' | 'mailchimp';
8
+ export type RiverbankNewsletterDestination = Readonly<{
9
+ tag: 'riverbank_list';
10
+ listId: NewsletterListId;
11
+ }>;
12
+ export type MailchimpNewsletterDestination = Readonly<{
13
+ tag: 'mailchimp_audience';
14
+ connectionId: MailchimpConnectionId;
15
+ audienceId: MailchimpAudienceId;
16
+ tags: readonly MailchimpTagName[];
17
+ }>;
18
+ export type NewsletterSignupAuthoringDestination = RiverbankNewsletterDestination | MailchimpNewsletterDestination;
19
+ export type NewsletterSignupDestinationValueError = Readonly<{
20
+ kind: 'invalid-destination-shape';
21
+ }> | Readonly<{
22
+ kind: 'invalid-destination-tag';
23
+ value: unknown;
24
+ }> | Readonly<{
25
+ kind: 'invalid-newsletter-list-id';
26
+ }> | Readonly<{
27
+ kind: 'invalid-mailchimp-connection-id';
28
+ }> | Readonly<{
29
+ kind: 'invalid-mailchimp-audience-id';
30
+ }> | Readonly<{
31
+ kind: 'invalid-mailchimp-tags';
32
+ }>;
33
+ export declare function parseNewsletterListId(value: unknown): NewsletterListId | null;
34
+ export declare function parseMailchimpConnectionId(value: unknown): MailchimpConnectionId | null;
35
+ export declare function parseMailchimpAudienceId(value: unknown): MailchimpAudienceId | null;
36
+ export declare function parseMailchimpTagName(value: unknown): MailchimpTagName | null;
37
+ export declare function parseNewsletterSignupDestinationProvider(value: unknown): NewsletterSignupDestinationProvider | null;
38
+ export declare function parseNewsletterSignupAuthoringDestinationValue(value: unknown): Result<NewsletterSignupAuthoringDestination, NewsletterSignupDestinationValueError>;