medusa-storefront-data 2.4.0 → 2.5.1

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 (125) hide show
  1. package/HOMEPAGE_CONFIG.md +38 -4
  2. package/dist/src/dynamic-config-schema/index.d.ts +103 -0
  3. package/dist/src/dynamic-config-schema/index.d.ts.map +1 -0
  4. package/dist/src/dynamic-config-schema/index.js +172 -0
  5. package/dist/src/dynamic-config-schema/sections/about-brand.d.ts +5 -0
  6. package/dist/src/dynamic-config-schema/sections/about-brand.d.ts.map +1 -0
  7. package/dist/src/dynamic-config-schema/sections/about-brand.js +30 -0
  8. package/dist/src/dynamic-config-schema/sections/baptism-picks.d.ts +5 -0
  9. package/dist/src/dynamic-config-schema/sections/baptism-picks.d.ts.map +1 -0
  10. package/dist/src/dynamic-config-schema/sections/baptism-picks.js +17 -0
  11. package/dist/src/dynamic-config-schema/sections/baptism.d.ts +5 -0
  12. package/dist/src/dynamic-config-schema/sections/baptism.d.ts.map +1 -0
  13. package/dist/src/dynamic-config-schema/sections/baptism.js +4 -0
  14. package/dist/src/dynamic-config-schema/sections/blog-posts.d.ts +5 -0
  15. package/dist/src/dynamic-config-schema/sections/blog-posts.d.ts.map +1 -0
  16. package/dist/src/dynamic-config-schema/sections/blog-posts.js +31 -0
  17. package/dist/src/dynamic-config-schema/sections/brand-marquee.d.ts +5 -0
  18. package/dist/src/dynamic-config-schema/sections/brand-marquee.d.ts.map +1 -0
  19. package/dist/src/dynamic-config-schema/sections/brand-marquee.js +9 -0
  20. package/dist/src/dynamic-config-schema/sections/brand-pillars.d.ts +5 -0
  21. package/dist/src/dynamic-config-schema/sections/brand-pillars.d.ts.map +1 -0
  22. package/dist/src/dynamic-config-schema/sections/brand-pillars.js +29 -0
  23. package/dist/src/dynamic-config-schema/sections/category-pills.d.ts +5 -0
  24. package/dist/src/dynamic-config-schema/sections/category-pills.d.ts.map +1 -0
  25. package/dist/src/dynamic-config-schema/sections/category-pills.js +4 -0
  26. package/dist/src/dynamic-config-schema/sections/celebrity-trust.d.ts +5 -0
  27. package/dist/src/dynamic-config-schema/sections/celebrity-trust.d.ts.map +1 -0
  28. package/dist/src/dynamic-config-schema/sections/celebrity-trust.js +4 -0
  29. package/dist/src/dynamic-config-schema/sections/features.d.ts +5 -0
  30. package/dist/src/dynamic-config-schema/sections/features.d.ts.map +1 -0
  31. package/dist/src/dynamic-config-schema/sections/features.js +12 -0
  32. package/dist/src/dynamic-config-schema/sections/hero.d.ts +6 -0
  33. package/dist/src/dynamic-config-schema/sections/hero.d.ts.map +1 -0
  34. package/dist/src/dynamic-config-schema/sections/hero.js +9 -0
  35. package/dist/src/dynamic-config-schema/sections/index.d.ts +24 -0
  36. package/dist/src/dynamic-config-schema/sections/index.d.ts.map +1 -0
  37. package/dist/src/dynamic-config-schema/sections/index.js +23 -0
  38. package/dist/src/dynamic-config-schema/sections/instagram-posts.d.ts +5 -0
  39. package/dist/src/dynamic-config-schema/sections/instagram-posts.d.ts.map +1 -0
  40. package/dist/src/dynamic-config-schema/sections/instagram-posts.js +30 -0
  41. package/dist/src/dynamic-config-schema/sections/loved-by-moms.d.ts +5 -0
  42. package/dist/src/dynamic-config-schema/sections/loved-by-moms.d.ts.map +1 -0
  43. package/dist/src/dynamic-config-schema/sections/loved-by-moms.js +4 -0
  44. package/dist/src/dynamic-config-schema/sections/luxe-favourites.d.ts +5 -0
  45. package/dist/src/dynamic-config-schema/sections/luxe-favourites.d.ts.map +1 -0
  46. package/dist/src/dynamic-config-schema/sections/luxe-favourites.js +4 -0
  47. package/dist/src/dynamic-config-schema/sections/new-arrivals-classic.d.ts +5 -0
  48. package/dist/src/dynamic-config-schema/sections/new-arrivals-classic.d.ts.map +1 -0
  49. package/dist/src/dynamic-config-schema/sections/new-arrivals-classic.js +12 -0
  50. package/dist/src/dynamic-config-schema/sections/new-arrivals.d.ts +5 -0
  51. package/dist/src/dynamic-config-schema/sections/new-arrivals.d.ts.map +1 -0
  52. package/dist/src/dynamic-config-schema/sections/new-arrivals.js +12 -0
  53. package/dist/src/dynamic-config-schema/sections/promo-announcements.d.ts +5 -0
  54. package/dist/src/dynamic-config-schema/sections/promo-announcements.d.ts.map +1 -0
  55. package/dist/src/dynamic-config-schema/sections/promo-announcements.js +16 -0
  56. package/dist/src/dynamic-config-schema/sections/promo-countdown.d.ts +5 -0
  57. package/dist/src/dynamic-config-schema/sections/promo-countdown.d.ts.map +1 -0
  58. package/dist/src/dynamic-config-schema/sections/promo-countdown.js +16 -0
  59. package/dist/src/dynamic-config-schema/sections/shop-by-age.d.ts +5 -0
  60. package/dist/src/dynamic-config-schema/sections/shop-by-age.d.ts.map +1 -0
  61. package/dist/src/dynamic-config-schema/sections/shop-by-age.js +4 -0
  62. package/dist/src/dynamic-config-schema/sections/shop-by-category.d.ts +5 -0
  63. package/dist/src/dynamic-config-schema/sections/shop-by-category.d.ts.map +1 -0
  64. package/dist/src/dynamic-config-schema/sections/shop-by-category.js +4 -0
  65. package/dist/src/dynamic-config-schema/sections/testimonials.d.ts +5 -0
  66. package/dist/src/dynamic-config-schema/sections/testimonials.d.ts.map +1 -0
  67. package/dist/src/dynamic-config-schema/sections/testimonials.js +9 -0
  68. package/dist/src/dynamic-config-schema/sections/theme-dresses.d.ts +5 -0
  69. package/dist/src/dynamic-config-schema/sections/theme-dresses.d.ts.map +1 -0
  70. package/dist/src/dynamic-config-schema/sections/theme-dresses.js +4 -0
  71. package/dist/src/dynamic-config-schema/sections/video-stories.d.ts +5 -0
  72. package/dist/src/dynamic-config-schema/sections/video-stories.d.ts.map +1 -0
  73. package/dist/src/dynamic-config-schema/sections/video-stories.js +24 -0
  74. package/dist/src/dynamic-config-schema/sections/why-choose-us.d.ts +5 -0
  75. package/dist/src/dynamic-config-schema/sections/why-choose-us.d.ts.map +1 -0
  76. package/dist/src/dynamic-config-schema/sections/why-choose-us.js +9 -0
  77. package/dist/src/dynamic-config-schema/shared.d.ts +35 -0
  78. package/dist/src/dynamic-config-schema/shared.d.ts.map +1 -0
  79. package/dist/src/dynamic-config-schema/shared.js +99 -0
  80. package/dist/src/dynamic-config-schema/site-configs.d.ts +11 -0
  81. package/dist/src/dynamic-config-schema/site-configs.d.ts.map +1 -0
  82. package/dist/src/dynamic-config-schema/site-configs.js +70 -0
  83. package/dist/src/server/brand-pillars-from-categories.d.ts +8 -0
  84. package/dist/src/server/brand-pillars-from-categories.d.ts.map +1 -0
  85. package/dist/src/server/brand-pillars-from-categories.js +92 -0
  86. package/dist/src/server/cart.js +20 -20
  87. package/dist/src/server/customer.js +11 -11
  88. package/dist/src/server/dynamic-config-api.d.ts +11 -0
  89. package/dist/src/server/dynamic-config-api.d.ts.map +1 -0
  90. package/dist/src/server/dynamic-config-api.js +46 -0
  91. package/dist/src/server/dynamic-config.d.ts +1 -84
  92. package/dist/src/server/dynamic-config.d.ts.map +1 -1
  93. package/dist/src/server/dynamic-config.js +0 -130
  94. package/dist/src/server/fulfillment.js +3 -3
  95. package/dist/src/server/home.d.ts +4 -15
  96. package/dist/src/server/home.d.ts.map +1 -1
  97. package/dist/src/server/home.js +1 -122
  98. package/dist/src/server/normalize-homepage-config.d.ts +7 -0
  99. package/dist/src/server/normalize-homepage-config.d.ts.map +1 -0
  100. package/dist/src/server/normalize-homepage-config.js +213 -0
  101. package/dist/src/server/orders.js +6 -6
  102. package/dist/src/server/page-input.d.ts.map +1 -1
  103. package/dist/src/server/page-input.js +3 -1
  104. package/dist/src/server/payment-details.js +5 -5
  105. package/dist/src/server/payment.js +2 -2
  106. package/dist/src/server/regions.js +2 -2
  107. package/dist/src/server/shoppable-looks.js +1 -1
  108. package/dist/src/util/store-client.d.ts +0 -2
  109. package/dist/src/util/store-client.d.ts.map +1 -1
  110. package/dist/src/util/store-client.js +0 -2
  111. package/package.json +1 -156
  112. package/src/server/brand-pillars-from-categories.ts +156 -0
  113. package/src/server/cart.ts +20 -20
  114. package/src/server/customer.ts +11 -11
  115. package/src/server/dynamic-config.ts +1 -172
  116. package/src/server/fulfillment.ts +3 -3
  117. package/src/server/home.ts +36 -211
  118. package/src/server/normalize-homepage-config.ts +240 -0
  119. package/src/server/orders.ts +6 -6
  120. package/src/server/page-input.ts +3 -1
  121. package/src/server/payment-details.ts +5 -5
  122. package/src/server/payment.ts +2 -2
  123. package/src/server/regions.ts +2 -2
  124. package/src/server/shoppable-looks.ts +1 -1
  125. package/src/util/store-client.ts +0 -3
@@ -4,7 +4,7 @@ Storefront **packages do not call** `GET /store/dynamic-config`. Segment copy us
4
4
 
5
5
  ## Tree-shakeable imports (one section)
6
6
 
7
- Import **only** the section UI and its loader. No `loadHomePageData`, no `registerAllHomeSections`, no full home barrel.
7
+ Import **only** the section UI and its loader. No full home barrel or global section registry.
8
8
 
9
9
  ```tsx
10
10
  // app/[countryCode]/page.tsx — single hero block
@@ -71,9 +71,29 @@ return (
71
71
  )
72
72
  ```
73
73
 
74
- ### Legacy compose registry
74
+ ### Main project page (no registration)
75
75
 
76
- `medusa-ui-home/home/register-sections` and `loadHomePageData` still exist but pull **every** section avoid for tree-shaking.
76
+ Sections accept props from their matching `load*SectionData` helperno `adaptHomeSection` or `registerAllHomeSections`:
77
+
78
+ ```tsx
79
+ import HeroSection from "medusa-ui-home/sections/hero"
80
+ import WhyChooseUsSection from "medusa-ui-home/sections/whyChooseUs"
81
+ import { loadHeroSectionData } from "medusa-storefront-data/home/sections/hero"
82
+ import { loadWhyChooseUsSectionData } from "medusa-storefront-data/home/sections/whyChooseUs"
83
+
84
+ const pageInput = /* optional CMS overrides */
85
+ const [hero, whyChooseUs] = await Promise.all([
86
+ loadHeroSectionData(countryCode, { pageInput }),
87
+ loadWhyChooseUsSectionData(countryCode, { pageInput }),
88
+ ])
89
+
90
+ return (
91
+ <>
92
+ {hero && <HeroSection {...hero} />}
93
+ {whyChooseUs && <WhyChooseUsSection {...whyChooseUs} />}
94
+ </>
95
+ )
96
+ ```
77
97
 
78
98
  ## Main project dynamic config
79
99
 
@@ -88,12 +108,26 @@ const pageInput = homepageConfigFromDynamicResponse(await getDynamicConfig())
88
108
 
89
109
  Pass `pageInput` only where you need CMS overrides; omit it to use package JSON defaults.
90
110
 
111
+ ## Medusa backend admin schemas (`medusa-ui-home`)
112
+
113
+ UI and dynamic-config schema live in the same section file — import only what you register:
114
+
115
+ ```ts
116
+ import HeroSection, {
117
+ heroHomepageSectionField,
118
+ bannerSlide,
119
+ } from "medusa-ui-home/sections/hero"
120
+ import { whyChooseUsHomepageSectionField } from "medusa-ui-home/sections/whyChooseUs"
121
+ ```
122
+
123
+ Compose `options.configs` in your Medusa project from each section’s `*HomepageSectionField` (and site-level structures you define locally). Merge API responses with `homepageConfigFromDynamicResponse` from `medusa-storefront-data/dynamic-config`.
124
+
91
125
  ## API reference
92
126
 
93
127
  | Export | Use |
94
128
  |--------|-----|
95
129
  | `loadHeroSectionData`, `loadNewArrivalsSectionData`, … | **One section** catalog + copy |
96
- | `loadHomePageData` | All sections (legacy) |
97
130
  | `getDynamicConfig()` | **Main project only** |
131
+ | `get*FromPageInput(pageInput)` | Read CMS copy/banners without fetching |
98
132
  | `homepageConfigFromDynamicResponse(raw)` | Merge API → `pageInput` |
99
133
  | `DEFAULT_PAGE_INPUT` | Package defaults |
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Storefront dynamic-config admin schemas for `medusa-plugin-dynamic-config`.
3
+ * Import in the Medusa backend and pass to `options.configs`.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * import { storefrontDynamicConfig } from "medusa-storefront-data/dynamic-config-schema"
8
+ * import { promoAnnouncementsHomepageSectionField } from "medusa-storefront-data/dynamic-config-schema/sections/promoAnnouncements"
9
+ *
10
+ * export const dynamicConfig = {
11
+ * ...storefrontDynamicConfig,
12
+ * "homepage-sections": {
13
+ * ...storefrontDynamicConfig["homepage-sections"],
14
+ * structure: [
15
+ * promoAnnouncementsHomepageSectionField,
16
+ * // …other sections you enable
17
+ * ],
18
+ * },
19
+ * }
20
+ * ```
21
+ */
22
+ import type { HomepageConfig } from "../server/homepage-config.types";
23
+ import type { DynamicConfigStructureField } from "./shared";
24
+ export * from "./shared";
25
+ export * from "./site-configs";
26
+ export * from "./sections";
27
+ /** All homepage section fields for the `homepage-sections` admin tab. */
28
+ export declare const homepageSectionsStructure: DynamicConfigStructureField[];
29
+ export type StorefrontDynamicConfigEntry = {
30
+ id: string;
31
+ title: string;
32
+ active: boolean;
33
+ structure: DynamicConfigStructureField[];
34
+ };
35
+ /**
36
+ * Plugin `options.configs` — one admin tab per key (matches split storefront API keys).
37
+ */
38
+ export declare const storefrontDynamicConfig: {
39
+ readonly "site-branding": {
40
+ readonly id: "site-branding";
41
+ readonly title: "Site & branding";
42
+ readonly active: true;
43
+ readonly structure: DynamicConfigStructureField[];
44
+ };
45
+ readonly contact: {
46
+ readonly id: "contact";
47
+ readonly title: "Contact";
48
+ readonly active: true;
49
+ readonly structure: DynamicConfigStructureField[];
50
+ };
51
+ readonly "social-links": {
52
+ readonly id: "social-links";
53
+ readonly title: "Social links";
54
+ readonly active: true;
55
+ readonly structure: DynamicConfigStructureField[];
56
+ };
57
+ readonly faqs: {
58
+ readonly id: "faqs";
59
+ readonly title: "FAQs";
60
+ readonly active: true;
61
+ readonly structure: DynamicConfigStructureField[];
62
+ };
63
+ readonly "hero-banners": {
64
+ readonly id: "hero-banners";
65
+ readonly title: "Hero banners";
66
+ readonly active: true;
67
+ readonly structure: DynamicConfigStructureField[];
68
+ };
69
+ readonly "homepage-sections": {
70
+ readonly id: "homepage-sections";
71
+ readonly title: "Homepage sections";
72
+ readonly active: true;
73
+ readonly structure: DynamicConfigStructureField[];
74
+ };
75
+ readonly "promo-bar": {
76
+ readonly id: "promo-bar";
77
+ readonly title: "Promo bar";
78
+ readonly active: true;
79
+ readonly structure: DynamicConfigStructureField[];
80
+ };
81
+ };
82
+ export type StorefrontDynamicConfigShape = {
83
+ site?: {
84
+ logo?: string;
85
+ description?: string;
86
+ contact?: Record<string, unknown>;
87
+ social?: unknown[];
88
+ faqs?: unknown[];
89
+ };
90
+ banners?: Record<string, unknown>;
91
+ sections?: Record<string, unknown>;
92
+ promoBar?: Record<string, unknown>;
93
+ };
94
+ /**
95
+ * Merges split `GET /store/dynamic-config` keys into simplified shape
96
+ * consumed by `normalizeHomepageConfig` / `homepageConfigFromDynamicResponse`.
97
+ */
98
+ export declare function mergeStorefrontDynamicConfig(dynamicConfigResponse: Record<string, unknown>): StorefrontDynamicConfigShape;
99
+ /**
100
+ * Builds legacy `homepage-config` for existing storefront parsers.
101
+ */
102
+ export declare function homepageConfigFromSplitDynamicConfig(dynamicConfigResponse: Record<string, unknown>): HomepageConfig;
103
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dynamic-config-schema/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AASrE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAA;AA2B3D,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA;AAE1B,yEAAyE;AACzE,eAAO,MAAM,yBAAyB,EAAE,2BAA2B,EAwBlE,CAAA;AAED,MAAM,MAAM,4BAA4B,GAAG;IACzC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,OAAO,CAAA;IACf,SAAS,EAAE,2BAA2B,EAAE,CAAA;CACzC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2C6B,CAAA;AAEjE,MAAM,MAAM,4BAA4B,GAAG;IACzC,IAAI,CAAC,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACjC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAA;QAClB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAA;KACjB,CAAA;IACD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC,CAAA;AAaD;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7C,4BAA4B,CA+B9B;AAED;;GAEG;AACH,wBAAgB,oCAAoC,CAClD,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7C,cAAc,CAiChB"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Storefront dynamic-config admin schemas for `medusa-plugin-dynamic-config`.
3
+ * Import in the Medusa backend and pass to `options.configs`.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * import { storefrontDynamicConfig } from "medusa-storefront-data/dynamic-config-schema"
8
+ * import { promoAnnouncementsHomepageSectionField } from "medusa-storefront-data/dynamic-config-schema/sections/promoAnnouncements"
9
+ *
10
+ * export const dynamicConfig = {
11
+ * ...storefrontDynamicConfig,
12
+ * "homepage-sections": {
13
+ * ...storefrontDynamicConfig["homepage-sections"],
14
+ * structure: [
15
+ * promoAnnouncementsHomepageSectionField,
16
+ * // …other sections you enable
17
+ * ],
18
+ * },
19
+ * }
20
+ * ```
21
+ */
22
+ import { contactStructure, faqsStructure, heroBannersStructure, promoBarStructure, siteBrandingStructure, socialLinksStructure, } from "./site-configs";
23
+ import { aboutBrandHomepageSectionField, baptismHomepageSectionField, baptismPicksHomepageSectionField, blogPostsHomepageSectionField, brandMarqueeHomepageSectionField, brandPillarsHomepageSectionField, categoryPillsHomepageSectionField, celebrityTrustHomepageSectionField, featuresHomepageSectionField, heroHomepageSectionField, instagramPostsHomepageSectionField, lovedByMomsHomepageSectionField, luxeFavouritesHomepageSectionField, newArrivalsClassicHomepageSectionField, newArrivalsHomepageSectionField, promoAnnouncementsHomepageSectionField, promoCountdownHomepageSectionField, shopByAgeHomepageSectionField, shopByCategoryHomepageSectionField, testimonialsHomepageSectionField, themeDressesHomepageSectionField, videoStoriesHomepageSectionField, whyChooseUsHomepageSectionField, } from "./sections";
24
+ export * from "./shared";
25
+ export * from "./site-configs";
26
+ export * from "./sections";
27
+ /** All homepage section fields for the `homepage-sections` admin tab. */
28
+ export const homepageSectionsStructure = [
29
+ promoAnnouncementsHomepageSectionField,
30
+ heroHomepageSectionField,
31
+ categoryPillsHomepageSectionField,
32
+ newArrivalsHomepageSectionField,
33
+ newArrivalsClassicHomepageSectionField,
34
+ promoCountdownHomepageSectionField,
35
+ celebrityTrustHomepageSectionField,
36
+ luxeFavouritesHomepageSectionField,
37
+ shopByCategoryHomepageSectionField,
38
+ baptismHomepageSectionField,
39
+ baptismPicksHomepageSectionField,
40
+ themeDressesHomepageSectionField,
41
+ brandMarqueeHomepageSectionField,
42
+ aboutBrandHomepageSectionField,
43
+ testimonialsHomepageSectionField,
44
+ brandPillarsHomepageSectionField,
45
+ instagramPostsHomepageSectionField,
46
+ featuresHomepageSectionField,
47
+ shopByAgeHomepageSectionField,
48
+ whyChooseUsHomepageSectionField,
49
+ lovedByMomsHomepageSectionField,
50
+ videoStoriesHomepageSectionField,
51
+ blogPostsHomepageSectionField,
52
+ ];
53
+ /**
54
+ * Plugin `options.configs` — one admin tab per key (matches split storefront API keys).
55
+ */
56
+ export const storefrontDynamicConfig = {
57
+ "site-branding": {
58
+ id: "site-branding",
59
+ title: "Site & branding",
60
+ active: true,
61
+ structure: siteBrandingStructure,
62
+ },
63
+ contact: {
64
+ id: "contact",
65
+ title: "Contact",
66
+ active: true,
67
+ structure: contactStructure,
68
+ },
69
+ "social-links": {
70
+ id: "social-links",
71
+ title: "Social links",
72
+ active: true,
73
+ structure: socialLinksStructure,
74
+ },
75
+ faqs: {
76
+ id: "faqs",
77
+ title: "FAQs",
78
+ active: true,
79
+ structure: faqsStructure,
80
+ },
81
+ "hero-banners": {
82
+ id: "hero-banners",
83
+ title: "Hero banners",
84
+ active: true,
85
+ structure: heroBannersStructure,
86
+ },
87
+ "homepage-sections": {
88
+ id: "homepage-sections",
89
+ title: "Homepage sections",
90
+ active: true,
91
+ structure: homepageSectionsStructure,
92
+ },
93
+ "promo-bar": {
94
+ id: "promo-bar",
95
+ title: "Promo bar",
96
+ active: true,
97
+ structure: promoBarStructure,
98
+ },
99
+ };
100
+ function asRecord(value) {
101
+ if (value && typeof value === "object" && !Array.isArray(value)) {
102
+ return value;
103
+ }
104
+ return undefined;
105
+ }
106
+ function asArray(value) {
107
+ return Array.isArray(value) ? value : undefined;
108
+ }
109
+ /**
110
+ * Merges split `GET /store/dynamic-config` keys into simplified shape
111
+ * consumed by `normalizeHomepageConfig` / `homepageConfigFromDynamicResponse`.
112
+ */
113
+ export function mergeStorefrontDynamicConfig(dynamicConfigResponse) {
114
+ const legacy = asRecord(dynamicConfigResponse["homepage-config"]);
115
+ if (legacy) {
116
+ return legacy;
117
+ }
118
+ const branding = asRecord(dynamicConfigResponse["site-branding"]);
119
+ const contact = asRecord(dynamicConfigResponse["contact"]);
120
+ const socialRoot = asRecord(dynamicConfigResponse["social-links"]);
121
+ const faqsRoot = asRecord(dynamicConfigResponse["faqs"]);
122
+ const promoBar = asRecord(dynamicConfigResponse["promo-bar"]);
123
+ const social = asArray(socialRoot?.links) ??
124
+ asArray(dynamicConfigResponse["social-links"]) ??
125
+ [];
126
+ const faqs = asArray(faqsRoot?.items) ?? asArray(dynamicConfigResponse["faqs"]) ?? [];
127
+ return {
128
+ site: {
129
+ ...branding,
130
+ contact,
131
+ social,
132
+ faqs,
133
+ },
134
+ banners: asRecord(dynamicConfigResponse["hero-banners"]),
135
+ sections: asRecord(dynamicConfigResponse["homepage-sections"]),
136
+ promoBar,
137
+ };
138
+ }
139
+ /**
140
+ * Builds legacy `homepage-config` for existing storefront parsers.
141
+ */
142
+ export function homepageConfigFromSplitDynamicConfig(dynamicConfigResponse) {
143
+ const merged = mergeStorefrontDynamicConfig(dynamicConfigResponse);
144
+ const site = asRecord(merged.site);
145
+ const banners = asRecord(merged.banners);
146
+ const sections = asRecord(merged.sections);
147
+ const promoBar = asRecord(merged.promoBar);
148
+ const config = {
149
+ logo: site?.logo,
150
+ "website-description": site?.description,
151
+ sections: sections,
152
+ };
153
+ if (banners?.desktop) {
154
+ config["homepage-banner-array"] = banners.desktop;
155
+ }
156
+ if (banners?.mobile) {
157
+ config["app-banner-array"] = banners.mobile;
158
+ }
159
+ if (site?.contact) {
160
+ config["contact-us"] = site.contact;
161
+ }
162
+ if (Array.isArray(site?.social) && site.social.length) {
163
+ config["social-links"] = site.social;
164
+ }
165
+ if (Array.isArray(site?.faqs) && site.faqs.length) {
166
+ config["faq-array"] = site.faqs;
167
+ }
168
+ if (promoBar) {
169
+ config["promo-bar"] = promoBar;
170
+ }
171
+ return config;
172
+ }
@@ -0,0 +1,5 @@
1
+ import { type DynamicConfigStructureField } from "../shared";
2
+ export declare const aboutBrandSectionId: "aboutBrand";
3
+ export declare const aboutBrandDynamicConfigStructure: DynamicConfigStructureField[];
4
+ export declare const aboutBrandHomepageSectionField: DynamicConfigStructureField;
5
+ //# sourceMappingURL=about-brand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"about-brand.d.ts","sourceRoot":"","sources":["../../../../src/dynamic-config-schema/sections/about-brand.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,2BAA2B,EACjC,MAAM,WAAW,CAAA;AAElB,eAAO,MAAM,mBAAmB,EAAG,YAAqB,CAAA;AAExD,eAAO,MAAM,gCAAgC,EAAE,2BAA2B,EAsBvE,CAAA;AAEH,eAAO,MAAM,8BAA8B,EAAE,2BAK5C,CAAA"}
@@ -0,0 +1,30 @@
1
+ import { long, short, } from "../shared";
2
+ export const aboutBrandSectionId = "aboutBrand";
3
+ export const aboutBrandDynamicConfigStructure = [
4
+ short("eyebrow", "Eyebrow"),
5
+ short("title", "Title"),
6
+ long("description", "Description"),
7
+ short("readMoreHref", "Read more link"),
8
+ {
9
+ id: "stats",
10
+ title: "Stats",
11
+ type: "array",
12
+ children: [
13
+ {
14
+ id: "stat",
15
+ title: "Stat",
16
+ type: "object",
17
+ children: [
18
+ short("value", "Value", true),
19
+ short("label", "Label", true),
20
+ ],
21
+ },
22
+ ],
23
+ },
24
+ ];
25
+ export const aboutBrandHomepageSectionField = {
26
+ id: aboutBrandSectionId,
27
+ title: "About brand",
28
+ type: "object",
29
+ children: aboutBrandDynamicConfigStructure,
30
+ };
@@ -0,0 +1,5 @@
1
+ import { type DynamicConfigStructureField } from "../shared";
2
+ export declare const baptismPicksSectionId: "baptismPicks";
3
+ export declare const baptismPicksDynamicConfigStructure: DynamicConfigStructureField[];
4
+ export declare const baptismPicksHomepageSectionField: DynamicConfigStructureField;
5
+ //# sourceMappingURL=baptism-picks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baptism-picks.d.ts","sourceRoot":"","sources":["../../../../src/dynamic-config-schema/sections/baptism-picks.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,2BAA2B,EACjC,MAAM,WAAW,CAAA;AAElB,eAAO,MAAM,qBAAqB,EAAG,cAAuB,CAAA;AAE5D,eAAO,MAAM,kCAAkC,EAAE,2BAA2B,EASzE,CAAA;AAEH,eAAO,MAAM,gCAAgC,EAAE,2BAK9C,CAAA"}
@@ -0,0 +1,17 @@
1
+ import { shoppableLookObject, short, } from "../shared";
2
+ export const baptismPicksSectionId = "baptismPicks";
3
+ export const baptismPicksDynamicConfigStructure = [
4
+ short("title", "Section title"),
5
+ {
6
+ id: "looks",
7
+ title: "Looks",
8
+ type: "array",
9
+ children: [shoppableLookObject],
10
+ },
11
+ ];
12
+ export const baptismPicksHomepageSectionField = {
13
+ id: baptismPicksSectionId,
14
+ title: "Baptism shoppable looks",
15
+ type: "object",
16
+ children: baptismPicksDynamicConfigStructure,
17
+ };
@@ -0,0 +1,5 @@
1
+ import { type DynamicConfigStructureField } from "../shared";
2
+ export declare const baptismSectionId: "baptism";
3
+ export declare const baptismHomepageSectionField: DynamicConfigStructureField;
4
+ export declare const baptismDynamicConfigStructure: DynamicConfigStructureField[];
5
+ //# sourceMappingURL=baptism.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baptism.d.ts","sourceRoot":"","sources":["../../../../src/dynamic-config-schema/sections/baptism.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,WAAW,CAAA;AAElB,eAAO,MAAM,gBAAgB,EAAG,SAAkB,CAAA;AAElD,eAAO,MAAM,2BAA2B,6BAGvC,CAAA;AAED,eAAO,MAAM,6BAA6B,+BACE,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { copyOnlyHomepageSection, } from "../shared";
2
+ export const baptismSectionId = "baptism";
3
+ export const baptismHomepageSectionField = copyOnlyHomepageSection(baptismSectionId, "Baptism collection header");
4
+ export const baptismDynamicConfigStructure = baptismHomepageSectionField.children ?? [];
@@ -0,0 +1,5 @@
1
+ import { type DynamicConfigStructureField } from "../shared";
2
+ export declare const blogPostsSectionId: "blogPosts";
3
+ export declare const blogPostsDynamicConfigStructure: DynamicConfigStructureField[];
4
+ export declare const blogPostsHomepageSectionField: DynamicConfigStructureField;
5
+ //# sourceMappingURL=blog-posts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-posts.d.ts","sourceRoot":"","sources":["../../../../src/dynamic-config-schema/sections/blog-posts.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,2BAA2B,EACjC,MAAM,WAAW,CAAA;AAElB,eAAO,MAAM,kBAAkB,EAAG,WAAoB,CAAA;AAEtD,eAAO,MAAM,+BAA+B,EAAE,2BAA2B,EAsBxE,CAAA;AAED,eAAO,MAAM,6BAA6B,EAAE,2BAK3C,CAAA"}
@@ -0,0 +1,31 @@
1
+ import { file, long, sectionCopyFields, short, } from "../shared";
2
+ export const blogPostsSectionId = "blogPosts";
3
+ export const blogPostsDynamicConfigStructure = [
4
+ ...sectionCopyFields(),
5
+ {
6
+ id: "posts",
7
+ title: "Blog posts",
8
+ type: "array",
9
+ children: [
10
+ {
11
+ id: "blog",
12
+ title: "Post",
13
+ type: "object",
14
+ children: [
15
+ short("title", "Title", true),
16
+ short("href", "Link", true),
17
+ long("excerpt", "Excerpt"),
18
+ short("category", "Category"),
19
+ short("date", "Date"),
20
+ file("image", "Thumbnail"),
21
+ ],
22
+ },
23
+ ],
24
+ },
25
+ ];
26
+ export const blogPostsHomepageSectionField = {
27
+ id: blogPostsSectionId,
28
+ title: "Blog posts",
29
+ type: "object",
30
+ children: blogPostsDynamicConfigStructure,
31
+ };
@@ -0,0 +1,5 @@
1
+ import { type DynamicConfigStructureField } from "../shared";
2
+ export declare const brandMarqueeSectionId: "brandMarquee";
3
+ export declare const brandMarqueeDynamicConfigStructure: DynamicConfigStructureField[];
4
+ export declare const brandMarqueeHomepageSectionField: DynamicConfigStructureField;
5
+ //# sourceMappingURL=brand-marquee.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brand-marquee.d.ts","sourceRoot":"","sources":["../../../../src/dynamic-config-schema/sections/brand-marquee.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,WAAW,CAAA;AAElB,eAAO,MAAM,qBAAqB,EAAG,cAAuB,CAAA;AAE5D,eAAO,MAAM,kCAAkC,EAAE,2BAA2B,EACvD,CAAA;AAErB,eAAO,MAAM,gCAAgC,EAAE,2BAK9C,CAAA"}
@@ -0,0 +1,9 @@
1
+ import { sectionCopyFields, } from "../shared";
2
+ export const brandMarqueeSectionId = "brandMarquee";
3
+ export const brandMarqueeDynamicConfigStructure = sectionCopyFields();
4
+ export const brandMarqueeHomepageSectionField = {
5
+ id: brandMarqueeSectionId,
6
+ title: "Brand marquee",
7
+ type: "object",
8
+ children: brandMarqueeDynamicConfigStructure,
9
+ };
@@ -0,0 +1,5 @@
1
+ import { type DynamicConfigStructureField } from "../shared";
2
+ export declare const brandPillarsSectionId: "brandPillars";
3
+ export declare const brandPillarsDynamicConfigStructure: DynamicConfigStructureField[];
4
+ export declare const brandPillarsHomepageSectionField: DynamicConfigStructureField;
5
+ //# sourceMappingURL=brand-pillars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brand-pillars.d.ts","sourceRoot":"","sources":["../../../../src/dynamic-config-schema/sections/brand-pillars.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,2BAA2B,EACjC,MAAM,WAAW,CAAA;AAElB,eAAO,MAAM,qBAAqB,EAAG,cAAuB,CAAA;AAE5D,eAAO,MAAM,kCAAkC,EAAE,2BAA2B,EAqBzE,CAAA;AAEH,eAAO,MAAM,gCAAgC,EAAE,2BAK9C,CAAA"}
@@ -0,0 +1,29 @@
1
+ import { file, long, sectionCopyFields, short, } from "../shared";
2
+ export const brandPillarsSectionId = "brandPillars";
3
+ export const brandPillarsDynamicConfigStructure = [
4
+ ...sectionCopyFields(),
5
+ {
6
+ id: "pillars",
7
+ title: "Pillars (optional — cards often come from categories)",
8
+ type: "array",
9
+ children: [
10
+ {
11
+ id: "pillar",
12
+ title: "Pillar",
13
+ type: "object",
14
+ children: [
15
+ short("title", "Title", true),
16
+ long("description", "Description", true),
17
+ file("image", "Image"),
18
+ file("icon", "Icon"),
19
+ ],
20
+ },
21
+ ],
22
+ },
23
+ ];
24
+ export const brandPillarsHomepageSectionField = {
25
+ id: brandPillarsSectionId,
26
+ title: "Brand pillars",
27
+ type: "object",
28
+ children: brandPillarsDynamicConfigStructure,
29
+ };
@@ -0,0 +1,5 @@
1
+ import { type DynamicConfigStructureField } from "../shared";
2
+ export declare const categoryPillsSectionId: "categoryPills";
3
+ export declare const categoryPillsHomepageSectionField: DynamicConfigStructureField;
4
+ export declare const categoryPillsDynamicConfigStructure: DynamicConfigStructureField[];
5
+ //# sourceMappingURL=category-pills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"category-pills.d.ts","sourceRoot":"","sources":["../../../../src/dynamic-config-schema/sections/category-pills.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,WAAW,CAAA;AAElB,eAAO,MAAM,sBAAsB,EAAG,eAAwB,CAAA;AAE9D,eAAO,MAAM,iCAAiC,6BACqB,CAAA;AAEnE,eAAO,MAAM,mCAAmC,+BACE,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { copyOnlyHomepageSection, } from "../shared";
2
+ export const categoryPillsSectionId = "categoryPills";
3
+ export const categoryPillsHomepageSectionField = copyOnlyHomepageSection(categoryPillsSectionId, "Category pills");
4
+ export const categoryPillsDynamicConfigStructure = categoryPillsHomepageSectionField.children ?? [];
@@ -0,0 +1,5 @@
1
+ import { type DynamicConfigStructureField } from "../shared";
2
+ export declare const celebrityTrustSectionId: "celebrityTrust";
3
+ export declare const celebrityTrustHomepageSectionField: DynamicConfigStructureField;
4
+ export declare const celebrityTrustDynamicConfigStructure: DynamicConfigStructureField[];
5
+ //# sourceMappingURL=celebrity-trust.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"celebrity-trust.d.ts","sourceRoot":"","sources":["../../../../src/dynamic-config-schema/sections/celebrity-trust.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,WAAW,CAAA;AAElB,eAAO,MAAM,uBAAuB,EAAG,gBAAyB,CAAA;AAEhE,eAAO,MAAM,kCAAkC,6BAG9C,CAAA;AAED,eAAO,MAAM,oCAAoC,+BACE,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { copyOnlyHomepageSection, } from "../shared";
2
+ export const celebrityTrustSectionId = "celebrityTrust";
3
+ export const celebrityTrustHomepageSectionField = copyOnlyHomepageSection(celebrityTrustSectionId, "Celebrity trust");
4
+ export const celebrityTrustDynamicConfigStructure = celebrityTrustHomepageSectionField.children ?? [];
@@ -0,0 +1,5 @@
1
+ import { type DynamicConfigStructureField } from "../shared";
2
+ export declare const featuresSectionId: "features";
3
+ export declare const featuresDynamicConfigStructure: DynamicConfigStructureField[];
4
+ export declare const featuresHomepageSectionField: DynamicConfigStructureField;
5
+ //# sourceMappingURL=features.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../../../src/dynamic-config-schema/sections/features.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,2BAA2B,EACjC,MAAM,WAAW,CAAA;AAElB,eAAO,MAAM,iBAAiB,EAAG,UAAmB,CAAA;AAEpD,eAAO,MAAM,8BAA8B,EAAE,2BAA2B,EAGvE,CAAA;AAED,eAAO,MAAM,4BAA4B,EAAE,2BAK1C,CAAA"}
@@ -0,0 +1,12 @@
1
+ import { featureItemsArray, sectionCopyFields, } from "../shared";
2
+ export const featuresSectionId = "features";
3
+ export const featuresDynamicConfigStructure = [
4
+ ...sectionCopyFields(),
5
+ featureItemsArray,
6
+ ];
7
+ export const featuresHomepageSectionField = {
8
+ id: featuresSectionId,
9
+ title: "Trust features",
10
+ type: "object",
11
+ children: featuresDynamicConfigStructure,
12
+ };
@@ -0,0 +1,6 @@
1
+ import type { DynamicConfigStructureField } from "../shared";
2
+ export declare const heroSectionId: "hero";
3
+ /** Hero carousel copy is configured via `hero-banners`; section block is unused. */
4
+ export declare const heroDynamicConfigStructure: DynamicConfigStructureField[];
5
+ export declare const heroHomepageSectionField: DynamicConfigStructureField;
6
+ //# sourceMappingURL=hero.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hero.d.ts","sourceRoot":"","sources":["../../../../src/dynamic-config-schema/sections/hero.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAA;AAE5D,eAAO,MAAM,aAAa,EAAG,MAAe,CAAA;AAE5C,oFAAoF;AACpF,eAAO,MAAM,0BAA0B,EAAE,2BAA2B,EAAO,CAAA;AAE3E,eAAO,MAAM,wBAAwB,EAAE,2BAKtC,CAAA"}
@@ -0,0 +1,9 @@
1
+ export const heroSectionId = "hero";
2
+ /** Hero carousel copy is configured via `hero-banners`; section block is unused. */
3
+ export const heroDynamicConfigStructure = [];
4
+ export const heroHomepageSectionField = {
5
+ id: heroSectionId,
6
+ title: "Hero (banners use hero-banners config)",
7
+ type: "object",
8
+ children: heroDynamicConfigStructure,
9
+ };