@rebuy/rebuy 3.5.0 → 3.6.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.cjs +740 -647
- package/dist/index.mjs +740 -647
- package/dist/schema/checkout-and-beyond/constants.cjs +16 -0
- package/dist/schema/checkout-and-beyond/constants.mjs +16 -0
- package/dist/schema/checkout-and-beyond/index.cjs +454 -362
- package/dist/schema/checkout-and-beyond/index.mjs +454 -362
- package/dist/schema/widget-data.cjs +508 -435
- package/dist/schema/widget-data.mjs +508 -435
- package/dist/schema/widgetData.d.ts +438 -147
- package/dist/schema/widgets/checkout-and-beyond/banner.d.ts +145 -48
- package/dist/schema/widgets/checkout-and-beyond/button.d.ts +154 -49
- package/dist/schema/widgets/checkout-and-beyond/carousel.d.ts +145 -48
- package/dist/schema/widgets/checkout-and-beyond/cartLine.d.ts +145 -48
- package/dist/schema/widgets/checkout-and-beyond/common.d.ts +29 -0
- package/dist/schema/widgets/checkout-and-beyond/discount.d.ts +146 -0
- package/dist/schema/widgets/checkout-and-beyond/icons.d.ts +1 -1
- package/dist/schema/widgets/checkout-and-beyond/image.d.ts +294 -100
- package/dist/schema/widgets/checkout-and-beyond/index.d.ts +1 -0
- package/dist/schema/widgets/checkout-and-beyond/layout.d.ts +148 -52
- package/dist/schema/widgets/checkout-and-beyond/monetize.d.ts +146 -49
- package/dist/schema/widgets/checkout-and-beyond/offers.d.ts +145 -48
- package/dist/schema/widgets/checkout-and-beyond/product.d.ts +146 -0
- package/dist/schema/widgets/checkout-and-beyond/products.d.ts +292 -0
- package/dist/schema/widgets/checkout-and-beyond/progressBar.d.ts +145 -48
- package/dist/schema/widgets/checkout-and-beyond/quantity.d.ts +146 -49
- package/dist/schema/widgets/checkout-and-beyond/reviews.d.ts +146 -49
- package/dist/schema/widgets/checkout-and-beyond/root.d.ts +146 -49
- package/dist/schema/widgets/checkout-and-beyond/rule.d.ts +140 -68
- package/dist/schema/widgets/checkout-and-beyond/text.d.ts +146 -49
- package/dist/schema/widgets/checkout-and-beyond/variables.d.ts +470 -0
- package/dist/schema/widgets/checkout-and-beyond/variants.d.ts +146 -49
- package/dist/schema/widgets/contentBlock.d.ts +146 -49
- package/dist/schema/widgets/lineItemEditor.d.ts +146 -49
- package/dist/schema/widgets/rebuyButton.d.ts +146 -49
- package/dist/server/index.cjs +492 -416
- package/dist/server/index.mjs +492 -416
- package/dist/transforms/index.cjs +393 -317
- package/dist/transforms/index.mjs +393 -317
- package/dist/transforms/monetizeV1/convertMonetizeToV2.d.ts +2 -2
- package/package.json +1 -1
package/dist/server/index.mjs
CHANGED
|
@@ -536,7 +536,7 @@ var CabUserConfig = z6.object({
|
|
|
536
536
|
|
|
537
537
|
// src/schema/widgets/checkout-and-beyond/image.ts
|
|
538
538
|
import { v7 as uuidv712 } from "uuid";
|
|
539
|
-
import { z as
|
|
539
|
+
import { z as z26 } from "zod";
|
|
540
540
|
|
|
541
541
|
// src/schema/widgets/checkout-and-beyond/common.ts
|
|
542
542
|
var freezeEnum = (values) => Object.freeze(Object.fromEntries(values.map((v) => [v, v])));
|
|
@@ -643,6 +643,8 @@ var languageKeys = [
|
|
|
643
643
|
"zh"
|
|
644
644
|
];
|
|
645
645
|
var LanguageKey = freezeEnum(languageKeys);
|
|
646
|
+
var mutatorEvents = ["item_added", "quantity_changed", "variant_selected"];
|
|
647
|
+
var MutatorEvent = freezeEnum(mutatorEvents);
|
|
646
648
|
var objectFits = ["cover", "contain"];
|
|
647
649
|
var ObjectFit = freezeEnum(objectFits);
|
|
648
650
|
var popoverPositions = ["inlineStart", "inlineEnd", "blockStart", "blockEnd"];
|
|
@@ -655,6 +657,10 @@ var progressTierUnits = ["currency", "item"];
|
|
|
655
657
|
var ProgressTierUnit = freezeEnum(progressTierUnits);
|
|
656
658
|
var quantityInputs = ["select", "number"];
|
|
657
659
|
var QuantityInput = freezeEnum(quantityInputs);
|
|
660
|
+
var resultCountOperators = ["equals", "greater_than", "less_than"];
|
|
661
|
+
var ResultCountOperator = freezeEnum(resultCountOperators);
|
|
662
|
+
var resultTagOperators = ["contains", "does_not_contain"];
|
|
663
|
+
var ResultTagOperator = freezeEnum(resultTagOperators);
|
|
658
664
|
var reviewsSizes = ["small", "default", "large"];
|
|
659
665
|
var ReviewsSize = freezeEnum(reviewsSizes);
|
|
660
666
|
var sectionTypes = [
|
|
@@ -687,6 +693,8 @@ var inlineTextSizeNames = ["extraSmall", "small", "base", "medium", "large", "ex
|
|
|
687
693
|
var InlineTextSizeName = freezeEnum(inlineTextSizeNames);
|
|
688
694
|
var textSizeNames = [...inlineTextSizeNames, "heading"];
|
|
689
695
|
var TextSizeName = freezeEnum(textSizeNames);
|
|
696
|
+
var variableEffects = ["set_false", "set_true", "toggle"];
|
|
697
|
+
var VariableEffect = freezeEnum(variableEffects);
|
|
690
698
|
var variantModes = ["multiple", "single"];
|
|
691
699
|
var VariantMode = freezeEnum(variantModes);
|
|
692
700
|
var variantSelectors = ["menu", "radio", "button"];
|
|
@@ -784,6 +792,19 @@ var HEX_COLOR_REGEX = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
|
784
792
|
var ROOT_RELATIVE_PATH_REGEX = /^\/(?!\/)/;
|
|
785
793
|
var HTML_TAGS_REGEX = /<\/?[a-zA-Z][^>]*>/g;
|
|
786
794
|
|
|
795
|
+
// src/schema/widgets/checkout-and-beyond/shared.ts
|
|
796
|
+
import { z as z25 } from "zod";
|
|
797
|
+
|
|
798
|
+
// src/schema/widgets/checkout-and-beyond/banner.ts
|
|
799
|
+
import { z as z10 } from "zod";
|
|
800
|
+
|
|
801
|
+
// src/schema/widgets/checkout-and-beyond/layout.ts
|
|
802
|
+
import { v7 as uuidv7 } from "uuid";
|
|
803
|
+
import { z as z9 } from "zod";
|
|
804
|
+
|
|
805
|
+
// src/schema/widgets/checkout-and-beyond/variables.ts
|
|
806
|
+
import { z as z8 } from "zod";
|
|
807
|
+
|
|
787
808
|
// src/schema/widgets/checkout-and-beyond/rule.ts
|
|
788
809
|
import { z as z7 } from "zod";
|
|
789
810
|
var ruleTypes = [
|
|
@@ -830,62 +851,108 @@ var RuleCondition = z7.object({
|
|
|
830
851
|
var RuleLogicBlock = z7.object({
|
|
831
852
|
rules: z7.array(RuleCondition).default(() => [])
|
|
832
853
|
});
|
|
833
|
-
var
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
z7.
|
|
838
|
-
z7.
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
key: z7.string().default("should_show"),
|
|
844
|
-
type: z7.literal("data_json").default("data_json"),
|
|
845
|
-
value: z7.string().default("true")
|
|
846
|
-
})
|
|
847
|
-
).default(() => [{ key: "should_show", type: "data_json", value: "true" }])
|
|
848
|
-
})
|
|
849
|
-
),
|
|
850
|
-
z7.strictObject({}).transform(() => [])
|
|
851
|
-
]).default(() => [])
|
|
854
|
+
var CABRulesetEntry = z7.object({
|
|
855
|
+
exitIfMatched: z7.boolean().default(true),
|
|
856
|
+
logic: z7.array(RuleLogicBlock).default(() => []),
|
|
857
|
+
output: z7.array(
|
|
858
|
+
z7.object({
|
|
859
|
+
key: z7.string().default("should_show"),
|
|
860
|
+
type: z7.literal("data_json").default("data_json"),
|
|
861
|
+
value: z7.string().default("true")
|
|
862
|
+
})
|
|
863
|
+
).default(() => [{ key: "should_show", type: "data_json", value: "true" }])
|
|
852
864
|
});
|
|
865
|
+
var CABRuleset = z7.union([z7.array(CABRulesetEntry), z7.strictObject({}).transform(() => [])]).default(() => []);
|
|
853
866
|
|
|
854
|
-
// src/schema/widgets/checkout-and-beyond/
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
867
|
+
// src/schema/widgets/checkout-and-beyond/variables.ts
|
|
868
|
+
var variableEffect = z8.enum(variableEffects);
|
|
869
|
+
var CABVariableSeed = z8.object({
|
|
870
|
+
dataSourceId: z8.number().nullable().default(null),
|
|
871
|
+
ruleset: CABRuleset
|
|
872
|
+
});
|
|
873
|
+
var CABVariable = z8.object({
|
|
874
|
+
/**
|
|
875
|
+
* Holds until the first seed verdict lands (and forever, for unseeded variables). Omitted, it derives
|
|
876
|
+
* from seededness — `false` with a `seed` (visibility is EARNED), `true` without — via the transform
|
|
877
|
+
* below; a cross-field default has no `.default()` spelling. An explicit value always wins.
|
|
878
|
+
*/
|
|
879
|
+
defaultValue: z8.boolean().optional(),
|
|
880
|
+
name: z8.string().min(1),
|
|
881
|
+
seed: CABVariableSeed.optional()
|
|
882
|
+
}).transform(({ defaultValue, ...variable }) => ({
|
|
883
|
+
defaultValue: defaultValue ?? variable.seed === void 0,
|
|
884
|
+
...variable
|
|
885
|
+
}));
|
|
886
|
+
var CABVariableEffect = z8.object({
|
|
887
|
+
effect: variableEffect.default(VariableEffect.toggle),
|
|
888
|
+
variable: z8.string().min(1)
|
|
889
|
+
});
|
|
890
|
+
var CABVisibility = z8.object({
|
|
891
|
+
variable: z8.string().min(1),
|
|
892
|
+
visibleWhen: z8.boolean().default(true)
|
|
893
|
+
});
|
|
894
|
+
var resultCountOperator = z8.enum(resultCountOperators);
|
|
895
|
+
var resultTagOperator = z8.enum(resultTagOperators);
|
|
896
|
+
var mutatorEvent = z8.enum(mutatorEvents);
|
|
897
|
+
var CABResultCountTrigger = z8.object({
|
|
898
|
+
operator: resultCountOperator.default(ResultCountOperator.equals),
|
|
899
|
+
type: z8.literal("result_count"),
|
|
900
|
+
value: z8.number().default(0)
|
|
901
|
+
});
|
|
902
|
+
var CABResultTagTrigger = z8.object({
|
|
903
|
+
operator: resultTagOperator.default(ResultTagOperator.contains),
|
|
904
|
+
type: z8.literal("result_tag"),
|
|
905
|
+
value: z8.string().min(1)
|
|
906
|
+
});
|
|
907
|
+
var CABEventTrigger = z8.object({
|
|
908
|
+
event: mutatorEvent,
|
|
909
|
+
type: z8.literal("event")
|
|
910
|
+
});
|
|
911
|
+
var CABVariableTrigger = z8.discriminatedUnion("type", [
|
|
912
|
+
CABEventTrigger,
|
|
913
|
+
CABResultCountTrigger,
|
|
914
|
+
CABResultTagTrigger
|
|
915
|
+
]);
|
|
916
|
+
var CABVariableMutator = z8.object({
|
|
917
|
+
effect: variableEffect.default(VariableEffect.set_false),
|
|
918
|
+
variable: z8.string().min(1),
|
|
919
|
+
when: CABVariableTrigger
|
|
920
|
+
});
|
|
921
|
+
var CABVariableFields = {
|
|
922
|
+
mutators: z8.array(CABVariableMutator).optional(),
|
|
923
|
+
variables: z8.array(CABVariable).refine((variables) => new Set(variables.map(({ name }) => name)).size === variables.length, {
|
|
924
|
+
message: "variable names must be unique within a section"
|
|
925
|
+
}).optional(),
|
|
926
|
+
visibility: CABVisibility.optional()
|
|
927
|
+
};
|
|
859
928
|
|
|
860
929
|
// src/schema/widgets/checkout-and-beyond/layout.ts
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
vertical: z8.enum(verticalAlignments).default(VerticalAlignment.top)
|
|
930
|
+
var GridItem = z9.union([z9.literal("auto"), z9.literal("fill"), z9.string().regex(/^\d+%$/), z9.number()]);
|
|
931
|
+
var CABLayoutSection = z9.object({
|
|
932
|
+
...CABVariableFields,
|
|
933
|
+
alignment: z9.object({
|
|
934
|
+
horizontal: z9.enum(horizontalAlignments).default(HorizontalAlignment.start),
|
|
935
|
+
vertical: z9.enum(verticalAlignments).default(VerticalAlignment.top)
|
|
868
936
|
}).default({
|
|
869
937
|
horizontal: HorizontalAlignment.start,
|
|
870
938
|
vertical: VerticalAlignment.top
|
|
871
939
|
}),
|
|
872
|
-
border:
|
|
873
|
-
buttonField:
|
|
874
|
-
direction:
|
|
875
|
-
grid:
|
|
876
|
-
columns:
|
|
877
|
-
rows:
|
|
940
|
+
border: z9.lazy(() => CABBorder),
|
|
941
|
+
buttonField: z9.enum(buttonFields).optional(),
|
|
942
|
+
direction: z9.enum(directions).default(Direction.rows),
|
|
943
|
+
grid: z9.object({
|
|
944
|
+
columns: z9.union([z9.array(GridItem), z9.undefined()]).default(() => ["auto"]),
|
|
945
|
+
rows: z9.union([z9.array(GridItem), z9.undefined()]).default(() => ["auto"])
|
|
878
946
|
}).default({ columns: ["auto"], rows: ["auto"] }).optional(),
|
|
879
|
-
name:
|
|
880
|
-
padding:
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
spacing: z8.enum(spacings).default(Spacing.base),
|
|
947
|
+
name: z9.string().optional(),
|
|
948
|
+
padding: z9.enum(spacings).default(Spacing.none),
|
|
949
|
+
sectionId: z9.uuid().default(() => uuidv7()),
|
|
950
|
+
sections: z9.union([z9.array(z9.lazy(() => CABSection)), z9.strictObject({}).transform(() => [])]).default(() => []),
|
|
951
|
+
sectionType: z9.literal(SectionType.layout).default(SectionType.layout),
|
|
952
|
+
spacing: z9.enum(spacings).default(Spacing.base),
|
|
886
953
|
/** Fire-and-forget impression pixel POSTed once when the section is shown (e.g. a Monetize offer view). */
|
|
887
|
-
viewUrl:
|
|
888
|
-
width:
|
|
954
|
+
viewUrl: z9.string().optional(),
|
|
955
|
+
width: z9.number().default(100)
|
|
889
956
|
});
|
|
890
957
|
|
|
891
958
|
// src/schema/widgets/checkout-and-beyond/utils.ts
|
|
@@ -955,11 +1022,11 @@ var isTextType = isSectionType(SectionType.text);
|
|
|
955
1022
|
var isVariantsType = isSectionType(SectionType.variants);
|
|
956
1023
|
|
|
957
1024
|
// src/schema/widgets/checkout-and-beyond/banner.ts
|
|
958
|
-
var CABBannerSection =
|
|
1025
|
+
var CABBannerSection = z10.lazy(
|
|
959
1026
|
() => CABLayoutSection.omit({ sectionType: true }).extend({
|
|
960
|
-
buttonField:
|
|
961
|
-
color:
|
|
962
|
-
dismissible:
|
|
1027
|
+
buttonField: z10.enum(buttonFields).optional(),
|
|
1028
|
+
color: z10.enum(bannerColors).default("info"),
|
|
1029
|
+
dismissible: z10.boolean().default(true),
|
|
963
1030
|
/**
|
|
964
1031
|
* The `s-banner` heading — localized content (a buyer can see a merchant-composed banner). Absent OR
|
|
965
1032
|
* blank ⇒ no heading; the renderer emits no heading slot for `''` rather than an empty one.
|
|
@@ -975,83 +1042,83 @@ var CABBannerSection = z9.lazy(
|
|
|
975
1042
|
* not a 500. Nothing emits `heading` yet; the first converter that maps merchant banner copy into it
|
|
976
1043
|
* either strips first or teaches `normalizeTextContent` to strip this field.
|
|
977
1044
|
*/
|
|
978
|
-
heading:
|
|
979
|
-
sectionType:
|
|
1045
|
+
heading: z10.record(z10.string(), z10.string().refine(checkForHTML, NO_HTML)).optional(),
|
|
1046
|
+
sectionType: z10.literal(SectionType.banner).default(SectionType.banner)
|
|
980
1047
|
})
|
|
981
1048
|
);
|
|
982
1049
|
|
|
983
1050
|
// src/schema/widgets/checkout-and-beyond/button.ts
|
|
984
1051
|
import { v7 as uuidv73 } from "uuid";
|
|
985
|
-
import { z as
|
|
1052
|
+
import { z as z12 } from "zod";
|
|
986
1053
|
|
|
987
1054
|
// src/schema/widgets/checkout-and-beyond/text.ts
|
|
988
1055
|
import { forEach, isString as isString2 } from "es-toolkit/compat";
|
|
989
1056
|
import { v7 as uuidv72 } from "uuid";
|
|
990
|
-
import { z as
|
|
991
|
-
var enumOrOmit = (...vals) =>
|
|
992
|
-
var TiptapText =
|
|
993
|
-
marks:
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
attrs:
|
|
1000
|
-
class:
|
|
1001
|
-
href:
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1057
|
+
import { z as z11 } from "zod";
|
|
1058
|
+
var enumOrOmit = (...vals) => z11.string().transform((val) => vals.includes(val) ? val : void 0).optional();
|
|
1059
|
+
var TiptapText = z11.object({
|
|
1060
|
+
marks: z11.union([
|
|
1061
|
+
z11.array(
|
|
1062
|
+
z11.discriminatedUnion("type", [
|
|
1063
|
+
z11.object({ type: z11.literal("bold") }),
|
|
1064
|
+
z11.object({ type: z11.literal("italic") }),
|
|
1065
|
+
z11.object({
|
|
1066
|
+
attrs: z11.object({
|
|
1067
|
+
class: z11.string().nullable(),
|
|
1068
|
+
href: z11.union([
|
|
1069
|
+
z11.url(),
|
|
1070
|
+
z11.literal("#"),
|
|
1071
|
+
z11.string().regex(DYNAMIC_TOKEN_REGEX),
|
|
1072
|
+
z11.string().regex(ROOT_RELATIVE_PATH_REGEX)
|
|
1006
1073
|
]),
|
|
1007
|
-
rel:
|
|
1008
|
-
target:
|
|
1074
|
+
rel: z11.string().default("noopener noreferrer nofollow"),
|
|
1075
|
+
target: z11.string().default("_blank")
|
|
1009
1076
|
}),
|
|
1010
|
-
type:
|
|
1077
|
+
type: z11.literal("link")
|
|
1011
1078
|
}),
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
attrs:
|
|
1079
|
+
z11.object({ type: z11.literal("strike") }),
|
|
1080
|
+
z11.object({
|
|
1081
|
+
attrs: z11.object({
|
|
1015
1082
|
color: enumOrOmit(...textColorNames).default(TextColorName.base),
|
|
1016
1083
|
fontSize: enumOrOmit(...textSizeNames).default(TextSizeName.base)
|
|
1017
1084
|
}),
|
|
1018
|
-
type:
|
|
1085
|
+
type: z11.literal("textStyle")
|
|
1019
1086
|
})
|
|
1020
1087
|
])
|
|
1021
1088
|
),
|
|
1022
|
-
|
|
1089
|
+
z11.strictObject({}).transform(() => [])
|
|
1023
1090
|
]).optional(),
|
|
1024
|
-
text:
|
|
1025
|
-
type:
|
|
1091
|
+
text: z11.string().default(""),
|
|
1092
|
+
type: z11.literal("text").default("text")
|
|
1026
1093
|
});
|
|
1027
|
-
var TiptapParagraph =
|
|
1028
|
-
attrs:
|
|
1094
|
+
var TiptapParagraph = z11.object({
|
|
1095
|
+
attrs: z11.object({
|
|
1029
1096
|
textAlign: enumOrOmit(...textAlignments)
|
|
1030
1097
|
}).default({ textAlign: TextAlignment.start }),
|
|
1031
|
-
content:
|
|
1032
|
-
type:
|
|
1098
|
+
content: z11.union([z11.array(TiptapText), z11.strictObject({}).transform(() => [])]).default(() => []),
|
|
1099
|
+
type: z11.literal("paragraph").default("paragraph")
|
|
1033
1100
|
});
|
|
1034
|
-
var TiptapDocument =
|
|
1035
|
-
attrs:
|
|
1101
|
+
var TiptapDocument = z11.object({
|
|
1102
|
+
attrs: z11.object({
|
|
1036
1103
|
blockSpacing: enumOrOmit(...spacings)
|
|
1037
1104
|
}).default({ blockSpacing: Spacing.base }),
|
|
1038
|
-
content:
|
|
1039
|
-
type:
|
|
1105
|
+
content: z11.union([z11.array(TiptapParagraph), z11.strictObject({}).transform(() => [])]).default(() => [TiptapParagraph.parse({})]),
|
|
1106
|
+
type: z11.literal("doc").default("doc")
|
|
1040
1107
|
});
|
|
1041
|
-
var CABTextTier =
|
|
1042
|
-
threshold:
|
|
1043
|
-
thresholds:
|
|
1044
|
-
tierId:
|
|
1045
|
-
tierType:
|
|
1108
|
+
var CABTextTier = z11.object({
|
|
1109
|
+
threshold: z11.number().int().nonnegative(),
|
|
1110
|
+
thresholds: z11.record(z11.string(), z11.number().int().nonnegative()).default(() => ({})),
|
|
1111
|
+
tierId: z11.string().optional(),
|
|
1112
|
+
tierType: z11.enum(progressTierTypes).default(ProgressTierType.shipping)
|
|
1046
1113
|
});
|
|
1047
|
-
var CABTextSection =
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
sectionId:
|
|
1054
|
-
sectionType:
|
|
1114
|
+
var CABTextSection = z11.object({
|
|
1115
|
+
...CABVariableFields,
|
|
1116
|
+
buttonField: z11.enum(buttonFields).optional(),
|
|
1117
|
+
content: z11.record(z11.string(), z11.union([z11.string(), TiptapDocument]).refine(checkForHTML, NO_HTML).optional()).default({ en: TiptapDocument.parse({}) }).optional(),
|
|
1118
|
+
name: z11.string().optional(),
|
|
1119
|
+
optionId: z11.number().optional(),
|
|
1120
|
+
sectionId: z11.uuid().default(() => uuidv72()),
|
|
1121
|
+
sectionType: z11.literal(SectionType.text).default(SectionType.text),
|
|
1055
1122
|
tier: CABTextTier.optional()
|
|
1056
1123
|
}).superRefine(({ buttonField, content }, ctx) => {
|
|
1057
1124
|
if (buttonField === ButtonField.destinationUrl && content) {
|
|
@@ -1073,35 +1140,35 @@ var CABTextSection = z10.object({
|
|
|
1073
1140
|
});
|
|
1074
1141
|
|
|
1075
1142
|
// src/schema/widgets/checkout-and-beyond/button.ts
|
|
1076
|
-
var CABButtonContent =
|
|
1077
|
-
() =>
|
|
1143
|
+
var CABButtonContent = z12.lazy(
|
|
1144
|
+
() => z12.discriminatedUnion("sectionType", [CABImageSection, CABLayoutSection, CABTextSection])
|
|
1078
1145
|
);
|
|
1079
|
-
var CABButtonSection =
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1146
|
+
var CABButtonSection = z12.object({
|
|
1147
|
+
...CABVariableFields,
|
|
1148
|
+
action: z12.union([z12.literal(""), z12.enum(buttonActions)]).default(""),
|
|
1149
|
+
buttonStyle: z12.enum(buttonStyles).default(ButtonStyle.primary),
|
|
1150
|
+
custom: z12.object({
|
|
1151
|
+
color: z12.string().regex(HEX_COLOR_REGEX).default("#005bd3"),
|
|
1152
|
+
height: z12.number().default(52),
|
|
1153
|
+
width: z12.number().default(300)
|
|
1086
1154
|
}).default({
|
|
1087
1155
|
color: "#005bd3",
|
|
1088
1156
|
height: 52,
|
|
1089
1157
|
width: 300
|
|
1090
1158
|
}),
|
|
1091
|
-
disableDowngrade:
|
|
1092
|
-
name:
|
|
1093
|
-
optionId:
|
|
1094
|
-
popover:
|
|
1095
|
-
alignment:
|
|
1096
|
-
position:
|
|
1159
|
+
disableDowngrade: z12.boolean().default(false),
|
|
1160
|
+
name: z12.string().optional(),
|
|
1161
|
+
optionId: z12.number().optional(),
|
|
1162
|
+
popover: z12.object({
|
|
1163
|
+
alignment: z12.enum(textAlignments).default(TextAlignment.center),
|
|
1164
|
+
position: z12.enum(popoverPositions).default(PopoverPosition.blockStart)
|
|
1097
1165
|
}).optional().default(() => ({
|
|
1098
1166
|
alignment: TextAlignment.center,
|
|
1099
1167
|
position: PopoverPosition.blockStart
|
|
1100
1168
|
})),
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
sectionType: z11.literal(SectionType.button).default(SectionType.button),
|
|
1169
|
+
sectionId: z12.uuid().default(() => uuidv73()),
|
|
1170
|
+
sections: z12.union([z12.array(CABButtonContent), z12.strictObject({}).transform(() => [])]).default(() => []),
|
|
1171
|
+
sectionType: z12.literal(SectionType.button).default(SectionType.button),
|
|
1105
1172
|
/**
|
|
1106
1173
|
* The smart-cart tier this button acts on (`addGift`/`removeGift`): scopes the click to one tier's gift. The
|
|
1107
1174
|
* client resolves the tier's gift (productId) from the progress-bar context by this `tierId` — the button node
|
|
@@ -1116,20 +1183,25 @@ var CABButtonSection = z11.object({
|
|
|
1116
1183
|
* lookup finds no tier and the click resolves to nothing. Safe to bound — the field is new, so there are no
|
|
1117
1184
|
* stored payloads to grandfather, and the producer is client code, not a merchant form.
|
|
1118
1185
|
*/
|
|
1119
|
-
tier:
|
|
1186
|
+
tier: z12.object({ tierId: z12.string().min(1) }).optional(),
|
|
1120
1187
|
/** Fire-and-forget pixel POSTed when the button is clicked (e.g. a Monetize decline). */
|
|
1121
|
-
trackingUrl:
|
|
1188
|
+
trackingUrl: z12.string().optional(),
|
|
1189
|
+
/**
|
|
1190
|
+
* Secondary effects applied to in-scope variables on click, alongside (never instead of) the primary
|
|
1191
|
+
* `action` — an `addToOrder` button can also flip a variable. Applied in array order.
|
|
1192
|
+
*/
|
|
1193
|
+
variableEffects: z12.array(CABVariableEffect).optional()
|
|
1122
1194
|
});
|
|
1123
1195
|
|
|
1124
1196
|
// src/schema/widgets/checkout-and-beyond/carousel.ts
|
|
1125
|
-
import { z as
|
|
1197
|
+
import { z as z17 } from "zod";
|
|
1126
1198
|
|
|
1127
1199
|
// src/schema/widgets/checkout-and-beyond/offers.ts
|
|
1128
|
-
import { z as
|
|
1200
|
+
import { z as z16 } from "zod";
|
|
1129
1201
|
|
|
1130
1202
|
// src/schema/widgets/checkout-and-beyond/dataSource.ts
|
|
1131
1203
|
import { v7 as uuidv74 } from "uuid";
|
|
1132
|
-
import { z as
|
|
1204
|
+
import { z as z13 } from "zod";
|
|
1133
1205
|
|
|
1134
1206
|
// src/schema/widgets/checkout-and-beyond/constants.ts
|
|
1135
1207
|
import { uniqBy } from "es-toolkit";
|
|
@@ -1208,72 +1280,74 @@ var widgetTypes = [
|
|
|
1208
1280
|
var WidgetType = freezeEnum(widgetTypes);
|
|
1209
1281
|
|
|
1210
1282
|
// src/schema/widgets/checkout-and-beyond/dataSource.ts
|
|
1211
|
-
var CABDiscount =
|
|
1212
|
-
amount:
|
|
1213
|
-
discountedBy:
|
|
1214
|
-
discountedFrom:
|
|
1215
|
-
type:
|
|
1283
|
+
var CABDiscount = z13.object({
|
|
1284
|
+
amount: z13.union([z13.number(), z13.string()]).catch(0),
|
|
1285
|
+
discountedBy: z13.string().optional(),
|
|
1286
|
+
discountedFrom: z13.enum(discountSources).optional().catch(void 0),
|
|
1287
|
+
type: z13.enum(discountTypes).catch("none")
|
|
1216
1288
|
});
|
|
1217
|
-
var CABIntegrations =
|
|
1218
|
-
judgeme:
|
|
1219
|
-
junip:
|
|
1220
|
-
klaviyo:
|
|
1221
|
-
loox:
|
|
1222
|
-
okendo:
|
|
1223
|
-
opinew:
|
|
1224
|
-
reviewsio:
|
|
1225
|
-
stamped:
|
|
1226
|
-
yotpo:
|
|
1289
|
+
var CABIntegrations = z13.object({
|
|
1290
|
+
judgeme: z13.boolean().default(false),
|
|
1291
|
+
junip: z13.boolean().default(false),
|
|
1292
|
+
klaviyo: z13.boolean().default(false),
|
|
1293
|
+
loox: z13.boolean().default(false),
|
|
1294
|
+
okendo: z13.boolean().default(false),
|
|
1295
|
+
opinew: z13.boolean().default(false),
|
|
1296
|
+
reviewsio: z13.boolean().default(false),
|
|
1297
|
+
stamped: z13.boolean().default(false),
|
|
1298
|
+
yotpo: z13.boolean().default(false)
|
|
1227
1299
|
});
|
|
1228
|
-
var CABDataSourceSection =
|
|
1229
|
-
dataSourceId:
|
|
1230
|
-
dataSourcePath:
|
|
1300
|
+
var CABDataSourceSection = z13.object({
|
|
1301
|
+
dataSourceId: z13.number().nullable().default(null),
|
|
1302
|
+
dataSourcePath: z13.string().default(DEFAULT_ENDPOINTS[0].value),
|
|
1231
1303
|
discount: CABDiscount.optional(),
|
|
1232
1304
|
integrations: CABIntegrations.optional(),
|
|
1233
|
-
limit:
|
|
1234
|
-
matchVariant:
|
|
1235
|
-
matchVariantOutOfStock:
|
|
1236
|
-
name:
|
|
1237
|
-
productType:
|
|
1238
|
-
sectionId:
|
|
1239
|
-
sectionType:
|
|
1305
|
+
limit: z13.number().default(1),
|
|
1306
|
+
matchVariant: z13.boolean().default(false),
|
|
1307
|
+
matchVariantOutOfStock: z13.boolean().default(false),
|
|
1308
|
+
name: z13.string().default(DEFAULT_ENDPOINTS[0].label),
|
|
1309
|
+
productType: z13.enum(productTypes).optional(),
|
|
1310
|
+
sectionId: z13.uuid().default(() => uuidv74()),
|
|
1311
|
+
sectionType: z13.literal(SectionType.dataSource).default(SectionType.dataSource),
|
|
1240
1312
|
/** Default subscribe-vs-one-time for `productType: both` (legacy `subscription_is_default`). */
|
|
1241
|
-
subscriptionIsDefault:
|
|
1242
|
-
treatAsGwp:
|
|
1313
|
+
subscriptionIsDefault: z13.boolean().default(false),
|
|
1314
|
+
treatAsGwp: z13.boolean().default(false)
|
|
1243
1315
|
});
|
|
1244
1316
|
|
|
1245
1317
|
// src/schema/widgets/checkout-and-beyond/products.ts
|
|
1246
1318
|
import { v7 as uuidv76 } from "uuid";
|
|
1247
|
-
import { z as
|
|
1319
|
+
import { z as z15 } from "zod";
|
|
1248
1320
|
|
|
1249
1321
|
// src/schema/widgets/checkout-and-beyond/product.ts
|
|
1250
1322
|
import { v7 as uuidv75 } from "uuid";
|
|
1251
|
-
import { z as
|
|
1252
|
-
var CABVariantContent =
|
|
1253
|
-
() =>
|
|
1323
|
+
import { z as z14 } from "zod";
|
|
1324
|
+
var CABVariantContent = z14.lazy(
|
|
1325
|
+
() => z14.discriminatedUnion("sectionType", [CABButtonSection, CABTextSection])
|
|
1254
1326
|
);
|
|
1255
|
-
var CABProductSection =
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1327
|
+
var CABProductSection = z14.object({
|
|
1328
|
+
...CABVariableFields,
|
|
1329
|
+
name: z14.string().optional(),
|
|
1330
|
+
productId: z14.number().nullable().default(null),
|
|
1331
|
+
sectionId: z14.uuid().default(() => uuidv75()),
|
|
1332
|
+
sections: z14.union([z14.array(CABVariantContent), z14.strictObject({}).transform(() => [])]).default(() => []),
|
|
1333
|
+
sectionType: z14.literal(SectionType.product).default(SectionType.product),
|
|
1334
|
+
selectors: z14.record(z14.string(), z14.enum(variantSelectors).default(VariantSelector.menu)).default(() => ({})),
|
|
1335
|
+
variantMode: z14.enum(variantModes).default(VariantMode.multiple)
|
|
1263
1336
|
});
|
|
1264
1337
|
|
|
1265
1338
|
// src/schema/widgets/checkout-and-beyond/products.ts
|
|
1266
|
-
var CABProductsSection =
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1339
|
+
var CABProductsSection = z15.object({
|
|
1340
|
+
...CABVariableFields,
|
|
1341
|
+
name: z15.string().optional(),
|
|
1342
|
+
sectionId: z15.uuid().default(() => uuidv76()),
|
|
1343
|
+
sections: z15.union([z15.array(z15.lazy(() => CABProductSection)), z15.strictObject({}).transform(() => [])]).default(() => []),
|
|
1344
|
+
sectionType: z15.literal(SectionType.products).default(SectionType.products)
|
|
1271
1345
|
});
|
|
1272
1346
|
|
|
1273
1347
|
// src/schema/widgets/checkout-and-beyond/offers.ts
|
|
1274
|
-
var CABOffersSection =
|
|
1348
|
+
var CABOffersSection = z16.lazy(
|
|
1275
1349
|
() => CABLayoutSection.omit({ sections: true, sectionType: true }).extend({
|
|
1276
|
-
sections:
|
|
1350
|
+
sections: z16.union([z16.array(z16.lazy(() => CABSection)), z16.strictObject({}).transform(() => [])]).default(() => [
|
|
1277
1351
|
CABBannerSection.parse({
|
|
1278
1352
|
buttonField: "undoAddToOrder",
|
|
1279
1353
|
color: "success",
|
|
@@ -1287,64 +1361,65 @@ var CABOffersSection = z15.lazy(
|
|
|
1287
1361
|
CABDataSourceSection.parse({}),
|
|
1288
1362
|
CABProductsSection.parse({})
|
|
1289
1363
|
]),
|
|
1290
|
-
sectionType:
|
|
1364
|
+
sectionType: z16.literal(SectionType.offers).default(SectionType.offers)
|
|
1291
1365
|
})
|
|
1292
1366
|
);
|
|
1293
1367
|
|
|
1294
1368
|
// src/schema/widgets/checkout-and-beyond/carousel.ts
|
|
1295
|
-
var CABCarouselSection =
|
|
1369
|
+
var CABCarouselSection = z17.lazy(
|
|
1296
1370
|
() => CABLayoutSection.omit({ sections: true, sectionType: true }).extend({
|
|
1297
|
-
autoAdvanceInterval:
|
|
1298
|
-
itemsAtOnce:
|
|
1371
|
+
autoAdvanceInterval: z17.number().default(0),
|
|
1372
|
+
itemsAtOnce: z17.number().min(1).default(1),
|
|
1299
1373
|
/** Card arrangement for the offers child (`horizontal` = side-by-side) — NOT the carousel's own `direction`. */
|
|
1300
|
-
offersDirection:
|
|
1301
|
-
sections:
|
|
1302
|
-
sectionType:
|
|
1374
|
+
offersDirection: z17.enum(offersDirections).default("vertical"),
|
|
1375
|
+
sections: z17.union([z17.array(z17.lazy(() => CABSection)), z17.strictObject({}).transform(() => [])]).default(() => [CABOffersSection.parse({})]),
|
|
1376
|
+
sectionType: z17.literal(SectionType.carousel).default(SectionType.carousel)
|
|
1303
1377
|
})
|
|
1304
1378
|
);
|
|
1305
1379
|
|
|
1306
1380
|
// src/schema/widgets/checkout-and-beyond/cartLine.ts
|
|
1307
|
-
import { z as
|
|
1308
|
-
var CABCartLineSection =
|
|
1381
|
+
import { z as z18 } from "zod";
|
|
1382
|
+
var CABCartLineSection = z18.lazy(
|
|
1309
1383
|
() => CABLayoutSection.omit({ sections: true, sectionType: true }).extend({
|
|
1310
|
-
sections:
|
|
1311
|
-
sectionType:
|
|
1384
|
+
sections: z18.union([z18.array(z18.lazy(() => CABSection)), z18.strictObject({}).transform(() => [])]).default(() => [CABButtonSection.parse({ action: ButtonAction.switchToSubscription })]),
|
|
1385
|
+
sectionType: z18.literal(SectionType.cartLine).default(SectionType.cartLine)
|
|
1312
1386
|
})
|
|
1313
1387
|
);
|
|
1314
1388
|
|
|
1315
1389
|
// src/schema/widgets/checkout-and-beyond/discount.ts
|
|
1316
1390
|
import { v7 as uuidv77 } from "uuid";
|
|
1317
|
-
import { z as
|
|
1318
|
-
var CABDiscountSection =
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1391
|
+
import { z as z19 } from "zod";
|
|
1392
|
+
var CABDiscountSection = z19.object({
|
|
1393
|
+
...CABVariableFields,
|
|
1394
|
+
amount: z19.union([z19.number(), z19.string()]).catch(0),
|
|
1395
|
+
discountedBy: z19.string().optional(),
|
|
1396
|
+
discountedFrom: z19.enum(discountSources).optional().catch(void 0),
|
|
1397
|
+
message: z19.string().optional(),
|
|
1398
|
+
name: z19.string().optional(),
|
|
1399
|
+
quantity: z19.number().default(1),
|
|
1400
|
+
sectionId: z19.uuid().default(() => uuidv77()),
|
|
1401
|
+
sectionType: z19.literal(SectionType.discount).default(SectionType.discount),
|
|
1402
|
+
type: z19.enum(discountTypes).catch("none")
|
|
1328
1403
|
});
|
|
1329
1404
|
|
|
1330
1405
|
// src/schema/widgets/checkout-and-beyond/monetize.ts
|
|
1331
1406
|
import { v7 as uuidv78 } from "uuid";
|
|
1332
|
-
import { z as
|
|
1333
|
-
var CABMonetizeSection =
|
|
1334
|
-
|
|
1407
|
+
import { z as z20 } from "zod";
|
|
1408
|
+
var CABMonetizeSection = z20.object({
|
|
1409
|
+
...CABVariableFields,
|
|
1410
|
+
name: z20.string().optional(),
|
|
1335
1411
|
/** Privacy Policy footer href (the widget's `privacy_policy_url` setting); the client relays it to `/cab/monetize`. */
|
|
1336
|
-
privacyPolicyUrl:
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
sectionType: z19.literal(SectionType.monetize).default(SectionType.monetize),
|
|
1412
|
+
privacyPolicyUrl: z20.string().optional(),
|
|
1413
|
+
sectionId: z20.uuid().default(() => uuidv78()),
|
|
1414
|
+
sectionType: z20.literal(SectionType.monetize).default(SectionType.monetize),
|
|
1340
1415
|
/** Ads-taxonomy sub-vertical id (the widget's `sub_vertical` setting); paired with `vertical`. */
|
|
1341
|
-
subVertical:
|
|
1416
|
+
subVertical: z20.string().optional(),
|
|
1342
1417
|
/** Ads-taxonomy vertical id (the widget's `vertical` setting) — with `subVertical`, the admin Monetize editor's two configurables. */
|
|
1343
|
-
vertical:
|
|
1418
|
+
vertical: z20.string().optional()
|
|
1344
1419
|
});
|
|
1345
1420
|
|
|
1346
1421
|
// src/schema/widgets/checkout-and-beyond/progressBar.ts
|
|
1347
|
-
import { z as
|
|
1422
|
+
import { z as z21 } from "zod";
|
|
1348
1423
|
|
|
1349
1424
|
// src/schema/widgets/checkout-and-beyond/giftLabels.ts
|
|
1350
1425
|
var GIFT_LABELS = {
|
|
@@ -1463,21 +1538,21 @@ var GIFT_LABELS = {
|
|
|
1463
1538
|
};
|
|
1464
1539
|
|
|
1465
1540
|
// src/schema/widgets/checkout-and-beyond/progressBar.ts
|
|
1466
|
-
var CABProgressTier =
|
|
1541
|
+
var CABProgressTier = z21.object({
|
|
1467
1542
|
/**
|
|
1468
1543
|
* Order-discount tiers only (onsite `discount`): the reward the order-discount Function applies at
|
|
1469
1544
|
* cart time, carried so the client can resolve the `{{discountAmount}}` token in this tier's copy.
|
|
1470
1545
|
* `fixedAmount`: shop-currency CENTS (FX-scaled by the client, like {@link CABProgressTier.threshold});
|
|
1471
1546
|
* `percentage`: the whole-percent number rendered raw (`{n}%`). Absent on non-discount tiers.
|
|
1472
1547
|
*/
|
|
1473
|
-
discount:
|
|
1548
|
+
discount: z21.object({ amount: z21.number().nonnegative(), type: z21.enum(["fixedAmount", "percentage"]) }).optional(),
|
|
1474
1549
|
/**
|
|
1475
1550
|
* Smart-cart product (gift) tiers only (onsite `filter_oos_variants`): when set, the client drops this
|
|
1476
1551
|
* tier entirely once its gift has NO in-stock eligible variant — the milestone, fill slot and gift
|
|
1477
1552
|
* controls all disappear, mirroring onsite removing the tier from `bar.tiers` before it renders. Absent
|
|
1478
1553
|
* on shipping/discount/decorative tiers and left off by default (the tier renders regardless of stock).
|
|
1479
1554
|
*/
|
|
1480
|
-
filterOosVariants:
|
|
1555
|
+
filterOosVariants: z21.boolean().default(false),
|
|
1481
1556
|
/**
|
|
1482
1557
|
* Smart-cart product (gift) tiers only: the reward unlocked at this tier. The client enriches
|
|
1483
1558
|
* `productId`/`variantIds` to live variants (availability, price) and adds the chosen one to the cart
|
|
@@ -1485,10 +1560,10 @@ var CABProgressTier = z20.object({
|
|
|
1485
1560
|
* tiers and on tiers with no configured product. Cart add/remove is a later stage; carried here so the
|
|
1486
1561
|
* tree is complete.
|
|
1487
1562
|
*/
|
|
1488
|
-
gift:
|
|
1489
|
-
productId:
|
|
1490
|
-
title:
|
|
1491
|
-
variantIds:
|
|
1563
|
+
gift: z21.object({
|
|
1564
|
+
productId: z21.number().int().positive(),
|
|
1565
|
+
title: z21.string().optional(),
|
|
1566
|
+
variantIds: z21.array(z21.number().int().positive()).default(() => [])
|
|
1492
1567
|
}).optional(),
|
|
1493
1568
|
/**
|
|
1494
1569
|
* The step-row label at this tier's slot (onsite `getTierLabel`): the merchant custom label, else the
|
|
@@ -1499,35 +1574,35 @@ var CABProgressTier = z20.object({
|
|
|
1499
1574
|
* turns a blank label into an absent key, and a client-authored blank means the same thing — the renderer
|
|
1500
1575
|
* emits no caption slot rather than an empty one). Plain text — a compact icon+label.
|
|
1501
1576
|
*/
|
|
1502
|
-
label:
|
|
1577
|
+
label: z21.record(z21.string(), z21.string()).optional(),
|
|
1503
1578
|
/**
|
|
1504
1579
|
* Smart-cart product (gift) tiers only (onsite `product_tier_image`): show the gift's product image in
|
|
1505
1580
|
* the step-row slot instead of the generic bag icon. The converter can't supply the image URL (config
|
|
1506
1581
|
* carries only product IDs), so the client resolves it (authoritative Shopify featured image, React
|
|
1507
1582
|
* parity) and falls back to the bag icon when the flag is off or no image resolves. Default false.
|
|
1508
1583
|
*/
|
|
1509
|
-
productTierImage:
|
|
1584
|
+
productTierImage: z21.boolean().default(false),
|
|
1510
1585
|
/**
|
|
1511
1586
|
* The tier's goal, measured per `unit`. `currency` (default): SHOP-currency cents — the canonical
|
|
1512
1587
|
* fallback: when the buyer's presentment currency has no entry in `thresholds`, the client
|
|
1513
1588
|
* multiplies this by the live FX rate (converter maps the v1 `unlock_price`, e.g. `75` → `7500`).
|
|
1514
1589
|
* `item`: a raw item count — no cents, no FX, no `thresholds` overrides.
|
|
1515
1590
|
*/
|
|
1516
|
-
threshold:
|
|
1591
|
+
threshold: z21.number().int().nonnegative(),
|
|
1517
1592
|
/**
|
|
1518
1593
|
* Per-presentment-currency goal overrides — lowercased ISO currency code → cents (e.g. `{ cad: 9900 }`).
|
|
1519
1594
|
* When the buyer's currency has an entry, the client uses it verbatim INSTEAD of FX-converting
|
|
1520
1595
|
* `threshold`, so merchants show intentional, clean per-market amounts (Shopify Markets) rather than a
|
|
1521
1596
|
* converted base. Defaults to `{}` — no overrides means always fall back to `threshold`.
|
|
1522
1597
|
*/
|
|
1523
|
-
thresholds:
|
|
1598
|
+
thresholds: z21.record(z21.string(), z21.number().int().nonnegative()).default(() => ({})),
|
|
1524
1599
|
/**
|
|
1525
1600
|
* Smart-cart tier identifier, mirrored onto the gift cart line's `_tier` attribute so the client can
|
|
1526
1601
|
* match an in-cart gift back to its tier (add on reach, remove on downgrade/decline). Absent on the
|
|
1527
1602
|
* shipping bar (single unlabeled tier, no gift).
|
|
1528
1603
|
*/
|
|
1529
|
-
tierId:
|
|
1530
|
-
tierType:
|
|
1604
|
+
tierId: z21.string().optional(),
|
|
1605
|
+
tierType: z21.enum(progressTierTypes).default(ProgressTierType.shipping),
|
|
1531
1606
|
/**
|
|
1532
1607
|
* What this tier's progress is measured in — PER TIER (onsite's `unlock_condition_type` model, NOT
|
|
1533
1608
|
* the React port's bar-level `tiers[0]` shortcut). `currency` compares money cents against the
|
|
@@ -1538,9 +1613,9 @@ var CABProgressTier = z20.object({
|
|
|
1538
1613
|
* count carries no injected noun (no English `item`/`items` inflection on localized copy); merchant
|
|
1539
1614
|
* template text supplies grammatically-neutral wording around the token.
|
|
1540
1615
|
*/
|
|
1541
|
-
unit:
|
|
1616
|
+
unit: z21.enum(progressTierUnits).default(ProgressTierUnit.currency)
|
|
1542
1617
|
});
|
|
1543
|
-
var CABProgressBarSection =
|
|
1618
|
+
var CABProgressBarSection = z21.lazy(
|
|
1544
1619
|
() => CABLayoutSection.omit({ sectionType: true }).extend({
|
|
1545
1620
|
/**
|
|
1546
1621
|
* The onsite bar id (smart-cart TPB bars only). The client mirrors it to the cart's `_barId` attribute
|
|
@@ -1549,35 +1624,35 @@ var CABProgressBarSection = z20.lazy(
|
|
|
1549
1624
|
* checkout reaches the extension without it, so the client writes it or the tier gift's 100% discount
|
|
1550
1625
|
* (and any tier order discount) never applies. Absent on the v1 shipping bar (no gift tiers, no id).
|
|
1551
1626
|
*/
|
|
1552
|
-
barId:
|
|
1627
|
+
barId: z21.string().optional(),
|
|
1553
1628
|
/** Empty = shown everywhere; otherwise uppercase ISO country codes. */
|
|
1554
|
-
countryCodes:
|
|
1629
|
+
countryCodes: z21.array(z21.string().transform((code) => code.trim().toUpperCase())).default(() => []),
|
|
1555
1630
|
/**
|
|
1556
1631
|
* Uppercase ISO codes where a higher-precedence geo bar applies, so this (default, non-geo) bar is
|
|
1557
1632
|
* hidden there — replicates React `getbar`'s geo-match-over-default precedence. Empty = never excluded.
|
|
1558
1633
|
*/
|
|
1559
|
-
excludeCountryCodes:
|
|
1634
|
+
excludeCountryCodes: z21.array(z21.string().transform((code) => code.trim().toUpperCase())).default(() => []),
|
|
1560
1635
|
/**
|
|
1561
1636
|
* Measure progress against the PRE-discount subtotal (onsite `exclude_discount_in_subtotal`, and
|
|
1562
1637
|
* forced on for bars with a discount tier so its own reward can't un-reach the tier). The client
|
|
1563
1638
|
* adds the cart's discount allocations back to the live subtotal.
|
|
1564
1639
|
*/
|
|
1565
|
-
excludeDiscountInSubtotal:
|
|
1640
|
+
excludeDiscountInSubtotal: z21.boolean().default(false),
|
|
1566
1641
|
/** Variant ids the client subtracts from the adjusted subtotal (React `bar.excluded_products`). */
|
|
1567
|
-
excludedVariantIds:
|
|
1642
|
+
excludedVariantIds: z21.array(z21.number().int().positive()).default(() => []),
|
|
1568
1643
|
/**
|
|
1569
1644
|
* When the cart holds a subscription item, treat the bar as reached regardless of subtotal (React
|
|
1570
1645
|
* `free_shipping_on_subscription(s)`). `freeShippingOnAll` is already a zero-threshold tier instead.
|
|
1571
1646
|
*/
|
|
1572
|
-
freeShippingOnSubscription:
|
|
1647
|
+
freeShippingOnSubscription: z21.boolean().default(false),
|
|
1573
1648
|
/** Localized heading over the gift controls (onsite `gift_area_title`, default 'FREE GIFTS'). */
|
|
1574
|
-
giftAreaTitle:
|
|
1649
|
+
giftAreaTitle: z21.record(z21.string(), z21.string()).default(() => ({ en: "FREE GIFTS" })),
|
|
1575
1650
|
/** Localized gift-control labels (add/remove/heading); a tier's gift `title` beats `yourGift`. */
|
|
1576
|
-
giftLabels:
|
|
1577
|
-
addGift:
|
|
1578
|
-
remove:
|
|
1579
|
-
selectOptions:
|
|
1580
|
-
yourGift:
|
|
1651
|
+
giftLabels: z21.object({
|
|
1652
|
+
addGift: z21.record(z21.string(), z21.string()).default(() => ({ ...GIFT_LABELS.addGift })),
|
|
1653
|
+
remove: z21.record(z21.string(), z21.string()).default(() => ({ ...GIFT_LABELS.remove })),
|
|
1654
|
+
selectOptions: z21.record(z21.string(), z21.string()).default(() => ({ ...GIFT_LABELS.selectOptions })),
|
|
1655
|
+
yourGift: z21.record(z21.string(), z21.string()).default(() => ({ ...GIFT_LABELS.yourGift }))
|
|
1581
1656
|
}).default(() => ({
|
|
1582
1657
|
addGift: { ...GIFT_LABELS.addGift },
|
|
1583
1658
|
remove: { ...GIFT_LABELS.remove },
|
|
@@ -1585,37 +1660,38 @@ var CABProgressBarSection = z20.lazy(
|
|
|
1585
1660
|
yourGift: { ...GIFT_LABELS.yourGift }
|
|
1586
1661
|
})),
|
|
1587
1662
|
/** The bar's a11y label; the merchant names it in the editor, else this default (React parity). */
|
|
1588
|
-
name:
|
|
1663
|
+
name: z21.string().default("Order progress"),
|
|
1589
1664
|
/**
|
|
1590
1665
|
* Bar fill color. An explicit (widget-authored) value is used verbatim; when absent the server
|
|
1591
1666
|
* fills it with the live shop theme's `buttonBackground` (React `useRebuyTheme` parity). Still
|
|
1592
1667
|
* absent after that ⇒ the theme fetch failed and the client renders its platform-default bar —
|
|
1593
1668
|
* optional, not defaulted, so "merchant chose no color" stays distinguishable from any real value.
|
|
1594
1669
|
*/
|
|
1595
|
-
progressColor:
|
|
1596
|
-
sectionType:
|
|
1670
|
+
progressColor: z21.string().optional(),
|
|
1671
|
+
sectionType: z21.literal(SectionType.progressBar).default(SectionType.progressBar),
|
|
1597
1672
|
/**
|
|
1598
1673
|
* The bar's milestones in the merchant's CONFIGURED order — the renderer does NOT sort them (022
|
|
1599
1674
|
* O-B2: sorting by resolved threshold reversed configured milestones on out-of-order or mixed-unit
|
|
1600
1675
|
* count-vs-cents bars). Drives the fill (even slot per tier) and, for smart-cart product tiers, the
|
|
1601
1676
|
* gift add/remove. The visual tier display lives in `sections` (composable), NOT here.
|
|
1602
1677
|
*/
|
|
1603
|
-
tiers:
|
|
1678
|
+
tiers: z21.union([z21.array(CABProgressTier), z21.strictObject({}).transform(() => [])]).default(() => [])
|
|
1604
1679
|
})
|
|
1605
1680
|
);
|
|
1606
1681
|
|
|
1607
1682
|
// src/schema/widgets/checkout-and-beyond/quantity.ts
|
|
1608
1683
|
import { v7 as uuidv79 } from "uuid";
|
|
1609
|
-
import { z as
|
|
1610
|
-
var CABQuantitySection =
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1684
|
+
import { z as z22 } from "zod";
|
|
1685
|
+
var CABQuantitySection = z22.object({
|
|
1686
|
+
...CABVariableFields,
|
|
1687
|
+
errorMessages: z22.record(
|
|
1688
|
+
z22.string(),
|
|
1689
|
+
z22.object({
|
|
1614
1690
|
/** `{{step}}` is interpolated at render — the off-increment message React never gave a merchant key. */
|
|
1615
|
-
increment:
|
|
1616
|
-
max:
|
|
1617
|
-
min:
|
|
1618
|
-
neg:
|
|
1691
|
+
increment: z22.string().optional(),
|
|
1692
|
+
max: z22.string().optional(),
|
|
1693
|
+
min: z22.string().optional(),
|
|
1694
|
+
neg: z22.string().optional()
|
|
1619
1695
|
})
|
|
1620
1696
|
).default({
|
|
1621
1697
|
en: {
|
|
@@ -1625,19 +1701,18 @@ var CABQuantitySection = z21.object({
|
|
|
1625
1701
|
neg: "Quantity cannot be negative"
|
|
1626
1702
|
}
|
|
1627
1703
|
}),
|
|
1628
|
-
inputType:
|
|
1629
|
-
max:
|
|
1630
|
-
min:
|
|
1704
|
+
inputType: z22.enum(quantityInputs).default(QuantityInput.select),
|
|
1705
|
+
max: z22.number().min(1).max(100).default(10),
|
|
1706
|
+
min: z22.number().min(1).default(1),
|
|
1631
1707
|
/** The a11y label for the quantity control; the merchant names it in the editor, else this default. */
|
|
1632
|
-
name:
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
sectionType: z21.literal(SectionType.quantity).default(SectionType.quantity)
|
|
1708
|
+
name: z22.string().default("Quantity"),
|
|
1709
|
+
sectionId: z22.uuid().default(() => uuidv79()),
|
|
1710
|
+
sectionType: z22.literal(SectionType.quantity).default(SectionType.quantity)
|
|
1636
1711
|
});
|
|
1637
1712
|
|
|
1638
1713
|
// src/schema/widgets/checkout-and-beyond/reviews.ts
|
|
1639
1714
|
import { v7 as uuidv710 } from "uuid";
|
|
1640
|
-
import { z as
|
|
1715
|
+
import { z as z23 } from "zod";
|
|
1641
1716
|
|
|
1642
1717
|
// src/schema/widgets/checkout-and-beyond/reviewLabels.ts
|
|
1643
1718
|
var REVIEW_LABELS = {
|
|
@@ -1700,50 +1775,50 @@ var REVIEW_LABELS = {
|
|
|
1700
1775
|
};
|
|
1701
1776
|
|
|
1702
1777
|
// src/schema/widgets/checkout-and-beyond/reviews.ts
|
|
1703
|
-
var CABReviewsSection =
|
|
1704
|
-
|
|
1778
|
+
var CABReviewsSection = z23.object({
|
|
1779
|
+
...CABVariableFields,
|
|
1780
|
+
color: z23.string().default("#fadb14"),
|
|
1705
1781
|
/**
|
|
1706
1782
|
* Localized review-count templates (`{{reviewCount}}`), one/other plural forms; the client picks the
|
|
1707
1783
|
* form via `Intl.PluralRules`. Defaults here (schema-first) so every tree localizes without converter
|
|
1708
1784
|
* or merchant work.
|
|
1709
1785
|
*/
|
|
1710
|
-
countLabels:
|
|
1711
|
-
one:
|
|
1712
|
-
other:
|
|
1786
|
+
countLabels: z23.object({
|
|
1787
|
+
one: z23.record(z23.string(), z23.string()).default(() => ({ ...REVIEW_LABELS.one })),
|
|
1788
|
+
other: z23.record(z23.string(), z23.string()).default(() => ({ ...REVIEW_LABELS.other }))
|
|
1713
1789
|
}).default(() => ({ one: { ...REVIEW_LABELS.one }, other: { ...REVIEW_LABELS.other } })),
|
|
1714
|
-
name:
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
size: z22.enum(reviewsSizes).default(ReviewsSize.default)
|
|
1790
|
+
name: z23.string().optional(),
|
|
1791
|
+
sectionId: z23.uuid().default(() => uuidv710()),
|
|
1792
|
+
sectionType: z23.literal(SectionType.reviews).default(SectionType.reviews),
|
|
1793
|
+
size: z23.enum(reviewsSizes).default(ReviewsSize.default)
|
|
1719
1794
|
});
|
|
1720
1795
|
|
|
1721
1796
|
// src/schema/widgets/checkout-and-beyond/variants.ts
|
|
1722
1797
|
import { slice } from "es-toolkit/compat";
|
|
1723
1798
|
import { v7 as uuidv711 } from "uuid";
|
|
1724
|
-
import { z as
|
|
1725
|
-
var CABVariantsSection =
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
sectionId:
|
|
1730
|
-
sectionType:
|
|
1731
|
-
selector:
|
|
1732
|
-
variantMode:
|
|
1799
|
+
import { z as z24 } from "zod";
|
|
1800
|
+
var CABVariantsSection = z24.object({
|
|
1801
|
+
...CABVariableFields,
|
|
1802
|
+
hideOutOfStockVariants: z24.boolean().default(false),
|
|
1803
|
+
name: z24.string().optional(),
|
|
1804
|
+
sectionId: z24.uuid().default(() => uuidv711()),
|
|
1805
|
+
sectionType: z24.literal(SectionType.variants).default(SectionType.variants),
|
|
1806
|
+
selector: z24.enum(slice(variantSelectors, 0, 3)).default(VariantSelector.menu),
|
|
1807
|
+
variantMode: z24.enum(variantModes).default(VariantMode.multiple)
|
|
1733
1808
|
});
|
|
1734
1809
|
|
|
1735
1810
|
// src/schema/widgets/checkout-and-beyond/shared.ts
|
|
1736
|
-
var CABBorder =
|
|
1737
|
-
radius:
|
|
1738
|
-
style:
|
|
1739
|
-
width:
|
|
1811
|
+
var CABBorder = z25.object({
|
|
1812
|
+
radius: z25.enum(borderRadii).default(BorderRadius.base),
|
|
1813
|
+
style: z25.enum(borderStyles).default(BorderStyle.none),
|
|
1814
|
+
width: z25.enum(borderWidths).default(BorderWidth.base)
|
|
1740
1815
|
}).default({
|
|
1741
1816
|
radius: BorderRadius.base,
|
|
1742
1817
|
style: BorderStyle.none,
|
|
1743
1818
|
width: BorderWidth.base
|
|
1744
1819
|
});
|
|
1745
|
-
var CABSection =
|
|
1746
|
-
() =>
|
|
1820
|
+
var CABSection = z25.lazy(
|
|
1821
|
+
() => z25.discriminatedUnion("sectionType", [
|
|
1747
1822
|
CABBannerSection,
|
|
1748
1823
|
CABButtonSection,
|
|
1749
1824
|
CABCarouselSection,
|
|
@@ -1765,16 +1840,17 @@ var CABSection = z24.lazy(
|
|
|
1765
1840
|
);
|
|
1766
1841
|
|
|
1767
1842
|
// src/schema/widgets/checkout-and-beyond/image.ts
|
|
1768
|
-
var CABImageSectionFields =
|
|
1769
|
-
|
|
1843
|
+
var CABImageSectionFields = z26.object({
|
|
1844
|
+
...CABVariableFields,
|
|
1845
|
+
altText: z26.string().refine(checkForHTML, NO_HTML).default(""),
|
|
1770
1846
|
/**
|
|
1771
1847
|
* Image width÷height (e.g. `46` for the progress-bar fill); `null` renders at natural size. Any POSITIVE
|
|
1772
1848
|
* ratio — never limited to 1, but never `0`/negative either: a renderer dividing by it would get `Infinity`,
|
|
1773
1849
|
* and CSS `aspect-ratio` drops a negative value and silently reverts to natural size.
|
|
1774
1850
|
*/
|
|
1775
|
-
aspectRatio:
|
|
1776
|
-
border:
|
|
1777
|
-
buttonField:
|
|
1851
|
+
aspectRatio: z26.number().positive().nullable().default(null),
|
|
1852
|
+
border: z26.lazy(() => CABBorder),
|
|
1853
|
+
buttonField: z26.enum(buttonFields).optional(),
|
|
1778
1854
|
/**
|
|
1779
1855
|
* `icon` renders `source` as a single `s-icon` by name (the uber-image path covers icons too), reading
|
|
1780
1856
|
* `iconSize`/`iconTone`. The other values are a harmless informational holdover from the previous
|
|
@@ -1793,30 +1869,29 @@ var CABImageSectionFields = z25.object({
|
|
|
1793
1869
|
* behavior degraded gracefully and told us about it. The client-assembled half of the invariant was never
|
|
1794
1870
|
* the risky half.
|
|
1795
1871
|
*/
|
|
1796
|
-
category:
|
|
1872
|
+
category: z26.enum(["gallery", "icon", "icons", "payment-methods", "secure-checkout"]).nullable().default(null),
|
|
1797
1873
|
/** `icon`-mode only: the `s-icon` `size`; `null` ⇒ the component default (`base`). Ignored by image treatments. */
|
|
1798
|
-
iconSize:
|
|
1874
|
+
iconSize: z26.enum(iconSizes).nullable().default(null),
|
|
1799
1875
|
/** `icon`-mode only: the `s-icon` `tone`; `null` ⇒ the component default (`auto`). Ignored by image treatments. */
|
|
1800
|
-
iconTone:
|
|
1801
|
-
name:
|
|
1802
|
-
naturalHeight:
|
|
1803
|
-
naturalWidth:
|
|
1876
|
+
iconTone: z26.enum(iconTones).nullable().default(null),
|
|
1877
|
+
name: z26.string().optional(),
|
|
1878
|
+
naturalHeight: z26.number().default(0),
|
|
1879
|
+
naturalWidth: z26.number().default(0),
|
|
1804
1880
|
/**
|
|
1805
1881
|
* `contain` (the component default): dimensionless images render in s-image's 1/1 default frame, and
|
|
1806
1882
|
* `cover` would crop non-square art (payment badges lost their edges — 15993); `contain` letterboxes.
|
|
1807
1883
|
*/
|
|
1808
|
-
objectFit:
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
sectionType: z25.literal(SectionType.image).default(SectionType.image),
|
|
1884
|
+
objectFit: z26.enum(objectFits).default(ObjectFit.contain),
|
|
1885
|
+
sectionId: z26.uuid().default(() => uuidv712()),
|
|
1886
|
+
sectionType: z26.literal(SectionType.image).default(SectionType.image),
|
|
1812
1887
|
/**
|
|
1813
1888
|
* An image URL or dynamic token, an empty default, or — when `category: 'icon'` — an icon NAME. Icon mode
|
|
1814
1889
|
* takes a name or `''` only, NOT a token: no renderer resolves a token to an icon today, so accepting one
|
|
1815
1890
|
* would promise a capability that doesn't exist. Widen the refine's carve-out to `DYNAMIC_TOKEN_REGEX` when a
|
|
1816
1891
|
* server-chosen tier icon actually needs it.
|
|
1817
1892
|
*/
|
|
1818
|
-
source:
|
|
1819
|
-
width:
|
|
1893
|
+
source: z26.union([z26.url(), z26.literal(""), z26.string().regex(DYNAMIC_TOKEN_REGEX), z26.enum(iconNames)]).default(""),
|
|
1894
|
+
width: z26.number().default(100)
|
|
1820
1895
|
});
|
|
1821
1896
|
var iconNameSet = new Set(iconNames);
|
|
1822
1897
|
var isIconName = (source) => iconNameSet.has(source);
|
|
@@ -1966,7 +2041,7 @@ var convertContentBlockTextToV2 = (language) => {
|
|
|
1966
2041
|
};
|
|
1967
2042
|
|
|
1968
2043
|
// src/schema/widgets/checkout-and-beyond/root.ts
|
|
1969
|
-
import { z as
|
|
2044
|
+
import { z as z27 } from "zod";
|
|
1970
2045
|
|
|
1971
2046
|
// src/schema/widgets/checkout-and-beyond/uiLabels.ts
|
|
1972
2047
|
var UI_LABELS = {
|
|
@@ -1982,8 +2057,8 @@ var UI_LABELS = {
|
|
|
1982
2057
|
};
|
|
1983
2058
|
|
|
1984
2059
|
// src/schema/widgets/checkout-and-beyond/root.ts
|
|
1985
|
-
var localized = (fallback) =>
|
|
1986
|
-
var CABUILabels =
|
|
2060
|
+
var localized = (fallback) => z27.record(z27.string(), z27.string()).default(() => ({ ...fallback })).transform((labels) => Object.keys(labels).length > 0 ? labels : { ...fallback });
|
|
2061
|
+
var CABUILabels = z27.object({
|
|
1987
2062
|
currentPage: localized(UI_LABELS.currentPage),
|
|
1988
2063
|
loadingOptions: localized(UI_LABELS.loadingOptions),
|
|
1989
2064
|
nextPage: localized(UI_LABELS.nextPage),
|
|
@@ -2004,37 +2079,37 @@ var CABUILabels = z26.object({
|
|
|
2004
2079
|
subscriptionOptions: { ...UI_LABELS.subscriptionOptions },
|
|
2005
2080
|
updating: { ...UI_LABELS.updating }
|
|
2006
2081
|
}));
|
|
2007
|
-
var TargetArea =
|
|
2008
|
-
fill:
|
|
2009
|
-
flip:
|
|
2010
|
-
icon:
|
|
2011
|
-
label:
|
|
2012
|
-
width:
|
|
2082
|
+
var TargetArea = z27.object({
|
|
2083
|
+
fill: z27.boolean().optional(),
|
|
2084
|
+
flip: z27.enum(["both", "horizontal", "vertical"]).optional(),
|
|
2085
|
+
icon: z27.string(),
|
|
2086
|
+
label: z27.string(),
|
|
2087
|
+
width: z27.string()
|
|
2013
2088
|
}).default(targetAreas[EditorMode.checkoutExtension][1]);
|
|
2014
|
-
var CABTracking =
|
|
2015
|
-
enableAttribution:
|
|
2016
|
-
enableSource:
|
|
2017
|
-
enableWidget:
|
|
2089
|
+
var CABTracking = z27.object({
|
|
2090
|
+
enableAttribution: z27.boolean().nullish().transform((value) => value ?? true),
|
|
2091
|
+
enableSource: z27.boolean().nullish().transform((value) => value ?? true),
|
|
2092
|
+
enableWidget: z27.boolean().nullish().transform((value) => value ?? true)
|
|
2018
2093
|
}).nullish().transform((value) => value ?? { enableAttribution: true, enableSource: true, enableWidget: true });
|
|
2019
|
-
var CABExperiment =
|
|
2020
|
-
elementId:
|
|
2021
|
-
experimentId:
|
|
2022
|
-
experimentType:
|
|
2023
|
-
selectedId:
|
|
2094
|
+
var CABExperiment = z27.object({
|
|
2095
|
+
elementId: z27.number(),
|
|
2096
|
+
experimentId: z27.number(),
|
|
2097
|
+
experimentType: z27.string(),
|
|
2098
|
+
selectedId: z27.number()
|
|
2024
2099
|
});
|
|
2025
2100
|
var CABRootSection = CABLayoutSection.extend({
|
|
2026
|
-
editorMode:
|
|
2101
|
+
editorMode: z27.enum(editorModes).default(EditorMode.checkoutExtension),
|
|
2027
2102
|
experiment: CABExperiment.optional(),
|
|
2028
2103
|
// Same rule as CABTracking above: the v1 converters pass raw legacy `previewMode` through, so a
|
|
2029
2104
|
// `null` must fall back rather than throw the widget; malformed values still throw.
|
|
2030
|
-
previewMode:
|
|
2031
|
-
storeId:
|
|
2105
|
+
previewMode: z27.boolean().nullish().transform((value) => value ?? false),
|
|
2106
|
+
storeId: z27.number().nullable().default(null),
|
|
2032
2107
|
targetArea: TargetArea.nullable(),
|
|
2033
2108
|
tracking: CABTracking,
|
|
2034
|
-
type:
|
|
2109
|
+
type: z27.enum(widgetTypes).default(WidgetType.ui_extension_content_block),
|
|
2035
2110
|
uiLabels: CABUILabels,
|
|
2036
|
-
version:
|
|
2037
|
-
widgetId:
|
|
2111
|
+
version: z27.literal(2).default(2),
|
|
2112
|
+
widgetId: z27.number().nullable().default(null)
|
|
2038
2113
|
});
|
|
2039
2114
|
|
|
2040
2115
|
// src/transforms/v1Location.ts
|
|
@@ -3188,6 +3263,7 @@ var convertOfferToV2 = ({ id, name, settings }) => {
|
|
|
3188
3263
|
sectionType: "carousel"
|
|
3189
3264
|
};
|
|
3190
3265
|
return CABRootSection.parse({
|
|
3266
|
+
alignment: { horizontal: "center", vertical: "top" },
|
|
3191
3267
|
direction: "rows",
|
|
3192
3268
|
editorMode: LOCATION_TO_EDITOR_MODE[settings.location ?? "checkout"],
|
|
3193
3269
|
// The widget name is required by the admin save schema; carry the legacy widget's name through.
|
|
@@ -3876,7 +3952,7 @@ var validateGifts = async (input, ctx) => {
|
|
|
3876
3952
|
};
|
|
3877
3953
|
|
|
3878
3954
|
// src/server/adsEngine.ts
|
|
3879
|
-
import { z as
|
|
3955
|
+
import { z as z28 } from "zod";
|
|
3880
3956
|
var SUPPLY_KEY = { production: "AQF5RKLR", staging: "Z56LQ7PS" };
|
|
3881
3957
|
var OFFER_LIMIT = 4;
|
|
3882
3958
|
var SUPPORTED_COUNTRIES = /* @__PURE__ */ new Set(["US", "CA"]);
|
|
@@ -3889,20 +3965,20 @@ var transactionItems = (input) => (input.transactionItems?.map(({ id, priceCents
|
|
|
3889
3965
|
title,
|
|
3890
3966
|
type
|
|
3891
3967
|
})) ?? input.cart.items.map(({ productId, quantity }) => ({ id: productId, quantity }))).slice(0, MAX_TRANSACTION_ITEMS);
|
|
3892
|
-
var AdsEngineOffer =
|
|
3893
|
-
click_url:
|
|
3894
|
-
cta:
|
|
3968
|
+
var AdsEngineOffer = z28.object({
|
|
3969
|
+
click_url: z28.string(),
|
|
3970
|
+
cta: z28.string(),
|
|
3895
3971
|
/** `omitempty` on the ad server — a bid without it must not fail the parse and drop the whole batch (composeOffer falls back to 'No Thanks'). */
|
|
3896
|
-
decline_cta:
|
|
3897
|
-
decline_url:
|
|
3898
|
-
description:
|
|
3899
|
-
headline:
|
|
3900
|
-
id:
|
|
3901
|
-
image_url:
|
|
3902
|
-
view_url:
|
|
3972
|
+
decline_cta: z28.string().catch(""),
|
|
3973
|
+
decline_url: z28.string(),
|
|
3974
|
+
description: z28.string(),
|
|
3975
|
+
headline: z28.string(),
|
|
3976
|
+
id: z28.string(),
|
|
3977
|
+
image_url: z28.string().optional(),
|
|
3978
|
+
view_url: z28.string()
|
|
3903
3979
|
});
|
|
3904
|
-
var AdsEngineResponse =
|
|
3905
|
-
offers:
|
|
3980
|
+
var AdsEngineResponse = z28.object({
|
|
3981
|
+
offers: z28.array(z28.unknown()).default([]).transform(
|
|
3906
3982
|
(offers) => offers.flatMap((offer) => {
|
|
3907
3983
|
const result = AdsEngineOffer.safeParse(offer);
|
|
3908
3984
|
return result.success ? [result.data] : [];
|
|
@@ -4217,7 +4293,7 @@ var postAnalyticsEvents = async (input, ctx) => {
|
|
|
4217
4293
|
};
|
|
4218
4294
|
|
|
4219
4295
|
// src/server/requestSchemas.ts
|
|
4220
|
-
import { z as
|
|
4296
|
+
import { z as z29 } from "zod";
|
|
4221
4297
|
var REQUEST_BOUNDS = {
|
|
4222
4298
|
/** Cart-level attributes per cart. */
|
|
4223
4299
|
CART_ATTRIBUTES_MAX: 100,
|
|
@@ -4248,50 +4324,50 @@ var REQUEST_BOUNDS = {
|
|
|
4248
4324
|
/** Rich ads transaction lines — the engine's ads contract. */
|
|
4249
4325
|
TRANSACTION_ITEMS_MAX: 50
|
|
4250
4326
|
};
|
|
4251
|
-
var KeyValue =
|
|
4252
|
-
key:
|
|
4253
|
-
value:
|
|
4327
|
+
var KeyValue = z29.object({
|
|
4328
|
+
key: z29.string().max(REQUEST_BOUNDS.STRING_KEY_MAX),
|
|
4329
|
+
value: z29.string().max(REQUEST_BOUNDS.STRING_VALUE_MAX).optional()
|
|
4254
4330
|
});
|
|
4255
|
-
var CartLineInputSchema =
|
|
4256
|
-
productId:
|
|
4257
|
-
properties:
|
|
4258
|
-
quantity:
|
|
4259
|
-
subscriptionId:
|
|
4260
|
-
variantId:
|
|
4331
|
+
var CartLineInputSchema = z29.object({
|
|
4332
|
+
productId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
4333
|
+
properties: z29.array(KeyValue).max(REQUEST_BOUNDS.LINE_PROPERTIES_MAX).optional(),
|
|
4334
|
+
quantity: z29.number(),
|
|
4335
|
+
subscriptionId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4336
|
+
variantId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX)
|
|
4261
4337
|
});
|
|
4262
|
-
var CartInputSchema =
|
|
4263
|
-
attributes:
|
|
4338
|
+
var CartInputSchema = z29.object({
|
|
4339
|
+
attributes: z29.array(KeyValue).max(REQUEST_BOUNDS.CART_ATTRIBUTES_MAX).optional(),
|
|
4264
4340
|
/**
|
|
4265
4341
|
* Presentment-per-shop-currency FX rate (buyer price ÷ shop price, e.g. `1.35` for a USD shop
|
|
4266
4342
|
* selling in CAD). Money rule thresholds are authored in SHOP currency, so the engine subtotal is
|
|
4267
4343
|
* divided by this before evaluation. Omit (or send 1) when the cart is already in the shop's currency.
|
|
4268
4344
|
*/
|
|
4269
|
-
currencyRate:
|
|
4345
|
+
currencyRate: z29.number().optional(),
|
|
4270
4346
|
/** Applied discount codes; the engine evaluates `discount_code` rules against them (sent as `[{code}]`). */
|
|
4271
|
-
discountCodes:
|
|
4347
|
+
discountCodes: z29.array(z29.string().max(REQUEST_BOUNDS.STRING_KEY_MAX)).max(REQUEST_BOUNDS.DISCOUNT_CODES_MAX).optional(),
|
|
4272
4348
|
/** Presentment cents of cart-level discount allocations, subtracted from `subtotal` for the engine. */
|
|
4273
|
-
discountTotal:
|
|
4274
|
-
items:
|
|
4349
|
+
discountTotal: z29.number().optional(),
|
|
4350
|
+
items: z29.array(CartLineInputSchema).max(REQUEST_BOUNDS.CART_ITEMS_MAX),
|
|
4275
4351
|
/** Presentment subtotal in cents. */
|
|
4276
|
-
subtotal:
|
|
4352
|
+
subtotal: z29.number()
|
|
4277
4353
|
});
|
|
4278
|
-
var WidgetSettingsInputSchema =
|
|
4279
|
-
cacheKey:
|
|
4280
|
-
id:
|
|
4281
|
-
key:
|
|
4282
|
-
shop:
|
|
4354
|
+
var WidgetSettingsInputSchema = z29.object({
|
|
4355
|
+
cacheKey: z29.number().optional(),
|
|
4356
|
+
id: z29.number(),
|
|
4357
|
+
key: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4358
|
+
shop: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
4283
4359
|
/** Stable per-buyer id; when present, enables sticky server-side A/B variant selection. */
|
|
4284
|
-
visitorId:
|
|
4360
|
+
visitorId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
|
|
4285
4361
|
});
|
|
4286
|
-
var UserConfigInputSchema =
|
|
4287
|
-
var DataSourceInputSchema =
|
|
4362
|
+
var UserConfigInputSchema = z29.object({ shop: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX) });
|
|
4363
|
+
var DataSourceInputSchema = z29.object({
|
|
4288
4364
|
cart: CartInputSchema,
|
|
4289
4365
|
/**
|
|
4290
4366
|
* Numeric Shopify company-location id when the buyer is a B2B session (`buyerIdentity.purchasingCompany`).
|
|
4291
4367
|
* Present ⇒ the orchestrator filters results by the location's catalog via admin-api (REB-23713); the
|
|
4292
4368
|
* client's country-context market check is bypassed for B2B (it false-negatives B2B-catalog products).
|
|
4293
4369
|
*/
|
|
4294
|
-
companyLocationId:
|
|
4370
|
+
companyLocationId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4295
4371
|
/**
|
|
4296
4372
|
* Buyer's market country (ISO 3166-1 alpha-2) — forwarded to the engine as the `country_code` PARAM
|
|
4297
4373
|
* when the shop's markets toggle is on (REB-21688; the sink was the `X-Country-Code` header under
|
|
@@ -4300,16 +4376,16 @@ var DataSourceInputSchema = z28.object({
|
|
|
4300
4376
|
* uppercase (the wire value is forwarded verbatim as the param) so a case-sensitive engine lookup
|
|
4301
4377
|
* can't silently miss a lowercase code — `adsEngine.ts` uppercases for the same reason.
|
|
4302
4378
|
*/
|
|
4303
|
-
country:
|
|
4304
|
-
customerId:
|
|
4305
|
-
dataSourcePath:
|
|
4379
|
+
country: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).regex(/^[A-Za-z]{2}$/, "must be an ISO 3166-1 alpha-2 country code (e.g. CA)").transform((value) => value.toUpperCase()).optional(),
|
|
4380
|
+
customerId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4381
|
+
dataSourcePath: z29.string().max(REQUEST_BOUNDS.STRING_KEY_MAX),
|
|
4306
4382
|
/**
|
|
4307
4383
|
* Engine `filter_inputs` override: `'no'` keeps in-cart (input) products in the results/rule
|
|
4308
4384
|
* outputs — gift validation sends it so a gift's own product can appear in its answer. Omitted = the
|
|
4309
4385
|
* engine's default filtering.
|
|
4310
4386
|
*/
|
|
4311
|
-
filterInputs:
|
|
4312
|
-
integrations:
|
|
4387
|
+
filterInputs: z29.enum(["no", "yes"]).optional(),
|
|
4388
|
+
integrations: z29.record(z29.string().max(REQUEST_BOUNDS.STRING_KEY_MAX), z29.boolean()).refine((record) => Object.keys(record).length <= REQUEST_BOUNDS.INTEGRATION_KEYS_MAX, {
|
|
4313
4389
|
message: `Too many integration keys (max ${REQUEST_BOUNDS.INTEGRATION_KEYS_MAX})`
|
|
4314
4390
|
}).optional(),
|
|
4315
4391
|
/**
|
|
@@ -4322,20 +4398,20 @@ var DataSourceInputSchema = z28.object({
|
|
|
4322
4398
|
* request header) fails the regex. Callers should send the buyer's resolved locale (e.g. Shopify
|
|
4323
4399
|
* checkout's `localization.language.isoCode`), not the request header verbatim.
|
|
4324
4400
|
*/
|
|
4325
|
-
language:
|
|
4326
|
-
limit:
|
|
4327
|
-
productType:
|
|
4328
|
-
shop:
|
|
4329
|
-
visitorId:
|
|
4401
|
+
language: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).regex(/^[A-Za-z0-9-]+$/, "must be a single BCP-47 tag (e.g. fr-CA), not a q-value list").optional(),
|
|
4402
|
+
limit: z29.number().max(REQUEST_BOUNDS.LIMIT_MAX),
|
|
4403
|
+
productType: z29.enum(["both", "one-time", "subscription"]).optional(),
|
|
4404
|
+
shop: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
4405
|
+
visitorId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
|
|
4330
4406
|
});
|
|
4331
|
-
var GiftInputSchema =
|
|
4332
|
-
cost:
|
|
4333
|
-
discounted:
|
|
4334
|
-
lineId:
|
|
4335
|
-
productId:
|
|
4336
|
-
widgetId:
|
|
4407
|
+
var GiftInputSchema = z29.object({
|
|
4408
|
+
cost: z29.number(),
|
|
4409
|
+
discounted: z29.boolean(),
|
|
4410
|
+
lineId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
4411
|
+
productId: z29.number(),
|
|
4412
|
+
widgetId: z29.number()
|
|
4337
4413
|
});
|
|
4338
|
-
var GiftValidationInputSchema =
|
|
4414
|
+
var GiftValidationInputSchema = z29.object({
|
|
4339
4415
|
cart: CartInputSchema,
|
|
4340
4416
|
/**
|
|
4341
4417
|
* Buyer's market country — threaded into the per-widget data-source evaluations, which forward it to
|
|
@@ -4344,71 +4420,71 @@ var GiftValidationInputSchema = z28.object({
|
|
|
4344
4420
|
* turns markets off); regex-bound and uppercase-normalized for the same reasons as
|
|
4345
4421
|
* `DataSourceInputSchema`'s `country`.
|
|
4346
4422
|
*/
|
|
4347
|
-
country:
|
|
4348
|
-
customerId:
|
|
4349
|
-
gifts:
|
|
4423
|
+
country: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).regex(/^[A-Za-z]{2}$/, "must be an ISO 3166-1 alpha-2 country code (e.g. CA)").transform((value) => value.toUpperCase()).optional(),
|
|
4424
|
+
customerId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4425
|
+
gifts: z29.array(GiftInputSchema).max(REQUEST_BOUNDS.GIFTS_MAX),
|
|
4350
4426
|
/**
|
|
4351
4427
|
* Buyer's checkout language — threaded into the per-widget data-source evaluations, which normalize
|
|
4352
4428
|
* and forward it as the engine `locale` param under the same markets-toggle gate (REB-21688). MUST be
|
|
4353
4429
|
* a single BCP-47 tag, for the same reason as `DataSourceInputSchema`'s `language` above.
|
|
4354
4430
|
*/
|
|
4355
|
-
language:
|
|
4356
|
-
shop:
|
|
4357
|
-
visitorId:
|
|
4431
|
+
language: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).regex(/^[A-Za-z0-9-]+$/, "must be a single BCP-47 tag (e.g. fr-CA), not a q-value list").optional(),
|
|
4432
|
+
shop: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
4433
|
+
visitorId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
|
|
4358
4434
|
});
|
|
4359
|
-
var MonetizeTransactionItemSchema =
|
|
4360
|
-
id:
|
|
4361
|
-
priceCents:
|
|
4362
|
-
quantity:
|
|
4363
|
-
title:
|
|
4364
|
-
type:
|
|
4435
|
+
var MonetizeTransactionItemSchema = z29.object({
|
|
4436
|
+
id: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
4437
|
+
priceCents: z29.number(),
|
|
4438
|
+
quantity: z29.number(),
|
|
4439
|
+
title: z29.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX),
|
|
4440
|
+
type: z29.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX)
|
|
4365
4441
|
});
|
|
4366
|
-
var MonetizeInputSchema =
|
|
4442
|
+
var MonetizeInputSchema = z29.object({
|
|
4367
4443
|
cart: CartInputSchema,
|
|
4368
|
-
country:
|
|
4369
|
-
currency:
|
|
4444
|
+
country: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4445
|
+
currency: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4370
4446
|
/** Ads-targeting identity/geo/locale fields (React parity); folded into the engine query verbatim. */
|
|
4371
|
-
customerEmail:
|
|
4372
|
-
customerFirstName:
|
|
4373
|
-
customerId:
|
|
4374
|
-
customerLastName:
|
|
4375
|
-
language:
|
|
4447
|
+
customerEmail: z29.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX).optional(),
|
|
4448
|
+
customerFirstName: z29.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX).optional(),
|
|
4449
|
+
customerId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4450
|
+
customerLastName: z29.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX).optional(),
|
|
4451
|
+
language: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4376
4452
|
/** Buyer-facing order name (e.g. `#1001`) for the server-composed "Order … Confirmed" chrome line. */
|
|
4377
|
-
orderName:
|
|
4453
|
+
orderName: z29.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX).optional(),
|
|
4378
4454
|
/** Ads surface label, forwarded verbatim; `customer_account` is measured/floored as its own surface (the account-area order list). */
|
|
4379
|
-
placement:
|
|
4455
|
+
placement: z29.enum(["customer_account", "order_status", "thank_you_page"]),
|
|
4380
4456
|
/** Privacy Policy footer href — the Monetize widget's `privacy_policy_url` setting (React parity). */
|
|
4381
|
-
privacyPolicyUrl:
|
|
4457
|
+
privacyPolicyUrl: z29.string().max(REQUEST_BOUNDS.STRING_URL_MAX).optional(),
|
|
4382
4458
|
/** 30-min rolling session id (React parity); used for the ads `session_id`, else the visitor id. */
|
|
4383
|
-
sessionId:
|
|
4384
|
-
shop:
|
|
4459
|
+
sessionId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4460
|
+
shop: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
4385
4461
|
/** Editor/QA indicator; OR-ed into the ads-engine `testing` flag so it stays out of billing/reporting. */
|
|
4386
|
-
testing:
|
|
4387
|
-
timezone:
|
|
4462
|
+
testing: z29.boolean().optional(),
|
|
4463
|
+
timezone: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4388
4464
|
/** Decorated (numeric) order id → the ads `transaction_id`. */
|
|
4389
|
-
transactionId:
|
|
4465
|
+
transactionId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4390
4466
|
/** Rich per-line ads items; capped at the engine's ads contract. Preferred over `cart.items`. */
|
|
4391
|
-
transactionItems:
|
|
4467
|
+
transactionItems: z29.array(MonetizeTransactionItemSchema).max(REQUEST_BOUNDS.TRANSACTION_ITEMS_MAX).optional(),
|
|
4392
4468
|
/** Order total in presentment cents (React prefers total over subtotal); else `cart.subtotal`. */
|
|
4393
|
-
transactionTotal:
|
|
4394
|
-
visitorId:
|
|
4395
|
-
zipCode:
|
|
4469
|
+
transactionTotal: z29.number().optional(),
|
|
4470
|
+
visitorId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4471
|
+
zipCode: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
|
|
4396
4472
|
});
|
|
4397
|
-
var AnalyticsEventInputSchema =
|
|
4398
|
-
name:
|
|
4399
|
-
properties:
|
|
4400
|
-
sentAt:
|
|
4473
|
+
var AnalyticsEventInputSchema = z29.object({
|
|
4474
|
+
name: z29.string().max(REQUEST_BOUNDS.STRING_KEY_MAX),
|
|
4475
|
+
properties: z29.record(z29.string().max(REQUEST_BOUNDS.STRING_KEY_MAX), z29.unknown()).optional(),
|
|
4476
|
+
sentAt: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
|
|
4401
4477
|
});
|
|
4402
|
-
var AnalyticsInputSchema =
|
|
4478
|
+
var AnalyticsInputSchema = z29.object({
|
|
4403
4479
|
/** Rebuy cart token (the `r_cart_token` cart attribute), when available — primary aggregation key. */
|
|
4404
|
-
cartToken:
|
|
4480
|
+
cartToken: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4405
4481
|
/** Shopify checkout token, when available — drives cart/checkout aggregation downstream. */
|
|
4406
|
-
checkoutToken:
|
|
4407
|
-
events:
|
|
4408
|
-
shop:
|
|
4409
|
-
visitorId:
|
|
4482
|
+
checkoutToken: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
4483
|
+
events: z29.array(AnalyticsEventInputSchema).max(REQUEST_BOUNDS.EVENTS_MAX),
|
|
4484
|
+
shop: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
4485
|
+
visitorId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
4410
4486
|
/** The widget id (smartBlockId) the events belong to. */
|
|
4411
|
-
widgetId:
|
|
4487
|
+
widgetId: z29.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
|
|
4412
4488
|
});
|
|
4413
4489
|
export {
|
|
4414
4490
|
AnalyticsEventInputSchema,
|