@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.
Files changed (43) hide show
  1. package/dist/index.js +204 -23
  2. package/dist/index.js.map +4 -4
  3. package/dist/index.mjs +204 -23
  4. package/dist/index.mjs.map +4 -4
  5. package/dist/schema/checkout-and-beyond/constants.js +2 -0
  6. package/dist/schema/checkout-and-beyond/constants.js.map +2 -2
  7. package/dist/schema/checkout-and-beyond/constants.mjs +2 -0
  8. package/dist/schema/checkout-and-beyond/constants.mjs.map +2 -2
  9. package/dist/schema/checkout-and-beyond/index.js +183 -6
  10. package/dist/schema/checkout-and-beyond/index.js.map +3 -3
  11. package/dist/schema/checkout-and-beyond/index.mjs +183 -6
  12. package/dist/schema/checkout-and-beyond/index.mjs.map +3 -3
  13. package/dist/schema/widget-data.js +197 -23
  14. package/dist/schema/widget-data.js.map +4 -4
  15. package/dist/schema/widget-data.mjs +197 -23
  16. package/dist/schema/widget-data.mjs.map +3 -3
  17. package/dist/schema/widgets/checkout-and-beyond/banner.d.ts +27 -25
  18. package/dist/schema/widgets/checkout-and-beyond/banner.d.ts.map +1 -1
  19. package/dist/schema/widgets/checkout-and-beyond/button.d.ts +5 -0
  20. package/dist/schema/widgets/checkout-and-beyond/button.d.ts.map +1 -1
  21. package/dist/schema/widgets/checkout-and-beyond/carousel.d.ts +25 -25
  22. package/dist/schema/widgets/checkout-and-beyond/cartLine.d.ts +25 -25
  23. package/dist/schema/widgets/checkout-and-beyond/common.d.ts +3 -1
  24. package/dist/schema/widgets/checkout-and-beyond/common.d.ts.map +1 -1
  25. package/dist/schema/widgets/checkout-and-beyond/icons.d.ts +124 -0
  26. package/dist/schema/widgets/checkout-and-beyond/icons.d.ts.map +1 -0
  27. package/dist/schema/widgets/checkout-and-beyond/image.d.ts +319 -2
  28. package/dist/schema/widgets/checkout-and-beyond/image.d.ts.map +1 -1
  29. package/dist/schema/widgets/checkout-and-beyond/index.d.ts +1 -0
  30. package/dist/schema/widgets/checkout-and-beyond/index.d.ts.map +1 -1
  31. package/dist/schema/widgets/checkout-and-beyond/offers.d.ts +25 -25
  32. package/dist/schema/widgets/checkout-and-beyond/progressBar.d.ts +25 -25
  33. package/dist/schema/widgets/checkout-and-beyond/progressBar.d.ts.map +1 -1
  34. package/dist/server/index.js +193 -25
  35. package/dist/server/index.js.map +4 -4
  36. package/dist/server/index.mjs +193 -25
  37. package/dist/server/index.mjs.map +4 -4
  38. package/dist/transforms/index.js +193 -25
  39. package/dist/transforms/index.js.map +3 -3
  40. package/dist/transforms/index.mjs +193 -25
  41. package/dist/transforms/index.mjs.map +3 -3
  42. package/dist/transforms/smartCart/convertSmartCartProgressBarToV2.d.ts.map +1 -1
  43. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1269,6 +1269,7 @@ var borderWidths = ["base", "medium", "thick"];
1269
1269
  var BorderWidth = freezeEnum(borderWidths);
1270
1270
  var buttonActions = [
1271
1271
  "acceptOffer",
1272
+ "addGift",
1272
1273
  "addToOrder",
1273
1274
  "declineAllOffers",
1274
1275
  "declineOffer",
@@ -1278,6 +1279,7 @@ var buttonActions = [
1278
1279
  "goToPrevPage",
1279
1280
  "goToURL",
1280
1281
  "removeFromOrder",
1282
+ "removeGift",
1281
1283
  "selectVariant",
1282
1284
  "showPagination",
1283
1285
  "switchToSubscription",
@@ -1576,22 +1578,10 @@ import { z as z27 } from "zod";
1576
1578
 
1577
1579
  // src/schema/widgets/checkout-and-beyond/banner.ts
1578
1580
  import { z as z11 } from "zod";
1579
- var CABBannerSection = z11.lazy(
1580
- () => CABLayoutSection.omit({ sectionType: true }).extend({
1581
- buttonField: z11.enum(buttonFields).optional(),
1582
- color: z11.enum(bannerColors).default("info"),
1583
- dismissible: z11.boolean().default(true),
1584
- sectionType: z11.literal(SectionType.banner).default(SectionType.banner)
1585
- })
1586
- );
1587
1581
 
1588
- // src/schema/widgets/checkout-and-beyond/button.ts
1589
- import { v7 as uuidv73 } from "uuid";
1590
- import { z as z14 } from "zod";
1591
-
1592
- // src/schema/widgets/checkout-and-beyond/image.ts
1593
- import { v7 as uuidv7 } from "uuid";
1594
- import { z as z12 } from "zod";
1582
+ // src/schema/widgets/checkout-and-beyond/utils.ts
1583
+ import { isPlainObject, mapValues } from "es-toolkit";
1584
+ import { every, get as get2, isArray, isString, map, size, toPairs } from "es-toolkit/compat";
1595
1585
 
1596
1586
  // src/schema/widgets/checkout-and-beyond/regex.ts
1597
1587
  var ARRAY_INDEX_STRING = /^(0|[1-9]\d*)$/;
@@ -1601,8 +1591,6 @@ var ROOT_RELATIVE_PATH_REGEX = /^\/(?!\/)/;
1601
1591
  var HTML_TAGS_REGEX = /<\/?[a-zA-Z][^>]*>/g;
1602
1592
 
1603
1593
  // src/schema/widgets/checkout-and-beyond/utils.ts
1604
- import { isPlainObject, mapValues } from "es-toolkit";
1605
- import { every, get as get2, isArray, isString, map, size, toPairs } from "es-toolkit/compat";
1606
1594
  var isHTML = (html = "") => {
1607
1595
  if (typeof window !== "undefined") {
1608
1596
  const parser = new DOMParser();
@@ -1644,13 +1632,158 @@ var convertNumericObjects = (input) => {
1644
1632
  return input;
1645
1633
  };
1646
1634
 
1635
+ // src/schema/widgets/checkout-and-beyond/banner.ts
1636
+ var CABBannerSection = z11.lazy(
1637
+ () => CABLayoutSection.omit({ sectionType: true }).extend({
1638
+ buttonField: z11.enum(buttonFields).optional(),
1639
+ color: z11.enum(bannerColors).default("info"),
1640
+ dismissible: z11.boolean().default(true),
1641
+ /**
1642
+ * The `s-banner` heading — localized content (a buyer can see a merchant-composed banner). Absent OR
1643
+ * blank ⇒ no heading; the renderer emits no heading slot for `''` rather than an empty one.
1644
+ *
1645
+ * Merchant-composed buyer-facing plain text, so it rejects HTML at the boundary the same way
1646
+ * `CABImageSection.altText` and `CABTextSection.content` do (the unchecked localized records elsewhere —
1647
+ * `progressBar`'s gift labels, `reviews`' plurals — are converter/constant-sourced, not merchant input).
1648
+ *
1649
+ * The refinement is a last-resort ASSERTION, not the normalization boundary: `normalizeTextContent` only
1650
+ * rewrites `sectionType: 'text'` nodes' `content`, so nothing strips markup or canonicalizes `{token}`
1651
+ * here. A producer must strip upstream the way `composeOffer` does for `altText`. Get it wrong and
1652
+ * `salvageSections` stubs the whole banner (children included) with a drift report — degraded, reported,
1653
+ * not a 500. Nothing emits `heading` yet; the first converter that maps merchant banner copy into it
1654
+ * either strips first or teaches `normalizeTextContent` to strip this field.
1655
+ */
1656
+ heading: z11.record(z11.string(), z11.string().refine(checkForHTML, NO_HTML)).optional(),
1657
+ sectionType: z11.literal(SectionType.banner).default(SectionType.banner)
1658
+ })
1659
+ );
1660
+
1661
+ // src/schema/widgets/checkout-and-beyond/button.ts
1662
+ import { v7 as uuidv73 } from "uuid";
1663
+ import { z as z14 } from "zod";
1664
+
1665
+ // src/schema/widgets/checkout-and-beyond/image.ts
1666
+ import { v7 as uuidv7 } from "uuid";
1667
+ import { z as z12 } from "zod";
1668
+
1669
+ // src/schema/widgets/checkout-and-beyond/icons.ts
1670
+ var iconNames = [
1671
+ "alert-circle",
1672
+ "alert-triangle",
1673
+ "alert-triangle-filled",
1674
+ "arrow-down",
1675
+ "arrow-left",
1676
+ "arrow-right",
1677
+ "arrow-up",
1678
+ "arrow-up-right",
1679
+ "bag",
1680
+ "bullet",
1681
+ "calendar",
1682
+ "camera",
1683
+ "caret-down",
1684
+ "cart",
1685
+ "cash-dollar",
1686
+ "categories",
1687
+ "check",
1688
+ "check-circle",
1689
+ "check-circle-filled",
1690
+ "chevron-down",
1691
+ "chevron-left",
1692
+ "chevron-right",
1693
+ "chevron-up",
1694
+ "circle",
1695
+ "clipboard",
1696
+ "clock",
1697
+ "credit-card",
1698
+ "delete",
1699
+ "delivered",
1700
+ "delivery",
1701
+ "disabled",
1702
+ "discount",
1703
+ "edit",
1704
+ "email",
1705
+ "empty",
1706
+ "external",
1707
+ "filter",
1708
+ "geolocation",
1709
+ "gift-card",
1710
+ "globe",
1711
+ "grid",
1712
+ "image",
1713
+ "info",
1714
+ "info-filled",
1715
+ "list-bulleted",
1716
+ "location",
1717
+ "lock",
1718
+ "map",
1719
+ "menu",
1720
+ "menu-horizontal",
1721
+ "menu-vertical",
1722
+ "minus",
1723
+ "mobile",
1724
+ "note",
1725
+ "order",
1726
+ "organization",
1727
+ "plus",
1728
+ "profile",
1729
+ "question-circle",
1730
+ "question-circle-filled",
1731
+ "reorder",
1732
+ "reset",
1733
+ "return",
1734
+ "savings",
1735
+ "search",
1736
+ "settings",
1737
+ "star",
1738
+ "star-filled",
1739
+ "star-half",
1740
+ "store",
1741
+ "truck",
1742
+ "upload",
1743
+ "x",
1744
+ "x-circle",
1745
+ "x-circle-filled"
1746
+ ];
1747
+ var IconName = freezeEnum(iconNames);
1748
+ var iconSizes = ["base", "large", "large-100", "small", "small-100", "small-200"];
1749
+ var IconSize = freezeEnum(iconSizes);
1750
+ var iconTones = ["auto", "critical", "custom", "info", "neutral", "success", "warning"];
1751
+ var IconTone = freezeEnum(iconTones);
1752
+
1647
1753
  // src/schema/widgets/checkout-and-beyond/image.ts
1648
- var CABImageSection = z12.object({
1754
+ var CABImageSectionFields = z12.object({
1649
1755
  altText: z12.string().refine(checkForHTML, NO_HTML).default(""),
1650
- aspectRatio: z12.literal(1).nullable().default(null),
1756
+ /**
1757
+ * Image width÷height (e.g. `46` for the progress-bar fill); `null` renders at natural size. Any POSITIVE
1758
+ * ratio — never limited to 1, but never `0`/negative either: a renderer dividing by it would get `Infinity`,
1759
+ * and CSS `aspect-ratio` drops a negative value and silently reverts to natural size.
1760
+ */
1761
+ aspectRatio: z12.number().positive().nullable().default(null),
1651
1762
  border: z12.lazy(() => CABBorder),
1652
1763
  buttonField: z12.enum(buttonFields).optional(),
1653
- category: z12.enum(["gallery", "icons", "payment-methods", "secure-checkout"]).nullable().default(null),
1764
+ /**
1765
+ * `icon` renders `source` as a single `s-icon` by name (the uber-image path covers icons too), reading
1766
+ * `iconSize`/`iconTone`. The other values are a harmless informational holdover from the previous
1767
+ * implementation — they were never significant to rendering (`icons`, plural, is NOT deprecated, just one of
1768
+ * those inert legacy tags); `icon` is the first value that means anything.
1769
+ *
1770
+ * INVARIANT, encoded by the `.superRefine` below (a refined object IS a valid `z.discriminatedUnion` member
1771
+ * in zod 4 — see `CABTextSection`): `category: 'icon'` ⇒ `source` is an icon name or `''` (icon not yet
1772
+ * chosen); any other category ⇒ `source` is NOT a bare icon name, so it stays a URL/token/`''`.
1773
+ *
1774
+ * Encoded rather than left to the renderer because `source` is ONE union with no category gate, so widening
1775
+ * it with `iconNames` also widened what a STORED payload may contain: 14 of the names are plain English
1776
+ * words (`image`, `x`, `search`, `note`, `order`, `globe`, …), and a legacy `source: 'image'` used to fail
1777
+ * parse — which `salvageSections` turns into a null-rendering stub PLUS a drift report. Ungated it would
1778
+ * instead parse and reach the renderer as `<img src="image">`: a broken image, silently, where the old
1779
+ * behavior degraded gracefully and told us about it. The client-assembled half of the invariant was never
1780
+ * the risky half.
1781
+ */
1782
+ category: z12.enum(["gallery", "icon", "icons", "payment-methods", "secure-checkout"]).nullable().default(null),
1783
+ /** `icon`-mode only: the `s-icon` `size`; `null` ⇒ the component default (`base`). Ignored by image treatments. */
1784
+ iconSize: z12.enum(iconSizes).nullable().default(null),
1785
+ /** `icon`-mode only: the `s-icon` `tone`; `null` ⇒ the component default (`auto`). Ignored by image treatments. */
1786
+ iconTone: z12.enum(iconTones).nullable().default(null),
1654
1787
  name: z12.string().optional(),
1655
1788
  naturalHeight: z12.number().default(0),
1656
1789
  naturalWidth: z12.number().default(0),
@@ -1662,9 +1795,31 @@ var CABImageSection = z12.object({
1662
1795
  rule: CABRule.optional(),
1663
1796
  sectionId: z12.uuid().default(() => uuidv7()),
1664
1797
  sectionType: z12.literal(SectionType.image).default(SectionType.image),
1665
- source: z12.union([z12.url(), z12.literal(""), z12.string().regex(DYNAMIC_TOKEN_REGEX)]).default(""),
1798
+ /**
1799
+ * An image URL or dynamic token, an empty default, or — when `category: 'icon'` — an icon NAME. Icon mode
1800
+ * takes a name or `''` only, NOT a token: no renderer resolves a token to an icon today, so accepting one
1801
+ * would promise a capability that doesn't exist. Widen the refine's carve-out to `DYNAMIC_TOKEN_REGEX` when a
1802
+ * server-chosen tier icon actually needs it.
1803
+ */
1804
+ source: z12.union([z12.url(), z12.literal(""), z12.string().regex(DYNAMIC_TOKEN_REGEX), z12.enum(iconNames)]).default(""),
1666
1805
  width: z12.number().default(100)
1667
1806
  });
1807
+ var iconNameSet = new Set(iconNames);
1808
+ var isIconName = (source) => iconNameSet.has(source);
1809
+ var CABImageSection = CABImageSectionFields.superRefine(({ category, source }, ctx) => {
1810
+ if (category === "icon" && source !== "" && !isIconName(source))
1811
+ ctx.addIssue({
1812
+ code: "custom",
1813
+ message: "icon-mode source must be an icon name",
1814
+ path: ["source"]
1815
+ });
1816
+ if (category !== "icon" && isIconName(source))
1817
+ ctx.addIssue({
1818
+ code: "custom",
1819
+ message: "source must be a URL or dynamic token unless category is `icon`",
1820
+ path: ["source"]
1821
+ });
1822
+ });
1668
1823
 
1669
1824
  // src/schema/widgets/checkout-and-beyond/text.ts
1670
1825
  import { forEach, isString as isString2 } from "es-toolkit/compat";
@@ -1784,6 +1939,21 @@ var CABButtonSection = z14.object({
1784
1939
  sectionId: z14.uuid().default(() => uuidv73()),
1785
1940
  sections: z14.union([z14.array(CABButtonContent), z14.strictObject({}).transform(() => [])]).default(() => []),
1786
1941
  sectionType: z14.literal(SectionType.button).default(SectionType.button),
1942
+ /**
1943
+ * The smart-cart tier this button acts on (`addGift`/`removeGift`): scopes the click to one tier's gift. The
1944
+ * client resolves the tier's gift (productId) from the progress-bar context by this `tierId` — the button node
1945
+ * stays data, no bespoke per-tier wiring. Absent on non-gift buttons (offer add/remove, navigation, links).
1946
+ *
1947
+ * Deliberately NOT `CABTextTier` (the shape `CABTextSection.tier` uses): a gift button acts on a tier the bar
1948
+ * already resolved, so it needs the id and nothing else. Reusing the text tier would make `threshold`
1949
+ * required, leave `tierId` optional, and DEFAULT `tierType` to `'shipping'` — a schema-supplied wrong answer
1950
+ * on a gift button. Unknown keys are stripped, so a client spreading a whole tier in still parses.
1951
+ *
1952
+ * `.min(1)` because an empty id IS the silently-id-less state this shape exists to prevent: the client's
1953
+ * lookup finds no tier and the click resolves to nothing. Safe to bound — the field is new, so there are no
1954
+ * stored payloads to grandfather, and the producer is client code, not a merchant form.
1955
+ */
1956
+ tier: z14.object({ tierId: z14.string().min(1) }).optional(),
1787
1957
  /** Fire-and-forget pixel POSTed when the button is clicked (e.g. a Monetize decline). */
1788
1958
  trackingUrl: z14.string().optional()
1789
1959
  });
@@ -2079,8 +2249,12 @@ var CABProgressTier = z23.object({
2079
2249
  }).optional(),
2080
2250
  /**
2081
2251
  * The step-row label at this tier's slot (onsite `getTierLabel`): the merchant custom label, else the
2082
- * type default ('Free Shipping' / product title / '{n}% Discount'). Localized content; blank ⇒ no
2083
- * label under the tier's icon. Plain text — the step row is a compact icon+label, not rich copy.
2252
+ * type default — 'Free Shipping' or '{n}% Discount'. A PRODUCT tier gets NO converter label: its name is
2253
+ * the gift PRODUCT title, which the converter can't supply (config carries only product IDs), so the
2254
+ * client resolves it (authoritative Shopify title, React parity) with its own localized generic fallback.
2255
+ * Localized content; absent OR blank ⇒ no label under the tier's icon (the converter's `toTierMeta` already
2256
+ * turns a blank label into an absent key, and a client-authored blank means the same thing — the renderer
2257
+ * emits no caption slot rather than an empty one). Plain text — a compact icon+label.
2084
2258
  */
2085
2259
  label: z23.record(z23.string(), z23.string()).optional(),
2086
2260
  /**
@@ -4164,6 +4338,7 @@ export {
4164
4338
  CABDiscountSection,
4165
4339
  CABExperiment,
4166
4340
  CABImageSection,
4341
+ CABImageSectionFields,
4167
4342
  CABIntegrations,
4168
4343
  CABLayoutSection,
4169
4344
  CABMonetizeSection,
@@ -4205,6 +4380,9 @@ export {
4205
4380
  HEX_COLOR_REGEX,
4206
4381
  HTML_TAGS_REGEX,
4207
4382
  HorizontalAlignment,
4383
+ IconName,
4384
+ IconSize,
4385
+ IconTone,
4208
4386
  Identity,
4209
4387
  ImageBlock,
4210
4388
  ImageContentBlock,
@@ -4299,6 +4477,9 @@ export {
4299
4477
  getIdFromGraphUrl,
4300
4478
  hasHTMLInDoc,
4301
4479
  horizontalAlignments,
4480
+ iconNames,
4481
+ iconSizes,
4482
+ iconTones,
4302
4483
  isBannerType,
4303
4484
  isBase64Encoded,
4304
4485
  isButtonType,