@rebuy/rebuy 3.28.0 → 3.29.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 +8 -1
- package/dist/index.mjs +8 -1
- package/dist/schema/checkout-and-beyond/index.cjs +8 -1
- package/dist/schema/checkout-and-beyond/index.mjs +8 -1
- package/dist/schema/widget-data.cjs +8 -1
- package/dist/schema/widget-data.mjs +8 -1
- package/dist/schema/widgets/checkout-and-beyond/common.d.ts +1 -1
- package/dist/server/index.cjs +362 -156
- package/dist/server/index.mjs +362 -156
- package/dist/transforms/index.cjs +236 -30
- package/dist/transforms/index.mjs +236 -30
- package/dist/transforms/postPurchase/convertImageBlock.d.ts +4 -0
- package/dist/transforms/postPurchase/convertImageContentBlock.d.ts +7 -0
- package/dist/transforms/postPurchase/convertImageContentText.d.ts +5 -0
- package/dist/transforms/postPurchase/convertImageFrame.d.ts +9 -0
- package/dist/transforms/postPurchase/convertMessagePreview.d.ts +3 -3
- package/dist/transforms/postPurchase/convertProductInformation.d.ts +4 -0
- package/dist/transforms/postPurchase/imageContentSettings.d.ts +50 -0
- package/dist/transforms/postPurchase/sizeImageSource.d.ts +2 -0
- package/dist/transforms/postPurchase/types.d.ts +7 -1
- package/package.json +1 -1
package/dist/server/index.mjs
CHANGED
|
@@ -1971,7 +1971,14 @@ var CABReviewsSection = z23.object({
|
|
|
1971
1971
|
sectionId: z23.uuid().default(() => uuidv710()),
|
|
1972
1972
|
sectionType: z23.literal(SectionType.reviews).default(SectionType.reviews),
|
|
1973
1973
|
size: z23.enum(reviewsSizes).default(ReviewsSize.default),
|
|
1974
|
-
|
|
1974
|
+
/**
|
|
1975
|
+
* Star outline color, interpolated into a style by the renderer, so it is hex-constrained like
|
|
1976
|
+
* `CABButtonSection.color`. The legacy source (`PostPurchaseSettings.styles.starStrokeColor`) is a free
|
|
1977
|
+
* string: its converter must validate and fall back to this default rather than let one odd value drop
|
|
1978
|
+
* the whole reviews section.
|
|
1979
|
+
*/
|
|
1980
|
+
strokeColor: z23.string().regex(HEX_COLOR_REGEX).default("#fadb14"),
|
|
1981
|
+
/** Star outline width in px; `0` draws no outline. The legacy `styles.strokeWidth` is a STRING ('1') — its converter coerces. */
|
|
1975
1982
|
strokeWidth: z23.number().nonnegative().default(0)
|
|
1976
1983
|
});
|
|
1977
1984
|
|
|
@@ -3720,7 +3727,7 @@ var convertOfferToV2 = ({ id, name, settings }) => {
|
|
|
3720
3727
|
var parseShielded = (schema, raw, transform = (input) => input) => schema.parse(transform(convertNumericObjects(deepCamelCase(raw))));
|
|
3721
3728
|
|
|
3722
3729
|
// src/transforms/postPurchase/convertMessagePreview.ts
|
|
3723
|
-
import { z as
|
|
3730
|
+
import { z as z36 } from "zod";
|
|
3724
3731
|
|
|
3725
3732
|
// src/transforms/postPurchase/convertCalloutBlock.ts
|
|
3726
3733
|
import { z as z31 } from "zod";
|
|
@@ -3943,6 +3950,150 @@ var convertCalloutBlock = (raw, report) => {
|
|
|
3943
3950
|
return sections.length ? [CABLayoutSection.parse({ alignment: { horizontal }, frame: "callout", sections })] : [];
|
|
3944
3951
|
};
|
|
3945
3952
|
|
|
3953
|
+
// src/transforms/postPurchase/convertImageFrame.ts
|
|
3954
|
+
import { z as z32 } from "zod";
|
|
3955
|
+
|
|
3956
|
+
// src/transforms/postPurchase/sizeImageSource.ts
|
|
3957
|
+
var sizeImageSource = (source, size) => {
|
|
3958
|
+
const extension = source.split(".").pop();
|
|
3959
|
+
for (const previous of ["small", "medium", "large", "original", "master"]) {
|
|
3960
|
+
source = source.replace(`_${previous}.${extension}`, `.${extension}`);
|
|
3961
|
+
}
|
|
3962
|
+
return source.replace(`.${extension}`, `${size === void 0 ? "" : `_${size}`}.${extension}`);
|
|
3963
|
+
};
|
|
3964
|
+
|
|
3965
|
+
// src/transforms/postPurchase/convertImageFrame.ts
|
|
3966
|
+
var Source = z32.url().default("https://cdn.shopify.com/s/files/1/0605/0555/5177/files/placeholder.jpg?v=1657762972");
|
|
3967
|
+
var DEFAULT_IMAGE_SIZE = 20;
|
|
3968
|
+
var convertImageFrame = (raw) => {
|
|
3969
|
+
const parsed = ImageBlock.shape.settings.options[0].safeParse(raw);
|
|
3970
|
+
if (!parsed.success) return null;
|
|
3971
|
+
const settings = parsed.data;
|
|
3972
|
+
const source = sizeImageSource(Source.parse(settings.image || void 0));
|
|
3973
|
+
const withAlt = CABImageSection.safeParse({ altText: settings.alt, source });
|
|
3974
|
+
const image = withAlt.success ? withAlt.data : CABImageSection.parse({ source });
|
|
3975
|
+
const size = settings.imageSize > 0 ? settings.imageSize : DEFAULT_IMAGE_SIZE;
|
|
3976
|
+
return CABLayoutSection.parse({
|
|
3977
|
+
alignment: { horizontal: "center" },
|
|
3978
|
+
direction: "grid",
|
|
3979
|
+
grid: { columns: size <= 1 ? ["100%"] : [size] },
|
|
3980
|
+
sections: [image],
|
|
3981
|
+
width: size <= 1 ? size * 100 : 100
|
|
3982
|
+
});
|
|
3983
|
+
};
|
|
3984
|
+
|
|
3985
|
+
// src/transforms/postPurchase/convertImageBlock.ts
|
|
3986
|
+
var dropMalformedAlt = (raw) => {
|
|
3987
|
+
if (typeof raw !== "object" || raw === null) return raw;
|
|
3988
|
+
const { settings, ...rest } = raw;
|
|
3989
|
+
if (typeof settings !== "object" || settings === null || Array.isArray(settings)) return raw;
|
|
3990
|
+
const { alt, ...restSettings } = settings;
|
|
3991
|
+
if (typeof alt === "string" || alt === void 0) return raw;
|
|
3992
|
+
return { ...rest, settings: restSettings };
|
|
3993
|
+
};
|
|
3994
|
+
var convertImageBlock = (raw, report) => {
|
|
3995
|
+
const block = ImageBlock.safeParse(dropMalformedAlt(raw));
|
|
3996
|
+
const image = block.success ? convertImageFrame(block.data.settings) : null;
|
|
3997
|
+
if (!image) {
|
|
3998
|
+
report?.({ detail: "Unreadable post-purchase image", kind: "section" });
|
|
3999
|
+
return [];
|
|
4000
|
+
}
|
|
4001
|
+
return [
|
|
4002
|
+
CABLayoutSection.parse({
|
|
4003
|
+
alignment: { horizontal: "center" },
|
|
4004
|
+
frame: "offer-content",
|
|
4005
|
+
sections: [image],
|
|
4006
|
+
spacing: "none"
|
|
4007
|
+
})
|
|
4008
|
+
];
|
|
4009
|
+
};
|
|
4010
|
+
|
|
4011
|
+
// src/transforms/postPurchase/convertImageContentBlock.ts
|
|
4012
|
+
import { z as z34 } from "zod";
|
|
4013
|
+
|
|
4014
|
+
// src/transforms/postPurchase/convertImageContentText.ts
|
|
4015
|
+
var fields2 = ["superTitle", "title", "description"];
|
|
4016
|
+
var convertImageContentText = (settings, report) => {
|
|
4017
|
+
const horizontal = { center: "center", leading: "start", trailing: "end" }[settings.horizontalAlignment];
|
|
4018
|
+
const sections = fields2.flatMap((field) => {
|
|
4019
|
+
const omit = () => {
|
|
4020
|
+
report?.({ detail: `Unreadable post-purchase image-content field: ${field}`, kind: "section" });
|
|
4021
|
+
return [];
|
|
4022
|
+
};
|
|
4023
|
+
const value = ImageContentBlock.shape.settings.shape[field].safeParse(settings[field]);
|
|
4024
|
+
if (!value.success) return omit();
|
|
4025
|
+
const text2 = value.data;
|
|
4026
|
+
if (text2 === null || text2 === "") return [];
|
|
4027
|
+
const content = typeof text2 === "string" ? {
|
|
4028
|
+
content: [
|
|
4029
|
+
{
|
|
4030
|
+
attrs: { textAlign: horizontal },
|
|
4031
|
+
content: [styledTextRun(text2, field !== "description", settings[`${field}Size`])]
|
|
4032
|
+
}
|
|
4033
|
+
]
|
|
4034
|
+
} : text2;
|
|
4035
|
+
const section = CABTextSection.safeParse({ content: { en: content } });
|
|
4036
|
+
return section.success ? [section.data] : omit();
|
|
4037
|
+
});
|
|
4038
|
+
return CABLayoutSection.parse({ alignment: { horizontal }, sections });
|
|
4039
|
+
};
|
|
4040
|
+
|
|
4041
|
+
// src/transforms/postPurchase/imageContentSettings.ts
|
|
4042
|
+
import { z as z33 } from "zod";
|
|
4043
|
+
var ImageContentSettings = ImageContentBlock.shape.settings.pick({
|
|
4044
|
+
descriptionSize: true,
|
|
4045
|
+
horizontalAlignment: true,
|
|
4046
|
+
superTitleSize: true,
|
|
4047
|
+
swapContent: true,
|
|
4048
|
+
titleSize: true
|
|
4049
|
+
}).extend({
|
|
4050
|
+
alt: z33.unknown().optional(),
|
|
4051
|
+
description: z33.unknown().optional(),
|
|
4052
|
+
image: z33.unknown().optional(),
|
|
4053
|
+
imagePlacement: ImageContentBlock.shape.settings.shape.imagePlacement.unwrap().nullable(),
|
|
4054
|
+
imageSize: ImageContentBlock.shape.settings.shape.imageSize.pipe(z33.number().positive()),
|
|
4055
|
+
superTitle: z33.unknown().optional(),
|
|
4056
|
+
title: z33.unknown().optional()
|
|
4057
|
+
});
|
|
4058
|
+
|
|
4059
|
+
// src/transforms/postPurchase/convertImageContentBlock.ts
|
|
4060
|
+
var Shell2 = z34.object({ settings: ImageContentSettings, type: z34.literal("image_content") });
|
|
4061
|
+
var PROPORTIONAL_BREAK_AT = 500;
|
|
4062
|
+
var convertImageContentBlock = (raw, report) => {
|
|
4063
|
+
const shell = Shell2.safeParse(raw);
|
|
4064
|
+
if (!shell.success) {
|
|
4065
|
+
report?.({ detail: "Unreadable post-purchase image-content block", kind: "section" });
|
|
4066
|
+
return [];
|
|
4067
|
+
}
|
|
4068
|
+
const settings = shell.data.settings;
|
|
4069
|
+
const alt = typeof settings.alt === "string" ? settings.alt : void 0;
|
|
4070
|
+
if (settings.alt !== void 0 && alt === void 0) {
|
|
4071
|
+
report?.({ detail: "Unreadable post-purchase image-content alt text", kind: "section" });
|
|
4072
|
+
}
|
|
4073
|
+
const image = convertImageFrame({ alt, image: settings.image, imageSize: settings.imageSize });
|
|
4074
|
+
if (!image) report?.({ detail: "Unreadable post-purchase image-content image", kind: "section" });
|
|
4075
|
+
const text2 = convertImageContentText(settings, report);
|
|
4076
|
+
const textFrame = CABLayoutSection.parse({ direction: "grid", grid: { columns: ["100%"] }, sections: [text2] });
|
|
4077
|
+
const placement = settings.imagePlacement ?? (settings.swapContent ? "right" : "left");
|
|
4078
|
+
const imageFirst = placement === "left" || placement === "top";
|
|
4079
|
+
const sections = imageFirst ? [image, textFrame] : [textFrame, image];
|
|
4080
|
+
const ordered = sections.filter((section) => section !== null);
|
|
4081
|
+
const inner = placement === "left" || placement === "right" ? CABLayoutSection.parse({
|
|
4082
|
+
sections: ordered,
|
|
4083
|
+
spacing: "loose",
|
|
4084
|
+
wrapping: {
|
|
4085
|
+
breakAt: settings.imageSize <= 1 ? PROPORTIONAL_BREAK_AT : settings.imageSize,
|
|
4086
|
+
maxPerLine: 2
|
|
4087
|
+
}
|
|
4088
|
+
}) : CABLayoutSection.parse({
|
|
4089
|
+
direction: "grid",
|
|
4090
|
+
grid: { columns: ["100%"] },
|
|
4091
|
+
sections: [CABLayoutSection.parse({ sections: ordered })],
|
|
4092
|
+
width: 95
|
|
4093
|
+
});
|
|
4094
|
+
return [CABLayoutSection.parse({ frame: "offer-content", sections: [inner], spacing: "none" })];
|
|
4095
|
+
};
|
|
4096
|
+
|
|
3946
4097
|
// src/transforms/postPurchase/convertPayButtonBlock.ts
|
|
3947
4098
|
var convertPayButtonBlock = (raw, report) => {
|
|
3948
4099
|
const omit = () => {
|
|
@@ -3971,6 +4122,60 @@ var convertPayButtonBlock = (raw, report) => {
|
|
|
3971
4122
|
];
|
|
3972
4123
|
};
|
|
3973
4124
|
|
|
4125
|
+
// src/transforms/postPurchase/convertProductInformation.ts
|
|
4126
|
+
var convertProductInformation = (raw, report) => {
|
|
4127
|
+
const block = ProductInformationBlock.safeParse(raw);
|
|
4128
|
+
if (!block.success) {
|
|
4129
|
+
report?.({ detail: "Unreadable post-purchase product information", kind: "section" });
|
|
4130
|
+
return [];
|
|
4131
|
+
}
|
|
4132
|
+
return [
|
|
4133
|
+
CABOffersSection.parse({
|
|
4134
|
+
direction: "grid",
|
|
4135
|
+
sections: [
|
|
4136
|
+
CABLayoutSection.parse({
|
|
4137
|
+
alignment: { horizontal: "center" },
|
|
4138
|
+
sections: [
|
|
4139
|
+
CABLayoutSection.parse({
|
|
4140
|
+
alignment: { horizontal: "center" },
|
|
4141
|
+
direction: "grid",
|
|
4142
|
+
grid: { columns: [250] },
|
|
4143
|
+
sections: [
|
|
4144
|
+
CABImageSection.parse({ altText: "{{productTitle}}", source: "{{productImage}}" })
|
|
4145
|
+
],
|
|
4146
|
+
width: 90
|
|
4147
|
+
})
|
|
4148
|
+
]
|
|
4149
|
+
}),
|
|
4150
|
+
CABLayoutSection.parse({
|
|
4151
|
+
sections: [
|
|
4152
|
+
CABTextSection.parse({
|
|
4153
|
+
content: {
|
|
4154
|
+
en: {
|
|
4155
|
+
content: [
|
|
4156
|
+
{
|
|
4157
|
+
content: [
|
|
4158
|
+
{
|
|
4159
|
+
marks: [{ attrs: { fontSize: "heading" }, type: "textStyle" }],
|
|
4160
|
+
text: "{{productTitle}}"
|
|
4161
|
+
}
|
|
4162
|
+
]
|
|
4163
|
+
}
|
|
4164
|
+
]
|
|
4165
|
+
}
|
|
4166
|
+
}
|
|
4167
|
+
}),
|
|
4168
|
+
CABReviewsSection.parse({}),
|
|
4169
|
+
CABTextSection.parse({ content: { en: "{{productDescription}}" } })
|
|
4170
|
+
]
|
|
4171
|
+
})
|
|
4172
|
+
],
|
|
4173
|
+
spacing: "extraLoose",
|
|
4174
|
+
wrapping: { breakAt: 500, maxPerLine: block.data.hideProductImage ? 1 : 2 }
|
|
4175
|
+
})
|
|
4176
|
+
];
|
|
4177
|
+
};
|
|
4178
|
+
|
|
3974
4179
|
// src/transforms/postPurchase/convertSeparatorBlock.ts
|
|
3975
4180
|
var convertSeparatorBlock = (raw, report) => {
|
|
3976
4181
|
if (!SeparatorBlock.safeParse(raw).success) {
|
|
@@ -3981,34 +4186,36 @@ var convertSeparatorBlock = (raw, report) => {
|
|
|
3981
4186
|
};
|
|
3982
4187
|
|
|
3983
4188
|
// src/transforms/postPurchase/convertTextBlock.ts
|
|
3984
|
-
import { z as
|
|
3985
|
-
var
|
|
4189
|
+
import { z as z35 } from "zod";
|
|
4190
|
+
var fields3 = ["superTitle", "title", "description"];
|
|
3986
4191
|
var styles = {
|
|
3987
4192
|
description: [{ attrs: { color: "base", fontSize: "small" }, type: "textStyle" }],
|
|
3988
4193
|
superTitle: [{ attrs: { color: "subdued", fontSize: "small" }, type: "textStyle" }],
|
|
3989
4194
|
title: [{ type: "bold" }, { attrs: { color: "base", fontSize: "large" }, type: "textStyle" }]
|
|
3990
4195
|
};
|
|
3991
4196
|
var settingsSchema = TextBlock.shape.settings;
|
|
3992
|
-
var
|
|
4197
|
+
var Shell3 = z35.object({
|
|
3993
4198
|
settings: settingsSchema.pick({ horizontalAlignment: true }).extend({
|
|
3994
|
-
description:
|
|
3995
|
-
superTitle:
|
|
3996
|
-
title:
|
|
4199
|
+
description: z35.unknown().optional(),
|
|
4200
|
+
superTitle: z35.unknown().optional(),
|
|
4201
|
+
title: z35.unknown().optional()
|
|
3997
4202
|
}),
|
|
3998
|
-
type:
|
|
4203
|
+
type: z35.literal("text")
|
|
3999
4204
|
});
|
|
4000
4205
|
var convertTextBlock = (raw, report) => {
|
|
4001
|
-
const shell =
|
|
4206
|
+
const shell = Shell3.safeParse(raw);
|
|
4002
4207
|
if (!shell.success) {
|
|
4003
4208
|
report?.({ detail: "Unreadable post-purchase text block", kind: "section" });
|
|
4004
4209
|
return [];
|
|
4005
4210
|
}
|
|
4006
|
-
const values =
|
|
4211
|
+
const values = fields3.map((field) => ({
|
|
4007
4212
|
field,
|
|
4008
4213
|
result: settingsSchema.shape[field].safeParse(shell.data.settings[field])
|
|
4009
4214
|
}));
|
|
4010
4215
|
const horizontal = { center: "center", leading: "start", trailing: "end" }[shell.data.settings.horizontalAlignment];
|
|
4011
|
-
const styled2 = values.every(
|
|
4216
|
+
const styled2 = values.every(
|
|
4217
|
+
({ result }) => result.success && (result.data === null || typeof result.data === "string")
|
|
4218
|
+
);
|
|
4012
4219
|
const omit = (field) => {
|
|
4013
4220
|
report?.({ detail: `Unreadable post-purchase text field: ${field}`, kind: "section" });
|
|
4014
4221
|
return [];
|
|
@@ -4021,20 +4228,18 @@ var convertTextBlock = (raw, report) => {
|
|
|
4021
4228
|
const section = CABTextSection.safeParse({ content: { en: content } });
|
|
4022
4229
|
return section.success ? [section.data] : omit(field);
|
|
4023
4230
|
});
|
|
4024
|
-
return [
|
|
4025
|
-
CABLayoutSection.parse({
|
|
4026
|
-
alignment: {
|
|
4027
|
-
horizontal
|
|
4028
|
-
},
|
|
4029
|
-
sections
|
|
4030
|
-
})
|
|
4031
|
-
];
|
|
4231
|
+
return sections.length ? [CABLayoutSection.parse({ alignment: { horizontal }, sections })] : [];
|
|
4032
4232
|
};
|
|
4033
4233
|
|
|
4034
4234
|
// src/transforms/postPurchase/convertTimerBlock.ts
|
|
4035
4235
|
var Presentation = TimerBlock.pick({ styles: true }).extend({
|
|
4036
4236
|
settings: TimerBlock.shape.settings.pick({ title: true })
|
|
4037
4237
|
});
|
|
4238
|
+
var withCountdown = (doc, run, textAlign) => {
|
|
4239
|
+
const paragraphs = doc.content.length ? doc.content : [TiptapParagraph.parse({ attrs: { textAlign } })];
|
|
4240
|
+
const last = paragraphs[paragraphs.length - 1];
|
|
4241
|
+
return { ...doc, content: [...paragraphs.slice(0, -1), { ...last, content: [...last.content, run] }] };
|
|
4242
|
+
};
|
|
4038
4243
|
var convertTimerBlock = (raw, report) => {
|
|
4039
4244
|
const omit = () => {
|
|
4040
4245
|
report?.({ detail: "Unreadable post-purchase timer display", kind: "section" });
|
|
@@ -4045,17 +4250,15 @@ var convertTimerBlock = (raw, report) => {
|
|
|
4045
4250
|
const { title } = parsed.data.settings;
|
|
4046
4251
|
const styles2 = parsed.data.styles;
|
|
4047
4252
|
const horizontal = { center: "center", leading: "start", trailing: "end" }[styles2.textAlignment];
|
|
4253
|
+
const countdown = styledTextRun(" {{timeRemaining}}", styles2.timerEmphasized, styles2.timerSize);
|
|
4048
4254
|
const content = typeof title === "string" ? {
|
|
4049
4255
|
content: [
|
|
4050
4256
|
{
|
|
4051
4257
|
attrs: { textAlign: horizontal },
|
|
4052
|
-
content: [
|
|
4053
|
-
styledTextRun(title, styles2.titleEmphasized, styles2.titleSize),
|
|
4054
|
-
styledTextRun(" {{timeRemaining}}", styles2.timerEmphasized, styles2.timerSize)
|
|
4055
|
-
]
|
|
4258
|
+
content: [styledTextRun(title, styles2.titleEmphasized, styles2.titleSize), countdown]
|
|
4056
4259
|
}
|
|
4057
4260
|
]
|
|
4058
|
-
} : title;
|
|
4261
|
+
} : withCountdown(title, countdown, horizontal);
|
|
4059
4262
|
const text2 = CABTextSection.safeParse({ content: { en: content } });
|
|
4060
4263
|
if (!text2.success) return omit();
|
|
4061
4264
|
return [
|
|
@@ -4069,14 +4272,17 @@ var convertTimerBlock = (raw, report) => {
|
|
|
4069
4272
|
};
|
|
4070
4273
|
|
|
4071
4274
|
// src/transforms/postPurchase/convertMessagePreview.ts
|
|
4072
|
-
var MessageWidget =
|
|
4073
|
-
blocks:
|
|
4074
|
-
type:
|
|
4275
|
+
var MessageWidget = z36.object({
|
|
4276
|
+
blocks: z36.array(z36.unknown()).min(1),
|
|
4277
|
+
type: z36.literal(WidgetType.shopify_post_purchase_extension)
|
|
4075
4278
|
});
|
|
4076
|
-
var BlockType2 =
|
|
4279
|
+
var BlockType2 = z36.object({ type: z36.string() });
|
|
4077
4280
|
var converters = {
|
|
4078
4281
|
callout_banner: convertCalloutBlock,
|
|
4282
|
+
image: convertImageBlock,
|
|
4283
|
+
image_content: convertImageContentBlock,
|
|
4079
4284
|
pay_button: convertPayButtonBlock,
|
|
4285
|
+
product_information: convertProductInformation,
|
|
4080
4286
|
separator: convertSeparatorBlock,
|
|
4081
4287
|
text: convertTextBlock,
|
|
4082
4288
|
timer: convertTimerBlock
|
|
@@ -4090,7 +4296,7 @@ var convertMessagePreview = (id, settings, report) => {
|
|
|
4090
4296
|
sections: parsed.data.blocks.flatMap((block) => {
|
|
4091
4297
|
const type = BlockType2.safeParse(block);
|
|
4092
4298
|
const kind = type.success ? type.data.type : void 0;
|
|
4093
|
-
const convert2 = kind ? converters[kind] : void 0;
|
|
4299
|
+
const convert2 = kind && Object.hasOwn(converters, kind) ? converters[kind] : void 0;
|
|
4094
4300
|
if (convert2) return convert2(block, report);
|
|
4095
4301
|
report?.({
|
|
4096
4302
|
detail: kind ? `Unsupported post-purchase block type: ${kind}` : "Unreadable post-purchase block: missing type",
|
|
@@ -4618,7 +4824,7 @@ var fetchDataSourceResults = async (input, ctx) => {
|
|
|
4618
4824
|
};
|
|
4619
4825
|
|
|
4620
4826
|
// src/server/adsEngine.ts
|
|
4621
|
-
import { z as
|
|
4827
|
+
import { z as z37 } from "zod";
|
|
4622
4828
|
var SUPPLY_KEY = { production: "AQF5RKLR", staging: "Z56LQ7PS" };
|
|
4623
4829
|
var OFFER_LIMIT = 4;
|
|
4624
4830
|
var SUPPORTED_COUNTRIES = /* @__PURE__ */ new Set(["US", "CA"]);
|
|
@@ -4631,28 +4837,28 @@ var transactionItems = (input) => (input.transactionItems?.map(({ id, priceCents
|
|
|
4631
4837
|
title,
|
|
4632
4838
|
type
|
|
4633
4839
|
})) ?? input.cart.items.map(({ productId, quantity }) => ({ id: productId, quantity }))).slice(0, MAX_TRANSACTION_ITEMS);
|
|
4634
|
-
var AdsEngineOffer =
|
|
4840
|
+
var AdsEngineOffer = z37.object({
|
|
4635
4841
|
/** Pill-style value prop ("Get $45 Cashback"). Carried through the parse; the card does not render it yet (REB-24429 — pill design pending). */
|
|
4636
|
-
callout:
|
|
4637
|
-
click_url:
|
|
4638
|
-
cta:
|
|
4842
|
+
callout: z37.string().catch(""),
|
|
4843
|
+
click_url: z37.string(),
|
|
4844
|
+
cta: z37.string(),
|
|
4639
4845
|
/** `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'). */
|
|
4640
|
-
decline_cta:
|
|
4641
|
-
decline_url:
|
|
4642
|
-
description:
|
|
4846
|
+
decline_cta: z37.string().catch(""),
|
|
4847
|
+
decline_url: z37.string(),
|
|
4848
|
+
description: z37.string(),
|
|
4643
4849
|
/** Short legal disclosure (FDIC / auto-renewal / FTC-affiliation lines). Rendered subdued under the CTAs. */
|
|
4644
|
-
disclaimer:
|
|
4850
|
+
disclaimer: z37.string().catch(""),
|
|
4645
4851
|
/** Long legal text behind the disclosure toggle in the composed card (REB-24429). */
|
|
4646
|
-
extended_disclaimer:
|
|
4647
|
-
headline:
|
|
4648
|
-
id:
|
|
4852
|
+
extended_disclaimer: z37.string().catch(""),
|
|
4853
|
+
headline: z37.string(),
|
|
4854
|
+
id: z37.string(),
|
|
4649
4855
|
/** Advertiser-supplied image alt; the composed card falls back to the stripped headline when empty. */
|
|
4650
|
-
image_alt:
|
|
4651
|
-
image_url:
|
|
4652
|
-
view_url:
|
|
4856
|
+
image_alt: z37.string().catch(""),
|
|
4857
|
+
image_url: z37.string().optional(),
|
|
4858
|
+
view_url: z37.string()
|
|
4653
4859
|
});
|
|
4654
|
-
var AdsEngineResponse =
|
|
4655
|
-
offers:
|
|
4860
|
+
var AdsEngineResponse = z37.object({
|
|
4861
|
+
offers: z37.array(z37.unknown()).default([]).transform(
|
|
4656
4862
|
(offers) => offers.flatMap((offer) => {
|
|
4657
4863
|
const result = AdsEngineOffer.safeParse(offer);
|
|
4658
4864
|
return result.success ? [result.data] : [];
|
|
@@ -4664,8 +4870,8 @@ var AdsEngineResponse = z34.object({
|
|
|
4664
4870
|
* offers-testing fixture on a test store forces it, REB-24467). Both optional: an older engine or a
|
|
4665
4871
|
* non-JSON body must not fail the parse and drop the offers.
|
|
4666
4872
|
*/
|
|
4667
|
-
request_id:
|
|
4668
|
-
testing:
|
|
4873
|
+
request_id: z37.string().optional().catch(void 0),
|
|
4874
|
+
testing: z37.boolean().optional().catch(void 0)
|
|
4669
4875
|
});
|
|
4670
4876
|
var adsHost = (host) => `offers.${host}`;
|
|
4671
4877
|
var isTestingRequest = (input, isProduction) => !isProduction || !!input.testing || input.customerEmail?.toLowerCase() === TEST_CUSTOMER_EMAIL;
|
|
@@ -5095,13 +5301,13 @@ var convertWidgetSettings = async (input, ctx) => {
|
|
|
5095
5301
|
};
|
|
5096
5302
|
|
|
5097
5303
|
// src/server/giftWidgets.ts
|
|
5098
|
-
import { z as
|
|
5099
|
-
var SettingsNumber =
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
]).pipe(
|
|
5103
|
-
var SgwpMilestoneSchema =
|
|
5104
|
-
selectable_product_quantity: SettingsNumber.pipe(
|
|
5304
|
+
import { z as z38 } from "zod";
|
|
5305
|
+
var SettingsNumber = z38.union([
|
|
5306
|
+
z38.number(),
|
|
5307
|
+
z38.string().trim().regex(/^-?\d+(\.\d+)?$/)
|
|
5308
|
+
]).pipe(z38.coerce.number());
|
|
5309
|
+
var SgwpMilestoneSchema = z38.object({
|
|
5310
|
+
selectable_product_quantity: SettingsNumber.pipe(z38.number().int().nonnegative()),
|
|
5105
5311
|
unlock_price: SettingsNumber
|
|
5106
5312
|
});
|
|
5107
5313
|
var fetchGiftWidgetSettings = async (widgetId, shop, ctx) => unwrapData(await ctx.fetchUpstream("/api/v1/widgets/settings", { id: String(widgetId), shop }, { host: ctx.host }));
|
|
@@ -5112,7 +5318,7 @@ var readDataSourcePath = (settings) => {
|
|
|
5112
5318
|
var readMilestones = (settings, report) => {
|
|
5113
5319
|
const raw = settings && typeof settings === "object" ? settings.milestones : void 0;
|
|
5114
5320
|
if (raw == null) return [];
|
|
5115
|
-
const parsed =
|
|
5321
|
+
const parsed = z38.array(SgwpMilestoneSchema).safeParse(raw);
|
|
5116
5322
|
if (parsed.success) return parsed.data;
|
|
5117
5323
|
report?.({
|
|
5118
5324
|
detail: [
|
|
@@ -5361,7 +5567,7 @@ var postAnalyticsEvents = async (input, ctx) => {
|
|
|
5361
5567
|
};
|
|
5362
5568
|
|
|
5363
5569
|
// src/server/requestSchemas.ts
|
|
5364
|
-
import { z as
|
|
5570
|
+
import { z as z39 } from "zod";
|
|
5365
5571
|
var REQUEST_BOUNDS = {
|
|
5366
5572
|
/** Cart-level attributes per cart. */
|
|
5367
5573
|
CART_ATTRIBUTES_MAX: 100,
|
|
@@ -5392,42 +5598,42 @@ var REQUEST_BOUNDS = {
|
|
|
5392
5598
|
/** Rich ads transaction lines — the engine's ads contract. */
|
|
5393
5599
|
TRANSACTION_ITEMS_MAX: 50
|
|
5394
5600
|
};
|
|
5395
|
-
var KeyValue =
|
|
5396
|
-
key:
|
|
5397
|
-
value:
|
|
5601
|
+
var KeyValue = z39.object({
|
|
5602
|
+
key: z39.string().max(REQUEST_BOUNDS.STRING_KEY_MAX),
|
|
5603
|
+
value: z39.string().max(REQUEST_BOUNDS.STRING_VALUE_MAX).optional()
|
|
5398
5604
|
});
|
|
5399
|
-
var CartLineInputSchema =
|
|
5400
|
-
productId:
|
|
5401
|
-
properties:
|
|
5402
|
-
quantity:
|
|
5403
|
-
subscriptionId:
|
|
5404
|
-
variantId:
|
|
5605
|
+
var CartLineInputSchema = z39.object({
|
|
5606
|
+
productId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
5607
|
+
properties: z39.array(KeyValue).max(REQUEST_BOUNDS.LINE_PROPERTIES_MAX).optional(),
|
|
5608
|
+
quantity: z39.number(),
|
|
5609
|
+
subscriptionId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5610
|
+
variantId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX)
|
|
5405
5611
|
});
|
|
5406
|
-
var CartInputSchema =
|
|
5407
|
-
attributes:
|
|
5612
|
+
var CartInputSchema = z39.object({
|
|
5613
|
+
attributes: z39.array(KeyValue).max(REQUEST_BOUNDS.CART_ATTRIBUTES_MAX).optional(),
|
|
5408
5614
|
/**
|
|
5409
5615
|
* Presentment-per-shop-currency FX rate (buyer price ÷ shop price, e.g. `1.35` for a USD shop
|
|
5410
5616
|
* selling in CAD). Money rule thresholds are authored in SHOP currency, so the engine subtotal is
|
|
5411
5617
|
* divided by this before evaluation. Omit (or send 1) when the cart is already in the shop's currency.
|
|
5412
5618
|
*/
|
|
5413
|
-
currencyRate:
|
|
5619
|
+
currencyRate: z39.number().optional(),
|
|
5414
5620
|
/** Applied discount codes; the engine evaluates `discount_code` rules against them (sent as `[{code}]`). */
|
|
5415
|
-
discountCodes:
|
|
5621
|
+
discountCodes: z39.array(z39.string().max(REQUEST_BOUNDS.STRING_KEY_MAX)).max(REQUEST_BOUNDS.DISCOUNT_CODES_MAX).optional(),
|
|
5416
5622
|
/** Presentment cents of cart-level discount allocations, subtracted from `subtotal` for the engine. */
|
|
5417
|
-
discountTotal:
|
|
5418
|
-
items:
|
|
5623
|
+
discountTotal: z39.number().optional(),
|
|
5624
|
+
items: z39.array(CartLineInputSchema).max(REQUEST_BOUNDS.CART_ITEMS_MAX),
|
|
5419
5625
|
/** Presentment subtotal in cents. */
|
|
5420
|
-
subtotal:
|
|
5626
|
+
subtotal: z39.number()
|
|
5421
5627
|
});
|
|
5422
|
-
var UserConfigInputSchema =
|
|
5423
|
-
var DataSourceInputSchema =
|
|
5628
|
+
var UserConfigInputSchema = z39.object({ shop: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX) });
|
|
5629
|
+
var DataSourceInputSchema = z39.object({
|
|
5424
5630
|
cart: CartInputSchema,
|
|
5425
5631
|
/**
|
|
5426
5632
|
* Numeric Shopify company-location id when the buyer is a B2B session (`buyerIdentity.purchasingCompany`).
|
|
5427
5633
|
* Present ⇒ the orchestrator filters results by the location's catalog via admin-api (REB-23713); the
|
|
5428
5634
|
* client's country-context market check is bypassed for B2B (it false-negatives B2B-catalog products).
|
|
5429
5635
|
*/
|
|
5430
|
-
companyLocationId:
|
|
5636
|
+
companyLocationId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5431
5637
|
/**
|
|
5432
5638
|
* Buyer's market country (ISO 3166-1 alpha-2) — forwarded to the engine as the `country_code` PARAM
|
|
5433
5639
|
* when the shop's markets toggle is on (REB-21688; the sink was the `X-Country-Code` header under
|
|
@@ -5436,16 +5642,16 @@ var DataSourceInputSchema = z36.object({
|
|
|
5436
5642
|
* uppercase (the wire value is forwarded verbatim as the param) so a case-sensitive engine lookup
|
|
5437
5643
|
* can't silently miss a lowercase code — `adsEngine.ts` uppercases for the same reason.
|
|
5438
5644
|
*/
|
|
5439
|
-
country:
|
|
5440
|
-
customerId:
|
|
5441
|
-
dataSourcePath:
|
|
5645
|
+
country: z39.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(),
|
|
5646
|
+
customerId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5647
|
+
dataSourcePath: z39.string().max(REQUEST_BOUNDS.STRING_KEY_MAX),
|
|
5442
5648
|
/**
|
|
5443
5649
|
* Engine `filter_inputs` override: `'no'` keeps in-cart (input) products in the results/rule
|
|
5444
5650
|
* outputs — gift validation sends it so a gift's own product can appear in its answer. Omitted = the
|
|
5445
5651
|
* engine's default filtering.
|
|
5446
5652
|
*/
|
|
5447
|
-
filterInputs:
|
|
5448
|
-
integrations:
|
|
5653
|
+
filterInputs: z39.enum(["no", "yes"]).optional(),
|
|
5654
|
+
integrations: z39.record(z39.string().max(REQUEST_BOUNDS.STRING_KEY_MAX), z39.boolean()).refine((record) => Object.keys(record).length <= REQUEST_BOUNDS.INTEGRATION_KEYS_MAX, {
|
|
5449
5655
|
message: `Too many integration keys (max ${REQUEST_BOUNDS.INTEGRATION_KEYS_MAX})`
|
|
5450
5656
|
}).optional(),
|
|
5451
5657
|
/**
|
|
@@ -5458,31 +5664,31 @@ var DataSourceInputSchema = z36.object({
|
|
|
5458
5664
|
* request header) fails the regex. Callers should send the buyer's resolved locale (e.g. Shopify
|
|
5459
5665
|
* checkout's `localization.language.isoCode`), not the request header verbatim.
|
|
5460
5666
|
*/
|
|
5461
|
-
language:
|
|
5462
|
-
limit:
|
|
5463
|
-
productType:
|
|
5464
|
-
shop:
|
|
5465
|
-
visitorId:
|
|
5667
|
+
language: z39.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(),
|
|
5668
|
+
limit: z39.number().max(REQUEST_BOUNDS.LIMIT_MAX),
|
|
5669
|
+
productType: z39.enum(["both", "one-time", "subscription"]).optional(),
|
|
5670
|
+
shop: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
5671
|
+
visitorId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
|
|
5466
5672
|
});
|
|
5467
|
-
var GiftInputSchema =
|
|
5468
|
-
cost:
|
|
5469
|
-
discounted:
|
|
5673
|
+
var GiftInputSchema = z39.object({
|
|
5674
|
+
cost: z39.number(),
|
|
5675
|
+
discounted: z39.boolean(),
|
|
5470
5676
|
/**
|
|
5471
5677
|
* Which gift attribution the line carries (REB-24363). Defaults to `gwp` because a client that predates
|
|
5472
5678
|
* the field only ever sent GWP lines — without the default an older extension's request would 422.
|
|
5473
5679
|
*/
|
|
5474
|
-
kind:
|
|
5475
|
-
lineId:
|
|
5476
|
-
productId:
|
|
5680
|
+
kind: z39.enum(GIFT_KINDS).default("gwp"),
|
|
5681
|
+
lineId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
5682
|
+
productId: z39.number(),
|
|
5477
5683
|
/**
|
|
5478
5684
|
* The line's unit count (REB-24363) — the selectable-GWP verdict trims surplus units against milestone
|
|
5479
5685
|
* capacity. The second deliberate default: a client predating the field sent only GWP lines, whose
|
|
5480
5686
|
* verdict is whole-line, so a missing quantity reads as one unit rather than 422ing the older request.
|
|
5481
5687
|
*/
|
|
5482
|
-
quantity:
|
|
5483
|
-
widgetId:
|
|
5688
|
+
quantity: z39.number().int().min(1).default(1),
|
|
5689
|
+
widgetId: z39.number()
|
|
5484
5690
|
});
|
|
5485
|
-
var GiftValidationInputSchema =
|
|
5691
|
+
var GiftValidationInputSchema = z39.object({
|
|
5486
5692
|
cart: CartInputSchema,
|
|
5487
5693
|
/**
|
|
5488
5694
|
* Buyer's market country — threaded into the per-widget data-source evaluations, which forward it to
|
|
@@ -5491,25 +5697,25 @@ var GiftValidationInputSchema = z36.object({
|
|
|
5491
5697
|
* turns markets off); regex-bound and uppercase-normalized for the same reasons as
|
|
5492
5698
|
* `DataSourceInputSchema`'s `country`.
|
|
5493
5699
|
*/
|
|
5494
|
-
country:
|
|
5495
|
-
customerId:
|
|
5496
|
-
gifts:
|
|
5700
|
+
country: z39.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(),
|
|
5701
|
+
customerId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5702
|
+
gifts: z39.array(GiftInputSchema).max(REQUEST_BOUNDS.GIFTS_MAX),
|
|
5497
5703
|
/**
|
|
5498
5704
|
* Buyer's checkout language — threaded into the per-widget data-source evaluations, which normalize
|
|
5499
5705
|
* and forward it as the engine `locale` param under the same markets-toggle gate (REB-21688). MUST be
|
|
5500
5706
|
* a single BCP-47 tag, for the same reason as `DataSourceInputSchema`'s `language` above.
|
|
5501
5707
|
*/
|
|
5502
|
-
language:
|
|
5503
|
-
shop:
|
|
5504
|
-
visitorId:
|
|
5708
|
+
language: z39.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(),
|
|
5709
|
+
shop: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
5710
|
+
visitorId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
|
|
5505
5711
|
});
|
|
5506
|
-
var GiftAdjustmentSchema =
|
|
5507
|
-
lineId:
|
|
5508
|
-
quantity:
|
|
5712
|
+
var GiftAdjustmentSchema = z39.object({
|
|
5713
|
+
lineId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
5714
|
+
quantity: z39.number().int().nonnegative()
|
|
5509
5715
|
});
|
|
5510
|
-
var GiftValidationResponseSchema =
|
|
5511
|
-
adjust:
|
|
5512
|
-
remove:
|
|
5716
|
+
var GiftValidationResponseSchema = z39.object({
|
|
5717
|
+
adjust: z39.array(GiftAdjustmentSchema).max(REQUEST_BOUNDS.GIFTS_MAX).default([]),
|
|
5718
|
+
remove: z39.array(z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX)).max(REQUEST_BOUNDS.GIFTS_MAX).refine(
|
|
5513
5719
|
(remove) => new Set(remove).size === remove.length,
|
|
5514
5720
|
"a line id may appear at most once in `remove`"
|
|
5515
5721
|
)
|
|
@@ -5520,47 +5726,47 @@ var GiftValidationResponseSchema = z36.object({
|
|
|
5520
5726
|
({ adjust }) => new Set(adjust.map(({ lineId }) => lineId)).size === adjust.length,
|
|
5521
5727
|
"a line id may appear at most once in `adjust`"
|
|
5522
5728
|
);
|
|
5523
|
-
var MonetizeTransactionItemSchema =
|
|
5524
|
-
id:
|
|
5525
|
-
priceCents:
|
|
5526
|
-
quantity:
|
|
5527
|
-
title:
|
|
5528
|
-
type:
|
|
5729
|
+
var MonetizeTransactionItemSchema = z39.object({
|
|
5730
|
+
id: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
5731
|
+
priceCents: z39.number(),
|
|
5732
|
+
quantity: z39.number(),
|
|
5733
|
+
title: z39.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX),
|
|
5734
|
+
type: z39.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX)
|
|
5529
5735
|
});
|
|
5530
|
-
var MonetizeInputSchema =
|
|
5736
|
+
var MonetizeInputSchema = z39.object({
|
|
5531
5737
|
cart: CartInputSchema,
|
|
5532
5738
|
/** Client-minted render-beacon correlation id; forwarded to the ads engine as `client_request_id`. */
|
|
5533
|
-
clientRequestId:
|
|
5534
|
-
country:
|
|
5535
|
-
currency:
|
|
5739
|
+
clientRequestId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5740
|
+
country: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5741
|
+
currency: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5536
5742
|
/** Ads-targeting identity/geo/locale fields (React parity); folded into the engine query verbatim. */
|
|
5537
|
-
customerEmail:
|
|
5538
|
-
customerFirstName:
|
|
5539
|
-
customerId:
|
|
5540
|
-
customerLastName:
|
|
5541
|
-
language:
|
|
5743
|
+
customerEmail: z39.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX).optional(),
|
|
5744
|
+
customerFirstName: z39.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX).optional(),
|
|
5745
|
+
customerId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5746
|
+
customerLastName: z39.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX).optional(),
|
|
5747
|
+
language: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5542
5748
|
/** Buyer-facing order name (e.g. `#1001`) for the server-composed "Order … Confirmed" chrome line. */
|
|
5543
|
-
orderName:
|
|
5749
|
+
orderName: z39.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX).optional(),
|
|
5544
5750
|
/** Ads surface label, forwarded verbatim; `customer_account` is measured/floored as its own surface (the account-area order list). */
|
|
5545
|
-
placement:
|
|
5751
|
+
placement: z39.enum(["customer_account", "order_status", "thank_you_page"]),
|
|
5546
5752
|
/** Privacy Policy footer href — the Monetize widget's `privacy_policy_url` setting (React parity). */
|
|
5547
|
-
privacyPolicyUrl:
|
|
5753
|
+
privacyPolicyUrl: z39.string().max(REQUEST_BOUNDS.STRING_URL_MAX).optional(),
|
|
5548
5754
|
/** 30-min rolling session id (React parity); used for the ads `session_id`, else the visitor id. */
|
|
5549
|
-
sessionId:
|
|
5550
|
-
shop:
|
|
5755
|
+
sessionId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5756
|
+
shop: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
5551
5757
|
/** Editor/QA indicator; OR-ed into the ads-engine `testing` flag so it stays out of billing/reporting. */
|
|
5552
|
-
testing:
|
|
5553
|
-
timezone:
|
|
5758
|
+
testing: z39.boolean().optional(),
|
|
5759
|
+
timezone: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5554
5760
|
/** Decorated (numeric) order id → the ads `transaction_id`. */
|
|
5555
|
-
transactionId:
|
|
5761
|
+
transactionId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5556
5762
|
/** Rich per-line ads items; capped at the engine's ads contract. Preferred over `cart.items`. */
|
|
5557
|
-
transactionItems:
|
|
5763
|
+
transactionItems: z39.array(MonetizeTransactionItemSchema).max(REQUEST_BOUNDS.TRANSACTION_ITEMS_MAX).optional(),
|
|
5558
5764
|
/** Order total in presentment cents (React prefers total over subtotal); else `cart.subtotal`. */
|
|
5559
|
-
transactionTotal:
|
|
5560
|
-
visitorId:
|
|
5561
|
-
zipCode:
|
|
5765
|
+
transactionTotal: z39.number().optional(),
|
|
5766
|
+
visitorId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5767
|
+
zipCode: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
|
|
5562
5768
|
});
|
|
5563
|
-
var WidgetSettingsInputSchema =
|
|
5769
|
+
var WidgetSettingsInputSchema = z39.object({
|
|
5564
5770
|
/**
|
|
5565
5771
|
* Same domain as `CabShopConfig.cacheKey`, for the same reason: this side WINS the orchestrator's
|
|
5566
5772
|
* `input.cacheKey ?? config.shop.cacheKey` (and an explicit value skips the config read entirely), so
|
|
@@ -5568,9 +5774,9 @@ var WidgetSettingsInputSchema = z36.object({
|
|
|
5568
5774
|
* and pin the edge copy permanently stale. `.catch(undefined)` because a bogus buster should degrade
|
|
5569
5775
|
* the read to un-busted, never 400 a widget render.
|
|
5570
5776
|
*/
|
|
5571
|
-
cacheKey:
|
|
5572
|
-
id:
|
|
5573
|
-
key:
|
|
5777
|
+
cacheKey: z39.number().int().positive().optional().catch(void 0),
|
|
5778
|
+
id: z39.number(),
|
|
5779
|
+
key: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5574
5780
|
/**
|
|
5575
5781
|
* Monetize context for inline hydration: when present AND the widget converts to a Monetize marker,
|
|
5576
5782
|
* the server fetches/composes the offer cards inside this same request (no second `/cab/monetize`
|
|
@@ -5579,36 +5785,36 @@ var WidgetSettingsInputSchema = z36.object({
|
|
|
5579
5785
|
* `privacyPolicyUrl` comes from the widget settings server-side (more authoritative than a relay).
|
|
5580
5786
|
*/
|
|
5581
5787
|
monetize: MonetizeInputSchema.omit({ privacyPolicyUrl: true, shop: true }).optional(),
|
|
5582
|
-
shop:
|
|
5788
|
+
shop: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
5583
5789
|
/** Stable per-buyer id; when present, enables sticky server-side A/B variant selection. */
|
|
5584
|
-
visitorId:
|
|
5790
|
+
visitorId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
|
|
5585
5791
|
});
|
|
5586
|
-
var AnalyticsEventInputSchema =
|
|
5587
|
-
name:
|
|
5588
|
-
properties:
|
|
5589
|
-
sentAt:
|
|
5792
|
+
var AnalyticsEventInputSchema = z39.object({
|
|
5793
|
+
name: z39.string().max(REQUEST_BOUNDS.STRING_KEY_MAX),
|
|
5794
|
+
properties: z39.record(z39.string().max(REQUEST_BOUNDS.STRING_KEY_MAX), z39.unknown()).optional(),
|
|
5795
|
+
sentAt: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
|
|
5590
5796
|
});
|
|
5591
|
-
var AnalyticsSegmentsInputSchema =
|
|
5592
|
-
device:
|
|
5593
|
-
source:
|
|
5594
|
-
visitor:
|
|
5797
|
+
var AnalyticsSegmentsInputSchema = z39.object({
|
|
5798
|
+
device: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional().catch(void 0),
|
|
5799
|
+
source: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional().catch(void 0),
|
|
5800
|
+
visitor: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional().catch(void 0)
|
|
5595
5801
|
});
|
|
5596
|
-
var AnalyticsInputSchema =
|
|
5802
|
+
var AnalyticsInputSchema = z39.object({
|
|
5597
5803
|
/** Rebuy cart token (the `r_cart_token` cart attribute), when available — primary aggregation key. */
|
|
5598
|
-
cartToken:
|
|
5804
|
+
cartToken: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5599
5805
|
/** Shopify checkout token, when available — drives cart/checkout aggregation downstream. */
|
|
5600
|
-
checkoutToken:
|
|
5601
|
-
events:
|
|
5806
|
+
checkoutToken: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
|
|
5807
|
+
events: z39.array(AnalyticsEventInputSchema).max(REQUEST_BOUNDS.EVENTS_MAX),
|
|
5602
5808
|
/**
|
|
5603
5809
|
* Request-scoped like the tokens: one visitor's segments apply to every event in the batch. The container
|
|
5604
5810
|
* degrades too (`null` is a realistic wire artifact of `attributes ? {…} : null`), so the degrade rule is
|
|
5605
5811
|
* total: nothing about `segments` can cost the envelope.
|
|
5606
5812
|
*/
|
|
5607
5813
|
segments: AnalyticsSegmentsInputSchema.optional().catch(void 0),
|
|
5608
|
-
shop:
|
|
5609
|
-
visitorId:
|
|
5814
|
+
shop: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
5815
|
+
visitorId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
|
|
5610
5816
|
/** The widget id (smartBlockId) the events belong to. */
|
|
5611
|
-
widgetId:
|
|
5817
|
+
widgetId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
|
|
5612
5818
|
});
|
|
5613
5819
|
export {
|
|
5614
5820
|
AnalyticsEventInputSchema,
|