@rebuy/rebuy 2.34.0-rc.3 → 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 +128 -67
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +128 -67
- package/dist/index.mjs.map +4 -4
- package/dist/schema/checkout-and-beyond/index.js +73 -16
- package/dist/schema/checkout-and-beyond/index.js.map +2 -2
- package/dist/schema/checkout-and-beyond/index.mjs +73 -16
- package/dist/schema/checkout-and-beyond/index.mjs.map +2 -2
- package/dist/schema/widget-data.js +98 -38
- package/dist/schema/widget-data.js.map +4 -4
- package/dist/schema/widget-data.mjs +98 -38
- package/dist/schema/widget-data.mjs.map +3 -3
- package/dist/schema/widgets/checkout-and-beyond/banner.d.ts +25 -25
- package/dist/schema/widgets/checkout-and-beyond/banner.d.ts.map +1 -1
- package/dist/schema/widgets/checkout-and-beyond/button.d.ts +1 -9
- 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/image.d.ts +223 -0
- package/dist/schema/widgets/checkout-and-beyond/image.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 +88 -34
- package/dist/server/index.js.map +4 -4
- package/dist/server/index.mjs +88 -34
- package/dist/server/index.mjs.map +4 -4
- package/dist/transforms/index.js +88 -34
- package/dist/transforms/index.js.map +3 -3
- package/dist/transforms/index.mjs +88 -34
- package/dist/transforms/index.mjs.map +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -42,6 +42,7 @@ __export(src_exports, {
|
|
|
42
42
|
CABDiscountSection: () => CABDiscountSection,
|
|
43
43
|
CABExperiment: () => CABExperiment,
|
|
44
44
|
CABImageSection: () => CABImageSection,
|
|
45
|
+
CABImageSectionFields: () => CABImageSectionFields,
|
|
45
46
|
CABIntegrations: () => CABIntegrations,
|
|
46
47
|
CABLayoutSection: () => CABLayoutSection,
|
|
47
48
|
CABMonetizeSection: () => CABMonetizeSection,
|
|
@@ -1830,13 +1831,82 @@ var import_zod27 = require("zod");
|
|
|
1830
1831
|
|
|
1831
1832
|
// src/schema/widgets/checkout-and-beyond/banner.ts
|
|
1832
1833
|
var import_zod11 = require("zod");
|
|
1834
|
+
|
|
1835
|
+
// src/schema/widgets/checkout-and-beyond/utils.ts
|
|
1836
|
+
var import_es_toolkit2 = require("es-toolkit");
|
|
1837
|
+
var import_compat = require("es-toolkit/compat");
|
|
1838
|
+
|
|
1839
|
+
// src/schema/widgets/checkout-and-beyond/regex.ts
|
|
1840
|
+
var ARRAY_INDEX_STRING = /^(0|[1-9]\d*)$/;
|
|
1841
|
+
var DYNAMIC_TOKEN_REGEX = /^\{\{\s*[A-Za-z]+\s*\}\}$/;
|
|
1842
|
+
var HEX_COLOR_REGEX = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
1843
|
+
var ROOT_RELATIVE_PATH_REGEX = /^\/(?!\/)/;
|
|
1844
|
+
var HTML_TAGS_REGEX = /<\/?[a-zA-Z][^>]*>/g;
|
|
1845
|
+
|
|
1846
|
+
// src/schema/widgets/checkout-and-beyond/utils.ts
|
|
1847
|
+
var isHTML = (html = "") => {
|
|
1848
|
+
if (typeof window !== "undefined") {
|
|
1849
|
+
const parser = new DOMParser();
|
|
1850
|
+
const doc = parser.parseFromString(html, "text/html");
|
|
1851
|
+
const hasHTML = (nodeList) => Array.from(nodeList).some((node) => node.nodeType === 1);
|
|
1852
|
+
return hasHTML(doc.body.childNodes) || hasHTML(doc.head.childNodes);
|
|
1853
|
+
}
|
|
1854
|
+
return html.search(HTML_TAGS_REGEX) !== -1;
|
|
1855
|
+
};
|
|
1856
|
+
var hasHTMLInDoc = (doc) => doc.content.some(({ content = [] }) => content.some(({ text }) => isHTML(text)));
|
|
1857
|
+
var checkForHTML = (input) => !((0, import_compat.isString)(input) && isHTML(input) || (0, import_es_toolkit2.isPlainObject)(input) && hasHTMLInDoc(input));
|
|
1858
|
+
var NO_HTML = { message: "HTML is not supported" };
|
|
1859
|
+
var isBannerType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.banner;
|
|
1860
|
+
var isButtonType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.button;
|
|
1861
|
+
var isCarouselType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.carousel;
|
|
1862
|
+
var isCartLineType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.cartLine;
|
|
1863
|
+
var isDataSourceType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.dataSource;
|
|
1864
|
+
var isDiscountType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.discount;
|
|
1865
|
+
var isImageType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.image;
|
|
1866
|
+
var isLayoutType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.layout;
|
|
1867
|
+
var isMonetizeType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.monetize;
|
|
1868
|
+
var isOffersType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.offers;
|
|
1869
|
+
var isOverlayType = (section) => isLayoutType(section) && (0, import_compat.get)(section, "buttonField") === ButtonField.overlayContent;
|
|
1870
|
+
var isProductType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.product;
|
|
1871
|
+
var isProductsType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.products;
|
|
1872
|
+
var isProgressBarType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.progressBar;
|
|
1873
|
+
var isQuantityType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.quantity;
|
|
1874
|
+
var isReviewsType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.reviews;
|
|
1875
|
+
var isTextType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.text;
|
|
1876
|
+
var isVariantsType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.variants;
|
|
1877
|
+
var hasOnlyNumericKeys = (input) => !!(0, import_compat.size)(input) && (0, import_compat.every)(input, (_, key) => ARRAY_INDEX_STRING.test(key) && Number.isSafeInteger(Number(key)));
|
|
1878
|
+
var numericObjectToArray = (input) => (0, import_compat.toPairs)(input).sort(([a], [b]) => Number(a) - Number(b)).map(([_, value]) => value);
|
|
1879
|
+
var convertNumericObjects = (input) => {
|
|
1880
|
+
if ((0, import_compat.isArray)(input)) return (0, import_compat.map)(input, convertNumericObjects);
|
|
1881
|
+
if ((0, import_es_toolkit2.isPlainObject)(input)) {
|
|
1882
|
+
const obj = input;
|
|
1883
|
+
return hasOnlyNumericKeys(obj) ? (0, import_compat.map)(numericObjectToArray(obj), convertNumericObjects) : (0, import_es_toolkit2.mapValues)(obj, convertNumericObjects);
|
|
1884
|
+
}
|
|
1885
|
+
return input;
|
|
1886
|
+
};
|
|
1887
|
+
|
|
1888
|
+
// src/schema/widgets/checkout-and-beyond/banner.ts
|
|
1833
1889
|
var CABBannerSection = import_zod11.z.lazy(
|
|
1834
1890
|
() => CABLayoutSection.omit({ sectionType: true }).extend({
|
|
1835
1891
|
buttonField: import_zod11.z.enum(buttonFields).optional(),
|
|
1836
1892
|
color: import_zod11.z.enum(bannerColors).default("info"),
|
|
1837
1893
|
dismissible: import_zod11.z.boolean().default(true),
|
|
1838
|
-
/**
|
|
1839
|
-
|
|
1894
|
+
/**
|
|
1895
|
+
* The `s-banner` heading — localized content (a buyer can see a merchant-composed banner). Absent OR
|
|
1896
|
+
* blank ⇒ no heading; the renderer emits no heading slot for `''` rather than an empty one.
|
|
1897
|
+
*
|
|
1898
|
+
* Merchant-composed buyer-facing plain text, so it rejects HTML at the boundary the same way
|
|
1899
|
+
* `CABImageSection.altText` and `CABTextSection.content` do (the unchecked localized records elsewhere —
|
|
1900
|
+
* `progressBar`'s gift labels, `reviews`' plurals — are converter/constant-sourced, not merchant input).
|
|
1901
|
+
*
|
|
1902
|
+
* The refinement is a last-resort ASSERTION, not the normalization boundary: `normalizeTextContent` only
|
|
1903
|
+
* rewrites `sectionType: 'text'` nodes' `content`, so nothing strips markup or canonicalizes `{token}`
|
|
1904
|
+
* here. A producer must strip upstream the way `composeOffer` does for `altText`. Get it wrong and
|
|
1905
|
+
* `salvageSections` stubs the whole banner (children included) with a drift report — degraded, reported,
|
|
1906
|
+
* not a 500. Nothing emits `heading` yet; the first converter that maps merchant banner copy into it
|
|
1907
|
+
* either strips first or teaches `normalizeTextContent` to strip this field.
|
|
1908
|
+
*/
|
|
1909
|
+
heading: import_zod11.z.record(import_zod11.z.string(), import_zod11.z.string().refine(checkForHTML, NO_HTML)).optional(),
|
|
1840
1910
|
sectionType: import_zod11.z.literal(SectionType.banner).default(SectionType.banner)
|
|
1841
1911
|
})
|
|
1842
1912
|
);
|
|
@@ -1933,62 +2003,15 @@ var IconSize = freezeEnum(iconSizes);
|
|
|
1933
2003
|
var iconTones = ["auto", "critical", "custom", "info", "neutral", "success", "warning"];
|
|
1934
2004
|
var IconTone = freezeEnum(iconTones);
|
|
1935
2005
|
|
|
1936
|
-
// src/schema/widgets/checkout-and-beyond/regex.ts
|
|
1937
|
-
var ARRAY_INDEX_STRING = /^(0|[1-9]\d*)$/;
|
|
1938
|
-
var DYNAMIC_TOKEN_REGEX = /^\{\{\s*[A-Za-z]+\s*\}\}$/;
|
|
1939
|
-
var HEX_COLOR_REGEX = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
1940
|
-
var ROOT_RELATIVE_PATH_REGEX = /^\/(?!\/)/;
|
|
1941
|
-
var HTML_TAGS_REGEX = /<\/?[a-zA-Z][^>]*>/g;
|
|
1942
|
-
|
|
1943
|
-
// src/schema/widgets/checkout-and-beyond/utils.ts
|
|
1944
|
-
var import_es_toolkit2 = require("es-toolkit");
|
|
1945
|
-
var import_compat = require("es-toolkit/compat");
|
|
1946
|
-
var isHTML = (html = "") => {
|
|
1947
|
-
if (typeof window !== "undefined") {
|
|
1948
|
-
const parser = new DOMParser();
|
|
1949
|
-
const doc = parser.parseFromString(html, "text/html");
|
|
1950
|
-
const hasHTML = (nodeList) => Array.from(nodeList).some((node) => node.nodeType === 1);
|
|
1951
|
-
return hasHTML(doc.body.childNodes) || hasHTML(doc.head.childNodes);
|
|
1952
|
-
}
|
|
1953
|
-
return html.search(HTML_TAGS_REGEX) !== -1;
|
|
1954
|
-
};
|
|
1955
|
-
var hasHTMLInDoc = (doc) => doc.content.some(({ content = [] }) => content.some(({ text }) => isHTML(text)));
|
|
1956
|
-
var checkForHTML = (input) => !((0, import_compat.isString)(input) && isHTML(input) || (0, import_es_toolkit2.isPlainObject)(input) && hasHTMLInDoc(input));
|
|
1957
|
-
var NO_HTML = { message: "HTML is not supported" };
|
|
1958
|
-
var isBannerType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.banner;
|
|
1959
|
-
var isButtonType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.button;
|
|
1960
|
-
var isCarouselType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.carousel;
|
|
1961
|
-
var isCartLineType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.cartLine;
|
|
1962
|
-
var isDataSourceType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.dataSource;
|
|
1963
|
-
var isDiscountType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.discount;
|
|
1964
|
-
var isImageType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.image;
|
|
1965
|
-
var isLayoutType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.layout;
|
|
1966
|
-
var isMonetizeType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.monetize;
|
|
1967
|
-
var isOffersType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.offers;
|
|
1968
|
-
var isOverlayType = (section) => isLayoutType(section) && (0, import_compat.get)(section, "buttonField") === ButtonField.overlayContent;
|
|
1969
|
-
var isProductType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.product;
|
|
1970
|
-
var isProductsType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.products;
|
|
1971
|
-
var isProgressBarType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.progressBar;
|
|
1972
|
-
var isQuantityType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.quantity;
|
|
1973
|
-
var isReviewsType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.reviews;
|
|
1974
|
-
var isTextType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.text;
|
|
1975
|
-
var isVariantsType = (section) => (0, import_compat.get)(section, "sectionType") === SectionType.variants;
|
|
1976
|
-
var hasOnlyNumericKeys = (input) => !!(0, import_compat.size)(input) && (0, import_compat.every)(input, (_, key) => ARRAY_INDEX_STRING.test(key) && Number.isSafeInteger(Number(key)));
|
|
1977
|
-
var numericObjectToArray = (input) => (0, import_compat.toPairs)(input).sort(([a], [b]) => Number(a) - Number(b)).map(([_, value]) => value);
|
|
1978
|
-
var convertNumericObjects = (input) => {
|
|
1979
|
-
if ((0, import_compat.isArray)(input)) return (0, import_compat.map)(input, convertNumericObjects);
|
|
1980
|
-
if ((0, import_es_toolkit2.isPlainObject)(input)) {
|
|
1981
|
-
const obj = input;
|
|
1982
|
-
return hasOnlyNumericKeys(obj) ? (0, import_compat.map)(numericObjectToArray(obj), convertNumericObjects) : (0, import_es_toolkit2.mapValues)(obj, convertNumericObjects);
|
|
1983
|
-
}
|
|
1984
|
-
return input;
|
|
1985
|
-
};
|
|
1986
|
-
|
|
1987
2006
|
// src/schema/widgets/checkout-and-beyond/image.ts
|
|
1988
|
-
var
|
|
2007
|
+
var CABImageSectionFields = import_zod12.z.object({
|
|
1989
2008
|
altText: import_zod12.z.string().refine(checkForHTML, NO_HTML).default(""),
|
|
1990
|
-
/**
|
|
1991
|
-
|
|
2009
|
+
/**
|
|
2010
|
+
* Image width÷height (e.g. `46` for the progress-bar fill); `null` renders at natural size. Any POSITIVE
|
|
2011
|
+
* ratio — never limited to 1, but never `0`/negative either: a renderer dividing by it would get `Infinity`,
|
|
2012
|
+
* and CSS `aspect-ratio` drops a negative value and silently reverts to natural size.
|
|
2013
|
+
*/
|
|
2014
|
+
aspectRatio: import_zod12.z.number().positive().nullable().default(null),
|
|
1992
2015
|
border: import_zod12.z.lazy(() => CABBorder),
|
|
1993
2016
|
buttonField: import_zod12.z.enum(buttonFields).optional(),
|
|
1994
2017
|
/**
|
|
@@ -1997,10 +2020,17 @@ var CABImageSection = import_zod12.z.object({
|
|
|
1997
2020
|
* implementation — they were never significant to rendering (`icons`, plural, is NOT deprecated, just one of
|
|
1998
2021
|
* those inert legacy tags); `icon` is the first value that means anything.
|
|
1999
2022
|
*
|
|
2000
|
-
* INVARIANT
|
|
2001
|
-
*
|
|
2002
|
-
*
|
|
2003
|
-
*
|
|
2023
|
+
* INVARIANT, encoded by the `.superRefine` below (a refined object IS a valid `z.discriminatedUnion` member
|
|
2024
|
+
* in zod 4 — see `CABTextSection`): `category: 'icon'` ⇒ `source` is an icon name or `''` (icon not yet
|
|
2025
|
+
* chosen); any other category ⇒ `source` is NOT a bare icon name, so it stays a URL/token/`''`.
|
|
2026
|
+
*
|
|
2027
|
+
* Encoded rather than left to the renderer because `source` is ONE union with no category gate, so widening
|
|
2028
|
+
* it with `iconNames` also widened what a STORED payload may contain: 14 of the names are plain English
|
|
2029
|
+
* words (`image`, `x`, `search`, `note`, `order`, `globe`, …), and a legacy `source: 'image'` used to fail
|
|
2030
|
+
* parse — which `salvageSections` turns into a null-rendering stub PLUS a drift report. Ungated it would
|
|
2031
|
+
* instead parse and reach the renderer as `<img src="image">`: a broken image, silently, where the old
|
|
2032
|
+
* behavior degraded gracefully and told us about it. The client-assembled half of the invariant was never
|
|
2033
|
+
* the risky half.
|
|
2004
2034
|
*/
|
|
2005
2035
|
category: import_zod12.z.enum(["gallery", "icon", "icons", "payment-methods", "secure-checkout"]).nullable().default(null),
|
|
2006
2036
|
/** `icon`-mode only: the `s-icon` `size`; `null` ⇒ the component default (`base`). Ignored by image treatments. */
|
|
@@ -2018,10 +2048,31 @@ var CABImageSection = import_zod12.z.object({
|
|
|
2018
2048
|
rule: CABRule.optional(),
|
|
2019
2049
|
sectionId: import_zod12.z.uuid().default(() => (0, import_uuid.v7)()),
|
|
2020
2050
|
sectionType: import_zod12.z.literal(SectionType.image).default(SectionType.image),
|
|
2021
|
-
/**
|
|
2051
|
+
/**
|
|
2052
|
+
* An image URL or dynamic token, an empty default, or — when `category: 'icon'` — an icon NAME. Icon mode
|
|
2053
|
+
* takes a name or `''` only, NOT a token: no renderer resolves a token to an icon today, so accepting one
|
|
2054
|
+
* would promise a capability that doesn't exist. Widen the refine's carve-out to `DYNAMIC_TOKEN_REGEX` when a
|
|
2055
|
+
* server-chosen tier icon actually needs it.
|
|
2056
|
+
*/
|
|
2022
2057
|
source: import_zod12.z.union([import_zod12.z.url(), import_zod12.z.literal(""), import_zod12.z.string().regex(DYNAMIC_TOKEN_REGEX), import_zod12.z.enum(iconNames)]).default(""),
|
|
2023
2058
|
width: import_zod12.z.number().default(100)
|
|
2024
2059
|
});
|
|
2060
|
+
var iconNameSet = new Set(iconNames);
|
|
2061
|
+
var isIconName = (source) => iconNameSet.has(source);
|
|
2062
|
+
var CABImageSection = CABImageSectionFields.superRefine(({ category, source }, ctx) => {
|
|
2063
|
+
if (category === "icon" && source !== "" && !isIconName(source))
|
|
2064
|
+
ctx.addIssue({
|
|
2065
|
+
code: "custom",
|
|
2066
|
+
message: "icon-mode source must be an icon name",
|
|
2067
|
+
path: ["source"]
|
|
2068
|
+
});
|
|
2069
|
+
if (category !== "icon" && isIconName(source))
|
|
2070
|
+
ctx.addIssue({
|
|
2071
|
+
code: "custom",
|
|
2072
|
+
message: "source must be a URL or dynamic token unless category is `icon`",
|
|
2073
|
+
path: ["source"]
|
|
2074
|
+
});
|
|
2075
|
+
});
|
|
2025
2076
|
|
|
2026
2077
|
// src/schema/widgets/checkout-and-beyond/text.ts
|
|
2027
2078
|
var import_compat2 = require("es-toolkit/compat");
|
|
@@ -2142,12 +2193,20 @@ var CABButtonSection = import_zod14.z.object({
|
|
|
2142
2193
|
sections: import_zod14.z.union([import_zod14.z.array(CABButtonContent), import_zod14.z.strictObject({}).transform(() => [])]).default(() => []),
|
|
2143
2194
|
sectionType: import_zod14.z.literal(SectionType.button).default(SectionType.button),
|
|
2144
2195
|
/**
|
|
2145
|
-
* The smart-cart tier this button acts on (`addGift`/`removeGift`): scopes the click to one tier's gift
|
|
2146
|
-
*
|
|
2147
|
-
*
|
|
2148
|
-
*
|
|
2196
|
+
* The smart-cart tier this button acts on (`addGift`/`removeGift`): scopes the click to one tier's gift. The
|
|
2197
|
+
* client resolves the tier's gift (productId) from the progress-bar context by this `tierId` — the button node
|
|
2198
|
+
* stays data, no bespoke per-tier wiring. Absent on non-gift buttons (offer add/remove, navigation, links).
|
|
2199
|
+
*
|
|
2200
|
+
* Deliberately NOT `CABTextTier` (the shape `CABTextSection.tier` uses): a gift button acts on a tier the bar
|
|
2201
|
+
* already resolved, so it needs the id and nothing else. Reusing the text tier would make `threshold`
|
|
2202
|
+
* required, leave `tierId` optional, and DEFAULT `tierType` to `'shipping'` — a schema-supplied wrong answer
|
|
2203
|
+
* on a gift button. Unknown keys are stripped, so a client spreading a whole tier in still parses.
|
|
2204
|
+
*
|
|
2205
|
+
* `.min(1)` because an empty id IS the silently-id-less state this shape exists to prevent: the client's
|
|
2206
|
+
* lookup finds no tier and the click resolves to nothing. Safe to bound — the field is new, so there are no
|
|
2207
|
+
* stored payloads to grandfather, and the producer is client code, not a merchant form.
|
|
2149
2208
|
*/
|
|
2150
|
-
tier:
|
|
2209
|
+
tier: import_zod14.z.object({ tierId: import_zod14.z.string().min(1) }).optional(),
|
|
2151
2210
|
/** Fire-and-forget pixel POSTed when the button is clicked (e.g. a Monetize decline). */
|
|
2152
2211
|
trackingUrl: import_zod14.z.string().optional()
|
|
2153
2212
|
});
|
|
@@ -2446,7 +2505,9 @@ var CABProgressTier = import_zod23.z.object({
|
|
|
2446
2505
|
* type default — 'Free Shipping' or '{n}% Discount'. A PRODUCT tier gets NO converter label: its name is
|
|
2447
2506
|
* the gift PRODUCT title, which the converter can't supply (config carries only product IDs), so the
|
|
2448
2507
|
* client resolves it (authoritative Shopify title, React parity) with its own localized generic fallback.
|
|
2449
|
-
* Localized content; absent ⇒ no label under the tier's icon
|
|
2508
|
+
* Localized content; absent OR blank ⇒ no label under the tier's icon (the converter's `toTierMeta` already
|
|
2509
|
+
* turns a blank label into an absent key, and a client-authored blank means the same thing — the renderer
|
|
2510
|
+
* emits no caption slot rather than an empty one). Plain text — a compact icon+label.
|
|
2450
2511
|
*/
|
|
2451
2512
|
label: import_zod23.z.record(import_zod23.z.string(), import_zod23.z.string()).optional(),
|
|
2452
2513
|
/**
|