@rebuy/rebuy 2.34.0 → 2.35.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/dist/index.js +204 -23
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +204 -23
- package/dist/index.mjs.map +4 -4
- package/dist/schema/checkout-and-beyond/constants.js +2 -0
- package/dist/schema/checkout-and-beyond/constants.js.map +2 -2
- package/dist/schema/checkout-and-beyond/constants.mjs +2 -0
- package/dist/schema/checkout-and-beyond/constants.mjs.map +2 -2
- package/dist/schema/checkout-and-beyond/index.js +183 -6
- package/dist/schema/checkout-and-beyond/index.js.map +3 -3
- package/dist/schema/checkout-and-beyond/index.mjs +183 -6
- package/dist/schema/checkout-and-beyond/index.mjs.map +3 -3
- package/dist/schema/widget-data.js +197 -23
- package/dist/schema/widget-data.js.map +4 -4
- package/dist/schema/widget-data.mjs +197 -23
- package/dist/schema/widget-data.mjs.map +3 -3
- package/dist/schema/widgets/checkout-and-beyond/banner.d.ts +27 -25
- package/dist/schema/widgets/checkout-and-beyond/banner.d.ts.map +1 -1
- package/dist/schema/widgets/checkout-and-beyond/button.d.ts +5 -0
- package/dist/schema/widgets/checkout-and-beyond/button.d.ts.map +1 -1
- package/dist/schema/widgets/checkout-and-beyond/carousel.d.ts +25 -25
- package/dist/schema/widgets/checkout-and-beyond/cartLine.d.ts +25 -25
- package/dist/schema/widgets/checkout-and-beyond/common.d.ts +3 -1
- package/dist/schema/widgets/checkout-and-beyond/common.d.ts.map +1 -1
- package/dist/schema/widgets/checkout-and-beyond/icons.d.ts +124 -0
- package/dist/schema/widgets/checkout-and-beyond/icons.d.ts.map +1 -0
- package/dist/schema/widgets/checkout-and-beyond/image.d.ts +319 -2
- package/dist/schema/widgets/checkout-and-beyond/image.d.ts.map +1 -1
- package/dist/schema/widgets/checkout-and-beyond/index.d.ts +1 -0
- package/dist/schema/widgets/checkout-and-beyond/index.d.ts.map +1 -1
- package/dist/schema/widgets/checkout-and-beyond/offers.d.ts +25 -25
- package/dist/schema/widgets/checkout-and-beyond/progressBar.d.ts +25 -25
- package/dist/schema/widgets/checkout-and-beyond/progressBar.d.ts.map +1 -1
- package/dist/server/index.js +193 -25
- package/dist/server/index.js.map +4 -4
- package/dist/server/index.mjs +193 -25
- package/dist/server/index.mjs.map +4 -4
- package/dist/transforms/index.js +193 -25
- package/dist/transforms/index.js.map +3 -3
- package/dist/transforms/index.mjs +193 -25
- package/dist/transforms/index.mjs.map +3 -3
- package/dist/transforms/smartCart/convertSmartCartProgressBarToV2.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/server/index.mjs
CHANGED
|
@@ -486,6 +486,7 @@ var borderWidths = ["base", "medium", "thick"];
|
|
|
486
486
|
var BorderWidth = freezeEnum(borderWidths);
|
|
487
487
|
var buttonActions = [
|
|
488
488
|
"acceptOffer",
|
|
489
|
+
"addGift",
|
|
489
490
|
"addToOrder",
|
|
490
491
|
"declineAllOffers",
|
|
491
492
|
"declineOffer",
|
|
@@ -495,6 +496,7 @@ var buttonActions = [
|
|
|
495
496
|
"goToPrevPage",
|
|
496
497
|
"goToURL",
|
|
497
498
|
"removeFromOrder",
|
|
499
|
+
"removeGift",
|
|
498
500
|
"selectVariant",
|
|
499
501
|
"showPagination",
|
|
500
502
|
"switchToSubscription",
|
|
@@ -624,6 +626,90 @@ var VariantSelector = freezeEnum(variantSelectors);
|
|
|
624
626
|
var verticalAlignments = ["top", "middle", "bottom"];
|
|
625
627
|
var VerticalAlignment = freezeEnum(verticalAlignments);
|
|
626
628
|
|
|
629
|
+
// src/schema/widgets/checkout-and-beyond/icons.ts
|
|
630
|
+
var iconNames = [
|
|
631
|
+
"alert-circle",
|
|
632
|
+
"alert-triangle",
|
|
633
|
+
"alert-triangle-filled",
|
|
634
|
+
"arrow-down",
|
|
635
|
+
"arrow-left",
|
|
636
|
+
"arrow-right",
|
|
637
|
+
"arrow-up",
|
|
638
|
+
"arrow-up-right",
|
|
639
|
+
"bag",
|
|
640
|
+
"bullet",
|
|
641
|
+
"calendar",
|
|
642
|
+
"camera",
|
|
643
|
+
"caret-down",
|
|
644
|
+
"cart",
|
|
645
|
+
"cash-dollar",
|
|
646
|
+
"categories",
|
|
647
|
+
"check",
|
|
648
|
+
"check-circle",
|
|
649
|
+
"check-circle-filled",
|
|
650
|
+
"chevron-down",
|
|
651
|
+
"chevron-left",
|
|
652
|
+
"chevron-right",
|
|
653
|
+
"chevron-up",
|
|
654
|
+
"circle",
|
|
655
|
+
"clipboard",
|
|
656
|
+
"clock",
|
|
657
|
+
"credit-card",
|
|
658
|
+
"delete",
|
|
659
|
+
"delivered",
|
|
660
|
+
"delivery",
|
|
661
|
+
"disabled",
|
|
662
|
+
"discount",
|
|
663
|
+
"edit",
|
|
664
|
+
"email",
|
|
665
|
+
"empty",
|
|
666
|
+
"external",
|
|
667
|
+
"filter",
|
|
668
|
+
"geolocation",
|
|
669
|
+
"gift-card",
|
|
670
|
+
"globe",
|
|
671
|
+
"grid",
|
|
672
|
+
"image",
|
|
673
|
+
"info",
|
|
674
|
+
"info-filled",
|
|
675
|
+
"list-bulleted",
|
|
676
|
+
"location",
|
|
677
|
+
"lock",
|
|
678
|
+
"map",
|
|
679
|
+
"menu",
|
|
680
|
+
"menu-horizontal",
|
|
681
|
+
"menu-vertical",
|
|
682
|
+
"minus",
|
|
683
|
+
"mobile",
|
|
684
|
+
"note",
|
|
685
|
+
"order",
|
|
686
|
+
"organization",
|
|
687
|
+
"plus",
|
|
688
|
+
"profile",
|
|
689
|
+
"question-circle",
|
|
690
|
+
"question-circle-filled",
|
|
691
|
+
"reorder",
|
|
692
|
+
"reset",
|
|
693
|
+
"return",
|
|
694
|
+
"savings",
|
|
695
|
+
"search",
|
|
696
|
+
"settings",
|
|
697
|
+
"star",
|
|
698
|
+
"star-filled",
|
|
699
|
+
"star-half",
|
|
700
|
+
"store",
|
|
701
|
+
"truck",
|
|
702
|
+
"upload",
|
|
703
|
+
"x",
|
|
704
|
+
"x-circle",
|
|
705
|
+
"x-circle-filled"
|
|
706
|
+
];
|
|
707
|
+
var IconName = freezeEnum(iconNames);
|
|
708
|
+
var iconSizes = ["base", "large", "large-100", "small", "small-100", "small-200"];
|
|
709
|
+
var IconSize = freezeEnum(iconSizes);
|
|
710
|
+
var iconTones = ["auto", "critical", "custom", "info", "neutral", "success", "warning"];
|
|
711
|
+
var IconTone = freezeEnum(iconTones);
|
|
712
|
+
|
|
627
713
|
// src/schema/widgets/checkout-and-beyond/regex.ts
|
|
628
714
|
var DYNAMIC_TOKEN_REGEX = /^\{\{\s*[A-Za-z]+\s*\}\}$/;
|
|
629
715
|
var HEX_COLOR_REGEX = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
@@ -734,12 +820,44 @@ var CABLayoutSection = z8.object({
|
|
|
734
820
|
width: z8.number().default(100)
|
|
735
821
|
});
|
|
736
822
|
|
|
823
|
+
// src/schema/widgets/checkout-and-beyond/utils.ts
|
|
824
|
+
import { isPlainObject, mapValues } from "es-toolkit";
|
|
825
|
+
import { every, get, isArray, isString, map, size, toPairs } from "es-toolkit/compat";
|
|
826
|
+
var isHTML = (html = "") => {
|
|
827
|
+
if (typeof window !== "undefined") {
|
|
828
|
+
const parser = new DOMParser();
|
|
829
|
+
const doc = parser.parseFromString(html, "text/html");
|
|
830
|
+
const hasHTML = (nodeList) => Array.from(nodeList).some((node) => node.nodeType === 1);
|
|
831
|
+
return hasHTML(doc.body.childNodes) || hasHTML(doc.head.childNodes);
|
|
832
|
+
}
|
|
833
|
+
return html.search(HTML_TAGS_REGEX) !== -1;
|
|
834
|
+
};
|
|
835
|
+
var hasHTMLInDoc = (doc) => doc.content.some(({ content = [] }) => content.some(({ text: text2 }) => isHTML(text2)));
|
|
836
|
+
var checkForHTML = (input) => !(isString(input) && isHTML(input) || isPlainObject(input) && hasHTMLInDoc(input));
|
|
837
|
+
var NO_HTML = { message: "HTML is not supported" };
|
|
838
|
+
|
|
737
839
|
// src/schema/widgets/checkout-and-beyond/banner.ts
|
|
738
840
|
var CABBannerSection = z9.lazy(
|
|
739
841
|
() => CABLayoutSection.omit({ sectionType: true }).extend({
|
|
740
842
|
buttonField: z9.enum(buttonFields).optional(),
|
|
741
843
|
color: z9.enum(bannerColors).default("info"),
|
|
742
844
|
dismissible: z9.boolean().default(true),
|
|
845
|
+
/**
|
|
846
|
+
* The `s-banner` heading — localized content (a buyer can see a merchant-composed banner). Absent OR
|
|
847
|
+
* blank ⇒ no heading; the renderer emits no heading slot for `''` rather than an empty one.
|
|
848
|
+
*
|
|
849
|
+
* Merchant-composed buyer-facing plain text, so it rejects HTML at the boundary the same way
|
|
850
|
+
* `CABImageSection.altText` and `CABTextSection.content` do (the unchecked localized records elsewhere —
|
|
851
|
+
* `progressBar`'s gift labels, `reviews`' plurals — are converter/constant-sourced, not merchant input).
|
|
852
|
+
*
|
|
853
|
+
* The refinement is a last-resort ASSERTION, not the normalization boundary: `normalizeTextContent` only
|
|
854
|
+
* rewrites `sectionType: 'text'` nodes' `content`, so nothing strips markup or canonicalizes `{token}`
|
|
855
|
+
* here. A producer must strip upstream the way `composeOffer` does for `altText`. Get it wrong and
|
|
856
|
+
* `salvageSections` stubs the whole banner (children included) with a drift report — degraded, reported,
|
|
857
|
+
* not a 500. Nothing emits `heading` yet; the first converter that maps merchant banner copy into it
|
|
858
|
+
* either strips first or teaches `normalizeTextContent` to strip this field.
|
|
859
|
+
*/
|
|
860
|
+
heading: z9.record(z9.string(), z9.string().refine(checkForHTML, NO_HTML)).optional(),
|
|
743
861
|
sectionType: z9.literal(SectionType.banner).default(SectionType.banner)
|
|
744
862
|
})
|
|
745
863
|
);
|
|
@@ -752,24 +870,6 @@ import { z as z11 } from "zod";
|
|
|
752
870
|
import { forEach, isString as isString2 } from "es-toolkit/compat";
|
|
753
871
|
import { v7 as uuidv72 } from "uuid";
|
|
754
872
|
import { z as z10 } from "zod";
|
|
755
|
-
|
|
756
|
-
// src/schema/widgets/checkout-and-beyond/utils.ts
|
|
757
|
-
import { isPlainObject, mapValues } from "es-toolkit";
|
|
758
|
-
import { every, get, isArray, isString, map, size, toPairs } from "es-toolkit/compat";
|
|
759
|
-
var isHTML = (html = "") => {
|
|
760
|
-
if (typeof window !== "undefined") {
|
|
761
|
-
const parser = new DOMParser();
|
|
762
|
-
const doc = parser.parseFromString(html, "text/html");
|
|
763
|
-
const hasHTML = (nodeList) => Array.from(nodeList).some((node) => node.nodeType === 1);
|
|
764
|
-
return hasHTML(doc.body.childNodes) || hasHTML(doc.head.childNodes);
|
|
765
|
-
}
|
|
766
|
-
return html.search(HTML_TAGS_REGEX) !== -1;
|
|
767
|
-
};
|
|
768
|
-
var hasHTMLInDoc = (doc) => doc.content.some(({ content = [] }) => content.some(({ text: text2 }) => isHTML(text2)));
|
|
769
|
-
var checkForHTML = (input) => !(isString(input) && isHTML(input) || isPlainObject(input) && hasHTMLInDoc(input));
|
|
770
|
-
var NO_HTML = { message: "HTML is not supported" };
|
|
771
|
-
|
|
772
|
-
// src/schema/widgets/checkout-and-beyond/text.ts
|
|
773
873
|
var enumOrOmit = (...vals) => z10.string().transform((val) => vals.includes(val) ? val : void 0).optional();
|
|
774
874
|
var TiptapText = z10.object({
|
|
775
875
|
marks: z10.union([
|
|
@@ -884,6 +984,21 @@ var CABButtonSection = z11.object({
|
|
|
884
984
|
sectionId: z11.uuid().default(() => uuidv73()),
|
|
885
985
|
sections: z11.union([z11.array(CABButtonContent), z11.strictObject({}).transform(() => [])]).default(() => []),
|
|
886
986
|
sectionType: z11.literal(SectionType.button).default(SectionType.button),
|
|
987
|
+
/**
|
|
988
|
+
* The smart-cart tier this button acts on (`addGift`/`removeGift`): scopes the click to one tier's gift. The
|
|
989
|
+
* client resolves the tier's gift (productId) from the progress-bar context by this `tierId` — the button node
|
|
990
|
+
* stays data, no bespoke per-tier wiring. Absent on non-gift buttons (offer add/remove, navigation, links).
|
|
991
|
+
*
|
|
992
|
+
* Deliberately NOT `CABTextTier` (the shape `CABTextSection.tier` uses): a gift button acts on a tier the bar
|
|
993
|
+
* already resolved, so it needs the id and nothing else. Reusing the text tier would make `threshold`
|
|
994
|
+
* required, leave `tierId` optional, and DEFAULT `tierType` to `'shipping'` — a schema-supplied wrong answer
|
|
995
|
+
* on a gift button. Unknown keys are stripped, so a client spreading a whole tier in still parses.
|
|
996
|
+
*
|
|
997
|
+
* `.min(1)` because an empty id IS the silently-id-less state this shape exists to prevent: the client's
|
|
998
|
+
* lookup finds no tier and the click resolves to nothing. Safe to bound — the field is new, so there are no
|
|
999
|
+
* stored payloads to grandfather, and the producer is client code, not a merchant form.
|
|
1000
|
+
*/
|
|
1001
|
+
tier: z11.object({ tierId: z11.string().min(1) }).optional(),
|
|
887
1002
|
/** Fire-and-forget pixel POSTed when the button is clicked (e.g. a Monetize decline). */
|
|
888
1003
|
trackingUrl: z11.string().optional()
|
|
889
1004
|
});
|
|
@@ -1257,8 +1372,12 @@ var CABProgressTier = z20.object({
|
|
|
1257
1372
|
}).optional(),
|
|
1258
1373
|
/**
|
|
1259
1374
|
* The step-row label at this tier's slot (onsite `getTierLabel`): the merchant custom label, else the
|
|
1260
|
-
* type default
|
|
1261
|
-
*
|
|
1375
|
+
* type default — 'Free Shipping' or '{n}% Discount'. A PRODUCT tier gets NO converter label: its name is
|
|
1376
|
+
* the gift PRODUCT title, which the converter can't supply (config carries only product IDs), so the
|
|
1377
|
+
* client resolves it (authoritative Shopify title, React parity) with its own localized generic fallback.
|
|
1378
|
+
* Localized content; absent OR blank ⇒ no label under the tier's icon (the converter's `toTierMeta` already
|
|
1379
|
+
* turns a blank label into an absent key, and a client-authored blank means the same thing — the renderer
|
|
1380
|
+
* emits no caption slot rather than an empty one). Plain text — a compact icon+label.
|
|
1262
1381
|
*/
|
|
1263
1382
|
label: z20.record(z20.string(), z20.string()).optional(),
|
|
1264
1383
|
/**
|
|
@@ -1519,12 +1638,39 @@ var CABSection = z24.lazy(
|
|
|
1519
1638
|
);
|
|
1520
1639
|
|
|
1521
1640
|
// src/schema/widgets/checkout-and-beyond/image.ts
|
|
1522
|
-
var
|
|
1641
|
+
var CABImageSectionFields = z25.object({
|
|
1523
1642
|
altText: z25.string().refine(checkForHTML, NO_HTML).default(""),
|
|
1524
|
-
|
|
1643
|
+
/**
|
|
1644
|
+
* Image width÷height (e.g. `46` for the progress-bar fill); `null` renders at natural size. Any POSITIVE
|
|
1645
|
+
* ratio — never limited to 1, but never `0`/negative either: a renderer dividing by it would get `Infinity`,
|
|
1646
|
+
* and CSS `aspect-ratio` drops a negative value and silently reverts to natural size.
|
|
1647
|
+
*/
|
|
1648
|
+
aspectRatio: z25.number().positive().nullable().default(null),
|
|
1525
1649
|
border: z25.lazy(() => CABBorder),
|
|
1526
1650
|
buttonField: z25.enum(buttonFields).optional(),
|
|
1527
|
-
|
|
1651
|
+
/**
|
|
1652
|
+
* `icon` renders `source` as a single `s-icon` by name (the uber-image path covers icons too), reading
|
|
1653
|
+
* `iconSize`/`iconTone`. The other values are a harmless informational holdover from the previous
|
|
1654
|
+
* implementation — they were never significant to rendering (`icons`, plural, is NOT deprecated, just one of
|
|
1655
|
+
* those inert legacy tags); `icon` is the first value that means anything.
|
|
1656
|
+
*
|
|
1657
|
+
* INVARIANT, encoded by the `.superRefine` below (a refined object IS a valid `z.discriminatedUnion` member
|
|
1658
|
+
* in zod 4 — see `CABTextSection`): `category: 'icon'` ⇒ `source` is an icon name or `''` (icon not yet
|
|
1659
|
+
* chosen); any other category ⇒ `source` is NOT a bare icon name, so it stays a URL/token/`''`.
|
|
1660
|
+
*
|
|
1661
|
+
* Encoded rather than left to the renderer because `source` is ONE union with no category gate, so widening
|
|
1662
|
+
* it with `iconNames` also widened what a STORED payload may contain: 14 of the names are plain English
|
|
1663
|
+
* words (`image`, `x`, `search`, `note`, `order`, `globe`, …), and a legacy `source: 'image'` used to fail
|
|
1664
|
+
* parse — which `salvageSections` turns into a null-rendering stub PLUS a drift report. Ungated it would
|
|
1665
|
+
* instead parse and reach the renderer as `<img src="image">`: a broken image, silently, where the old
|
|
1666
|
+
* behavior degraded gracefully and told us about it. The client-assembled half of the invariant was never
|
|
1667
|
+
* the risky half.
|
|
1668
|
+
*/
|
|
1669
|
+
category: z25.enum(["gallery", "icon", "icons", "payment-methods", "secure-checkout"]).nullable().default(null),
|
|
1670
|
+
/** `icon`-mode only: the `s-icon` `size`; `null` ⇒ the component default (`base`). Ignored by image treatments. */
|
|
1671
|
+
iconSize: z25.enum(iconSizes).nullable().default(null),
|
|
1672
|
+
/** `icon`-mode only: the `s-icon` `tone`; `null` ⇒ the component default (`auto`). Ignored by image treatments. */
|
|
1673
|
+
iconTone: z25.enum(iconTones).nullable().default(null),
|
|
1528
1674
|
name: z25.string().optional(),
|
|
1529
1675
|
naturalHeight: z25.number().default(0),
|
|
1530
1676
|
naturalWidth: z25.number().default(0),
|
|
@@ -1536,9 +1682,31 @@ var CABImageSection = z25.object({
|
|
|
1536
1682
|
rule: CABRule.optional(),
|
|
1537
1683
|
sectionId: z25.uuid().default(() => uuidv712()),
|
|
1538
1684
|
sectionType: z25.literal(SectionType.image).default(SectionType.image),
|
|
1539
|
-
|
|
1685
|
+
/**
|
|
1686
|
+
* An image URL or dynamic token, an empty default, or — when `category: 'icon'` — an icon NAME. Icon mode
|
|
1687
|
+
* takes a name or `''` only, NOT a token: no renderer resolves a token to an icon today, so accepting one
|
|
1688
|
+
* would promise a capability that doesn't exist. Widen the refine's carve-out to `DYNAMIC_TOKEN_REGEX` when a
|
|
1689
|
+
* server-chosen tier icon actually needs it.
|
|
1690
|
+
*/
|
|
1691
|
+
source: z25.union([z25.url(), z25.literal(""), z25.string().regex(DYNAMIC_TOKEN_REGEX), z25.enum(iconNames)]).default(""),
|
|
1540
1692
|
width: z25.number().default(100)
|
|
1541
1693
|
});
|
|
1694
|
+
var iconNameSet = new Set(iconNames);
|
|
1695
|
+
var isIconName = (source) => iconNameSet.has(source);
|
|
1696
|
+
var CABImageSection = CABImageSectionFields.superRefine(({ category, source }, ctx) => {
|
|
1697
|
+
if (category === "icon" && source !== "" && !isIconName(source))
|
|
1698
|
+
ctx.addIssue({
|
|
1699
|
+
code: "custom",
|
|
1700
|
+
message: "icon-mode source must be an icon name",
|
|
1701
|
+
path: ["source"]
|
|
1702
|
+
});
|
|
1703
|
+
if (category !== "icon" && isIconName(source))
|
|
1704
|
+
ctx.addIssue({
|
|
1705
|
+
code: "custom",
|
|
1706
|
+
message: "source must be a URL or dynamic token unless category is `icon`",
|
|
1707
|
+
path: ["source"]
|
|
1708
|
+
});
|
|
1709
|
+
});
|
|
1542
1710
|
|
|
1543
1711
|
// src/transforms/contentBlockV1/stripContentBlockHtml.ts
|
|
1544
1712
|
var HTML_COMMENT_RE = /<!--[\s\S]*?-->/g;
|
|
@@ -3016,7 +3184,7 @@ var tierLabel = (tier) => {
|
|
|
3016
3184
|
if (type === "shipping") return "Free Shipping";
|
|
3017
3185
|
if (type === "discount")
|
|
3018
3186
|
return tier.discountType === "fixedAmount" ? "{{discountAmount}} Off" : `${tier.discountAmountFromTotal ?? 0}% Discount`;
|
|
3019
|
-
return
|
|
3187
|
+
return void 0;
|
|
3020
3188
|
};
|
|
3021
3189
|
var discountOf = (tier) => {
|
|
3022
3190
|
if (tier.type !== "discount") return void 0;
|