medusa-storefront-data 2.0.0 → 2.3.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.
@@ -1,6 +1,7 @@
1
1
  "use server";
2
2
  import { cache } from "react";
3
3
  import { getAuthHeaders } from "../cookies";
4
+ import { DEFAULT_HOMEPAGE_SECTIONS, HOME_SECTION_COPY_ID_LIST, } from "./homepage-section-defaults";
4
5
  export const getDynamicConfig = cache(async () => {
5
6
  try {
6
7
  const publishableKey = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY;
@@ -84,10 +85,10 @@ export const getHomeBannersFromConfig = async () => {
84
85
  const banner = item["homepage-banner"];
85
86
  return {
86
87
  image: banner?.["homepage-banner-image"],
87
- title: banner?.["homepage-banner-title"],
88
- subtitle: banner?.["homepage-banner-subtitle"],
89
- description: banner?.["homepage-banner-description"],
90
- buttonName: banner?.["homepage-banner-button-name"],
88
+ title: normalizeCmsText(banner?.["homepage-banner-title"]),
89
+ subtitle: normalizeCmsText(banner?.["homepage-banner-subtitle"]),
90
+ description: normalizeCmsText(banner?.["homepage-banner-description"]),
91
+ buttonName: normalizeBannerButtonName(banner?.["homepage-banner-button-name"]),
91
92
  buttonLink: banner?.["homepage-banner-button-link"],
92
93
  };
93
94
  });
@@ -107,10 +108,10 @@ export const getAppBannersFromConfig = async () => {
107
108
  const banner = item["app-banner"];
108
109
  return {
109
110
  image: banner?.["app-banner-image"],
110
- title: banner?.["app-banner-title"],
111
- subtitle: banner?.["app-banner-subtitle"],
112
- description: banner?.["app-banner-description"],
113
- buttonName: banner?.["app-banner-button-name"],
111
+ title: normalizeCmsText(banner?.["app-banner-title"]),
112
+ subtitle: normalizeCmsText(banner?.["app-banner-subtitle"]),
113
+ description: normalizeCmsText(banner?.["app-banner-description"]),
114
+ buttonName: normalizeBannerButtonName(banner?.["app-banner-button-name"]),
114
115
  buttonLink: banner?.["app-banner-button-link"],
115
116
  };
116
117
  });
@@ -137,27 +138,220 @@ export const getWebsiteDescriptionFromConfig = async () => {
137
138
  return null;
138
139
  }
139
140
  };
141
+ /** Why choose us — defaults + `sections.whyChooseUs` override. */
140
142
  export const getFeaturesFromConfig = async () => {
141
143
  try {
142
- const config = await getDynamicConfig();
143
- const homepageConfig = config?.["homepage-config"];
144
- if (!homepageConfig)
145
- return null;
146
- const title = homepageConfig["why-choose-us-title"] || "Why Choose Us?";
147
- const featuresRaw = homepageConfig["why-choose-us-features"] || [];
148
- const features = featuresRaw.map((item) => {
149
- const feature = item?.feature || item;
150
- return {
151
- name: feature?.["feature-name"] || "",
152
- icon: feature?.["feature-icon"] || "",
153
- };
154
- }).filter((f) => f.name && f.icon);
144
+ const block = await getMergedSectionBlock("whyChooseUs");
145
+ const copy = parseSectionCopy(block);
146
+ const title = copy.title ?? copy.name ?? "";
147
+ const featuresRaw = block.features ?? block.items ?? [];
148
+ const features = parseFeatureIconList(featuresRaw);
155
149
  return { title, features };
156
150
  }
157
- catch (error) {
158
- return null;
151
+ catch {
152
+ const block = DEFAULT_HOMEPAGE_SECTIONS.whyChooseUs;
153
+ const copy = parseSectionCopy(block);
154
+ return {
155
+ title: copy.title ?? copy.name ?? "",
156
+ features: parseFeatureIconList(block.features ?? []),
157
+ };
158
+ }
159
+ };
160
+ function parseFeatureIconList(raw) {
161
+ if (!Array.isArray(raw))
162
+ return [];
163
+ return raw
164
+ .map((item) => {
165
+ if (!item || typeof item !== "object")
166
+ return null;
167
+ const feature = item.feature ?? item;
168
+ const row = feature;
169
+ const name = normalizeCmsText(row["feature-name"] ?? row.name) ?? "";
170
+ const icon = normalizeCmsText(row["feature-icon"] ?? row.icon) ?? "";
171
+ return name && icon ? { name, icon } : null;
172
+ })
173
+ .filter(Boolean);
174
+ }
175
+ const EMAIL_PATTERN = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
176
+ /** Fix common UTF-8 mojibake from CMS copy-paste (e.g. em dash, apostrophe). */
177
+ function normalizeCmsText(value) {
178
+ if (typeof value !== "string" || !value.trim())
179
+ return undefined;
180
+ return value
181
+ .trim()
182
+ .replace(/ΓÇö/g, "—")
183
+ .replace(/ΓÇÖ/g, "'")
184
+ .replace(/ΓÇ£|ΓÇ¥/g, '"')
185
+ .replace(/≡ƒÿÄ≡ƒæòΓ£¿/g, " 👕✨");
186
+ }
187
+ const EMPTY_SECTION_COPY = {
188
+ title: null,
189
+ name: null,
190
+ text: null,
191
+ description: null,
192
+ subtitle: null,
193
+ eyebrow: null,
194
+ };
195
+ export function parseSectionCopy(block) {
196
+ if (!block || typeof block !== "object")
197
+ return { ...EMPTY_SECTION_COPY };
198
+ const row = block;
199
+ return {
200
+ title: normalizeCmsText(row.title) ?? null,
201
+ name: normalizeCmsText(row.name) ?? null,
202
+ text: normalizeCmsText(row.text) ?? null,
203
+ description: normalizeCmsText(row.description) ?? null,
204
+ subtitle: normalizeCmsText(row.subtitle) ?? null,
205
+ eyebrow: normalizeCmsText(row.eyebrow) ?? null,
206
+ };
207
+ }
208
+ const HOME_SECTION_COPY_IDS = new Set(HOME_SECTION_COPY_ID_LIST);
209
+ function sectionIdFromConfigKey(key) {
210
+ const id = key.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
211
+ return HOME_SECTION_COPY_IDS.has(id) ? id : null;
212
+ }
213
+ async function getHomepageSectionsRoot() {
214
+ const config = await getDynamicConfig();
215
+ const root = config?.["homepage-config"]?.sections;
216
+ return root && typeof root === "object"
217
+ ? root
218
+ : {};
219
+ }
220
+ function findSectionBlock(root, id) {
221
+ for (const [key, value] of Object.entries(root)) {
222
+ if (sectionIdFromConfigKey(key) !== id)
223
+ continue;
224
+ if (value && typeof value === "object") {
225
+ return value;
226
+ }
227
+ if (typeof value === "string") {
228
+ return { text: value };
229
+ }
230
+ }
231
+ return null;
232
+ }
233
+ /** Merge CMS section block onto package defaults (override wins when set). */
234
+ export function mergeSectionBlock(defaults, override) {
235
+ if (!override)
236
+ return { ...defaults };
237
+ const merged = { ...defaults };
238
+ for (const [key, value] of Object.entries(override)) {
239
+ if (value === undefined || value === null)
240
+ continue;
241
+ if (Array.isArray(value)) {
242
+ if (value.length > 0)
243
+ merged[key] = value;
244
+ continue;
245
+ }
246
+ if (typeof value === "string") {
247
+ if (value.trim())
248
+ merged[key] = value.trim();
249
+ continue;
250
+ }
251
+ if (typeof value === "boolean" || typeof value === "number") {
252
+ merged[key] = value;
253
+ continue;
254
+ }
255
+ if (typeof value === "object") {
256
+ const base = merged[key] && typeof merged[key] === "object" && !Array.isArray(merged[key])
257
+ ? merged[key]
258
+ : {};
259
+ merged[key] = mergeSectionBlock(base, value);
260
+ }
261
+ }
262
+ return merged;
263
+ }
264
+ async function getMergedSectionBlock(id) {
265
+ const root = await getHomepageSectionsRoot();
266
+ const defaults = DEFAULT_HOMEPAGE_SECTIONS[id] ?? {};
267
+ const override = findSectionBlock(root, id);
268
+ return mergeSectionBlock({ ...defaults }, override);
269
+ }
270
+ function mergeSectionCopy(base, patch) {
271
+ const pick = (override, fallback) => override ?? fallback;
272
+ return {
273
+ title: pick(patch.title ?? patch.name, base.title ?? base.name),
274
+ name: pick(patch.name, base.name),
275
+ text: pick(patch.text, base.text),
276
+ description: pick(patch.description, base.description),
277
+ subtitle: pick(patch.subtitle, base.subtitle),
278
+ eyebrow: pick(patch.eyebrow, base.eyebrow),
279
+ };
280
+ }
281
+ function parseAnnouncementMessages(block) {
282
+ if (!block)
283
+ return [];
284
+ const raw = block.messages ?? block.items ?? block["announcement-messages"];
285
+ if (!Array.isArray(raw))
286
+ return [];
287
+ return raw
288
+ .map((item) => {
289
+ if (typeof item === "string")
290
+ return item.trim();
291
+ if (item && typeof item === "object") {
292
+ const row = item;
293
+ const nested = (row.message ?? row.text);
294
+ return typeof nested === "string" ? nested.trim() : "";
295
+ }
296
+ return "";
297
+ })
298
+ .filter(Boolean);
299
+ }
300
+ /**
301
+ * Merged section copy: package defaults + `homepage-config.sections` overrides.
302
+ */
303
+ export const getHomeSectionsCopyFromConfig = async () => {
304
+ try {
305
+ const copy = {};
306
+ for (const id of HOME_SECTION_COPY_ID_LIST) {
307
+ const block = await getMergedSectionBlock(id);
308
+ copy[id] = parseSectionCopy(block);
309
+ }
310
+ return copy;
311
+ }
312
+ catch {
313
+ const fallback = {};
314
+ for (const id of HOME_SECTION_COPY_ID_LIST) {
315
+ fallback[id] = parseSectionCopy(DEFAULT_HOMEPAGE_SECTIONS[id]);
316
+ }
317
+ return fallback;
318
+ }
319
+ };
320
+ /** Trust badge row — defaults + `sections.features` override. */
321
+ export const getTrustFeaturesFromConfig = async () => {
322
+ try {
323
+ const block = await getMergedSectionBlock("features");
324
+ const copy = parseSectionCopy(block);
325
+ const title = copy.title ?? copy.name;
326
+ const description = copy.description ?? copy.text;
327
+ const rawList = block.features ?? block.items ?? [];
328
+ const features = parseFeatureIconList(rawList);
329
+ return { title: title ?? null, description: description ?? null, features };
330
+ }
331
+ catch {
332
+ const block = DEFAULT_HOMEPAGE_SECTIONS.features;
333
+ const copy = parseSectionCopy(block);
334
+ return {
335
+ title: copy.title,
336
+ description: copy.description,
337
+ features: parseFeatureIconList(block.features ?? []),
338
+ };
159
339
  }
160
340
  };
341
+ function normalizeBannerButtonName(value) {
342
+ const text = normalizeCmsText(value);
343
+ if (!text)
344
+ return undefined;
345
+ if (/^shop\s+now\s*1$/i.test(text))
346
+ return "Shop Now";
347
+ return text;
348
+ }
349
+ function normalizeConfigEmail(value) {
350
+ if (typeof value !== "string")
351
+ return undefined;
352
+ const trimmed = value.trim();
353
+ return EMAIL_PATTERN.test(trimmed) ? trimmed : undefined;
354
+ }
161
355
  export const getContactInfoFromConfig = async () => {
162
356
  try {
163
357
  const config = await getDynamicConfig();
@@ -167,10 +361,7 @@ export const getContactInfoFromConfig = async () => {
167
361
  }
168
362
  return {
169
363
  phone: contactConfig["contact-phone"],
170
- email: typeof contactConfig["contact-email"] === "string" &&
171
- /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(contactConfig["contact-email"].trim())
172
- ? contactConfig["contact-email"].trim()
173
- : undefined,
364
+ email: normalizeConfigEmail(contactConfig["contact-email"]),
174
365
  address: contactConfig["contact-address"],
175
366
  };
176
367
  }
@@ -178,28 +369,84 @@ export const getContactInfoFromConfig = async () => {
178
369
  return null;
179
370
  }
180
371
  };
372
+ function normalizeVideoStoryUrl(entry) {
373
+ if (typeof entry === "string" && entry.trim())
374
+ return entry.trim();
375
+ if (!entry || typeof entry !== "object")
376
+ return null;
377
+ const row = entry;
378
+ const nested = row["video-story"] ??
379
+ row["video_stories"] ??
380
+ row;
381
+ const url = nested["video-url"] ??
382
+ nested["video_url"] ??
383
+ nested.url ??
384
+ nested.src ??
385
+ nested.video;
386
+ return typeof url === "string" && url.trim() ? url.trim() : null;
387
+ }
388
+ /**
389
+ * Homepage video stories/reviews carousel (`homepage-config.video-stories`).
390
+ */
391
+ export const getVideoStoriesFromConfig = async () => {
392
+ try {
393
+ const config = await getDynamicConfig();
394
+ const homepageConfig = config?.["homepage-config"];
395
+ if (!homepageConfig)
396
+ return null;
397
+ const block = await getMergedSectionBlock("videoStories");
398
+ const copy = parseSectionCopy(block);
399
+ const title = copy.title ?? copy.name ?? "";
400
+ const raw = block["video-urls"] ??
401
+ block.videoUrls ??
402
+ block.videos ??
403
+ block["video-stories"] ??
404
+ homepageConfig["video-stories"] ??
405
+ homepageConfig["video-stories-array"] ??
406
+ homepageConfig["video_stories"] ??
407
+ [];
408
+ const list = Array.isArray(raw) ? raw : [raw];
409
+ const videoUrls = list
410
+ .map(normalizeVideoStoryUrl)
411
+ .filter((url) => Boolean(url));
412
+ return { title, videoUrls };
413
+ }
414
+ catch {
415
+ const block = DEFAULT_HOMEPAGE_SECTIONS.videoStories;
416
+ const copy = parseSectionCopy(block);
417
+ return {
418
+ title: copy.title ?? copy.name ?? "",
419
+ videoUrls: [],
420
+ };
421
+ }
422
+ };
181
423
  export const getTestimonialsFromConfig = async () => {
182
424
  try {
183
425
  const config = await getDynamicConfig();
184
426
  const homepageConfig = config?.["homepage-config"];
185
427
  if (!homepageConfig)
186
428
  return null;
187
- const title = homepageConfig["rating-title"] || "Happy Parents Say About Us";
429
+ const block = await getMergedSectionBlock("testimonials");
430
+ const copy = parseSectionCopy(block);
431
+ const title = copy.title ?? copy.name ?? "";
188
432
  const ratings = homepageConfig["ratings"] || [];
189
- const testimonials = ratings.map((item, index) => {
190
- const review = item?.review || item;
433
+ let testimonials = (Array.isArray(ratings) ? ratings : []).map((item, index) => {
434
+ const row = item;
435
+ const review = (row?.review ?? row);
191
436
  return {
192
437
  id: `review-${index}`,
193
- text: review?.["review-description"] || "",
194
- name: review?.["review-user-name"] || "",
195
- rating: parseFloat(review?.["review-rating"] || "5"),
196
- avatar: review?.["review-profile-image"] || undefined,
438
+ text: String(review?.["review-description"] ?? "").trim(),
439
+ name: String(review?.["review-user-name"] ?? "").trim(),
440
+ rating: parseFloat(String(review?.["review-rating"] ?? "5")),
441
+ avatar: review?.["review-profile-image"],
197
442
  };
198
443
  }).filter((t) => t.text && t.name);
199
444
  return { title, testimonials };
200
445
  }
201
- catch (error) {
202
- return null;
446
+ catch {
447
+ const block = DEFAULT_HOMEPAGE_SECTIONS.testimonials;
448
+ const copy = parseSectionCopy(block);
449
+ return { title: copy.title ?? copy.name ?? "", testimonials: [] };
203
450
  }
204
451
  };
205
452
  export const getSocialLinksFromConfig = async () => {
@@ -249,15 +496,177 @@ export const getFaqsFromConfig = async () => {
249
496
  return null;
250
497
  }
251
498
  };
499
+ export const getAnnouncementMessagesFromConfig = async () => {
500
+ try {
501
+ const block = await getMergedSectionBlock("promoAnnouncements");
502
+ return parseAnnouncementMessages(block);
503
+ }
504
+ catch {
505
+ return parseAnnouncementMessages(DEFAULT_HOMEPAGE_SECTIONS.promoAnnouncements);
506
+ }
507
+ };
508
+ export const getAboutBrandFromConfig = async () => {
509
+ try {
510
+ const config = await getDynamicConfig();
511
+ const merged = await getMergedSectionBlock("aboutBrand");
512
+ const legacy = config?.["homepage-config"]?.["about-brand"] ??
513
+ config?.["homepage-config"]?.["who-we-are"];
514
+ const b = mergeSectionBlock(merged, legacy && typeof legacy === "object"
515
+ ? legacy
516
+ : null);
517
+ const statsRaw = (b.stats ?? b["about-stats"] ?? []);
518
+ const stats = Array.isArray(statsRaw)
519
+ ? statsRaw
520
+ .map((s) => {
521
+ if (!s || typeof s !== "object")
522
+ return null;
523
+ const row = s;
524
+ const label = String(row.label ?? row.name ?? "").trim();
525
+ const value = String(row.value ?? "").trim();
526
+ return label && value ? { label, value } : null;
527
+ })
528
+ .filter(Boolean)
529
+ : [];
530
+ const copy = parseSectionCopy(b);
531
+ return {
532
+ eyebrow: copy.eyebrow ?? "",
533
+ title: copy.title ?? copy.name ?? "",
534
+ description: copy.description ?? copy.text ?? "",
535
+ readMoreHref: String(b.readMoreHref ?? b["read-more-link"] ?? "/about"),
536
+ stats,
537
+ };
538
+ }
539
+ catch {
540
+ const b = DEFAULT_HOMEPAGE_SECTIONS.aboutBrand;
541
+ const copy = parseSectionCopy(b);
542
+ return {
543
+ eyebrow: copy.eyebrow ?? "",
544
+ title: copy.title ?? copy.name ?? "",
545
+ description: copy.description ?? copy.text ?? "",
546
+ readMoreHref: String(b.readMoreHref ?? "/about"),
547
+ stats: (b.stats ?? []),
548
+ };
549
+ }
550
+ };
551
+ export const getBrandPillarsFromConfig = async () => {
552
+ try {
553
+ const block = await getMergedSectionBlock("brandPillars");
554
+ const copy = parseSectionCopy(block);
555
+ const sectionTitle = copy.title ?? copy.name ?? "";
556
+ const raw = block.pillars ?? block["brand-pillars"] ?? [];
557
+ const pillars = (Array.isArray(raw) ? raw : [])
558
+ .map((item) => {
559
+ if (!item || typeof item !== "object")
560
+ return null;
561
+ const row = item["pillar"] ?? item;
562
+ const p = row;
563
+ const title = String(p.title ?? p.name ?? "").trim();
564
+ const description = String(p.description ?? p.text ?? "").trim();
565
+ const image = (p.image ?? p.icon);
566
+ return title && description ? { title, description, image } : null;
567
+ })
568
+ .filter(Boolean);
569
+ return { sectionTitle, pillars };
570
+ }
571
+ catch {
572
+ const block = DEFAULT_HOMEPAGE_SECTIONS.brandPillars;
573
+ const copy = parseSectionCopy(block);
574
+ const raw = block.pillars ?? [];
575
+ return {
576
+ sectionTitle: copy.title ?? copy.name ?? "",
577
+ pillars: [...(Array.isArray(raw) ? raw : [])],
578
+ };
579
+ }
580
+ };
581
+ export const getBlogPostsFromConfig = async () => {
582
+ try {
583
+ const block = await getMergedSectionBlock("blogPosts");
584
+ const raw = block.posts ?? block["blog-posts"] ?? block["blog-array"] ?? [];
585
+ const posts = (Array.isArray(raw) ? raw : [])
586
+ .map((item) => {
587
+ if (!item || typeof item !== "object")
588
+ return null;
589
+ const row = item["blog"] ?? item;
590
+ const b = row;
591
+ const title = String(b.title ?? "").trim();
592
+ const href = String(b.href ?? b.link ?? b.url ?? "").trim();
593
+ if (!title || !href)
594
+ return null;
595
+ return {
596
+ title,
597
+ href,
598
+ excerpt: String(b.excerpt ?? b.description ?? "").trim() || undefined,
599
+ category: String(b.category ?? b.tag ?? "").trim() || undefined,
600
+ date: String(b.date ?? "").trim() || undefined,
601
+ image: (b.image ?? b.thumbnail),
602
+ };
603
+ })
604
+ .filter(Boolean);
605
+ return posts;
606
+ }
607
+ catch {
608
+ const block = DEFAULT_HOMEPAGE_SECTIONS.blogPosts;
609
+ const raw = block.posts ?? [];
610
+ return (Array.isArray(raw) ? raw : [])
611
+ .map((item) => {
612
+ if (!item || typeof item !== "object")
613
+ return null;
614
+ const b = item;
615
+ const title = String(b.title ?? "").trim();
616
+ const href = String(b.href ?? b.link ?? "").trim();
617
+ if (!title || !href)
618
+ return null;
619
+ return { title, href };
620
+ })
621
+ .filter(Boolean);
622
+ }
623
+ };
624
+ function readPromoCountdownBlock(block) {
625
+ if (!block || typeof block !== "object") {
626
+ return { code: null, message: null, endAt: null, active: undefined };
627
+ }
628
+ const row = block;
629
+ const code = normalizeCmsText(row["promo-code"] ?? row.code ?? row["coupon-code"]) ?? null;
630
+ const message = normalizeCmsText(row["promo-text"] ?? row.message ?? row.text) ?? null;
631
+ const endAtRaw = row["end-at"] ?? row.endAt ?? row["ends-at"];
632
+ const endAt = typeof endAtRaw === "string" && endAtRaw.trim() ? endAtRaw.trim() : null;
633
+ const activeRaw = row["promo-active"] ?? row.active;
634
+ const active = typeof activeRaw === "boolean" ? activeRaw : undefined;
635
+ return { code, message, endAt, active };
636
+ }
637
+ /** Promo countdown — defaults + `sections.promoCountdown` override. */
638
+ export const getPromoCountdownFromConfig = async () => {
639
+ try {
640
+ const block = await getMergedSectionBlock("promoCountdown");
641
+ const fromBlock = readPromoCountdownBlock(block);
642
+ const defaults = readPromoCountdownBlock(DEFAULT_HOMEPAGE_SECTIONS.promoCountdown);
643
+ return {
644
+ code: fromBlock.code ?? defaults.code,
645
+ message: fromBlock.message ?? defaults.message,
646
+ endAt: fromBlock.endAt ?? defaults.endAt,
647
+ active: fromBlock.active ?? defaults.active ?? false,
648
+ };
649
+ }
650
+ catch {
651
+ const defaults = readPromoCountdownBlock(DEFAULT_HOMEPAGE_SECTIONS.promoCountdown);
652
+ return {
653
+ code: defaults.code,
654
+ message: defaults.message,
655
+ endAt: defaults.endAt,
656
+ active: defaults.active ?? false,
657
+ };
658
+ }
659
+ };
660
+ export { DEFAULT_HOMEPAGE_SECTIONS } from "./homepage-section-defaults";
252
661
  export const getPromoBarConfig = async () => {
253
662
  try {
254
663
  const config = await getDynamicConfig();
255
664
  const promoConfig = config?.["homepage-config"]?.["promo-bar"];
256
665
  return {
257
- text: promoConfig?.["promo-text"] || null,
666
+ text: normalizeCmsText(promoConfig?.["promo-text"]) || null,
258
667
  code: promoConfig?.["promo-code"] || null,
259
668
  value: promoConfig?.["promo-value"] || null,
260
- active: promoConfig?.["promo-active"] ?? false
669
+ active: promoConfig?.["promo-active"] ?? false,
261
670
  };
262
671
  }
263
672
  catch (error) {
@@ -1,5 +1,5 @@
1
1
  import { HttpTypes } from "@medusajs/types";
2
2
  export declare const listCartShippingMethods: (cartId: string) => Promise<HttpTypes.StoreCartShippingOptionWithServiceZone[] | null>;
3
3
  export declare const calculatePriceForShippingOption: (optionId: string, cartId: string, data?: Record<string, unknown>) => Promise<HttpTypes.StoreCartShippingOption | null>;
4
- export declare const getShiprocketServiceability: (pincode: string, variant_id: string, cod?: number) => Promise<Record<string, unknown> | null>;
4
+ export declare const getShiprocketServiceability: (pincode: string, variant_id: string, cod?: number) => Promise<import("medusa-services/fulfillment").ShiprocketServiceabilityResult | null>;
5
5
  //# sourceMappingURL=fulfillment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fulfillment.d.ts","sourceRoot":"","sources":["../../src/server/fulfillment.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAQ3C,eAAO,MAAM,uBAAuB,GAAU,QAAQ,MAAM,uEA0B3D,CAAA;AAED,eAAO,MAAM,+BAA+B,GAC1C,UAAU,MAAM,EAChB,QAAQ,MAAM,EACd,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,sDAc/B,CAAA;AAED,eAAO,MAAM,2BAA2B,GAAU,SAAS,MAAM,EAAE,YAAY,MAAM,EAAE,MAAK,MAAU,4CAWrG,CAAA"}
1
+ {"version":3,"file":"fulfillment.d.ts","sourceRoot":"","sources":["../../src/server/fulfillment.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAQ3C,eAAO,MAAM,uBAAuB,GAAU,QAAQ,MAAM,uEA0B3D,CAAA;AAED,eAAO,MAAM,+BAA+B,GAC1C,UAAU,MAAM,EAChB,QAAQ,MAAM,EACd,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,sDAc/B,CAAA;AAED,eAAO,MAAM,2BAA2B,GAAU,SAAS,MAAM,EAAE,YAAY,MAAM,EAAE,MAAK,MAAU,yFAWrG,CAAA"}
@@ -1,15 +1,42 @@
1
+ import { HttpTypes } from "@medusajs/types";
1
2
  import { getRegion } from "./regions";
3
+ import { type AboutBrandConfig, type BrandPillarConfig, type BlogPostConfig, type HomeSectionsCopy, type TrustFeaturesConfig } from "./dynamic-config";
2
4
  export type HomePageData = {
3
5
  region: Awaited<ReturnType<typeof getRegion>>;
4
6
  collections: Array<Record<string, unknown>>;
5
- categories: unknown[];
6
- newArrivals: unknown[];
7
- bestsellers: unknown[];
7
+ categories: HttpTypes.StoreProductCategory[];
8
+ newArrivals: HttpTypes.StoreProduct[];
9
+ bestsellers: HttpTypes.StoreProduct[];
8
10
  testimonials: unknown | null;
9
11
  ratings: unknown[];
12
+ videoStories: {
13
+ title: string;
14
+ videoUrls: string[];
15
+ } | null;
16
+ announcementMessages: string[];
17
+ promoCountdown: {
18
+ code: string | null;
19
+ message: string | null;
20
+ endAt: string | null;
21
+ active: boolean;
22
+ };
23
+ luxeFavourites: HttpTypes.StoreProduct[];
24
+ celebrityProduct: HttpTypes.StoreProduct | null;
25
+ baptismGirl: HttpTypes.StoreProduct[];
26
+ baptismBoy: HttpTypes.StoreProduct[];
27
+ baptismPicks: HttpTypes.StoreProduct[];
28
+ themeProducts: HttpTypes.StoreProduct[];
29
+ aboutBrand: AboutBrandConfig;
30
+ brandPillars: {
31
+ sectionTitle: string;
32
+ pillars: BrandPillarConfig[];
33
+ };
34
+ blogPosts: BlogPostConfig[];
35
+ sectionsCopy: HomeSectionsCopy;
36
+ trustFeatures: TrustFeaturesConfig;
10
37
  };
11
38
  /**
12
- * Parallel home page data loader (replaces per-page Promise.all boilerplate).
39
+ * Parallel home page data loader for full storefront homepage sections.
13
40
  */
14
41
  export declare function loadHomePageData(countryCode: string): Promise<HomePageData | null>;
15
42
  //# sourceMappingURL=home.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"home.d.ts","sourceRoot":"","sources":["../../src/server/home.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAItC,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,OAAO,EAAE,CAAC;IACtB,WAAW,EAAE,OAAO,EAAE,CAAC;IACvB,WAAW,EAAE,OAAO,EAAE,CAAC;IACvB,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,OAAO,EAAE,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA6CxF"}
1
+ {"version":3,"file":"home.d.ts","sourceRoot":"","sources":["../../src/server/home.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAUL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAiC1B,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;KACjB,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,SAAS,CAAC,YAAY,EAAE,CAAC;IACvC,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,YAAY,EAAE,gBAAgB,CAAC;IAC/B,aAAa,EAAE,mBAAmB,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA2HxF"}