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
@@ -42,42 +42,6 @@ export function getLogoFromPageInput(pageInput) {
42
42
  const config = resolvePageInput(pageInput);
43
43
  return config.logo || null;
44
44
  }
45
- /** @deprecated Fetch in main project; pass `pageInput` into layout/pages instead. */
46
- export const getLogoFromConfig = async () => {
47
- const config = await getDynamicConfig();
48
- return getLogoFromPageInput(config?.["homepage-config"] ?? null);
49
- };
50
- export const getBannerImageFromConfig = async () => {
51
- try {
52
- const config = await getDynamicConfig();
53
- const bannerArray = config?.["homepage-config"]?.["homepage-banner-array"];
54
- if (bannerArray && bannerArray.length > 0) {
55
- const firstBanner = bannerArray[0];
56
- const image = firstBanner?.["homepage-banner"]?.["homepage-banner-image"];
57
- return image || null;
58
- }
59
- return null;
60
- }
61
- catch (error) {
62
- return null;
63
- }
64
- };
65
- export const getMobileBannerFromConfig = async () => {
66
- try {
67
- const config = await getDynamicConfig();
68
- const bannerArray = config?.["homepage-config"]?.["app-banner-array"];
69
- if (bannerArray && bannerArray.length > 0) {
70
- const firstBanner = bannerArray[0];
71
- const image = firstBanner?.["app-banner"]?.["app-banner-image"] || null;
72
- const link = firstBanner?.["app-banner"]?.["app-banner-button-link"] || firstBanner?.["app-banner"]?.["app-banner-link"] || null;
73
- return { image, link };
74
- }
75
- return { image: null, link: null };
76
- }
77
- catch (error) {
78
- return { image: null, link: null };
79
- }
80
- };
81
45
  export function getHomeBannersFromPageInput(pageInput) {
82
46
  const config = resolvePageInput(pageInput);
83
47
  const bannerArray = config["homepage-banner-array"];
@@ -114,31 +78,12 @@ export function getAppBannersFromPageInput(pageInput) {
114
78
  }
115
79
  return null;
116
80
  }
117
- /** @deprecated Pass `pageInput` from main project. */
118
- export const getHomeBannersFromConfig = async () => {
119
- const config = await getDynamicConfig();
120
- return getHomeBannersFromPageInput(config?.["homepage-config"] ?? null);
121
- };
122
- /** @deprecated Pass `pageInput` from main project. */
123
- export const getAppBannersFromConfig = async () => {
124
- const config = await getDynamicConfig();
125
- return getAppBannersFromPageInput(config?.["homepage-config"] ?? null);
126
- };
127
81
  // Legacy function for backward compatibility
128
- export const getMobileBannerImageFromConfig = async () => {
129
- const { image } = await getMobileBannerFromConfig();
130
- return image;
131
- };
132
82
  export function getWebsiteDescriptionFromPageInput(pageInput) {
133
83
  const config = resolvePageInput(pageInput);
134
84
  const desc = config["website-description"] || config["website_description"];
135
85
  return desc || null;
136
86
  }
137
- /** @deprecated Pass `pageInput` from main project. */
138
- export const getWebsiteDescriptionFromConfig = async () => {
139
- const config = await getDynamicConfig();
140
- return getWebsiteDescriptionFromPageInput(config?.["homepage-config"] ?? null);
141
- };
142
87
  /** Why choose us — defaults + `sections.whyChooseUs` override. */
143
88
  export function getFeaturesFromPageInput(pageInput) {
144
89
  const block = getMergedSectionBlock("whyChooseUs", pageInput);
@@ -148,11 +93,6 @@ export function getFeaturesFromPageInput(pageInput) {
148
93
  const features = parseFeatureIconList(featuresRaw);
149
94
  return { title, features };
150
95
  }
151
- /** @deprecated Pass `pageInput` from main project. */
152
- export const getFeaturesFromConfig = async () => {
153
- const config = await getDynamicConfig();
154
- return getFeaturesFromPageInput(config?.["homepage-config"] ?? null);
155
- };
156
96
  function parseFeatureIconList(raw) {
157
97
  if (!Array.isArray(raw))
158
98
  return [];
@@ -280,11 +220,6 @@ export function getHomeSectionsCopyFromPageInput(pageInput) {
280
220
  }
281
221
  return copy;
282
222
  }
283
- /** @deprecated Pass `pageInput` from main project instead of fetching here. */
284
- export const getHomeSectionsCopyFromConfig = async () => {
285
- const config = await getDynamicConfig();
286
- return getHomeSectionsCopyFromPageInput(config?.["homepage-config"] ?? null);
287
- };
288
223
  /** Trust badge row — defaults + `sections.features` override. */
289
224
  export function getTrustFeaturesFromPageInput(pageInput) {
290
225
  const block = getMergedSectionBlock("features", pageInput);
@@ -295,11 +230,6 @@ export function getTrustFeaturesFromPageInput(pageInput) {
295
230
  const features = parseFeatureIconList(rawList);
296
231
  return { title: title ?? null, description: description ?? null, features };
297
232
  }
298
- /** @deprecated Pass `pageInput` from main project. */
299
- export const getTrustFeaturesFromConfig = async () => {
300
- const config = await getDynamicConfig();
301
- return getTrustFeaturesFromPageInput(config?.["homepage-config"] ?? null);
302
- };
303
233
  function normalizeBannerButtonName(value) {
304
234
  const text = normalizeCmsText(value);
305
235
  if (!text)
@@ -325,11 +255,6 @@ export function getContactInfoFromPageInput(pageInput) {
325
255
  address: contactConfig["contact-address"],
326
256
  };
327
257
  }
328
- /** @deprecated Pass `pageInput` from main project. */
329
- export const getContactInfoFromConfig = async () => {
330
- const config = await getDynamicConfig();
331
- return getContactInfoFromPageInput(config?.["homepage-config"] ?? null);
332
- };
333
258
  function normalizeVideoStoryUrl(entry) {
334
259
  if (typeof entry === "string" && entry.trim())
335
260
  return entry.trim();
@@ -368,11 +293,6 @@ export function getVideoStoriesFromPageInput(pageInput) {
368
293
  .filter((url) => Boolean(url));
369
294
  return { title, videoUrls };
370
295
  }
371
- /** @deprecated Pass `pageInput` from main project. */
372
- export const getVideoStoriesFromConfig = async () => {
373
- const config = await getDynamicConfig();
374
- return getVideoStoriesFromPageInput(config?.["homepage-config"] ?? null);
375
- };
376
296
  function parseTestimonialRow(item, index) {
377
297
  if (!item || typeof item !== "object")
378
298
  return null;
@@ -430,11 +350,6 @@ export function getTestimonialsFromPageInput(pageInput) {
430
350
  }
431
351
  return { title, subtitle, testimonials };
432
352
  }
433
- /** @deprecated Pass `pageInput` from main project. */
434
- export const getTestimonialsFromConfig = async () => {
435
- const config = await getDynamicConfig();
436
- return getTestimonialsFromPageInput(config?.["homepage-config"] ?? null);
437
- };
438
353
  export function getSocialLinksFromPageInput(pageInput) {
439
354
  const config = resolvePageInput(pageInput);
440
355
  const socialLinksRaw = config["social-links"] || [];
@@ -450,11 +365,6 @@ export function getSocialLinksFromPageInput(pageInput) {
450
365
  .filter((l) => l.name && l.url);
451
366
  return socialLinks.length > 0 ? socialLinks : null;
452
367
  }
453
- /** @deprecated Pass `pageInput` from main project. */
454
- export const getSocialLinksFromConfig = async () => {
455
- const config = await getDynamicConfig();
456
- return getSocialLinksFromPageInput(config?.["homepage-config"] ?? null);
457
- };
458
368
  export function getFaqsFromPageInput(pageInput) {
459
369
  const config = resolvePageInput(pageInput);
460
370
  const faqsRaw = config["faq-array"] || [];
@@ -480,20 +390,10 @@ export function getFaqsFromPageInput(pageInput) {
480
390
  }));
481
391
  return faqs.length > 0 ? faqs : null;
482
392
  }
483
- /** @deprecated Pass `pageInput` from main project. */
484
- export const getFaqsFromConfig = async () => {
485
- const config = await getDynamicConfig();
486
- return getFaqsFromPageInput(config?.["homepage-config"] ?? null);
487
- };
488
393
  export function getAnnouncementMessagesFromPageInput(pageInput) {
489
394
  const block = getMergedSectionBlock("promoAnnouncements", pageInput);
490
395
  return parseAnnouncementMessages(block);
491
396
  }
492
- /** @deprecated Pass `pageInput` from main project. */
493
- export const getAnnouncementMessagesFromConfig = async () => {
494
- const config = await getDynamicConfig();
495
- return getAnnouncementMessagesFromPageInput(config?.["homepage-config"] ?? null);
496
- };
497
397
  export function getAboutBrandFromPageInput(pageInput) {
498
398
  const homepageConfig = resolvePageInput(pageInput);
499
399
  const merged = getMergedSectionBlock("aboutBrand", pageInput);
@@ -523,11 +423,6 @@ export function getAboutBrandFromPageInput(pageInput) {
523
423
  stats,
524
424
  };
525
425
  }
526
- /** @deprecated Pass `pageInput` from main project. */
527
- export const getAboutBrandFromConfig = async () => {
528
- const config = await getDynamicConfig();
529
- return getAboutBrandFromPageInput(config?.["homepage-config"] ?? null);
530
- };
531
426
  export function getBrandPillarsFromPageInput(pageInput) {
532
427
  const block = getMergedSectionBlock("brandPillars", pageInput);
533
428
  const copy = parseSectionCopy(block);
@@ -547,11 +442,6 @@ export function getBrandPillarsFromPageInput(pageInput) {
547
442
  .filter(Boolean);
548
443
  return { sectionTitle, pillars };
549
444
  }
550
- /** @deprecated Pass `pageInput` from main project. */
551
- export const getBrandPillarsFromConfig = async () => {
552
- const config = await getDynamicConfig();
553
- return getBrandPillarsFromPageInput(config?.["homepage-config"] ?? null);
554
- };
555
445
  export function getBlogPostsFromPageInput(pageInput) {
556
446
  const block = getMergedSectionBlock("blogPosts", pageInput);
557
447
  const raw = block.posts ?? block["blog-posts"] ?? block["blog-array"] ?? [];
@@ -576,11 +466,6 @@ export function getBlogPostsFromPageInput(pageInput) {
576
466
  })
577
467
  .filter(Boolean);
578
468
  }
579
- /** @deprecated Pass `pageInput` from main project. */
580
- export const getBlogPostsFromConfig = async () => {
581
- const config = await getDynamicConfig();
582
- return getBlogPostsFromPageInput(config?.["homepage-config"] ?? null);
583
- };
584
469
  function readPromoCountdownBlock(block) {
585
470
  if (!block || typeof block !== "object") {
586
471
  return {
@@ -617,11 +502,6 @@ export function getPromoCountdownFromPageInput(pageInput) {
617
502
  ctaHref: fromBlock.ctaHref ?? defaults.ctaHref,
618
503
  };
619
504
  }
620
- /** @deprecated Pass `pageInput` from main project. */
621
- export const getPromoCountdownFromConfig = async () => {
622
- const config = await getDynamicConfig();
623
- return getPromoCountdownFromPageInput(config?.["homepage-config"] ?? null);
624
- };
625
505
  function parseInstagramPostRow(item, index) {
626
506
  if (!item || typeof item !== "object")
627
507
  return null;
@@ -680,11 +560,6 @@ export function getInstagramPostsFromPageInput(pageInput) {
680
560
  posts,
681
561
  };
682
562
  }
683
- /** @deprecated Pass `pageInput` from main project. */
684
- export const getInstagramPostsFromConfig = async () => {
685
- const config = await getDynamicConfig();
686
- return getInstagramPostsFromPageInput(config?.["homepage-config"] ?? null);
687
- };
688
563
  export { DEFAULT_HOMEPAGE_SECTIONS, } from "./homepage-section-defaults";
689
564
  export { HOMEPAGE_SECTION_IDS } from "./homepage-config.types";
690
565
  export function getPromoBarFromPageInput(pageInput) {
@@ -696,8 +571,3 @@ export function getPromoBarFromPageInput(pageInput) {
696
571
  const active = Boolean(promoConfig?.["promo-active"]);
697
572
  return { text, code, value, active };
698
573
  }
699
- /** @deprecated Pass `pageInput` from main project. */
700
- export const getPromoBarConfig = async () => {
701
- const config = await getDynamicConfig();
702
- return getPromoBarFromPageInput(config?.["homepage-config"] ?? null);
703
- };
@@ -2,7 +2,7 @@
2
2
  import { sdk } from "../config";
3
3
  import { getAuthHeaders, getCacheOptions } from "../cookies";
4
4
  import { medusaShippingOptionCalculate, medusaShiprocketServiceability, } from "medusa-services/fulfillment";
5
- import { getStoreCartClientOptions } from "../util/store-client";
5
+ import { getStoreClientOptions } from "../util/store-client";
6
6
  export const listCartShippingMethods = async (cartId) => {
7
7
  const headers = {
8
8
  ...(await getAuthHeaders()),
@@ -27,7 +27,7 @@ export const listCartShippingMethods = async (cartId) => {
27
27
  };
28
28
  export const calculatePriceForShippingOption = async (optionId, cartId, data) => {
29
29
  try {
30
- const options = await getStoreCartClientOptions();
30
+ const options = await getStoreClientOptions();
31
31
  const { shipping_option } = await medusaShippingOptionCalculate(optionId, cartId, options, data);
32
32
  return shipping_option;
33
33
  }
@@ -37,7 +37,7 @@ export const calculatePriceForShippingOption = async (optionId, cartId, data) =>
37
37
  };
38
38
  export const getShiprocketServiceability = async (pincode, variant_id, cod = 0) => {
39
39
  try {
40
- const options = await getStoreCartClientOptions();
40
+ const options = await getStoreClientOptions();
41
41
  return await medusaShiprocketServiceability({ pincode, variant_id, cod }, options);
42
42
  }
43
43
  catch {
@@ -1,11 +1,9 @@
1
- import "server-only";
2
- import { HttpTypes } from "@medusajs/types";
3
- import { getRegion } from "./regions";
4
- import type { HomepageConfig } from "./homepage-config.types";
1
+ import type { HttpTypes } from "@medusajs/types";
5
2
  import type { InstagramPostsData, AboutBrandConfig, BrandPillarConfig, BlogPostConfig, HomeSectionsCopy, TrustFeaturesConfig, HomepageBanner } from "./dynamic-config";
6
- import { type ShoppableLook } from "./shoppable-looks";
3
+ import type { ShoppableLook } from "./shoppable-looks";
4
+ /** Shape returned by the legacy `loadHomePageData` loader (removed — use per-section loaders). */
7
5
  export type HomePageData = {
8
- region: Awaited<ReturnType<typeof getRegion>>;
6
+ region: HttpTypes.StoreRegion | null;
9
7
  collections: Array<Record<string, unknown>>;
10
8
  categories: HttpTypes.StoreProductCategory[];
11
9
  newArrivals: HttpTypes.StoreProduct[];
@@ -50,13 +48,4 @@ export type HomePageData = {
50
48
  }>;
51
49
  };
52
50
  };
53
- export type LoadHomePageDataOptions = {
54
- /** Merged `homepage-config` from main project (fetched via dynamic-config API there). */
55
- pageInput?: HomepageConfig | null;
56
- };
57
- /**
58
- * Parallel home page data loader. Catalog APIs run here; segment copy comes from
59
- * `pageInput` (or package JSON defaults) — no dynamic-config fetch in this package.
60
- */
61
- export declare function loadHomePageData(countryCode: string, options?: LoadHomePageDataOptions): Promise<HomePageData | null>;
62
51
  //# sourceMappingURL=home.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"home.d.ts","sourceRoot":"","sources":["../../../src/server/home.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAC;AAiC3B,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC;IAC9C,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5C,UAAU,EAAE,SAAS,CAAC,oBAAoB,EAAE,CAAC;IAC7C,WAAW,EAAE,SAAS,CAAC,YAAY,EAAE,CAAC;IACtC,WAAW,EAAE,SAAS,CAAC,YAAY,EAAE,CAAC;IACtC,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5D,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,cAAc,EAAE;QACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,MAAM,EAAE,OAAO,CAAC;QAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;KACxB,CAAC;IACF,cAAc,EAAE,SAAS,CAAC,YAAY,EAAE,CAAC;IACzC,gBAAgB,EAAE,SAAS,CAAC,YAAY,GAAG,IAAI,CAAC;IAChD,WAAW,EAAE,SAAS,CAAC,YAAY,EAAE,CAAC;IACtC,UAAU,EAAE,SAAS,CAAC,YAAY,EAAE,CAAC;IACrC,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B,aAAa,EAAE,SAAS,CAAC,YAAY,EAAE,CAAC;IACxC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,YAAY,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,iBAAiB,EAAE,CAAA;KAAE,CAAC;IACrE,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,cAAc,EAAE,kBAAkB,CAAC;IACnC,YAAY,EAAE,gBAAgB,CAAC;IAC/B,aAAa,EAAE,mBAAmB,CAAC;IACnC,WAAW,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IACrC,UAAU,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IACpC,mBAAmB,EAAE;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACjD,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,yFAAyF;IACzF,SAAS,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;CACnC,CAAC;AAEF;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAwH9B"}
1
+ {"version":3,"file":"home.d.ts","sourceRoot":"","sources":["../../../src/server/home.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACf,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEtD,kGAAkG;AAClG,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAA;IACpC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAC3C,UAAU,EAAE,SAAS,CAAC,oBAAoB,EAAE,CAAA;IAC5C,WAAW,EAAE,SAAS,CAAC,YAAY,EAAE,CAAA;IACrC,WAAW,EAAE,SAAS,CAAC,YAAY,EAAE,CAAA;IACrC,YAAY,EAAE,OAAO,GAAG,IAAI,CAAA;IAC5B,OAAO,EAAE,OAAO,EAAE,CAAA;IAClB,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAA;IAC3D,oBAAoB,EAAE,MAAM,EAAE,CAAA;IAC9B,cAAc,EAAE;QACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;QACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;QACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;QACpB,MAAM,EAAE,OAAO,CAAA;QACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;QACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KACvB,CAAA;IACD,cAAc,EAAE,SAAS,CAAC,YAAY,EAAE,CAAA;IACxC,gBAAgB,EAAE,SAAS,CAAC,YAAY,GAAG,IAAI,CAAA;IAC/C,WAAW,EAAE,SAAS,CAAC,YAAY,EAAE,CAAA;IACrC,UAAU,EAAE,SAAS,CAAC,YAAY,EAAE,CAAA;IACpC,YAAY,EAAE,aAAa,EAAE,CAAA;IAC7B,aAAa,EAAE,SAAS,CAAC,YAAY,EAAE,CAAA;IACvC,UAAU,EAAE,gBAAgB,CAAA;IAC5B,YAAY,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,iBAAiB,EAAE,CAAA;KAAE,CAAA;IACpE,SAAS,EAAE,cAAc,EAAE,CAAA;IAC3B,cAAc,EAAE,kBAAkB,CAAA;IAClC,YAAY,EAAE,gBAAgB,CAAA;IAC9B,aAAa,EAAE,mBAAmB,CAAA;IAClC,WAAW,EAAE,cAAc,EAAE,GAAG,IAAI,CAAA;IACpC,UAAU,EAAE,cAAc,EAAE,GAAG,IAAI,CAAA;IACnC,mBAAmB,EAAE;QACnB,KAAK,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAChD,CAAA;CACF,CAAA"}
@@ -1,122 +1 @@
1
- import "server-only";
2
- import { listCollections } from "./collections";
3
- import { listCategories } from "./categories";
4
- import { listProductsWithSort, getProductsByTag, listProducts } from "./products";
5
- import { getRegion } from "./regions";
6
- import { fetchRatings } from "medusa-reviews-logic/server";
7
- import { getBaptismPicksLooks, } from "./shoppable-looks";
8
- import { resolveHomeSegmentConfigData } from "./resolve-home-segment-data";
9
- async function productsForCategoryIds(countryCode, categoryIds, limit) {
10
- if (!categoryIds.length)
11
- return [];
12
- try {
13
- const { response } = await listProducts({
14
- countryCode,
15
- queryParams: {
16
- category_id: categoryIds,
17
- limit,
18
- },
19
- });
20
- return response.products ?? [];
21
- }
22
- catch {
23
- return [];
24
- }
25
- }
26
- function categoryIdsMatching(categories, pattern) {
27
- return categories
28
- .filter((c) => pattern.test((c.name || c.handle || "").toLowerCase()))
29
- .map((c) => c.id)
30
- .filter(Boolean);
31
- }
32
- /**
33
- * Parallel home page data loader. Catalog APIs run here; segment copy comes from
34
- * `pageInput` (or package JSON defaults) — no dynamic-config fetch in this package.
35
- */
36
- export async function loadHomePageData(countryCode, options) {
37
- const pageInput = options?.pageInput ?? null;
38
- const segmentConfig = resolveHomeSegmentConfigData(pageInput);
39
- const region = await getRegion(countryCode);
40
- if (!region)
41
- return null;
42
- const [collectionsResult, categoriesResult, newArrivalsResult, bestsellersResult, allRatings, themeByTag, baptismByTag,] = await Promise.all([
43
- listCollections({ fields: "id, handle, title, metadata" }).catch(() => ({
44
- collections: [],
45
- })),
46
- listCategories({
47
- limit: 100,
48
- fields: "id,handle,name,metadata,parent_category_id,*parent_category,*parent_category.parent_category",
49
- }).catch(() => []),
50
- listProductsWithSort({
51
- page: 1,
52
- queryParams: { limit: 12 },
53
- sortBy: "created_at",
54
- countryCode,
55
- }).catch(() => ({ response: { products: [] } })),
56
- getProductsByTag({
57
- tagValue: "bestseller",
58
- limit: 10,
59
- countryCode,
60
- }).catch(() => []),
61
- fetchRatings(),
62
- getProductsByTag({ tagValue: "theme", limit: 8, countryCode }).catch(() => []),
63
- getProductsByTag({ tagValue: "baptism", limit: 12, countryCode }).catch(() => []),
64
- ]);
65
- const categories = (categoriesResult ?? []);
66
- const collections = collectionsResult.collections ?? [];
67
- const newArrivals = newArrivalsResult
68
- .response?.products ?? [];
69
- const bestsellers = (bestsellersResult ?? []);
70
- const girlIds = categoryIdsMatching(categories, /baptism.*girl|girl.*baptism|^girl$/);
71
- const boyIds = categoryIdsMatching(categories, /baptism.*boy|boy.*baptism|^boy$/);
72
- const baptismIds = categoryIdsMatching(categories, /baptism/);
73
- const [baptismGirl, baptismBoy] = await Promise.all([
74
- girlIds.length
75
- ? productsForCategoryIds(countryCode, girlIds, 8)
76
- : baptismByTag.filter((p) => /girl/i.test(p.title || "")).slice(0, 8),
77
- boyIds.length
78
- ? productsForCategoryIds(countryCode, boyIds, 8)
79
- : baptismByTag.filter((p) => /boy/i.test(p.title || "")).slice(0, 8),
80
- ]);
81
- let baptismFallback = [];
82
- if (baptismGirl.length === 0 && baptismBoy.length === 0) {
83
- baptismFallback =
84
- baptismIds.length > 0
85
- ? await productsForCategoryIds(countryCode, baptismIds, 12)
86
- : baptismByTag;
87
- }
88
- const resolvedBaptismGirl = baptismGirl.length > 0 ? baptismGirl : baptismFallback.slice(0, 8);
89
- const resolvedBaptismBoy = baptismBoy.length > 0 ? baptismBoy : baptismFallback.slice(0, 8);
90
- const themeProducts = themeByTag.length > 0
91
- ? themeByTag
92
- : await productsForCategoryIds(countryCode, categoryIdsMatching(categories, /theme/), 8);
93
- const baptismPicksFallback = (baptismByTag.length ? baptismByTag : baptismFallback).slice(0, 8);
94
- const baptismPicks = await getBaptismPicksLooks(countryCode, baptismPicksFallback, pageInput);
95
- return {
96
- region,
97
- collections: collections,
98
- categories,
99
- newArrivals,
100
- bestsellers,
101
- testimonials: segmentConfig.testimonials,
102
- ratings: allRatings ?? [],
103
- videoStories: segmentConfig.videoStories,
104
- announcementMessages: segmentConfig.announcementMessages,
105
- promoCountdown: segmentConfig.promoCountdown,
106
- luxeFavourites: bestsellers.slice(0, 4),
107
- celebrityProduct: bestsellers[0] ?? newArrivals[0] ?? null,
108
- baptismGirl: resolvedBaptismGirl,
109
- baptismBoy: resolvedBaptismBoy,
110
- baptismPicks,
111
- themeProducts,
112
- aboutBrand: segmentConfig.aboutBrand,
113
- brandPillars: segmentConfig.brandPillars,
114
- blogPosts: segmentConfig.blogPosts,
115
- instagramPosts: segmentConfig.instagramPosts,
116
- sectionsCopy: segmentConfig.sectionsCopy,
117
- trustFeatures: segmentConfig.trustFeatures,
118
- homeBanners: segmentConfig.homeBanners,
119
- appBanners: segmentConfig.appBanners,
120
- whyChooseUsFeatures: segmentConfig.whyChooseUsFeatures,
121
- };
122
- }
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { HomepageConfig } from "./homepage-config.types";
2
+ /**
3
+ * Accepts simplified `homepage-config` (site / banners / sections) or legacy shape.
4
+ * Storefront always receives the legacy `HomepageConfig` it already parses.
5
+ */
6
+ export declare function normalizeHomepageConfig(input: unknown): HomepageConfig;
7
+ //# sourceMappingURL=normalize-homepage-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize-homepage-config.d.ts","sourceRoot":"","sources":["../../../src/server/normalize-homepage-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAwM7D;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAmCtE"}
@@ -0,0 +1,213 @@
1
+ function asObject(v) {
2
+ return v && typeof v === "object" && !Array.isArray(v) ? v : null;
3
+ }
4
+ function asArray(v) {
5
+ return Array.isArray(v) ? v : [];
6
+ }
7
+ /** Map simplified banner row → legacy `homepage-banner` / `app-banner` entry. */
8
+ function legacyBannerEntry(row, prefix) {
9
+ const r = asObject(row);
10
+ if (!r)
11
+ return null;
12
+ const image = r.image ?? r[`${prefix}-image`];
13
+ if (!image)
14
+ return null;
15
+ return {
16
+ [prefix]: {
17
+ [`${prefix}-image`]: image,
18
+ [`${prefix}-title`]: r.title ?? r[`${prefix}-title`],
19
+ [`${prefix}-subtitle`]: r.subtitle ?? r[`${prefix}-subtitle`],
20
+ [`${prefix}-description`]: r.description ?? r[`${prefix}-description`],
21
+ [`${prefix}-button-name`]: r.buttonText ?? r.buttonName ?? r[`${prefix}-button-name`],
22
+ [`${prefix}-button-link`]: r.buttonLink ?? r[`${prefix}-button-link`],
23
+ ...(prefix === "app-banner" && r.link != null
24
+ ? { "app-banner-link": r.link }
25
+ : {}),
26
+ },
27
+ };
28
+ }
29
+ function normalizeBanners(site) {
30
+ const banners = asObject(site?.banners) ?? asObject(site);
31
+ const desktopRaw = banners?.desktop ?? banners?.["homepage-banner-array"] ?? site?.["homepage-banner-array"];
32
+ const mobileRaw = banners?.mobile ?? banners?.["app-banner-array"] ?? site?.["app-banner-array"];
33
+ const desktop = asArray(desktopRaw)
34
+ .map((row) => legacyBannerEntry(row, "homepage-banner"))
35
+ .filter(Boolean);
36
+ const mobile = asArray(mobileRaw)
37
+ .map((row) => legacyBannerEntry(row, "app-banner"))
38
+ .filter(Boolean);
39
+ return { desktop, mobile };
40
+ }
41
+ function normalizeContact(site) {
42
+ const c = asObject(site?.contact) ?? asObject(site?.["contact-us"]);
43
+ if (!c)
44
+ return undefined;
45
+ return {
46
+ "contact-phone": c.phone ?? c["contact-phone"],
47
+ "contact-email": c.email ?? c["contact-email"],
48
+ "contact-whatsapp": c.whatsapp ?? c["contact-whatsapp"],
49
+ "contact-address": c.address ?? c["contact-address"],
50
+ };
51
+ }
52
+ function normalizeSocial(site) {
53
+ const raw = site?.social ?? site?.["social-links"];
54
+ return asArray(raw).map((item) => {
55
+ const row = asObject(item?.["social-link"]) ?? asObject(item);
56
+ if (!row)
57
+ return null;
58
+ return {
59
+ "social-link": {
60
+ "social-platform-name": row.name ?? row["social-platform-name"],
61
+ "social-platform-url": row.url ?? row["social-platform-url"],
62
+ "social-platform-icon": row.icon ?? row["social-platform-icon"],
63
+ },
64
+ };
65
+ }).filter(Boolean);
66
+ }
67
+ function normalizeFaqs(site) {
68
+ const raw = site?.faqs ?? site?.["faq-array"];
69
+ return asArray(raw).map((item) => {
70
+ const f = asObject(item?.faq) ?? asObject(item);
71
+ if (!f)
72
+ return null;
73
+ return {
74
+ faq: {
75
+ "faq-category": f.category ?? f["faq-category"],
76
+ "faq-question": f.question ?? f["faq-question"],
77
+ "faq-answer": f.answer ?? f["faq-answer"],
78
+ },
79
+ };
80
+ }).filter(Boolean);
81
+ }
82
+ function normalizeTestimonialItem(item) {
83
+ const r = asObject(item?.testimonial) ?? asObject(item);
84
+ if (!r)
85
+ return null;
86
+ const text = String(r.text ?? r.description ?? "").trim();
87
+ const name = String(r.name ?? "").trim();
88
+ if (!text || !name)
89
+ return null;
90
+ return { text, name, avatar: r.avatar, rating: r.rating };
91
+ }
92
+ function normalizeSections(sections) {
93
+ const out = { ...sections };
94
+ const promoAnnouncements = asObject(sections.promoAnnouncements);
95
+ if (promoAnnouncements?.messages) {
96
+ const messages = asArray(promoAnnouncements.messages)
97
+ .map((m) => {
98
+ if (typeof m === "string")
99
+ return m.trim();
100
+ const row = asObject(m);
101
+ return String(row?.message ?? row?.text ?? "").trim();
102
+ })
103
+ .filter(Boolean);
104
+ out.promoAnnouncements = { ...promoAnnouncements, messages };
105
+ }
106
+ const testimonials = asObject(sections.testimonials);
107
+ if (testimonials) {
108
+ const items = testimonials.items ??
109
+ testimonials.testimonials ??
110
+ testimonials.reviews;
111
+ if (Array.isArray(items)) {
112
+ out.testimonials = {
113
+ ...testimonials,
114
+ items: items.map(normalizeTestimonialItem).filter(Boolean),
115
+ };
116
+ }
117
+ }
118
+ const promo = asObject(sections.promoCountdown);
119
+ if (promo) {
120
+ out.promoCountdown = {
121
+ code: promo.code ?? promo["promo-code"],
122
+ text: promo.text ?? promo.message ?? promo["promo-text"],
123
+ "end-at": promo.endAt ?? promo["end-at"],
124
+ active: promo.active ?? promo["promo-active"],
125
+ "cta-label": promo.ctaLabel ?? promo["cta-label"],
126
+ "cta-href": promo.ctaHref ?? promo["cta-href"],
127
+ };
128
+ }
129
+ const baptism = asObject(sections.baptismPicks);
130
+ if (baptism?.looks) {
131
+ out.baptismPicks = {
132
+ title: baptism.title,
133
+ looks: asArray(baptism.looks).map((look) => {
134
+ const L = asObject(look?.look) ?? asObject(look);
135
+ if (!L)
136
+ return null;
137
+ return {
138
+ image: L.image,
139
+ "product-ids": L.productIds ?? L["product-ids"],
140
+ "product-handles": L.productHandles ?? L["product-handles"],
141
+ };
142
+ }).filter(Boolean),
143
+ };
144
+ }
145
+ const ig = asObject(sections.instagramPosts);
146
+ if (ig) {
147
+ out.instagramPosts = {
148
+ title: ig.title,
149
+ handle: ig.handle,
150
+ "profile-url": ig.profileUrl ?? ig["profile-url"],
151
+ "profile-image": ig.profileImage ?? ig["profile-image"],
152
+ posts: asArray(ig.posts).map((p) => {
153
+ const row = asObject(p?.post) ?? asObject(p);
154
+ return row ? { image: row.image, url: row.url ?? row.link } : null;
155
+ }).filter(Boolean),
156
+ };
157
+ }
158
+ const about = asObject(sections.aboutBrand);
159
+ if (about) {
160
+ out.aboutBrand = {
161
+ eyebrow: about.eyebrow,
162
+ title: about.title,
163
+ description: about.description ?? about.text,
164
+ readMoreHref: about.readMoreHref ?? about["read-more-link"],
165
+ stats: about.stats,
166
+ };
167
+ }
168
+ // brandPillars: title only in simplified CMS (cards from categories in storefront)
169
+ const pillars = asObject(sections.brandPillars);
170
+ if (pillars && !pillars.pillars) {
171
+ out.brandPillars = {
172
+ title: pillars.title,
173
+ description: pillars.description,
174
+ };
175
+ }
176
+ return out;
177
+ }
178
+ /**
179
+ * Accepts simplified `homepage-config` (site / banners / sections) or legacy shape.
180
+ * Storefront always receives the legacy `HomepageConfig` it already parses.
181
+ */
182
+ export function normalizeHomepageConfig(input) {
183
+ if (!input || typeof input !== "object")
184
+ return {};
185
+ const raw = input;
186
+ const site = asObject(raw.site);
187
+ const hasSimplifiedSite = Boolean(site);
188
+ if (!hasSimplifiedSite) {
189
+ return raw;
190
+ }
191
+ const { desktop, mobile } = normalizeBanners(raw);
192
+ const sections = normalizeSections(asObject(raw.sections) ?? {});
193
+ const legacy = {
194
+ logo: site?.logo ?? raw.logo,
195
+ "website-description": site?.description ??
196
+ raw["website-description"],
197
+ sections: sections,
198
+ };
199
+ if (desktop.length)
200
+ legacy["homepage-banner-array"] = desktop;
201
+ if (mobile.length)
202
+ legacy["app-banner-array"] = mobile;
203
+ const contact = normalizeContact(site);
204
+ if (contact)
205
+ legacy["contact-us"] = contact;
206
+ const social = normalizeSocial(site);
207
+ if (social.length)
208
+ legacy["social-links"] = social;
209
+ const faqs = normalizeFaqs(site);
210
+ if (faqs.length)
211
+ legacy["faq-array"] = faqs;
212
+ return legacy;
213
+ }