@rebuy/rebuy 3.52.0 → 3.53.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.
@@ -6297,9 +6297,9 @@ import { z as z54 } from "zod";
6297
6297
  import { z as z52 } from "zod";
6298
6298
  var PostPurchaseProductGallery = z52.object({
6299
6299
  /**
6300
- * The product had more than one image before `images` was capped at the sub-image limit, so a
6301
- * renderer shows the thumbnail row even when the cap leaves one image (legacy checks the count
6302
- * before slicing). Older replies omit it; fall back to `images.length > 1`.
6300
+ * Show the thumbnail row: the product had more than one image before `images` was capped at the
6301
+ * sub-image limit, and that limit allows at least one thumbnail. It stays true when the cap leaves one
6302
+ * image (legacy checks the count before slicing). Older replies omit it; fall back to `images.length > 1`.
6303
6303
  */
6304
6304
  hasMultiple: z52.boolean().optional(),
6305
6305
  images: z52.array(
@@ -6467,9 +6467,12 @@ var subscriptionUnavailable = (normalized, plan, allowCollection, quantity3) =>
6467
6467
  const { data, effective, original } = normalized;
6468
6468
  const unavailable = "An eligible subscription plan with supported shipping and discount is required";
6469
6469
  if (data.length !== 1 || data[0].variants.length !== 1) return unavailable;
6470
- if (effective.productType === "one-time" || [original, effective].some(
6471
- (config) => !allowCollection && config.productLimit !== 1 || config.upgradeToSubscription.allow || !quantity3 && config.quantityInputs.enabled && (config.quantityInputs.minValue !== config.quantityInputs.maxValue || config.quantityInputs.defaultQuantity !== config.quantityInputs.minValue)
6472
- ))
6470
+ if (
6471
+ // Legacy STS ran whatever the product type: its trigger forced the subscription option on.
6472
+ effective.productType === "one-time" && !quantity3?.sts || [original, effective].some(
6473
+ (config) => !allowCollection && config.productLimit !== 1 || config.upgradeToSubscription.allow && !quantity3?.sts || !quantity3 && config.quantityInputs.enabled && (config.quantityInputs.minValue !== config.quantityInputs.maxValue || config.quantityInputs.defaultQuantity !== config.quantityInputs.minValue)
6474
+ )
6475
+ )
6473
6476
  return unavailable;
6474
6477
  const product = data[0];
6475
6478
  const variant2 = product.variants[0];
@@ -6494,16 +6497,19 @@ var postPurchasePrimaryImage = (product) => {
6494
6497
  };
6495
6498
 
6496
6499
  // src/server/postPurchaseProductGallery.ts
6497
- var postPurchaseProductGallery = (product, limit) => ({
6498
- hasMultiple: (product.images?.length ?? 0) > 1,
6499
- images: (product.images ?? []).slice(0, limit ?? 0).map((image) => ({
6500
- description: image.alt ?? product.title,
6501
- id: image.id,
6502
- source: sizeImageSource(image.src, "800x800"),
6503
- thumbnail: sizeImageSource(image.src, "200x200")
6504
- })),
6505
- selectedImageId: product.images?.find((image) => image.id === product.variants[0].imageId)?.id
6506
- });
6500
+ var postPurchaseProductGallery = (product, limit) => {
6501
+ const cap = Math.max(Math.floor(limit ?? 0), 0);
6502
+ return {
6503
+ hasMultiple: (product.images?.length ?? 0) > 1 && cap >= 1,
6504
+ images: (product.images ?? []).slice(0, cap).map((image) => ({
6505
+ description: image.alt ?? product.title,
6506
+ id: image.id,
6507
+ source: sizeImageSource(image.src, "800x800"),
6508
+ thumbnail: sizeImageSource(image.src, "200x200")
6509
+ })),
6510
+ selectedImageId: product.images?.find((image) => image.id === product.variants[0].imageId)?.id
6511
+ };
6512
+ };
6507
6513
 
6508
6514
  // src/transforms/postPurchase/convertDescriptionRte.ts
6509
6515
  import { z as z58 } from "zod";
@@ -7196,7 +7202,7 @@ var PostPurchaseMemberIdentity = z75.object({
7196
7202
  }).strict();
7197
7203
 
7198
7204
  // src/schema/postPurchaseAdmission.ts
7199
- var PurchaseAdmissionModeSchema = z76.enum(["purchase", "upgrade"]);
7205
+ var PurchaseAdmissionModeSchema = z76.enum(["purchase", "sts"]);
7200
7206
  var selection = PreparedPostPurchaseProduct.shape.selection;
7201
7207
  var EventCalculationSchema = PostPurchaseProductCosts.pick({ currencyCode: true, totalMinor: true }).strict();
7202
7208
  var PurchaseExpectedSchema = z76.object({
@@ -7218,8 +7224,8 @@ var PurchaseExpectedSchema = z76.object({
7218
7224
  ({ member, progressRevision }) => !member || progressRevision !== void 0,
7219
7225
  "Captured member requires progress"
7220
7226
  ).refine(
7221
- ({ mode, selection: { sellingPlanId } }) => mode !== "upgrade" || sellingPlanId !== void 0,
7222
- "An upgrade selects a subscription"
7227
+ ({ mode, selection: { sellingPlanId } }) => mode !== "sts" || sellingPlanId !== void 0,
7228
+ "An STS selects a subscription"
7223
7229
  ).refine(({ buyerConsentToSubscriptions: consent, changeset, selection: selection4 }) => {
7224
7230
  const [change, shipping] = changeset.changes;
7225
7231
  if (selection4.sellingPlanId === void 0)
@@ -7235,7 +7241,7 @@ var PurchaseReceiptSchema = z76.object({
7235
7241
  changesetToken: z76.string().min(1),
7236
7242
  mode: PurchaseAdmissionModeSchema.optional(),
7237
7243
  operationId: z76.uuid(),
7238
- /** The server-bound one-time line an upgrade refunds; its quantity is the order's, not the selection's. */
7244
+ /** The server-bound one-time line an STS refunds; its quantity is the order's, not the selection's. */
7239
7245
  originalLine: z76.strictObject({ quantity: selection.shape.quantity, variantId: selection.shape.variantId }).optional(),
7240
7246
  requiresSubscriptionConsent: z76.boolean(),
7241
7247
  selection
@@ -7243,8 +7249,8 @@ var PurchaseReceiptSchema = z76.object({
7243
7249
  ({ requiresSubscriptionConsent, selection: selection4 }) => requiresSubscriptionConsent === (selection4.sellingPlanId !== void 0),
7244
7250
  "Receipt consent must match its selected plan"
7245
7251
  ).refine(
7246
- ({ mode, originalLine, selection: { sellingPlanId, variantId } }) => mode === "upgrade" ? sellingPlanId !== void 0 && originalLine?.variantId === variantId : originalLine === void 0,
7247
- "An upgrade Receipt binds the original line of its subscribed variant, and only an upgrade does"
7252
+ ({ mode, originalLine, selection: { sellingPlanId, variantId } }) => mode === "sts" ? sellingPlanId !== void 0 && originalLine?.variantId === variantId : originalLine === void 0,
7253
+ "An STS Receipt binds the original line of its subscribed variant, and only an STS does"
7248
7254
  );
7249
7255
  var PurchaseResponseSchema = z76.object({ data: PurchaseReceiptSchema, successful: z76.literal(true) });
7250
7256
 
@@ -7368,14 +7374,41 @@ var projectPostPurchaseVariantCatalog = (product, settings) => {
7368
7374
  });
7369
7375
  };
7370
7376
 
7371
- // src/schema/postPurchaseQuantity.ts
7377
+ // src/schema/postPurchaseOfferEligibility.ts
7372
7378
  import { z as z82 } from "zod";
7379
+ var selection2 = PreparedPostPurchaseProduct.shape.selection;
7380
+ var PostPurchaseOfferSkipReason = z82.enum(["empty", "no-eligible-subscription"]);
7381
+ var PostPurchaseOfferEligibilityContext = z82.object({
7382
+ excludedProductIds: PostPurchaseExcludedProductIds,
7383
+ originalLineItems: z82.array(selection2.pick({ productId: true, sellingPlanId: true, variantId: true }))
7384
+ });
7385
+ var PostPurchaseStsOptions = z82.object({ sts: z82.boolean().optional() }).strict();
7386
+ var PostPurchaseStsContext = z82.object({
7387
+ originalLineItems: z82.array(
7388
+ selection2.pick({ productId: true, quantity: true, sellingPlanId: true, variantId: true })
7389
+ )
7390
+ });
7391
+ var PostPurchaseOfferEligibility = z82.discriminatedUnion("status", [
7392
+ z82.object({
7393
+ members: z82.array(
7394
+ z82.object({ productId: selection2.shape.productId, productIndex: z82.number().int().nonnegative() })
7395
+ ),
7396
+ /** Present only with STS on: each member switches one original one-time line to subscription. */
7397
+ mode: z82.literal("sts").optional(),
7398
+ status: z82.literal("retain")
7399
+ }),
7400
+ z82.object({ reason: PostPurchaseOfferSkipReason, status: z82.literal("skip") }),
7401
+ z82.object({ reason: z82.literal("eligible-sts").optional(), status: z82.literal("unavailable") })
7402
+ ]);
7403
+
7404
+ // src/schema/postPurchaseQuantity.ts
7405
+ import { z as z83 } from "zod";
7373
7406
  var quantity2 = PreparedPostPurchaseProduct.shape.selection.shape.quantity;
7374
7407
  var PostPurchaseQuantityChoice = PostPurchaseCollectionChoice.extend({ quantity: quantity2.optional() });
7375
7408
  var PostPurchaseQuantityPolicy = PostPurchaseSettings.shape.quantityInputs.omit({ defaultQuantity: true }).extend({
7376
7409
  initialQuantity: quantity2,
7377
7410
  maxValue: quantity2,
7378
- minValue: z82.literal(0).transform(() => 1).or(quantity2)
7411
+ minValue: z83.literal(0).transform(() => 1).or(quantity2)
7379
7412
  }).refine(({ maxValue, minValue }) => minValue <= maxValue, "Quantity bounds are reversed");
7380
7413
 
7381
7414
  // src/server/readPostPurchaseQuantity.ts
@@ -7405,40 +7438,88 @@ var readPostPurchaseQuantity = ({
7405
7438
  return { policy, quantity: quantity3 };
7406
7439
  };
7407
7440
 
7441
+ // src/server/postPurchaseSts.ts
7442
+ var stsAllowed = ({ effective, original }) => [original, effective].some((config) => config.upgradeToSubscription.allow);
7443
+ var postPurchaseStsLine = (normalized, product, lines, variantId) => {
7444
+ if (!product.sellingPlanGroups?.length || product.productGroupVariants.length) return void 0;
7445
+ for (const variant2 of product.variants) {
7446
+ const matched = lines.filter((line) => line.sellingPlanId === void 0 && line.variantId === variant2.id);
7447
+ const data = [{ ...product, variants: [variant2] }];
7448
+ if ((variantId === void 0 || variant2.id === variantId) && matched.length === 1 && postPurchaseVariantAvailable(variant2) && projectPostPurchasePlanCatalog({ ...normalized, data })?.plans.length)
7449
+ return { data, line: matched[0] };
7450
+ }
7451
+ };
7452
+ var preparePostPurchaseStsView = (widgetId, normalized, product, context, requested, report) => {
7453
+ const { originalLineItems } = PostPurchaseStsContext.parse(context);
7454
+ const found = postPurchaseStsLine(normalized, product, originalLineItems, requested.variantId);
7455
+ if (!found) return null;
7456
+ const whole = found.line.quantity;
7457
+ if (requested.quantity !== void 0 && requested.quantity !== whole)
7458
+ throw new PostPurchaseQuantityUnavailable("An STS covers the whole original quantity");
7459
+ const bounds = { initialQuantity: whole, maxValue: whole, minValue: whole };
7460
+ const policy = PostPurchaseQuantityPolicy.parse({ enabled: false, ...bounds });
7461
+ const quantity3 = { policy, quantity: whole, sts: true };
7462
+ const input = { ...normalized, data: found.data };
7463
+ return {
7464
+ quantity: quantity3,
7465
+ sts: {
7466
+ emailRefundNotice: normalized.effective.upgradeToSubscription.emailRefundNotice,
7467
+ originalLine: { quantity: whole, variantId: found.line.variantId }
7468
+ },
7469
+ view: prepareNormalizedPostPurchaseView(widgetId, input, report, requested.choice, quantity3, true)
7470
+ };
7471
+ };
7472
+ var prepareStsCollectionMember = (widgetId, normalized, { product, productIndex }, context, choice, report) => {
7473
+ const stsResult = preparePostPurchaseStsView(widgetId, normalized, product, context, { choice }, report);
7474
+ return stsResult && { productId: product.id, productIndex, reportingProduct: void 0, view: stsResult.view };
7475
+ };
7476
+
7477
+ // src/server/preparePostPurchaseStsMember.ts
7478
+ var preparePostPurchaseStsMember = (widgetId, settings, response, selected, sts, requestedQuantity, report) => {
7479
+ const { members, normalized } = normalizePostPurchaseCollection(settings, response);
7480
+ if (!stsAllowed(normalized)) return void 0;
7481
+ const member = members.find(({ product }) => product.id === selected.productId);
7482
+ const quantity3 = requestedQuantity && ("quantity" in requestedQuantity ? requestedQuantity.quantity : requestedQuantity.expectedQuantity);
7483
+ const prepared = member && preparePostPurchaseStsView(widgetId, normalized, member.product, sts, { ...selected, quantity: quantity3 }, report);
7484
+ if (!member || !prepared) return null;
7485
+ const { view, ...facts } = prepared;
7486
+ return { ...facts, member: { productId: member.product.id, productIndex: member.productIndex, view }, normalized };
7487
+ };
7488
+
7408
7489
  // src/schema/postPurchaseVariantDefault.ts
7409
- import { z as z83 } from "zod";
7490
+ import { z as z84 } from "zod";
7410
7491
  var values = PostPurchaseVariantValues.partial().extend({
7411
7492
  option1: PostPurchaseVariantValues.shape.option1.nullish()
7412
7493
  });
7413
7494
  var variant = values.extend({
7414
7495
  id: PostPurchaseVariantId,
7415
- inventoryManagement: z83.string().nullable(),
7416
- inventoryPolicy: z83.string(),
7417
- inventoryQuantity: z83.number()
7496
+ inventoryManagement: z84.string().nullable(),
7497
+ inventoryPolicy: z84.string(),
7498
+ inventoryQuantity: z84.number()
7418
7499
  });
7419
- var options = z83.array(PostPurchaseVariantOption.pick({ name: true, values: true }));
7420
- var PostPurchaseVariantDefaultProduct = z83.object({
7500
+ var options = z84.array(PostPurchaseVariantOption.pick({ name: true, values: true }));
7501
+ var PostPurchaseVariantDefaultProduct = z84.object({
7421
7502
  id: PostPurchaseProductId,
7422
7503
  options,
7423
7504
  selectedVariant: variant.optional(),
7424
- variants: z83.array(variant)
7505
+ variants: z84.array(variant)
7425
7506
  });
7426
7507
  var PostPurchaseVariantDefaultSettings = PostPurchaseSettings.shape.productOptions.pick({
7427
7508
  hideOutOfStockVariants: true,
7428
7509
  matchVariant: true
7429
7510
  });
7430
- var PostPurchaseOrderAttributes = z83.record(z83.string(), z83.array(z83.string())).default({});
7431
- var PostPurchaseOriginalVariants = z83.array(
7432
- z83.object({ productId: PostPurchaseProductId, variantId: PostPurchaseVariantId })
7511
+ var PostPurchaseOrderAttributes = z84.record(z84.string(), z84.array(z84.string())).default({});
7512
+ var PostPurchaseOriginalVariants = z84.array(
7513
+ z84.object({ productId: PostPurchaseProductId, variantId: PostPurchaseVariantId })
7433
7514
  );
7434
- var PostPurchaseAttributeProducts = z83.array(
7435
- z83.object({ id: PostPurchaseProductId, options, variants: z83.array(values.extend({ id: PostPurchaseVariantId })) })
7515
+ var PostPurchaseAttributeProducts = z84.array(
7516
+ z84.object({ id: PostPurchaseProductId, options, variants: z84.array(values.extend({ id: PostPurchaseVariantId })) })
7436
7517
  );
7437
7518
 
7438
7519
  // src/schema/postPurchaseVariantDefaultContext.ts
7439
- import { z as z84 } from "zod";
7440
- var PostPurchaseVariantDefaultContext = z84.object({
7441
- enrichedLineItems: z84.unknown().optional(),
7520
+ import { z as z85 } from "zod";
7521
+ var PostPurchaseVariantDefaultContext = z85.object({
7522
+ enrichedLineItems: z85.unknown().optional(),
7442
7523
  originalVariants: PostPurchaseOriginalVariants
7443
7524
  });
7444
7525
 
@@ -7513,8 +7594,10 @@ var resolvePostPurchaseMemberDefault = (product, original, context) => {
7513
7594
  };
7514
7595
 
7515
7596
  // src/server/preparePostPurchaseMemberView.ts
7516
- var prepareMember = (widgetId, settings, response, requested, report, excludedProductIds, requestedQuantity, defaults) => {
7597
+ var prepareMember = (widgetId, settings, response, requested, report, excludedProductIds, requestedQuantity, defaults, sts) => {
7517
7598
  const selected = PostPurchaseCollectionChoice.parse(requested);
7599
+ const stsResult = sts && preparePostPurchaseStsMember(widgetId, settings, response, selected, sts, requestedQuantity, report);
7600
+ if (stsResult !== void 0) return stsResult;
7518
7601
  const { members, normalized } = normalizePostPurchaseCollection(settings, response, excludedProductIds);
7519
7602
  const found = members.find(({ product: product2 }) => product2.id === selected.productId);
7520
7603
  if (!found) return null;
@@ -7541,7 +7624,7 @@ var preparePostPurchaseMemberAdmissionView = (widgetId, settings, response, requ
7541
7624
  };
7542
7625
 
7543
7626
  // src/server/preparePostPurchaseQuantityView.ts
7544
- var preparePostPurchaseQuantityView = (widgetId, settings, response, requested, report, excludedProductIds, defaults) => {
7627
+ var preparePostPurchaseQuantityView = (widgetId, settings, response, requested, report, excludedProductIds, defaults, sts) => {
7545
7628
  const { quantity: quantity3, ...selection4 } = PostPurchaseQuantityChoice.parse(requested);
7546
7629
  const prepared = prepareMember(
7547
7630
  widgetId,
@@ -7551,15 +7634,21 @@ var preparePostPurchaseQuantityView = (widgetId, settings, response, requested,
7551
7634
  report,
7552
7635
  excludedProductIds,
7553
7636
  { quantity: quantity3 },
7554
- defaults
7637
+ defaults,
7638
+ sts
7555
7639
  );
7556
- return prepared ? { ...prepared.member, quantityPolicy: prepared.quantity.policy } : null;
7640
+ if (!prepared) return null;
7641
+ return {
7642
+ ...prepared.member,
7643
+ quantityPolicy: prepared.quantity.policy,
7644
+ ..."sts" in prepared && { sts: prepared.sts }
7645
+ };
7557
7646
  };
7558
7647
 
7559
7648
  // src/server/preparePostPurchaseQuantityAdmissionView.ts
7560
- var selection2 = PostPurchaseQuantityChoice.required({ quantity: true });
7561
- var preparePostPurchaseQuantityAdmissionView = (widgetId, settings, response, expected, report, excludedProductIds, defaults) => {
7562
- const { quantity: expectedQuantity, ...requested } = selection2.parse(expected);
7649
+ var selection3 = PostPurchaseQuantityChoice.required({ quantity: true });
7650
+ var preparePostPurchaseQuantityAdmissionView = (widgetId, settings, response, expected, report, excludedProductIds, defaults, sts) => {
7651
+ const { quantity: expectedQuantity, ...requested } = selection3.parse(expected);
7563
7652
  const prepared = prepareMember(
7564
7653
  widgetId,
7565
7654
  settings,
@@ -7568,11 +7657,17 @@ var preparePostPurchaseQuantityAdmissionView = (widgetId, settings, response, ex
7568
7657
  report,
7569
7658
  excludedProductIds,
7570
7659
  { expectedQuantity },
7571
- defaults
7660
+ defaults,
7661
+ sts
7572
7662
  );
7573
7663
  if (!prepared) return null;
7574
7664
  const { removePartialOrder } = PostPurchaseSettings.shape.advance.parse(prepared.normalized.effective.advance);
7575
- return { ...prepared.member, quantityPolicy: prepared.quantity.policy, removePartialOrder };
7665
+ return {
7666
+ ...prepared.member,
7667
+ quantityPolicy: prepared.quantity.policy,
7668
+ removePartialOrder,
7669
+ ..."sts" in prepared && { sts: prepared.sts }
7670
+ };
7576
7671
  };
7577
7672
 
7578
7673
  // src/schema/postPurchaseGroup.ts
@@ -7735,11 +7830,16 @@ var preparePostPurchaseCollectionGroup = (widgetId, settings, response, member,
7735
7830
 
7736
7831
  // src/server/preparePostPurchaseCollectionView.ts
7737
7832
  var CollectionChoice = PostPurchaseCollectionChoice.omit({ variantId: true });
7738
- var preparePostPurchaseCollectionView = (widgetId, settings, response, report, requested, excludedProductIds, defaults = { originalVariants: [] }) => {
7833
+ var preparePostPurchaseCollectionView = (widgetId, settings, response, report, requested, excludedProductIds, defaults, sts) => {
7739
7834
  const { members, normalized } = normalizePostPurchaseCollection(settings, response);
7740
7835
  const excluded = PostPurchaseExcludedProductIds.parse(excludedProductIds);
7741
7836
  const selected = CollectionChoice.optional().parse(requested);
7837
+ const stsMode = sts && stsAllowed(normalized) ? sts : void 0;
7742
7838
  const projected = members.map((member) => {
7839
+ if (stsMode) {
7840
+ const choice = member.product.id === selected?.productId ? selected.choice : void 0;
7841
+ return prepareStsCollectionMember(widgetId, normalized, member, stsMode, choice, report);
7842
+ }
7743
7843
  if (member.product.productGroupVariants.length) {
7744
7844
  if (selected?.productId === member.product.id && selected.choice)
7745
7845
  throw new Error("Grouped choices require selected merchandise");
@@ -7750,7 +7850,7 @@ var preparePostPurchaseCollectionView = (widgetId, settings, response, report, r
7750
7850
  member,
7751
7851
  normalized,
7752
7852
  excluded,
7753
- defaults,
7853
+ defaults ?? { originalVariants: [] },
7754
7854
  report
7755
7855
  );
7756
7856
  return group;
@@ -7781,25 +7881,6 @@ var preparePostPurchaseCollectionView = (widgetId, settings, response, report, r
7781
7881
  };
7782
7882
  };
7783
7883
 
7784
- // src/schema/postPurchaseOfferEligibility.ts
7785
- import { z as z85 } from "zod";
7786
- var selection3 = PreparedPostPurchaseProduct.shape.selection;
7787
- var PostPurchaseOfferSkipReason = z85.enum(["empty", "no-eligible-subscription"]);
7788
- var PostPurchaseOfferEligibilityContext = z85.object({
7789
- excludedProductIds: PostPurchaseExcludedProductIds,
7790
- originalLineItems: z85.array(selection3.pick({ productId: true, sellingPlanId: true, variantId: true }))
7791
- });
7792
- var PostPurchaseOfferEligibility = z85.discriminatedUnion("status", [
7793
- z85.object({
7794
- members: z85.array(
7795
- z85.object({ productId: selection3.shape.productId, productIndex: z85.number().int().nonnegative() })
7796
- ),
7797
- status: z85.literal("retain")
7798
- }),
7799
- z85.object({ reason: PostPurchaseOfferSkipReason, status: z85.literal("skip") }),
7800
- z85.object({ reason: z85.literal("eligible-upgrade").optional(), status: z85.literal("unavailable") })
7801
- ]);
7802
-
7803
7884
  // src/server/postPurchaseMemberEligibility.ts
7804
7885
  var PostPurchaseInventoryUnavailable = class extends Error {
7805
7886
  };
@@ -7828,22 +7909,28 @@ var postPurchaseMemberEligibility = (normalized, product, excluded) => {
7828
7909
  };
7829
7910
 
7830
7911
  // src/server/classifyPostPurchaseOffer.ts
7831
- var classifyPostPurchaseOffer = (settings, response, context) => {
7912
+ var identities = (members) => members.map(({ product, productIndex }) => ({ productId: product.id, productIndex }));
7913
+ var classifyPostPurchaseOffer = (settings, response, context, options2) => {
7832
7914
  try {
7833
7915
  const trusted = PostPurchaseOfferEligibilityContext.parse(context);
7916
+ const { sts: stsMode = false } = PostPurchaseStsOptions.parse(options2 ?? {});
7834
7917
  const { members, normalized } = normalizePostPurchaseCollection(settings, response);
7835
7918
  const configurations = [normalized.original, normalized.effective];
7836
- const upgrades = configurations.some((config) => config.upgradeToSubscription.allow);
7919
+ const stsEnabled = configurations.some((config) => config.upgradeToSubscription.allow);
7920
+ const sts = stsEnabled && stsMode;
7837
7921
  const oneTime = new Set(
7838
7922
  trusted.originalLineItems.filter((line) => line.sellingPlanId === void 0).map((line) => line.variantId)
7839
7923
  );
7840
- if (upgrades && members.some(
7924
+ if (stsEnabled && !stsMode && members.some(
7841
7925
  ({ product }) => product.sellingPlanGroups?.length && product.variants.some((variant2) => oneTime.has(variant2.id))
7842
7926
  ))
7843
- return { reason: "eligible-upgrade", status: "unavailable" };
7844
- if (normalized.effective.productType !== "one-time") {
7927
+ return { reason: "eligible-sts", status: "unavailable" };
7928
+ if (normalized.effective.productType !== "one-time" || sts) {
7845
7929
  configurations.forEach((config) => PostPurchaseSubscriptionSettings.parse(config.subscription));
7846
7930
  }
7931
+ const lines = trusted.originalLineItems;
7932
+ const stsMembers = sts ? members.filter(({ product }) => postPurchaseStsLine(normalized, product, lines)) : [];
7933
+ if (stsMembers.length) return { members: identities(stsMembers), mode: "sts", status: "retain" };
7847
7934
  const classified = members.map((member) => {
7848
7935
  try {
7849
7936
  return {
@@ -7857,19 +7944,13 @@ var classifyPostPurchaseOffer = (settings, response, context) => {
7857
7944
  }
7858
7945
  });
7859
7946
  if (!members.length) return { reason: "empty", status: "skip" };
7860
- if (upgrades) return { reason: "no-eligible-subscription", status: "skip" };
7947
+ if (stsEnabled) return { reason: "no-eligible-subscription", status: "skip" };
7861
7948
  const candidates = classified.filter(
7862
7949
  ({ product }) => product.productGroupVariants.length ? readPostPurchaseGroup(product, normalized.effective, trusted.excludedProductIds).entries.length > 0 : !trusted.excludedProductIds.includes(product.id)
7863
7950
  );
7864
7951
  if (!candidates.length) return { reason: "empty", status: "skip" };
7865
7952
  const retained = candidates.filter(({ eligible }) => eligible);
7866
- return retained.length ? {
7867
- members: retained.map(({ product, productIndex }) => ({
7868
- productId: product.id,
7869
- productIndex
7870
- })),
7871
- status: "retain"
7872
- } : { reason: "no-eligible-subscription", status: "skip" };
7953
+ return retained.length ? { members: identities(retained), status: "retain" } : { reason: "no-eligible-subscription", status: "skip" };
7873
7954
  } catch {
7874
7955
  return { status: "unavailable" };
7875
7956
  }
@@ -2,7 +2,8 @@ import type { PostPurchaseProductGallery } from '../schema/postPurchaseProductGa
2
2
  import type { PostPurchaseProductSettings } from '../schema/postPurchaseProductSettings';
3
3
  import type { PostPurchaseProductSource } from '../schema/postPurchaseProductSource';
4
4
  /**
5
- * Display-only catalog facts (L67); a selected image may lie outside the configured thumbnail limit, and
6
- * `hasMultiple` counts the images before the limit applies (legacy ProductOffer).
5
+ * Display-only catalog facts (L67); a selected image may lie outside the configured thumbnail limit. The cap is
6
+ * guarded like `convertProductInformation`: floored, and anything below 1 (unset, negative or fractional) shows
7
+ * no thumbnails. `hasMultiple` counts the images before the cap (legacy ProductOffer), but only when a row shows.
7
8
  */
8
9
  export declare const postPurchaseProductGallery: (product: PostPurchaseProductSource["data"][number], limit: PostPurchaseProductSettings["subImages"]) => PostPurchaseProductGallery;