@asteby/storefront-react 0.4.0 → 0.5.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.
- package/README.md +82 -0
- package/dist/chunk-2WZIWIBW.js +75 -0
- package/dist/chunk-2WZIWIBW.js.map +1 -0
- package/dist/chunk-672OTUM2.js +60 -0
- package/dist/chunk-672OTUM2.js.map +1 -0
- package/dist/{chunk-C6QZNKRE.js → chunk-6CVKW7F3.js} +6 -37
- package/dist/chunk-6CVKW7F3.js.map +1 -0
- package/dist/chunk-DQBL2DFJ.js +40 -0
- package/dist/chunk-DQBL2DFJ.js.map +1 -0
- package/dist/index.cjs +264 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +124 -6
- package/dist/index.d.ts +124 -6
- package/dist/index.js +263 -69
- package/dist/index.js.map +1 -1
- package/dist/mockups.js +2 -1
- package/dist/mockups.js.map +1 -1
- package/dist/payments.cjs +766 -0
- package/dist/payments.cjs.map +1 -0
- package/dist/payments.d.cts +364 -0
- package/dist/payments.d.ts +364 -0
- package/dist/payments.js +680 -0
- package/dist/payments.js.map +1 -0
- package/dist/promotions.cjs +573 -0
- package/dist/promotions.cjs.map +1 -0
- package/dist/promotions.d.cts +243 -0
- package/dist/promotions.d.ts +243 -0
- package/dist/promotions.js +480 -0
- package/dist/promotions.js.map +1 -0
- package/package.json +23 -2
- package/dist/chunk-C6QZNKRE.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
1
|
+
export { DEFAULT_IMAGE_WIDTHS, Image, Money, ProductPrice, defaultImageLoader } from './chunk-6CVKW7F3.js';
|
|
2
|
+
export { ThemeStyle, isSafeCssValue, themeFontsHref, themeToCss, themeToCssVariables, tokenName } from './chunk-672OTUM2.js';
|
|
3
|
+
import { useOptionalStorefront } from './chunk-DQBL2DFJ.js';
|
|
4
|
+
export { StorefrontProvider, useOptionalStorefront, useStorefront, useStorefrontClient } from './chunk-DQBL2DFJ.js';
|
|
3
5
|
import { createContext, useRef, useState, useCallback, useEffect, useMemo, useContext, Fragment as Fragment$1, useId } from 'react';
|
|
4
|
-
import {
|
|
6
|
+
import { resolveAvailability, productAvailability, availabilityView, availabilityMessages, formatAvailabilityMessage, cartLineProblemView, isStorefrontError, schemaAvailability, formatMoney } from '@asteby/storefront';
|
|
5
7
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
6
8
|
import { toSchemaOpeningHours, isValidPoint, rankByDistance, openStatus, directionsUrl } from '@asteby/storefront/geo';
|
|
7
9
|
|
|
@@ -347,6 +349,7 @@ function useProductOptions(product, config = {}) {
|
|
|
347
349
|
exists: exact ? true : loose.length > 0 && Object.keys(selectedOptions).length < product.options.length,
|
|
348
350
|
available: exact ? exact.available_for_sale : Object.keys(selectedOptions).length < product.options.length && loose.some((v) => v.available_for_sale),
|
|
349
351
|
variant: exact,
|
|
352
|
+
availability: exact ? resolveAvailability(exact) : loose.length ? productAvailability({ variants: loose, available_for_sale: loose.some((v) => v.available_for_sale) }) : null,
|
|
350
353
|
search: `?${search.toString()}`
|
|
351
354
|
};
|
|
352
355
|
})
|
|
@@ -365,21 +368,32 @@ function toMerchandise(product, variant) {
|
|
|
365
368
|
function AddToCartButton({
|
|
366
369
|
variantId,
|
|
367
370
|
quantity = 1,
|
|
371
|
+
availability,
|
|
372
|
+
availabilitySource,
|
|
373
|
+
lowStockThreshold,
|
|
374
|
+
locale,
|
|
368
375
|
merchandise,
|
|
369
376
|
onAdded,
|
|
370
377
|
onClick,
|
|
371
378
|
disabled,
|
|
372
|
-
children
|
|
379
|
+
children,
|
|
373
380
|
type = "button",
|
|
374
381
|
...rest
|
|
375
382
|
}) {
|
|
376
383
|
const cart = useCart();
|
|
384
|
+
const sf = useOptionalStorefront();
|
|
385
|
+
const resolved = availability ?? (availabilitySource ? resolveAvailability(availabilitySource, { lowStockThreshold: lowStockThreshold ?? null }) : null);
|
|
386
|
+
const view = resolved ? availabilityView(resolved, locale ?? sf?.locale ?? "es-MX") : null;
|
|
387
|
+
const blocked = view ? !view.ctaEnabled : false;
|
|
388
|
+
const qty = view?.maxPerOrder != null ? Math.min(quantity, view.maxPerOrder) : quantity;
|
|
389
|
+
const label = children ?? view?.ctaLabel ?? "Agregar al carrito";
|
|
377
390
|
const [adding, setAdding] = useState(false);
|
|
378
391
|
return /* @__PURE__ */ jsx(
|
|
379
392
|
"button",
|
|
380
393
|
{
|
|
381
394
|
type,
|
|
382
|
-
disabled: disabled || !variantId || adding,
|
|
395
|
+
disabled: disabled || !variantId || adding || blocked,
|
|
396
|
+
"data-availability": view?.status,
|
|
383
397
|
"aria-busy": adding || void 0,
|
|
384
398
|
"data-adding": adding || void 0,
|
|
385
399
|
onClick: async (event) => {
|
|
@@ -387,17 +401,247 @@ function AddToCartButton({
|
|
|
387
401
|
if (event.defaultPrevented || !variantId) return;
|
|
388
402
|
setAdding(true);
|
|
389
403
|
try {
|
|
390
|
-
const result = await cart.addLines([{ variant_id: variantId, quantity, ...merchandise ? { merchandise } : {} }]);
|
|
404
|
+
const result = await cart.addLines([{ variant_id: variantId, quantity: qty, ...merchandise ? { merchandise } : {} }]);
|
|
391
405
|
if (result) onAdded?.();
|
|
392
406
|
} finally {
|
|
393
407
|
setAdding(false);
|
|
394
408
|
}
|
|
395
409
|
},
|
|
396
410
|
...rest,
|
|
397
|
-
children
|
|
411
|
+
children: label
|
|
398
412
|
}
|
|
399
413
|
);
|
|
400
414
|
}
|
|
415
|
+
var SR_ONLY = {
|
|
416
|
+
position: "absolute",
|
|
417
|
+
width: 1,
|
|
418
|
+
height: 1,
|
|
419
|
+
margin: -1,
|
|
420
|
+
padding: 0,
|
|
421
|
+
overflow: "hidden",
|
|
422
|
+
clip: "rect(0 0 0 0)",
|
|
423
|
+
whiteSpace: "nowrap",
|
|
424
|
+
border: 0
|
|
425
|
+
};
|
|
426
|
+
function SrOnly({ children }) {
|
|
427
|
+
return /* @__PURE__ */ jsx("span", { style: SR_ONLY, children });
|
|
428
|
+
}
|
|
429
|
+
function useLocale(locale) {
|
|
430
|
+
const sf = useOptionalStorefront();
|
|
431
|
+
return locale ?? sf?.locale ?? "es-MX";
|
|
432
|
+
}
|
|
433
|
+
function pickAvailability({ availability, source, lowStockThreshold }) {
|
|
434
|
+
const opts = { lowStockThreshold: lowStockThreshold ?? null };
|
|
435
|
+
if (availability) return availability;
|
|
436
|
+
return source ? resolveAvailability(source, opts) : null;
|
|
437
|
+
}
|
|
438
|
+
function useAvailability(input) {
|
|
439
|
+
const locale = useLocale(input.locale);
|
|
440
|
+
const a = pickAvailability(input);
|
|
441
|
+
return useMemo(
|
|
442
|
+
() => a ? availabilityView(a, locale, { messages: input.messages ?? null }) : null,
|
|
443
|
+
// `a` is rebuilt from props each render; key by its content
|
|
444
|
+
[JSON.stringify(a), locale, input.messages]
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
function AvailabilityBadge({
|
|
448
|
+
availability,
|
|
449
|
+
source,
|
|
450
|
+
lowStockThreshold,
|
|
451
|
+
locale,
|
|
452
|
+
messages,
|
|
453
|
+
placement = "detail",
|
|
454
|
+
live,
|
|
455
|
+
...rest
|
|
456
|
+
}) {
|
|
457
|
+
const view = useAvailability({ availability, source, lowStockThreshold, locale, messages });
|
|
458
|
+
const loc = useLocale(locale);
|
|
459
|
+
if (!view) return null;
|
|
460
|
+
if (placement === "card" && !view.showOnCard) return null;
|
|
461
|
+
const m = availabilityMessages(loc, messages);
|
|
462
|
+
return /* @__PURE__ */ jsxs(
|
|
463
|
+
"span",
|
|
464
|
+
{
|
|
465
|
+
"data-availability": view.status,
|
|
466
|
+
"data-tone": view.tone,
|
|
467
|
+
"data-placement": placement,
|
|
468
|
+
...live ? { role: "status" } : {},
|
|
469
|
+
...rest,
|
|
470
|
+
children: [
|
|
471
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": view.srText !== view.label ? true : void 0, children: view.label }),
|
|
472
|
+
view.srText !== view.label && /* @__PURE__ */ jsx(SrOnly, { children: view.srText }),
|
|
473
|
+
placement === "detail" && view.sublabel && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
474
|
+
" ",
|
|
475
|
+
/* @__PURE__ */ jsx("span", { "data-availability-note": "eta", children: view.sublabel })
|
|
476
|
+
] }),
|
|
477
|
+
placement === "detail" && view.maxPerOrder !== null && view.status !== "out_of_stock" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
478
|
+
" ",
|
|
479
|
+
/* @__PURE__ */ jsx("span", { "data-availability-note": "max", children: formatAvailabilityMessage(m.max_per_order, { n: view.maxPerOrder }) })
|
|
480
|
+
] })
|
|
481
|
+
]
|
|
482
|
+
}
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
function VariantOptionState({ children, availability, source, lowStockThreshold, locale, messages, ...rest }) {
|
|
486
|
+
const a = pickAvailability({ availability, source, lowStockThreshold });
|
|
487
|
+
const loc = useLocale(locale);
|
|
488
|
+
if (!a) return /* @__PURE__ */ jsx("span", { ...rest, children });
|
|
489
|
+
const m = availabilityMessages(loc, messages);
|
|
490
|
+
const status = availabilityView(a, loc, { messages: messages ?? null }).status;
|
|
491
|
+
if (status === "out_of_stock") {
|
|
492
|
+
return /* @__PURE__ */ jsxs("span", { "data-availability": status, ...rest, children: [
|
|
493
|
+
/* @__PURE__ */ jsx("s", { children }),
|
|
494
|
+
/* @__PURE__ */ jsxs(SrOnly, { children: [
|
|
495
|
+
" (",
|
|
496
|
+
m["option.sold_out"],
|
|
497
|
+
")"
|
|
498
|
+
] })
|
|
499
|
+
] });
|
|
500
|
+
}
|
|
501
|
+
if (status === "backorder" || status === "preorder") {
|
|
502
|
+
return /* @__PURE__ */ jsxs("span", { "data-availability": status, ...rest, children: [
|
|
503
|
+
children,
|
|
504
|
+
" ",
|
|
505
|
+
/* @__PURE__ */ jsxs("span", { "data-availability-tag": true, children: [
|
|
506
|
+
"(",
|
|
507
|
+
m[status === "backorder" ? "option.backorder" : "option.preorder"],
|
|
508
|
+
")"
|
|
509
|
+
] })
|
|
510
|
+
] });
|
|
511
|
+
}
|
|
512
|
+
return /* @__PURE__ */ jsx("span", { "data-availability": status, ...rest, children });
|
|
513
|
+
}
|
|
514
|
+
function RestockNotifyForm({
|
|
515
|
+
sku,
|
|
516
|
+
market,
|
|
517
|
+
allowPhone = false,
|
|
518
|
+
action,
|
|
519
|
+
client: clientProp,
|
|
520
|
+
enhance = true,
|
|
521
|
+
onSubscribed,
|
|
522
|
+
onError,
|
|
523
|
+
availability,
|
|
524
|
+
source,
|
|
525
|
+
lowStockThreshold,
|
|
526
|
+
locale,
|
|
527
|
+
messages,
|
|
528
|
+
...rest
|
|
529
|
+
}) {
|
|
530
|
+
const sf = useOptionalStorefront();
|
|
531
|
+
const view = useAvailability({ availability, source, lowStockThreshold, locale, messages });
|
|
532
|
+
const loc = useLocale(locale);
|
|
533
|
+
const id = useId();
|
|
534
|
+
const [state, setState] = useState("idle");
|
|
535
|
+
if (!view?.showNotify) return null;
|
|
536
|
+
const m = availabilityMessages(loc, messages);
|
|
537
|
+
const client = clientProp ?? sf?.client ?? null;
|
|
538
|
+
if (state === "done") {
|
|
539
|
+
return /* @__PURE__ */ jsx("p", { role: "status", "data-restock": "done", children: m["notify.done"] });
|
|
540
|
+
}
|
|
541
|
+
const submit = enhance && client ? (e) => {
|
|
542
|
+
e.preventDefault();
|
|
543
|
+
const form = new FormData(e.currentTarget);
|
|
544
|
+
const email = String(form.get("email") ?? "").trim();
|
|
545
|
+
const phone = String(form.get("phone") ?? "").trim();
|
|
546
|
+
if (!email && !phone) {
|
|
547
|
+
setState("error");
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
setState("sending");
|
|
551
|
+
client.restock.subscribe({ sku, locale: loc, consent: true, ...email ? { email } : {}, ...phone ? { phone } : {}, ...market ? { market } : {} }).then(() => {
|
|
552
|
+
setState("done");
|
|
553
|
+
onSubscribed?.();
|
|
554
|
+
}).catch((err) => {
|
|
555
|
+
setState("error");
|
|
556
|
+
onError?.(err);
|
|
557
|
+
});
|
|
558
|
+
} : void 0;
|
|
559
|
+
return /* @__PURE__ */ jsx("form", { method: "post", ...action !== void 0 ? { action } : {}, ...rest, onSubmit: submit, "data-restock": state, children: /* @__PURE__ */ jsxs("fieldset", { children: [
|
|
560
|
+
/* @__PURE__ */ jsx("legend", { children: m["notify.title"] }),
|
|
561
|
+
/* @__PURE__ */ jsx("input", { type: "hidden", name: "sku", value: sku }),
|
|
562
|
+
/* @__PURE__ */ jsx("input", { type: "hidden", name: "locale", value: loc }),
|
|
563
|
+
market && /* @__PURE__ */ jsx("input", { type: "hidden", name: "market", value: market }),
|
|
564
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
565
|
+
/* @__PURE__ */ jsx("label", { htmlFor: `${id}-email`, children: m["notify.email"] }),
|
|
566
|
+
" ",
|
|
567
|
+
/* @__PURE__ */ jsx("input", { id: `${id}-email`, name: "email", type: "email", autoComplete: "email", required: !allowPhone })
|
|
568
|
+
] }),
|
|
569
|
+
allowPhone && /* @__PURE__ */ jsxs("p", { children: [
|
|
570
|
+
/* @__PURE__ */ jsx("label", { htmlFor: `${id}-phone`, children: m["notify.phone"] }),
|
|
571
|
+
" ",
|
|
572
|
+
/* @__PURE__ */ jsx("input", { id: `${id}-phone`, name: "phone", type: "tel", autoComplete: "tel" })
|
|
573
|
+
] }),
|
|
574
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
575
|
+
/* @__PURE__ */ jsx("input", { id: `${id}-consent`, name: "consent", type: "checkbox", value: "true", required: true }),
|
|
576
|
+
" ",
|
|
577
|
+
/* @__PURE__ */ jsx("label", { htmlFor: `${id}-consent`, children: m["notify.consent"] })
|
|
578
|
+
] }),
|
|
579
|
+
/* @__PURE__ */ jsx("button", { type: "submit", disabled: state === "sending", "aria-busy": state === "sending" || void 0, children: m["notify.submit"] }),
|
|
580
|
+
state === "error" && /* @__PURE__ */ jsx("p", { role: "alert", children: m["notify.error"] })
|
|
581
|
+
] }) });
|
|
582
|
+
}
|
|
583
|
+
function CartLineProblem({ line, locale, messages, onAdjust, onRemove, ...rest }) {
|
|
584
|
+
const cart = useOptionalCart();
|
|
585
|
+
const loc = useLocale(locale);
|
|
586
|
+
if (!line.problem) return null;
|
|
587
|
+
const view = cartLineProblemView(line.problem, loc, { messages: messages ?? null, lineQuantity: line.quantity });
|
|
588
|
+
const adjust = onAdjust ?? (cart ? (id, q) => cart.updateLines([{ id, quantity: q }]) : void 0);
|
|
589
|
+
const remove = onRemove ?? (cart ? (id) => cart.removeLines([id]) : void 0);
|
|
590
|
+
return /* @__PURE__ */ jsxs("div", { "data-cart-line-problem": view.code, ...rest, children: [
|
|
591
|
+
/* @__PURE__ */ jsx("p", { children: view.message }),
|
|
592
|
+
view.adjustTo !== null && adjust && /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void adjust(line.id, view.adjustTo), children: view.adjustLabel }),
|
|
593
|
+
remove && /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void remove(line.id), children: view.removeLabel })
|
|
594
|
+
] });
|
|
595
|
+
}
|
|
596
|
+
function StockConflictAlert({
|
|
597
|
+
error: errorProp,
|
|
598
|
+
cart: cartProp,
|
|
599
|
+
locale,
|
|
600
|
+
messages,
|
|
601
|
+
onAdjust,
|
|
602
|
+
onRemove,
|
|
603
|
+
onDismiss,
|
|
604
|
+
autoFocus = true,
|
|
605
|
+
...rest
|
|
606
|
+
}) {
|
|
607
|
+
const cartCtx = useOptionalCart();
|
|
608
|
+
const loc = useLocale(locale);
|
|
609
|
+
const ref = useRef(null);
|
|
610
|
+
const error = errorProp !== void 0 ? errorProp : cartCtx?.error ?? null;
|
|
611
|
+
const cart = cartProp !== void 0 ? cartProp : cartCtx?.cart ?? null;
|
|
612
|
+
const active = isStorefrontError(error) && error.code === "insufficient_stock";
|
|
613
|
+
useEffect(() => {
|
|
614
|
+
if (active && autoFocus) ref.current?.focus({ preventScroll: true });
|
|
615
|
+
}, [active, error, autoFocus]);
|
|
616
|
+
if (!active) return null;
|
|
617
|
+
const m = availabilityMessages(loc, messages);
|
|
618
|
+
const lines = error.stockLines;
|
|
619
|
+
const adjust = onAdjust ?? (cartCtx ? (id, q) => cartCtx.updateLines([{ id, quantity: q }]) : void 0);
|
|
620
|
+
const remove = onRemove ?? (cartCtx ? (id) => cartCtx.removeLines([id]) : void 0);
|
|
621
|
+
return /* @__PURE__ */ jsxs("div", { ref, role: "alert", tabIndex: -1, "data-stock-conflict": true, ...rest, children: [
|
|
622
|
+
/* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("strong", { children: m["conflict.title"] }) }),
|
|
623
|
+
/* @__PURE__ */ jsx("p", { children: m["conflict.body"] }),
|
|
624
|
+
lines.length > 0 && /* @__PURE__ */ jsx("ul", { children: lines.map((l) => {
|
|
625
|
+
const cartLine = cart?.lines.find((x) => l.line_id ? x.id === l.line_id : x.merchandise.sku === l.sku);
|
|
626
|
+
const lineId = l.line_id ?? cartLine?.id ?? null;
|
|
627
|
+
const view = cartLineProblemView(l, loc, { messages: messages ?? null, ...cartLine ? { lineQuantity: cartLine.quantity } : {} });
|
|
628
|
+
return /* @__PURE__ */ jsxs("li", { "data-cart-line-problem": view.code, children: [
|
|
629
|
+
/* @__PURE__ */ jsx("span", { children: cartLine ? `${cartLine.merchandise.product.title}${cartLine.merchandise.title ? ` (${cartLine.merchandise.title})` : ""}` : l.sku }),
|
|
630
|
+
": ",
|
|
631
|
+
/* @__PURE__ */ jsx("span", { children: view.message }),
|
|
632
|
+
lineId && view.adjustTo !== null && adjust && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
633
|
+
" ",
|
|
634
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => void adjust(lineId, view.adjustTo), children: view.adjustLabel })
|
|
635
|
+
] }),
|
|
636
|
+
lineId && remove && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
637
|
+
" ",
|
|
638
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => void remove(lineId), children: view.removeLabel })
|
|
639
|
+
] })
|
|
640
|
+
] }, `${l.sku}:${l.line_id ?? ""}`);
|
|
641
|
+
}) }),
|
|
642
|
+
onDismiss && /* @__PURE__ */ jsx("button", { type: "button", onClick: onDismiss, children: m["conflict.dismiss"] })
|
|
643
|
+
] });
|
|
644
|
+
}
|
|
401
645
|
var clean = (s, max) => {
|
|
402
646
|
if (!s) return void 0;
|
|
403
647
|
const text = s.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -431,7 +675,8 @@ function seoMeta(input) {
|
|
|
431
675
|
function seoOf(seo, fallbackTitle, fallbackDescription) {
|
|
432
676
|
return { title: seo.title ?? fallbackTitle, description: seo.description ?? fallbackDescription ?? null };
|
|
433
677
|
}
|
|
434
|
-
|
|
678
|
+
var OG_AVAILABILITY = { in_stock: "in stock", low_stock: "in stock", out_of_stock: "out of stock", backorder: "backorder", preorder: "preorder" };
|
|
679
|
+
function productMeta(product, shop, url, options = {}) {
|
|
435
680
|
const { title, description } = seoOf(product.seo, product.title, product.description);
|
|
436
681
|
const meta = seoMeta({
|
|
437
682
|
title,
|
|
@@ -446,7 +691,7 @@ function productMeta(product, shop, url) {
|
|
|
446
691
|
meta.push(
|
|
447
692
|
{ property: "product:price:amount", content: product.price_range.min.amount },
|
|
448
693
|
{ property: "product:price:currency", content: product.price_range.min.currency_code },
|
|
449
|
-
{ property: "product:availability", content: product.
|
|
694
|
+
{ property: "product:availability", content: OG_AVAILABILITY[productAvailability(product, options).status] ?? "out of stock" }
|
|
450
695
|
);
|
|
451
696
|
if (product.vendor) meta.push({ property: "product:brand", content: product.vendor });
|
|
452
697
|
return meta;
|
|
@@ -483,22 +728,24 @@ function withVariant(url, variantId) {
|
|
|
483
728
|
return `${url}${url.includes("?") ? "&" : "?"}variant=${encodeURIComponent(variantId)}`;
|
|
484
729
|
}
|
|
485
730
|
}
|
|
486
|
-
function productJsonLd(product, shop, url) {
|
|
731
|
+
function productJsonLd(product, shop, url, options = {}) {
|
|
487
732
|
const images = product.images.length ? product.images.map((i) => i.url) : product.featured_image ? [product.featured_image.url] : [];
|
|
488
|
-
const offers = product.variants.map(
|
|
489
|
-
(v)
|
|
733
|
+
const offers = product.variants.map((v) => {
|
|
734
|
+
const availability = resolveAvailability(v, options);
|
|
735
|
+
return compact({
|
|
490
736
|
"@type": "Offer",
|
|
491
737
|
sku: v.sku,
|
|
492
738
|
gtin: v.barcode ?? void 0,
|
|
493
739
|
name: product.variants.length > 1 ? `${product.title} - ${v.title}` : void 0,
|
|
494
740
|
price: v.price.amount,
|
|
495
741
|
priceCurrency: v.price.currency_code,
|
|
496
|
-
availability:
|
|
742
|
+
availability: schemaAvailability(availability.status),
|
|
743
|
+
availabilityStarts: availability.status === "preorder" ? availability.preorder_release_at ?? void 0 : void 0,
|
|
497
744
|
itemCondition: "https://schema.org/NewCondition",
|
|
498
745
|
url: product.variants.length > 1 ? withVariant(url, v.id) : url,
|
|
499
746
|
seller: shop ? { "@type": "Organization", name: shop.name } : void 0
|
|
500
|
-
})
|
|
501
|
-
);
|
|
747
|
+
});
|
|
748
|
+
});
|
|
502
749
|
const additionalProperty = Object.entries(product.attributes).map(([name, value]) => ({ "@type": "PropertyValue", name, value }));
|
|
503
750
|
return compact({
|
|
504
751
|
"@context": CONTEXT,
|
|
@@ -783,59 +1030,6 @@ function Sections({ sections, registry, context, renderUnknown, onInvalid }) {
|
|
|
783
1030
|
return /* @__PURE__ */ jsx(Component, { ...props, section: { id: section.id, type: section.type }, context }, key);
|
|
784
1031
|
}) });
|
|
785
1032
|
}
|
|
786
|
-
var DEFAULT_FONT_FALLBACK = 'ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif';
|
|
787
|
-
var MONO_FALLBACK = "ui-monospace, SFMono-Regular, Menlo, monospace";
|
|
788
|
-
function tokenName(key) {
|
|
789
|
-
return key.trim().replace(/^-+/, "").replace(/^color-/, "").replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[\s_.]+/g, "-").toLowerCase().replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
790
|
-
}
|
|
791
|
-
function isSafeCssValue(value) {
|
|
792
|
-
if (!value || value.length > 200) return false;
|
|
793
|
-
if (/[;{}<>\\]/.test(value)) return false;
|
|
794
|
-
if (/url\s*\(|expression\s*\(|@import/i.test(value)) return false;
|
|
795
|
-
return true;
|
|
796
|
-
}
|
|
797
|
-
function fontStack(family, role, fallback) {
|
|
798
|
-
const name = family.replace(/["']/g, "").trim();
|
|
799
|
-
if (!name || !isSafeCssValue(name)) return null;
|
|
800
|
-
return `"${name}", ${role === "mono" ? MONO_FALLBACK : fallback}`;
|
|
801
|
-
}
|
|
802
|
-
function themeToCssVariables(theme, options = {}) {
|
|
803
|
-
const naming = options.naming ?? "both";
|
|
804
|
-
const vars = {};
|
|
805
|
-
for (const [key, raw] of Object.entries(theme?.tokens ?? {})) {
|
|
806
|
-
const name = tokenName(key);
|
|
807
|
-
const value = String(raw).trim();
|
|
808
|
-
if (!name || !isSafeCssValue(value)) continue;
|
|
809
|
-
if (naming !== "metacore") vars[`--color-${name}`] = value;
|
|
810
|
-
if (naming !== "color") vars[`--${name}`] = value;
|
|
811
|
-
}
|
|
812
|
-
const fallback = options.fontFallback ?? DEFAULT_FONT_FALLBACK;
|
|
813
|
-
for (const [role, family] of Object.entries(theme?.fonts ?? {})) {
|
|
814
|
-
const name = tokenName(role);
|
|
815
|
-
const stack = typeof family === "string" ? fontStack(family, name, fallback) : null;
|
|
816
|
-
if (name && stack) vars[`--font-${name}`] = stack;
|
|
817
|
-
}
|
|
818
|
-
if (theme?.radius && isSafeCssValue(theme.radius.trim())) vars["--radius"] = theme.radius.trim();
|
|
819
|
-
return vars;
|
|
820
|
-
}
|
|
821
|
-
function themeToCss(theme, options = {}) {
|
|
822
|
-
const vars = themeToCssVariables(theme, options);
|
|
823
|
-
const body = Object.entries(vars).map(([k, v]) => `${k}:${v}`).join(";");
|
|
824
|
-
if (!body) return "";
|
|
825
|
-
const selector = (options.selector ?? ":root").replace(/[{}<>]/g, "");
|
|
826
|
-
return `${selector}{${body}}`;
|
|
827
|
-
}
|
|
828
|
-
function themeFontsHref(theme, weights = [400, 500, 600, 700]) {
|
|
829
|
-
const families = [...new Set(Object.values(theme?.fonts ?? {}).map((f) => String(f).replace(/["']/g, "").trim()).filter((f) => f && isSafeCssValue(f)))];
|
|
830
|
-
if (!families.length) return null;
|
|
831
|
-
const params = families.map((f) => `family=${encodeURIComponent(f).replace(/%20/g, "+")}:wght@${weights.join(";")}`).join("&");
|
|
832
|
-
return `https://fonts.googleapis.com/css2?${params}&display=swap`;
|
|
833
|
-
}
|
|
834
|
-
function ThemeStyle({ theme, nonce, id = "storefront-theme", ...options }) {
|
|
835
|
-
const css = themeToCss(theme, options);
|
|
836
|
-
if (!css) return null;
|
|
837
|
-
return /* @__PURE__ */ jsx("style", { id, nonce, "data-storefront-theme": "", dangerouslySetInnerHTML: { __html: css } });
|
|
838
|
-
}
|
|
839
1033
|
var MESSAGES = {
|
|
840
1034
|
unsupported: "Tu navegador no permite obtener tu ubicaci\xF3n.",
|
|
841
1035
|
insecure: "La ubicaci\xF3n solo est\xE1 disponible en conexiones seguras (HTTPS).",
|
|
@@ -1183,6 +1377,6 @@ function NearestLocationForm({
|
|
|
1183
1377
|
);
|
|
1184
1378
|
}
|
|
1185
1379
|
|
|
1186
|
-
export { AddToCartButton, CART_COOKIE_NAME, CartProvider, DirectionsLink, JsonLd, LocationList, LocationPicker, NearestLocationForm, OpenStatus, PickupOption, SELECTED_LOCATION_PARAM, SELECTED_LOCATION_STORAGE_KEY, SectionRegistry, Sections,
|
|
1380
|
+
export { AddToCartButton, AvailabilityBadge, CART_COOKIE_NAME, CartLineProblem, CartProvider, DirectionsLink, JsonLd, LocationList, LocationPicker, NearestLocationForm, OpenStatus, PickupOption, RestockNotifyForm, SELECTED_LOCATION_PARAM, SELECTED_LOCATION_STORAGE_KEY, SectionRegistry, Sections, SrOnly, StockConflictAlert, VariantOptionState, VariantSelector, breadcrumbJsonLd, collectionJsonLd, collectionMeta, createSectionRegistry, defineSection, faqJsonLd, getCartIdFromCookie, localBusinessJsonLd, openingHoursJsonLd, optimisticCart, organizationJsonLd, productJsonLd, productMeta, readCartCookie, readSelectedLocationId, resolveSectionProps, sectionJsonSchema, seoMeta, serializeCartCookie, serializeJsonLd, toMerchandise, useAvailability, useCart, useGeolocation, useNearestLocations, useOptionalCart, useProductOptions, useSelectedLocation, writeCartCookie };
|
|
1187
1381
|
//# sourceMappingURL=index.js.map
|
|
1188
1382
|
//# sourceMappingURL=index.js.map
|