@rebuy/rebuy 3.28.1 → 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.
@@ -3727,7 +3727,7 @@ var convertOfferToV2 = ({ id, name, settings }) => {
3727
3727
  var parseShielded = (schema, raw, transform = (input) => input) => schema.parse(transform(convertNumericObjects(deepCamelCase(raw))));
3728
3728
 
3729
3729
  // src/transforms/postPurchase/convertMessagePreview.ts
3730
- import { z as z33 } from "zod";
3730
+ import { z as z36 } from "zod";
3731
3731
 
3732
3732
  // src/transforms/postPurchase/convertCalloutBlock.ts
3733
3733
  import { z as z31 } from "zod";
@@ -3950,6 +3950,150 @@ var convertCalloutBlock = (raw, report) => {
3950
3950
  return sections.length ? [CABLayoutSection.parse({ alignment: { horizontal }, frame: "callout", sections })] : [];
3951
3951
  };
3952
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
+
3953
4097
  // src/transforms/postPurchase/convertPayButtonBlock.ts
3954
4098
  var convertPayButtonBlock = (raw, report) => {
3955
4099
  const omit = () => {
@@ -3978,6 +4122,60 @@ var convertPayButtonBlock = (raw, report) => {
3978
4122
  ];
3979
4123
  };
3980
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
+
3981
4179
  // src/transforms/postPurchase/convertSeparatorBlock.ts
3982
4180
  var convertSeparatorBlock = (raw, report) => {
3983
4181
  if (!SeparatorBlock.safeParse(raw).success) {
@@ -3988,29 +4186,29 @@ var convertSeparatorBlock = (raw, report) => {
3988
4186
  };
3989
4187
 
3990
4188
  // src/transforms/postPurchase/convertTextBlock.ts
3991
- import { z as z32 } from "zod";
3992
- var fields2 = ["superTitle", "title", "description"];
4189
+ import { z as z35 } from "zod";
4190
+ var fields3 = ["superTitle", "title", "description"];
3993
4191
  var styles = {
3994
4192
  description: [{ attrs: { color: "base", fontSize: "small" }, type: "textStyle" }],
3995
4193
  superTitle: [{ attrs: { color: "subdued", fontSize: "small" }, type: "textStyle" }],
3996
4194
  title: [{ type: "bold" }, { attrs: { color: "base", fontSize: "large" }, type: "textStyle" }]
3997
4195
  };
3998
4196
  var settingsSchema = TextBlock.shape.settings;
3999
- var Shell2 = z32.object({
4197
+ var Shell3 = z35.object({
4000
4198
  settings: settingsSchema.pick({ horizontalAlignment: true }).extend({
4001
- description: z32.unknown().optional(),
4002
- superTitle: z32.unknown().optional(),
4003
- title: z32.unknown().optional()
4199
+ description: z35.unknown().optional(),
4200
+ superTitle: z35.unknown().optional(),
4201
+ title: z35.unknown().optional()
4004
4202
  }),
4005
- type: z32.literal("text")
4203
+ type: z35.literal("text")
4006
4204
  });
4007
4205
  var convertTextBlock = (raw, report) => {
4008
- const shell = Shell2.safeParse(raw);
4206
+ const shell = Shell3.safeParse(raw);
4009
4207
  if (!shell.success) {
4010
4208
  report?.({ detail: "Unreadable post-purchase text block", kind: "section" });
4011
4209
  return [];
4012
4210
  }
4013
- const values = fields2.map((field) => ({
4211
+ const values = fields3.map((field) => ({
4014
4212
  field,
4015
4213
  result: settingsSchema.shape[field].safeParse(shell.data.settings[field])
4016
4214
  }));
@@ -4074,14 +4272,17 @@ var convertTimerBlock = (raw, report) => {
4074
4272
  };
4075
4273
 
4076
4274
  // src/transforms/postPurchase/convertMessagePreview.ts
4077
- var MessageWidget = z33.object({
4078
- blocks: z33.array(z33.unknown()).min(1),
4079
- type: z33.literal(WidgetType.shopify_post_purchase_extension)
4275
+ var MessageWidget = z36.object({
4276
+ blocks: z36.array(z36.unknown()).min(1),
4277
+ type: z36.literal(WidgetType.shopify_post_purchase_extension)
4080
4278
  });
4081
- var BlockType2 = z33.object({ type: z33.string() });
4279
+ var BlockType2 = z36.object({ type: z36.string() });
4082
4280
  var converters = {
4083
4281
  callout_banner: convertCalloutBlock,
4282
+ image: convertImageBlock,
4283
+ image_content: convertImageContentBlock,
4084
4284
  pay_button: convertPayButtonBlock,
4285
+ product_information: convertProductInformation,
4085
4286
  separator: convertSeparatorBlock,
4086
4287
  text: convertTextBlock,
4087
4288
  timer: convertTimerBlock
@@ -4623,7 +4824,7 @@ var fetchDataSourceResults = async (input, ctx) => {
4623
4824
  };
4624
4825
 
4625
4826
  // src/server/adsEngine.ts
4626
- import { z as z34 } from "zod";
4827
+ import { z as z37 } from "zod";
4627
4828
  var SUPPLY_KEY = { production: "AQF5RKLR", staging: "Z56LQ7PS" };
4628
4829
  var OFFER_LIMIT = 4;
4629
4830
  var SUPPORTED_COUNTRIES = /* @__PURE__ */ new Set(["US", "CA"]);
@@ -4636,28 +4837,28 @@ var transactionItems = (input) => (input.transactionItems?.map(({ id, priceCents
4636
4837
  title,
4637
4838
  type
4638
4839
  })) ?? input.cart.items.map(({ productId, quantity }) => ({ id: productId, quantity }))).slice(0, MAX_TRANSACTION_ITEMS);
4639
- var AdsEngineOffer = z34.object({
4840
+ var AdsEngineOffer = z37.object({
4640
4841
  /** Pill-style value prop ("Get $45 Cashback"). Carried through the parse; the card does not render it yet (REB-24429 — pill design pending). */
4641
- callout: z34.string().catch(""),
4642
- click_url: z34.string(),
4643
- cta: z34.string(),
4842
+ callout: z37.string().catch(""),
4843
+ click_url: z37.string(),
4844
+ cta: z37.string(),
4644
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'). */
4645
- decline_cta: z34.string().catch(""),
4646
- decline_url: z34.string(),
4647
- description: z34.string(),
4846
+ decline_cta: z37.string().catch(""),
4847
+ decline_url: z37.string(),
4848
+ description: z37.string(),
4648
4849
  /** Short legal disclosure (FDIC / auto-renewal / FTC-affiliation lines). Rendered subdued under the CTAs. */
4649
- disclaimer: z34.string().catch(""),
4850
+ disclaimer: z37.string().catch(""),
4650
4851
  /** Long legal text behind the disclosure toggle in the composed card (REB-24429). */
4651
- extended_disclaimer: z34.string().catch(""),
4652
- headline: z34.string(),
4653
- id: z34.string(),
4852
+ extended_disclaimer: z37.string().catch(""),
4853
+ headline: z37.string(),
4854
+ id: z37.string(),
4654
4855
  /** Advertiser-supplied image alt; the composed card falls back to the stripped headline when empty. */
4655
- image_alt: z34.string().catch(""),
4656
- image_url: z34.string().optional(),
4657
- view_url: z34.string()
4856
+ image_alt: z37.string().catch(""),
4857
+ image_url: z37.string().optional(),
4858
+ view_url: z37.string()
4658
4859
  });
4659
- var AdsEngineResponse = z34.object({
4660
- offers: z34.array(z34.unknown()).default([]).transform(
4860
+ var AdsEngineResponse = z37.object({
4861
+ offers: z37.array(z37.unknown()).default([]).transform(
4661
4862
  (offers) => offers.flatMap((offer) => {
4662
4863
  const result = AdsEngineOffer.safeParse(offer);
4663
4864
  return result.success ? [result.data] : [];
@@ -4669,8 +4870,8 @@ var AdsEngineResponse = z34.object({
4669
4870
  * offers-testing fixture on a test store forces it, REB-24467). Both optional: an older engine or a
4670
4871
  * non-JSON body must not fail the parse and drop the offers.
4671
4872
  */
4672
- request_id: z34.string().optional().catch(void 0),
4673
- testing: z34.boolean().optional().catch(void 0)
4873
+ request_id: z37.string().optional().catch(void 0),
4874
+ testing: z37.boolean().optional().catch(void 0)
4674
4875
  });
4675
4876
  var adsHost = (host) => `offers.${host}`;
4676
4877
  var isTestingRequest = (input, isProduction) => !isProduction || !!input.testing || input.customerEmail?.toLowerCase() === TEST_CUSTOMER_EMAIL;
@@ -5100,13 +5301,13 @@ var convertWidgetSettings = async (input, ctx) => {
5100
5301
  };
5101
5302
 
5102
5303
  // src/server/giftWidgets.ts
5103
- import { z as z35 } from "zod";
5104
- var SettingsNumber = z35.union([
5105
- z35.number(),
5106
- z35.string().trim().regex(/^-?\d+(\.\d+)?$/)
5107
- ]).pipe(z35.coerce.number());
5108
- var SgwpMilestoneSchema = z35.object({
5109
- selectable_product_quantity: SettingsNumber.pipe(z35.number().int().nonnegative()),
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()),
5110
5311
  unlock_price: SettingsNumber
5111
5312
  });
5112
5313
  var fetchGiftWidgetSettings = async (widgetId, shop, ctx) => unwrapData(await ctx.fetchUpstream("/api/v1/widgets/settings", { id: String(widgetId), shop }, { host: ctx.host }));
@@ -5117,7 +5318,7 @@ var readDataSourcePath = (settings) => {
5117
5318
  var readMilestones = (settings, report) => {
5118
5319
  const raw = settings && typeof settings === "object" ? settings.milestones : void 0;
5119
5320
  if (raw == null) return [];
5120
- const parsed = z35.array(SgwpMilestoneSchema).safeParse(raw);
5321
+ const parsed = z38.array(SgwpMilestoneSchema).safeParse(raw);
5121
5322
  if (parsed.success) return parsed.data;
5122
5323
  report?.({
5123
5324
  detail: [
@@ -5366,7 +5567,7 @@ var postAnalyticsEvents = async (input, ctx) => {
5366
5567
  };
5367
5568
 
5368
5569
  // src/server/requestSchemas.ts
5369
- import { z as z36 } from "zod";
5570
+ import { z as z39 } from "zod";
5370
5571
  var REQUEST_BOUNDS = {
5371
5572
  /** Cart-level attributes per cart. */
5372
5573
  CART_ATTRIBUTES_MAX: 100,
@@ -5397,42 +5598,42 @@ var REQUEST_BOUNDS = {
5397
5598
  /** Rich ads transaction lines — the engine's ads contract. */
5398
5599
  TRANSACTION_ITEMS_MAX: 50
5399
5600
  };
5400
- var KeyValue = z36.object({
5401
- key: z36.string().max(REQUEST_BOUNDS.STRING_KEY_MAX),
5402
- value: z36.string().max(REQUEST_BOUNDS.STRING_VALUE_MAX).optional()
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()
5403
5604
  });
5404
- var CartLineInputSchema = z36.object({
5405
- productId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5406
- properties: z36.array(KeyValue).max(REQUEST_BOUNDS.LINE_PROPERTIES_MAX).optional(),
5407
- quantity: z36.number(),
5408
- subscriptionId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5409
- variantId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX)
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)
5410
5611
  });
5411
- var CartInputSchema = z36.object({
5412
- attributes: z36.array(KeyValue).max(REQUEST_BOUNDS.CART_ATTRIBUTES_MAX).optional(),
5612
+ var CartInputSchema = z39.object({
5613
+ attributes: z39.array(KeyValue).max(REQUEST_BOUNDS.CART_ATTRIBUTES_MAX).optional(),
5413
5614
  /**
5414
5615
  * Presentment-per-shop-currency FX rate (buyer price ÷ shop price, e.g. `1.35` for a USD shop
5415
5616
  * selling in CAD). Money rule thresholds are authored in SHOP currency, so the engine subtotal is
5416
5617
  * divided by this before evaluation. Omit (or send 1) when the cart is already in the shop's currency.
5417
5618
  */
5418
- currencyRate: z36.number().optional(),
5619
+ currencyRate: z39.number().optional(),
5419
5620
  /** Applied discount codes; the engine evaluates `discount_code` rules against them (sent as `[{code}]`). */
5420
- discountCodes: z36.array(z36.string().max(REQUEST_BOUNDS.STRING_KEY_MAX)).max(REQUEST_BOUNDS.DISCOUNT_CODES_MAX).optional(),
5621
+ discountCodes: z39.array(z39.string().max(REQUEST_BOUNDS.STRING_KEY_MAX)).max(REQUEST_BOUNDS.DISCOUNT_CODES_MAX).optional(),
5421
5622
  /** Presentment cents of cart-level discount allocations, subtracted from `subtotal` for the engine. */
5422
- discountTotal: z36.number().optional(),
5423
- items: z36.array(CartLineInputSchema).max(REQUEST_BOUNDS.CART_ITEMS_MAX),
5623
+ discountTotal: z39.number().optional(),
5624
+ items: z39.array(CartLineInputSchema).max(REQUEST_BOUNDS.CART_ITEMS_MAX),
5424
5625
  /** Presentment subtotal in cents. */
5425
- subtotal: z36.number()
5626
+ subtotal: z39.number()
5426
5627
  });
5427
- var UserConfigInputSchema = z36.object({ shop: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX) });
5428
- var DataSourceInputSchema = z36.object({
5628
+ var UserConfigInputSchema = z39.object({ shop: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX) });
5629
+ var DataSourceInputSchema = z39.object({
5429
5630
  cart: CartInputSchema,
5430
5631
  /**
5431
5632
  * Numeric Shopify company-location id when the buyer is a B2B session (`buyerIdentity.purchasingCompany`).
5432
5633
  * Present ⇒ the orchestrator filters results by the location's catalog via admin-api (REB-23713); the
5433
5634
  * client's country-context market check is bypassed for B2B (it false-negatives B2B-catalog products).
5434
5635
  */
5435
- companyLocationId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5636
+ companyLocationId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5436
5637
  /**
5437
5638
  * Buyer's market country (ISO 3166-1 alpha-2) — forwarded to the engine as the `country_code` PARAM
5438
5639
  * when the shop's markets toggle is on (REB-21688; the sink was the `X-Country-Code` header under
@@ -5441,16 +5642,16 @@ var DataSourceInputSchema = z36.object({
5441
5642
  * uppercase (the wire value is forwarded verbatim as the param) so a case-sensitive engine lookup
5442
5643
  * can't silently miss a lowercase code — `adsEngine.ts` uppercases for the same reason.
5443
5644
  */
5444
- country: z36.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(),
5445
- customerId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5446
- dataSourcePath: z36.string().max(REQUEST_BOUNDS.STRING_KEY_MAX),
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),
5447
5648
  /**
5448
5649
  * Engine `filter_inputs` override: `'no'` keeps in-cart (input) products in the results/rule
5449
5650
  * outputs — gift validation sends it so a gift's own product can appear in its answer. Omitted = the
5450
5651
  * engine's default filtering.
5451
5652
  */
5452
- filterInputs: z36.enum(["no", "yes"]).optional(),
5453
- integrations: z36.record(z36.string().max(REQUEST_BOUNDS.STRING_KEY_MAX), z36.boolean()).refine((record) => Object.keys(record).length <= REQUEST_BOUNDS.INTEGRATION_KEYS_MAX, {
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, {
5454
5655
  message: `Too many integration keys (max ${REQUEST_BOUNDS.INTEGRATION_KEYS_MAX})`
5455
5656
  }).optional(),
5456
5657
  /**
@@ -5463,31 +5664,31 @@ var DataSourceInputSchema = z36.object({
5463
5664
  * request header) fails the regex. Callers should send the buyer's resolved locale (e.g. Shopify
5464
5665
  * checkout's `localization.language.isoCode`), not the request header verbatim.
5465
5666
  */
5466
- language: z36.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(),
5467
- limit: z36.number().max(REQUEST_BOUNDS.LIMIT_MAX),
5468
- productType: z36.enum(["both", "one-time", "subscription"]).optional(),
5469
- shop: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5470
- visitorId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
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()
5471
5672
  });
5472
- var GiftInputSchema = z36.object({
5473
- cost: z36.number(),
5474
- discounted: z36.boolean(),
5673
+ var GiftInputSchema = z39.object({
5674
+ cost: z39.number(),
5675
+ discounted: z39.boolean(),
5475
5676
  /**
5476
5677
  * Which gift attribution the line carries (REB-24363). Defaults to `gwp` because a client that predates
5477
5678
  * the field only ever sent GWP lines — without the default an older extension's request would 422.
5478
5679
  */
5479
- kind: z36.enum(GIFT_KINDS).default("gwp"),
5480
- lineId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5481
- productId: z36.number(),
5680
+ kind: z39.enum(GIFT_KINDS).default("gwp"),
5681
+ lineId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5682
+ productId: z39.number(),
5482
5683
  /**
5483
5684
  * The line's unit count (REB-24363) — the selectable-GWP verdict trims surplus units against milestone
5484
5685
  * capacity. The second deliberate default: a client predating the field sent only GWP lines, whose
5485
5686
  * verdict is whole-line, so a missing quantity reads as one unit rather than 422ing the older request.
5486
5687
  */
5487
- quantity: z36.number().int().min(1).default(1),
5488
- widgetId: z36.number()
5688
+ quantity: z39.number().int().min(1).default(1),
5689
+ widgetId: z39.number()
5489
5690
  });
5490
- var GiftValidationInputSchema = z36.object({
5691
+ var GiftValidationInputSchema = z39.object({
5491
5692
  cart: CartInputSchema,
5492
5693
  /**
5493
5694
  * Buyer's market country — threaded into the per-widget data-source evaluations, which forward it to
@@ -5496,25 +5697,25 @@ var GiftValidationInputSchema = z36.object({
5496
5697
  * turns markets off); regex-bound and uppercase-normalized for the same reasons as
5497
5698
  * `DataSourceInputSchema`'s `country`.
5498
5699
  */
5499
- country: z36.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(),
5500
- customerId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5501
- gifts: z36.array(GiftInputSchema).max(REQUEST_BOUNDS.GIFTS_MAX),
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),
5502
5703
  /**
5503
5704
  * Buyer's checkout language — threaded into the per-widget data-source evaluations, which normalize
5504
5705
  * and forward it as the engine `locale` param under the same markets-toggle gate (REB-21688). MUST be
5505
5706
  * a single BCP-47 tag, for the same reason as `DataSourceInputSchema`'s `language` above.
5506
5707
  */
5507
- language: z36.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(),
5508
- shop: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5509
- visitorId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
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()
5510
5711
  });
5511
- var GiftAdjustmentSchema = z36.object({
5512
- lineId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5513
- quantity: z36.number().int().nonnegative()
5712
+ var GiftAdjustmentSchema = z39.object({
5713
+ lineId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5714
+ quantity: z39.number().int().nonnegative()
5514
5715
  });
5515
- var GiftValidationResponseSchema = z36.object({
5516
- adjust: z36.array(GiftAdjustmentSchema).max(REQUEST_BOUNDS.GIFTS_MAX).default([]),
5517
- remove: z36.array(z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX)).max(REQUEST_BOUNDS.GIFTS_MAX).refine(
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(
5518
5719
  (remove) => new Set(remove).size === remove.length,
5519
5720
  "a line id may appear at most once in `remove`"
5520
5721
  )
@@ -5525,47 +5726,47 @@ var GiftValidationResponseSchema = z36.object({
5525
5726
  ({ adjust }) => new Set(adjust.map(({ lineId }) => lineId)).size === adjust.length,
5526
5727
  "a line id may appear at most once in `adjust`"
5527
5728
  );
5528
- var MonetizeTransactionItemSchema = z36.object({
5529
- id: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5530
- priceCents: z36.number(),
5531
- quantity: z36.number(),
5532
- title: z36.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX),
5533
- type: z36.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX)
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)
5534
5735
  });
5535
- var MonetizeInputSchema = z36.object({
5736
+ var MonetizeInputSchema = z39.object({
5536
5737
  cart: CartInputSchema,
5537
5738
  /** Client-minted render-beacon correlation id; forwarded to the ads engine as `client_request_id`. */
5538
- clientRequestId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5539
- country: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5540
- currency: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
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(),
5541
5742
  /** Ads-targeting identity/geo/locale fields (React parity); folded into the engine query verbatim. */
5542
- customerEmail: z36.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX).optional(),
5543
- customerFirstName: z36.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX).optional(),
5544
- customerId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5545
- customerLastName: z36.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX).optional(),
5546
- language: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
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(),
5547
5748
  /** Buyer-facing order name (e.g. `#1001`) for the server-composed "Order … Confirmed" chrome line. */
5548
- orderName: z36.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX).optional(),
5749
+ orderName: z39.string().max(REQUEST_BOUNDS.STRING_TEXT_MAX).optional(),
5549
5750
  /** Ads surface label, forwarded verbatim; `customer_account` is measured/floored as its own surface (the account-area order list). */
5550
- placement: z36.enum(["customer_account", "order_status", "thank_you_page"]),
5751
+ placement: z39.enum(["customer_account", "order_status", "thank_you_page"]),
5551
5752
  /** Privacy Policy footer href — the Monetize widget's `privacy_policy_url` setting (React parity). */
5552
- privacyPolicyUrl: z36.string().max(REQUEST_BOUNDS.STRING_URL_MAX).optional(),
5753
+ privacyPolicyUrl: z39.string().max(REQUEST_BOUNDS.STRING_URL_MAX).optional(),
5553
5754
  /** 30-min rolling session id (React parity); used for the ads `session_id`, else the visitor id. */
5554
- sessionId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5555
- shop: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5755
+ sessionId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5756
+ shop: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5556
5757
  /** Editor/QA indicator; OR-ed into the ads-engine `testing` flag so it stays out of billing/reporting. */
5557
- testing: z36.boolean().optional(),
5558
- timezone: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5758
+ testing: z39.boolean().optional(),
5759
+ timezone: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5559
5760
  /** Decorated (numeric) order id → the ads `transaction_id`. */
5560
- transactionId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5761
+ transactionId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5561
5762
  /** Rich per-line ads items; capped at the engine's ads contract. Preferred over `cart.items`. */
5562
- transactionItems: z36.array(MonetizeTransactionItemSchema).max(REQUEST_BOUNDS.TRANSACTION_ITEMS_MAX).optional(),
5763
+ transactionItems: z39.array(MonetizeTransactionItemSchema).max(REQUEST_BOUNDS.TRANSACTION_ITEMS_MAX).optional(),
5563
5764
  /** Order total in presentment cents (React prefers total over subtotal); else `cart.subtotal`. */
5564
- transactionTotal: z36.number().optional(),
5565
- visitorId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5566
- zipCode: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
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()
5567
5768
  });
5568
- var WidgetSettingsInputSchema = z36.object({
5769
+ var WidgetSettingsInputSchema = z39.object({
5569
5770
  /**
5570
5771
  * Same domain as `CabShopConfig.cacheKey`, for the same reason: this side WINS the orchestrator's
5571
5772
  * `input.cacheKey ?? config.shop.cacheKey` (and an explicit value skips the config read entirely), so
@@ -5573,9 +5774,9 @@ var WidgetSettingsInputSchema = z36.object({
5573
5774
  * and pin the edge copy permanently stale. `.catch(undefined)` because a bogus buster should degrade
5574
5775
  * the read to un-busted, never 400 a widget render.
5575
5776
  */
5576
- cacheKey: z36.number().int().positive().optional().catch(void 0),
5577
- id: z36.number(),
5578
- key: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
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(),
5579
5780
  /**
5580
5781
  * Monetize context for inline hydration: when present AND the widget converts to a Monetize marker,
5581
5782
  * the server fetches/composes the offer cards inside this same request (no second `/cab/monetize`
@@ -5584,36 +5785,36 @@ var WidgetSettingsInputSchema = z36.object({
5584
5785
  * `privacyPolicyUrl` comes from the widget settings server-side (more authoritative than a relay).
5585
5786
  */
5586
5787
  monetize: MonetizeInputSchema.omit({ privacyPolicyUrl: true, shop: true }).optional(),
5587
- shop: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5788
+ shop: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5588
5789
  /** Stable per-buyer id; when present, enables sticky server-side A/B variant selection. */
5589
- visitorId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
5790
+ visitorId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
5590
5791
  });
5591
- var AnalyticsEventInputSchema = z36.object({
5592
- name: z36.string().max(REQUEST_BOUNDS.STRING_KEY_MAX),
5593
- properties: z36.record(z36.string().max(REQUEST_BOUNDS.STRING_KEY_MAX), z36.unknown()).optional(),
5594
- sentAt: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
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()
5595
5796
  });
5596
- var AnalyticsSegmentsInputSchema = z36.object({
5597
- device: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional().catch(void 0),
5598
- source: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional().catch(void 0),
5599
- visitor: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional().catch(void 0)
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)
5600
5801
  });
5601
- var AnalyticsInputSchema = z36.object({
5802
+ var AnalyticsInputSchema = z39.object({
5602
5803
  /** Rebuy cart token (the `r_cart_token` cart attribute), when available — primary aggregation key. */
5603
- cartToken: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5804
+ cartToken: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5604
5805
  /** Shopify checkout token, when available — drives cart/checkout aggregation downstream. */
5605
- checkoutToken: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5606
- events: z36.array(AnalyticsEventInputSchema).max(REQUEST_BOUNDS.EVENTS_MAX),
5806
+ checkoutToken: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional(),
5807
+ events: z39.array(AnalyticsEventInputSchema).max(REQUEST_BOUNDS.EVENTS_MAX),
5607
5808
  /**
5608
5809
  * Request-scoped like the tokens: one visitor's segments apply to every event in the batch. The container
5609
5810
  * degrades too (`null` is a realistic wire artifact of `attributes ? {…} : null`), so the degrade rule is
5610
5811
  * total: nothing about `segments` can cost the envelope.
5611
5812
  */
5612
5813
  segments: AnalyticsSegmentsInputSchema.optional().catch(void 0),
5613
- shop: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5614
- visitorId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5814
+ shop: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5815
+ visitorId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX),
5615
5816
  /** The widget id (smartBlockId) the events belong to. */
5616
- widgetId: z36.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
5817
+ widgetId: z39.string().max(REQUEST_BOUNDS.STRING_ID_MAX).optional()
5617
5818
  });
5618
5819
  export {
5619
5820
  AnalyticsEventInputSchema,