@rebuy/rebuy 3.57.0 → 3.59.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.
@@ -37,8 +37,8 @@ var getValidGwpProductIds = (matchedRules = []) => new Set(
37
37
 
38
38
  // src/gwp/hasUnsupportedRuleTypes.ts
39
39
  var UNSUPPORTED_RULE_TYPES = ["url", "order_tag"];
40
- var UNSUPPORTED_RULE_TYPE_PREFIX = "geolocation_";
41
- var isUnsupportedType = (type = "") => UNSUPPORTED_RULE_TYPES.includes(type) || type.startsWith(UNSUPPORTED_RULE_TYPE_PREFIX);
40
+ var UNSUPPORTED_RULE_TYPE_FRAGMENT = "geolocation";
41
+ var isUnsupportedType = (type = "") => UNSUPPORTED_RULE_TYPES.includes(type) || type.includes(UNSUPPORTED_RULE_TYPE_FRAGMENT);
42
42
  var ruleHasUnsupportedType = (rule) => (rule.logic ?? []).some((group) => (group.rules ?? []).some((item) => isUnsupportedType(item.type)));
43
43
  var hasUnsupportedRuleTypes = (metadata) => [...metadata?.matchedRules ?? [], ...metadata?.unmatchedRules ?? []].some(ruleHasUnsupportedType);
44
44
 
@@ -5,8 +5,8 @@ var getValidGwpProductIds = (matchedRules = []) => new Set(
5
5
 
6
6
  // src/gwp/hasUnsupportedRuleTypes.ts
7
7
  var UNSUPPORTED_RULE_TYPES = ["url", "order_tag"];
8
- var UNSUPPORTED_RULE_TYPE_PREFIX = "geolocation_";
9
- var isUnsupportedType = (type = "") => UNSUPPORTED_RULE_TYPES.includes(type) || type.startsWith(UNSUPPORTED_RULE_TYPE_PREFIX);
8
+ var UNSUPPORTED_RULE_TYPE_FRAGMENT = "geolocation";
9
+ var isUnsupportedType = (type = "") => UNSUPPORTED_RULE_TYPES.includes(type) || type.includes(UNSUPPORTED_RULE_TYPE_FRAGMENT);
10
10
  var ruleHasUnsupportedType = (rule) => (rule.logic ?? []).some((group) => (group.rules ?? []).some((item) => isUnsupportedType(item.type)));
11
11
  var hasUnsupportedRuleTypes = (metadata) => [...metadata?.matchedRules ?? [], ...metadata?.unmatchedRules ?? []].some(ruleHasUnsupportedType);
12
12
 
package/dist/index.cjs CHANGED
@@ -1698,7 +1698,7 @@ var OfferProductDiscount = import_zod5.z.object({
1698
1698
  type: import_zod5.z.string()
1699
1699
  });
1700
1700
  var OfferProductOption = import_zod5.z.object({
1701
- id: import_zod5.z.number(),
1701
+ id: import_zod5.z.number().optional(),
1702
1702
  name: import_zod5.z.string(),
1703
1703
  position: import_zod5.z.number(),
1704
1704
  values: import_zod5.z.array(import_zod5.z.string())
@@ -1710,7 +1710,7 @@ var OfferProductVariant = import_zod5.z.object({
1710
1710
  inventoryManagement: import_zod5.z.string().nullable(),
1711
1711
  inventoryPolicy: import_zod5.z.string(),
1712
1712
  inventoryQuantity: import_zod5.z.number(),
1713
- link: import_zod5.z.string(),
1713
+ link: import_zod5.z.string().optional(),
1714
1714
  option1: import_zod5.z.string(),
1715
1715
  option2: import_zod5.z.string().nullable(),
1716
1716
  option3: import_zod5.z.string().nullable(),
@@ -1723,12 +1723,12 @@ var OfferProduct = import_zod5.z.object({
1723
1723
  id: import_zod5.z.number(),
1724
1724
  image: import_zod5.z.object({ src: import_zod5.z.string() }).nullish(),
1725
1725
  /**
1726
- * `variantIds` is optional: the engine omits `variant_ids` (rather than sending `[]`) on an image tied to no
1726
+ * `variantIds` is nullish: the engine omits `variant_ids` (rather than sending `[]`) on an image tied to no
1727
1727
  * variant — seen live on the `recommended` data source while `top_sellers` sends `[]` for the same image
1728
- * (REB-24958). A missing list means "not variant-specific", exactly like `[]`, so the image keeps its `src`
1729
- * and the product is never dropped over it.
1728
+ * (REB-24958). A missing (or `null`) list means "not variant-specific", exactly like `[]`, so the image
1729
+ * keeps its `src` and the product is never dropped over it.
1730
1730
  */
1731
- images: import_zod5.z.array(import_zod5.z.object({ src: import_zod5.z.string(), variantIds: import_zod5.z.array(import_zod5.z.number()).optional() })).nullish(),
1731
+ images: import_zod5.z.array(import_zod5.z.object({ src: import_zod5.z.string(), variantIds: import_zod5.z.array(import_zod5.z.number()).nullish() })).nullish(),
1732
1732
  link: import_zod5.z.string().optional(),
1733
1733
  metafields: import_zod5.z.array(import_zod5.z.object({ key: import_zod5.z.string(), namespace: import_zod5.z.string(), value: import_zod5.z.string() })).optional(),
1734
1734
  options: import_zod5.z.array(OfferProductOption),
@@ -3313,7 +3313,15 @@ var StsCompensationProgressSchema = import_zod42.z.union([
3313
3313
  AttemptSchema2,
3314
3314
  FinishedSchema.extend({ status: import_zod42.z.enum(["removed", "failed", "unknown"]) })
3315
3315
  ]);
3316
- var StsReviewReasonSchema = import_zod42.z.enum(["refund-unknown", "compensation-failed", "compensation-unknown"]);
3316
+ var StsReviewReasonSchema = import_zod42.z.enum([
3317
+ "refund-unknown",
3318
+ "compensation-failed",
3319
+ "compensation-unknown",
3320
+ "charge-unconfirmed",
3321
+ "refund-lost",
3322
+ "compensation-lost",
3323
+ "refund-owed"
3324
+ ]);
3317
3325
  var StsReviewProgressSchema = import_zod42.z.strictObject({
3318
3326
  markedAt: PostPurchaseTimestampSchema,
3319
3327
  marker: AcceptedMetafieldResultSchema.shape.status,
@@ -3325,6 +3333,12 @@ var reviewReason = (refund, compensation) => {
3325
3333
  return `compensation-${compensation.status}`;
3326
3334
  return null;
3327
3335
  };
3336
+ var judgedReason = (refund, compensation) => {
3337
+ if (refund === null) return "charge-unconfirmed";
3338
+ if (refund.status === "attempted") return "refund-lost";
3339
+ if (compensation?.status === "attempted") return "compensation-lost";
3340
+ return compensation?.status === "removed" ? "refund-owed" : null;
3341
+ };
3328
3342
  var StsProgressSchema = import_zod42.z.strictObject({
3329
3343
  compensation: StsCompensationProgressSchema.nullable(),
3330
3344
  operationId: PurchaseReceiptSchema.shape.operationId,
@@ -3333,10 +3347,11 @@ var StsProgressSchema = import_zod42.z.strictObject({
3333
3347
  }).refine(
3334
3348
  ({ compensation, refund }) => compensation === null || refund?.status === "failed",
3335
3349
  "Compensation follows a known refund failure only"
3336
- ).refine(
3337
- ({ compensation, refund, review }) => (review?.reason ?? null) === reviewReason(refund, compensation),
3338
- "Review must match the unresolved outcome"
3339
- );
3350
+ ).refine(({ compensation, refund, review }) => {
3351
+ const resolved = reviewReason(refund, compensation);
3352
+ const reason = review?.reason ?? null;
3353
+ return reason === resolved || resolved === null && reason === judgedReason(refund, compensation);
3354
+ }, "Review must match the unresolved outcome");
3340
3355
 
3341
3356
  // src/schema/postPurchaseFollowups.ts
3342
3357
  var RequiredHealthSchema = import_zod43.z.union([
@@ -4918,8 +4933,10 @@ var PurchaseRecoveryRequestSchema = DecideRequestSchema.strict();
4918
4933
  var PurchaseRecoveryResponseSchema = import_zod84.z.object({
4919
4934
  data: import_zod84.z.object({
4920
4935
  /**
4921
- * Strict, so a client pinned before a new optional field rejects a reply that carries it rather than
4922
- * stripping it. Release the client before rebuy-api starts emitting a field added here.
4936
+ * Strict, so rebuy-api (which validates its own reply against this schema) can never emit a field the
4937
+ * contract does not name. cab-post-purchase reads recovery with hand guards that ignore extra keys, so
4938
+ * the strictness never reaches it: release rebuy-api (the pin bump) first, then the client that reads a
4939
+ * field added here.
4923
4940
  */
4924
4941
  operation: import_zod84.z.object({
4925
4942
  /** Absent from a rebuy-api that predates it. */
package/dist/index.mjs CHANGED
@@ -1218,7 +1218,7 @@ var OfferProductDiscount = z5.object({
1218
1218
  type: z5.string()
1219
1219
  });
1220
1220
  var OfferProductOption = z5.object({
1221
- id: z5.number(),
1221
+ id: z5.number().optional(),
1222
1222
  name: z5.string(),
1223
1223
  position: z5.number(),
1224
1224
  values: z5.array(z5.string())
@@ -1230,7 +1230,7 @@ var OfferProductVariant = z5.object({
1230
1230
  inventoryManagement: z5.string().nullable(),
1231
1231
  inventoryPolicy: z5.string(),
1232
1232
  inventoryQuantity: z5.number(),
1233
- link: z5.string(),
1233
+ link: z5.string().optional(),
1234
1234
  option1: z5.string(),
1235
1235
  option2: z5.string().nullable(),
1236
1236
  option3: z5.string().nullable(),
@@ -1243,12 +1243,12 @@ var OfferProduct = z5.object({
1243
1243
  id: z5.number(),
1244
1244
  image: z5.object({ src: z5.string() }).nullish(),
1245
1245
  /**
1246
- * `variantIds` is optional: the engine omits `variant_ids` (rather than sending `[]`) on an image tied to no
1246
+ * `variantIds` is nullish: the engine omits `variant_ids` (rather than sending `[]`) on an image tied to no
1247
1247
  * variant — seen live on the `recommended` data source while `top_sellers` sends `[]` for the same image
1248
- * (REB-24958). A missing list means "not variant-specific", exactly like `[]`, so the image keeps its `src`
1249
- * and the product is never dropped over it.
1248
+ * (REB-24958). A missing (or `null`) list means "not variant-specific", exactly like `[]`, so the image
1249
+ * keeps its `src` and the product is never dropped over it.
1250
1250
  */
1251
- images: z5.array(z5.object({ src: z5.string(), variantIds: z5.array(z5.number()).optional() })).nullish(),
1251
+ images: z5.array(z5.object({ src: z5.string(), variantIds: z5.array(z5.number()).nullish() })).nullish(),
1252
1252
  link: z5.string().optional(),
1253
1253
  metafields: z5.array(z5.object({ key: z5.string(), namespace: z5.string(), value: z5.string() })).optional(),
1254
1254
  options: z5.array(OfferProductOption),
@@ -2833,7 +2833,15 @@ var StsCompensationProgressSchema = z42.union([
2833
2833
  AttemptSchema2,
2834
2834
  FinishedSchema.extend({ status: z42.enum(["removed", "failed", "unknown"]) })
2835
2835
  ]);
2836
- var StsReviewReasonSchema = z42.enum(["refund-unknown", "compensation-failed", "compensation-unknown"]);
2836
+ var StsReviewReasonSchema = z42.enum([
2837
+ "refund-unknown",
2838
+ "compensation-failed",
2839
+ "compensation-unknown",
2840
+ "charge-unconfirmed",
2841
+ "refund-lost",
2842
+ "compensation-lost",
2843
+ "refund-owed"
2844
+ ]);
2837
2845
  var StsReviewProgressSchema = z42.strictObject({
2838
2846
  markedAt: PostPurchaseTimestampSchema,
2839
2847
  marker: AcceptedMetafieldResultSchema.shape.status,
@@ -2845,6 +2853,12 @@ var reviewReason = (refund, compensation) => {
2845
2853
  return `compensation-${compensation.status}`;
2846
2854
  return null;
2847
2855
  };
2856
+ var judgedReason = (refund, compensation) => {
2857
+ if (refund === null) return "charge-unconfirmed";
2858
+ if (refund.status === "attempted") return "refund-lost";
2859
+ if (compensation?.status === "attempted") return "compensation-lost";
2860
+ return compensation?.status === "removed" ? "refund-owed" : null;
2861
+ };
2848
2862
  var StsProgressSchema = z42.strictObject({
2849
2863
  compensation: StsCompensationProgressSchema.nullable(),
2850
2864
  operationId: PurchaseReceiptSchema.shape.operationId,
@@ -2853,10 +2867,11 @@ var StsProgressSchema = z42.strictObject({
2853
2867
  }).refine(
2854
2868
  ({ compensation, refund }) => compensation === null || refund?.status === "failed",
2855
2869
  "Compensation follows a known refund failure only"
2856
- ).refine(
2857
- ({ compensation, refund, review }) => (review?.reason ?? null) === reviewReason(refund, compensation),
2858
- "Review must match the unresolved outcome"
2859
- );
2870
+ ).refine(({ compensation, refund, review }) => {
2871
+ const resolved = reviewReason(refund, compensation);
2872
+ const reason = review?.reason ?? null;
2873
+ return reason === resolved || resolved === null && reason === judgedReason(refund, compensation);
2874
+ }, "Review must match the unresolved outcome");
2860
2875
 
2861
2876
  // src/schema/postPurchaseFollowups.ts
2862
2877
  var RequiredHealthSchema = z43.union([
@@ -4438,8 +4453,10 @@ var PurchaseRecoveryRequestSchema = DecideRequestSchema.strict();
4438
4453
  var PurchaseRecoveryResponseSchema = z84.object({
4439
4454
  data: z84.object({
4440
4455
  /**
4441
- * Strict, so a client pinned before a new optional field rejects a reply that carries it rather than
4442
- * stripping it. Release the client before rebuy-api starts emitting a field added here.
4456
+ * Strict, so rebuy-api (which validates its own reply against this schema) can never emit a field the
4457
+ * contract does not name. cab-post-purchase reads recovery with hand guards that ignore extra keys, so
4458
+ * the strictness never reaches it: release rebuy-api (the pin bump) first, then the client that reads a
4459
+ * field added here.
4443
4460
  */
4444
4461
  operation: z84.object({
4445
4462
  /** Absent from a rebuy-api that predates it. */
@@ -21,7 +21,7 @@ export declare const OfferProduct: z.ZodObject<{
21
21
  }, z.core.$strip>>>;
22
22
  images: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
23
23
  src: z.ZodString;
24
- variantIds: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
24
+ variantIds: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodNumber>>>;
25
25
  }, z.core.$strip>>>>;
26
26
  link: z.ZodOptional<z.ZodString>;
27
27
  metafields: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -30,7 +30,7 @@ export declare const OfferProduct: z.ZodObject<{
30
30
  value: z.ZodString;
31
31
  }, z.core.$strip>>>;
32
32
  options: z.ZodArray<z.ZodObject<{
33
- id: z.ZodNumber;
33
+ id: z.ZodOptional<z.ZodNumber>;
34
34
  name: z.ZodString;
35
35
  position: z.ZodNumber;
36
36
  values: z.ZodArray<z.ZodString>;
@@ -46,7 +46,7 @@ export declare const OfferProduct: z.ZodObject<{
46
46
  inventoryManagement: z.ZodNullable<z.ZodString>;
47
47
  inventoryPolicy: z.ZodString;
48
48
  inventoryQuantity: z.ZodNumber;
49
- link: z.ZodString;
49
+ link: z.ZodOptional<z.ZodString>;
50
50
  option1: z.ZodString;
51
51
  option2: z.ZodNullable<z.ZodString>;
52
52
  option3: z.ZodNullable<z.ZodString>;
@@ -169,6 +169,10 @@ export declare const AcceptedFollowupsResponseSchema: z.ZodObject<{
169
169
  "refund-unknown": "refund-unknown";
170
170
  "compensation-failed": "compensation-failed";
171
171
  "compensation-unknown": "compensation-unknown";
172
+ "charge-unconfirmed": "charge-unconfirmed";
173
+ "refund-lost": "refund-lost";
174
+ "compensation-lost": "compensation-lost";
175
+ "refund-owed": "refund-owed";
172
176
  }>;
173
177
  }, z.core.$strict>>;
174
178
  }, z.core.$strict>>;
@@ -152,6 +152,10 @@ export declare const PurchaseRecoveryResponseSchema: z.ZodObject<{
152
152
  "refund-unknown": "refund-unknown";
153
153
  "compensation-failed": "compensation-failed";
154
154
  "compensation-unknown": "compensation-unknown";
155
+ "charge-unconfirmed": "charge-unconfirmed";
156
+ "refund-lost": "refund-lost";
157
+ "compensation-lost": "compensation-lost";
158
+ "refund-owed": "refund-owed";
155
159
  }>;
156
160
  }, z.core.$strict>>;
157
161
  }, z.core.$strict>>;
@@ -36,11 +36,25 @@ export declare const StsCompensationProgressSchema: z.ZodUnion<readonly [z.ZodOb
36
36
  * Why the STS is left for a person; `marker` is the `subscription_rollback_failed` metafield write. A
37
37
  * `marker` of `unavailable` means the marker could not be written, NOT that no review is needed: the review
38
38
  * stands whatever the marker status.
39
+ *
40
+ * The first three follow from a finished step. The rest are a server's judgement the steps cannot show, so
41
+ * each is allowed (never required) beside one state only:
42
+ * - `charge-unconfirmed`: the server sweep could not confirm the charge (no result reported in time, or an
43
+ * Unknown one), so no step will ever start. Without it a late `/purchases/accepted` reads as not started,
44
+ * which looks pending forever.
45
+ * - `refund-lost` / `compensation-lost`: that step was sent but its outcome was never saved, so it stays
46
+ * `attempted` and may have moved money.
47
+ * - `refund-owed`: the rollback removed the subscription line, but apiv2's removal never refunds, so the
48
+ * buyer may still have been charged for it.
39
49
  */
40
50
  export declare const StsReviewReasonSchema: z.ZodEnum<{
41
51
  "refund-unknown": "refund-unknown";
42
52
  "compensation-failed": "compensation-failed";
43
53
  "compensation-unknown": "compensation-unknown";
54
+ "charge-unconfirmed": "charge-unconfirmed";
55
+ "refund-lost": "refund-lost";
56
+ "compensation-lost": "compensation-lost";
57
+ "refund-owed": "refund-owed";
44
58
  }>;
45
59
  export declare const StsReviewProgressSchema: z.ZodObject<{
46
60
  markedAt: z.ZodNumber;
@@ -56,12 +70,18 @@ export declare const StsReviewProgressSchema: z.ZodObject<{
56
70
  "refund-unknown": "refund-unknown";
57
71
  "compensation-failed": "compensation-failed";
58
72
  "compensation-unknown": "compensation-unknown";
73
+ "charge-unconfirmed": "charge-unconfirmed";
74
+ "refund-lost": "refund-lost";
75
+ "compensation-lost": "compensation-lost";
76
+ "refund-owed": "refund-owed";
59
77
  }>;
60
78
  }, z.core.$strict>;
61
79
  /**
62
80
  * The refund-compensation saga of one admitted STS, `null` steps not yet started. Compensation follows a
63
81
  * known refund failure only, and a review is recorded exactly when the outcome is unresolved (an unknown
64
- * refund, or a failed or unknown rollback), so a compensated or unresolved STS never reads as switched.
82
+ * refund, or a failed or unknown rollback), so a compensated or unresolved STS never reads as switched. A
83
+ * server may also record a review the steps cannot show (an unconfirmed charge, a lost step, a refund owed
84
+ * after the rollback), only beside the one state it applies to.
65
85
  */
66
86
  export declare const StsProgressSchema: z.ZodObject<{
67
87
  compensation: z.ZodNullable<z.ZodUnion<readonly [z.ZodObject<{
@@ -107,6 +127,10 @@ export declare const StsProgressSchema: z.ZodObject<{
107
127
  "refund-unknown": "refund-unknown";
108
128
  "compensation-failed": "compensation-failed";
109
129
  "compensation-unknown": "compensation-unknown";
130
+ "charge-unconfirmed": "charge-unconfirmed";
131
+ "refund-lost": "refund-lost";
132
+ "compensation-lost": "compensation-lost";
133
+ "refund-owed": "refund-owed";
110
134
  }>;
111
135
  }, z.core.$strict>>;
112
136
  }, z.core.$strict>;
@@ -81,8 +81,8 @@ var getValidGwpProductIds = (matchedRules = []) => new Set(
81
81
 
82
82
  // src/gwp/hasUnsupportedRuleTypes.ts
83
83
  var UNSUPPORTED_RULE_TYPES = ["url", "order_tag"];
84
- var UNSUPPORTED_RULE_TYPE_PREFIX = "geolocation_";
85
- var isUnsupportedType = (type = "") => UNSUPPORTED_RULE_TYPES.includes(type) || type.startsWith(UNSUPPORTED_RULE_TYPE_PREFIX);
84
+ var UNSUPPORTED_RULE_TYPE_FRAGMENT = "geolocation";
85
+ var isUnsupportedType = (type = "") => UNSUPPORTED_RULE_TYPES.includes(type) || type.includes(UNSUPPORTED_RULE_TYPE_FRAGMENT);
86
86
  var ruleHasUnsupportedType = (rule) => (rule.logic ?? []).some((group) => (group.rules ?? []).some((item) => isUnsupportedType(item.type)));
87
87
  var hasUnsupportedRuleTypes = (metadata) => [...metadata?.matchedRules ?? [], ...metadata?.unmatchedRules ?? []].some(ruleHasUnsupportedType);
88
88
 
@@ -364,7 +364,7 @@ var OfferProductDiscount = import_zod3.z.object({
364
364
  type: import_zod3.z.string()
365
365
  });
366
366
  var OfferProductOption = import_zod3.z.object({
367
- id: import_zod3.z.number(),
367
+ id: import_zod3.z.number().optional(),
368
368
  name: import_zod3.z.string(),
369
369
  position: import_zod3.z.number(),
370
370
  values: import_zod3.z.array(import_zod3.z.string())
@@ -376,7 +376,7 @@ var OfferProductVariant = import_zod3.z.object({
376
376
  inventoryManagement: import_zod3.z.string().nullable(),
377
377
  inventoryPolicy: import_zod3.z.string(),
378
378
  inventoryQuantity: import_zod3.z.number(),
379
- link: import_zod3.z.string(),
379
+ link: import_zod3.z.string().optional(),
380
380
  option1: import_zod3.z.string(),
381
381
  option2: import_zod3.z.string().nullable(),
382
382
  option3: import_zod3.z.string().nullable(),
@@ -389,12 +389,12 @@ var OfferProduct = import_zod3.z.object({
389
389
  id: import_zod3.z.number(),
390
390
  image: import_zod3.z.object({ src: import_zod3.z.string() }).nullish(),
391
391
  /**
392
- * `variantIds` is optional: the engine omits `variant_ids` (rather than sending `[]`) on an image tied to no
392
+ * `variantIds` is nullish: the engine omits `variant_ids` (rather than sending `[]`) on an image tied to no
393
393
  * variant — seen live on the `recommended` data source while `top_sellers` sends `[]` for the same image
394
- * (REB-24958). A missing list means "not variant-specific", exactly like `[]`, so the image keeps its `src`
395
- * and the product is never dropped over it.
394
+ * (REB-24958). A missing (or `null`) list means "not variant-specific", exactly like `[]`, so the image
395
+ * keeps its `src` and the product is never dropped over it.
396
396
  */
397
- images: import_zod3.z.array(import_zod3.z.object({ src: import_zod3.z.string(), variantIds: import_zod3.z.array(import_zod3.z.number()).optional() })).nullish(),
397
+ images: import_zod3.z.array(import_zod3.z.object({ src: import_zod3.z.string(), variantIds: import_zod3.z.array(import_zod3.z.number()).nullish() })).nullish(),
398
398
  link: import_zod3.z.string().optional(),
399
399
  metafields: import_zod3.z.array(import_zod3.z.object({ key: import_zod3.z.string(), namespace: import_zod3.z.string(), value: import_zod3.z.string() })).optional(),
400
400
  options: import_zod3.z.array(OfferProductOption),
@@ -426,6 +426,8 @@ var filterByB2bAvailability = async (products, input, ctx) => {
426
426
  productIds: products.map(productGid),
427
427
  shopifyShopDomain: input.shop
428
428
  },
429
+ /** admin-api verifies it (REB-25081); absent, the call is unauthenticated (log-only there until enforced). */
430
+ ...ctx.sessionToken && { headers: { Authorization: `Bearer ${ctx.sessionToken}` } },
429
431
  host: ctx.host,
430
432
  method: "POST"
431
433
  }
@@ -6192,6 +6194,10 @@ var reportOncePerResponse = (response, report, events) => {
6192
6194
  }
6193
6195
  };
6194
6196
 
6197
+ // src/server/postPurchaseSellingPlanRequirement.ts
6198
+ var requiresOwnSellingPlan = (product) => product.requiresSellingPlan === true;
6199
+ var requiresUnsuppliedSellingPlan = (product) => requiresOwnSellingPlan(product) && !product.sellingPlanGroups?.length;
6200
+
6195
6201
  // src/server/readPostPurchaseProductSource.ts
6196
6202
  var Envelope = PostPurchaseProductSource.extend({ data: import_zod45.z.array(import_zod45.z.unknown()) });
6197
6203
  var Product3 = PostPurchaseProductSource.shape.data.element;
@@ -6204,9 +6210,9 @@ var readPostPurchaseProductSource = (response, report) => {
6204
6210
  const parsed = Product3.safeParse(raw);
6205
6211
  if (parsed.success) {
6206
6212
  rememberPostPurchaseProductSource(parsed.data, response, productIndex);
6207
- if (parsed.data.requiresSellingPlan && !parsed.data.sellingPlanGroups.length)
6213
+ if (requiresUnsuppliedSellingPlan(parsed.data))
6208
6214
  drift.push({
6209
- detail: `Dropped post-purchase product ${parsed.data.id}: data.${productIndex}.requiresSellingPlan`,
6215
+ detail: `Ineligible post-purchase product ${parsed.data.id}: data.${productIndex}.requiresSellingPlan`,
6210
6216
  kind: "product"
6211
6217
  });
6212
6218
  return [{ product: parsed.data, productIndex }];
@@ -6397,19 +6403,20 @@ var readPostPurchaseModernPlans = (raw, allocations) => {
6397
6403
  };
6398
6404
 
6399
6405
  // src/server/postPurchasePlanCatalog.ts
6406
+ var hasLegacyPlanGroups = ({ sellingPlanGroups }) => typeof sellingPlanGroups[0]?.id === "number";
6400
6407
  var projectPostPurchasePlanCatalog = (normalized, report) => {
6401
6408
  const { data } = normalized;
6402
- if (data.length === 1 && data[0].variants.length > 1) return null;
6403
6409
  if (normalized.emptiedByDrop && !data.length) return null;
6410
+ if (data.length === 1 && data[0].variants.length > 1) return null;
6404
6411
  try {
6405
- if (data.length !== 1 || data[0].variants.length !== 1) throw new Error("Ambiguous product");
6412
+ if (data.length !== 1 || data[0].variants.length !== 1) throw new Error("No single product and variant");
6406
6413
  const product = data[0];
6407
6414
  const variant2 = product.variants[0];
6408
6415
  if (variant2.productId !== product.id) throw new Error("Foreign variant");
6409
6416
  const groups = product.sellingPlanGroups;
6410
6417
  const required = groups.map((group) => group.requiresSellingPlan);
6411
6418
  if (required.some((flag) => flag !== required[0])) throw new Error("Conflicting requirement");
6412
- const plans = typeof groups[0]?.id === "number" ? readPostPurchaseLegacyPlans(groups[0], variant2.id) : readPostPurchaseModernPlans(groups, variant2.sellingPlanAllocations);
6419
+ const plans = hasLegacyPlanGroups(product) ? readPostPurchaseLegacyPlans(groups[0], variant2.id) : readPostPurchaseModernPlans(groups, variant2.sellingPlanAllocations);
6413
6420
  const unique = /* @__PURE__ */ new Map();
6414
6421
  for (const plan of plans) {
6415
6422
  const previous = unique.get(plan.id);
@@ -6422,8 +6429,7 @@ var projectPostPurchasePlanCatalog = (normalized, report) => {
6422
6429
  discountPercentage: postPurchasePlanDiscountPercentage(variant2.price, plan.adjustment)
6423
6430
  })),
6424
6431
  productId: product.id,
6425
- // REB-25048: a v2 product flags the requirement on itself and carries no selling plan groups
6426
- requiresSellingPlan: (required[0] ?? false) || product.requiresSellingPlan === true,
6432
+ requiresSellingPlan: (required[0] ?? false) || requiresOwnSellingPlan(product),
6427
6433
  variantId: variant2.id
6428
6434
  });
6429
6435
  } catch {
@@ -6976,7 +6982,7 @@ var oneTimeUnavailable = (normalized, allowCollection, quantity3) => {
6976
6982
  return "Only fixed one-time configuration is supported";
6977
6983
  const product = data[0];
6978
6984
  const variant2 = product.variants[0];
6979
- if (product.productGroupVariants.length || product.requiresSellingPlan === true || product.sellingPlanGroups?.some((group) => group.requiresSellingPlan))
6985
+ if (product.productGroupVariants.length || requiresOwnSellingPlan(product) || product.sellingPlanGroups?.some((group) => group.requiresSellingPlan))
6980
6986
  return "A one-time variant without product groups or a required selling plan is required";
6981
6987
  if (!postPurchaseVariantAvailable(variant2)) return VARIANT_UNAVAILABLE;
6982
6988
  if (variant2.productId !== product.id) throw new Error("Product variant identity mismatch");
@@ -7647,7 +7653,7 @@ var reportUnreadableStsLine = (product, field, report) => {
7647
7653
  };
7648
7654
  var postPurchaseStsLine = (normalized, product, lines, variantId, report) => {
7649
7655
  if (!product.sellingPlanGroups?.length || product.productGroupVariants.length) return void 0;
7650
- const modern = typeof product.sellingPlanGroups[0].id !== "number";
7656
+ const modern = !hasLegacyPlanGroups(product);
7651
7657
  for (const [index, variant2] of product.variants.entries()) {
7652
7658
  const matched = lines.filter((line) => line.sellingPlanId === void 0 && line.variantId === variant2.id);
7653
7659
  const data = [{ ...product, variants: [variant2] }];
@@ -7655,7 +7661,7 @@ var postPurchaseStsLine = (normalized, product, lines, variantId, report) => {
7655
7661
  const unread = [];
7656
7662
  if (projectPostPurchasePlanCatalog({ ...normalized, data }, (event) => unread.push(event))?.plans.length)
7657
7663
  return { data, line: matched[0] };
7658
- const field = modern && !PostPurchasePlanAllocations.safeParse(variant2.sellingPlanAllocations).success ? `variants.${index}.sellingPlanAllocations` : unread.length ? "sellingPlanGroups" : void 0;
7664
+ const field = modern && !PostPurchasePlanAllocations.safeParse(variant2.sellingPlanAllocations).success ? `variants.${index}.sellingPlanAllocations` : !unread.length ? void 0 : variant2.productId === product.id ? "sellingPlanGroups" : `variants.${index}.productId`;
7659
7665
  if (report && field) reportUnreadableStsLine(product, field, report);
7660
7666
  }
7661
7667
  }
@@ -8097,7 +8103,7 @@ var eligibility = (normalized, product, excluded) => {
8097
8103
  if (product.productGroupVariants.length) {
8098
8104
  const group = readPostPurchaseGroup(product, normalized.effective, excluded);
8099
8105
  if (!group.entries.length) return void 0;
8100
- return group.entries.map(({ product: option }) => postPurchaseMemberEligibility(normalized, option)).some(Boolean);
8106
+ return group.entries.map(({ product: option }) => eligibility(normalized, option)).some(Boolean);
8101
8107
  }
8102
8108
  if (!product.variants.length) return false;
8103
8109
  const variants = projectPostPurchaseVariantCatalog(product, normalized.effective).variants;
@@ -8,8 +8,8 @@ var getValidGwpProductIds = (matchedRules = []) => new Set(
8
8
 
9
9
  // src/gwp/hasUnsupportedRuleTypes.ts
10
10
  var UNSUPPORTED_RULE_TYPES = ["url", "order_tag"];
11
- var UNSUPPORTED_RULE_TYPE_PREFIX = "geolocation_";
12
- var isUnsupportedType = (type = "") => UNSUPPORTED_RULE_TYPES.includes(type) || type.startsWith(UNSUPPORTED_RULE_TYPE_PREFIX);
11
+ var UNSUPPORTED_RULE_TYPE_FRAGMENT = "geolocation";
12
+ var isUnsupportedType = (type = "") => UNSUPPORTED_RULE_TYPES.includes(type) || type.includes(UNSUPPORTED_RULE_TYPE_FRAGMENT);
13
13
  var ruleHasUnsupportedType = (rule) => (rule.logic ?? []).some((group) => (group.rules ?? []).some((item) => isUnsupportedType(item.type)));
14
14
  var hasUnsupportedRuleTypes = (metadata) => [...metadata?.matchedRules ?? [], ...metadata?.unmatchedRules ?? []].some(ruleHasUnsupportedType);
15
15
 
@@ -291,7 +291,7 @@ var OfferProductDiscount = z3.object({
291
291
  type: z3.string()
292
292
  });
293
293
  var OfferProductOption = z3.object({
294
- id: z3.number(),
294
+ id: z3.number().optional(),
295
295
  name: z3.string(),
296
296
  position: z3.number(),
297
297
  values: z3.array(z3.string())
@@ -303,7 +303,7 @@ var OfferProductVariant = z3.object({
303
303
  inventoryManagement: z3.string().nullable(),
304
304
  inventoryPolicy: z3.string(),
305
305
  inventoryQuantity: z3.number(),
306
- link: z3.string(),
306
+ link: z3.string().optional(),
307
307
  option1: z3.string(),
308
308
  option2: z3.string().nullable(),
309
309
  option3: z3.string().nullable(),
@@ -316,12 +316,12 @@ var OfferProduct = z3.object({
316
316
  id: z3.number(),
317
317
  image: z3.object({ src: z3.string() }).nullish(),
318
318
  /**
319
- * `variantIds` is optional: the engine omits `variant_ids` (rather than sending `[]`) on an image tied to no
319
+ * `variantIds` is nullish: the engine omits `variant_ids` (rather than sending `[]`) on an image tied to no
320
320
  * variant — seen live on the `recommended` data source while `top_sellers` sends `[]` for the same image
321
- * (REB-24958). A missing list means "not variant-specific", exactly like `[]`, so the image keeps its `src`
322
- * and the product is never dropped over it.
321
+ * (REB-24958). A missing (or `null`) list means "not variant-specific", exactly like `[]`, so the image
322
+ * keeps its `src` and the product is never dropped over it.
323
323
  */
324
- images: z3.array(z3.object({ src: z3.string(), variantIds: z3.array(z3.number()).optional() })).nullish(),
324
+ images: z3.array(z3.object({ src: z3.string(), variantIds: z3.array(z3.number()).nullish() })).nullish(),
325
325
  link: z3.string().optional(),
326
326
  metafields: z3.array(z3.object({ key: z3.string(), namespace: z3.string(), value: z3.string() })).optional(),
327
327
  options: z3.array(OfferProductOption),
@@ -353,6 +353,8 @@ var filterByB2bAvailability = async (products, input, ctx) => {
353
353
  productIds: products.map(productGid),
354
354
  shopifyShopDomain: input.shop
355
355
  },
356
+ /** admin-api verifies it (REB-25081); absent, the call is unauthenticated (log-only there until enforced). */
357
+ ...ctx.sessionToken && { headers: { Authorization: `Bearer ${ctx.sessionToken}` } },
356
358
  host: ctx.host,
357
359
  method: "POST"
358
360
  }
@@ -6119,6 +6121,10 @@ var reportOncePerResponse = (response, report, events) => {
6119
6121
  }
6120
6122
  };
6121
6123
 
6124
+ // src/server/postPurchaseSellingPlanRequirement.ts
6125
+ var requiresOwnSellingPlan = (product) => product.requiresSellingPlan === true;
6126
+ var requiresUnsuppliedSellingPlan = (product) => requiresOwnSellingPlan(product) && !product.sellingPlanGroups?.length;
6127
+
6122
6128
  // src/server/readPostPurchaseProductSource.ts
6123
6129
  var Envelope = PostPurchaseProductSource.extend({ data: z45.array(z45.unknown()) });
6124
6130
  var Product3 = PostPurchaseProductSource.shape.data.element;
@@ -6131,9 +6137,9 @@ var readPostPurchaseProductSource = (response, report) => {
6131
6137
  const parsed = Product3.safeParse(raw);
6132
6138
  if (parsed.success) {
6133
6139
  rememberPostPurchaseProductSource(parsed.data, response, productIndex);
6134
- if (parsed.data.requiresSellingPlan && !parsed.data.sellingPlanGroups.length)
6140
+ if (requiresUnsuppliedSellingPlan(parsed.data))
6135
6141
  drift.push({
6136
- detail: `Dropped post-purchase product ${parsed.data.id}: data.${productIndex}.requiresSellingPlan`,
6142
+ detail: `Ineligible post-purchase product ${parsed.data.id}: data.${productIndex}.requiresSellingPlan`,
6137
6143
  kind: "product"
6138
6144
  });
6139
6145
  return [{ product: parsed.data, productIndex }];
@@ -6324,19 +6330,20 @@ var readPostPurchaseModernPlans = (raw, allocations) => {
6324
6330
  };
6325
6331
 
6326
6332
  // src/server/postPurchasePlanCatalog.ts
6333
+ var hasLegacyPlanGroups = ({ sellingPlanGroups }) => typeof sellingPlanGroups[0]?.id === "number";
6327
6334
  var projectPostPurchasePlanCatalog = (normalized, report) => {
6328
6335
  const { data } = normalized;
6329
- if (data.length === 1 && data[0].variants.length > 1) return null;
6330
6336
  if (normalized.emptiedByDrop && !data.length) return null;
6337
+ if (data.length === 1 && data[0].variants.length > 1) return null;
6331
6338
  try {
6332
- if (data.length !== 1 || data[0].variants.length !== 1) throw new Error("Ambiguous product");
6339
+ if (data.length !== 1 || data[0].variants.length !== 1) throw new Error("No single product and variant");
6333
6340
  const product = data[0];
6334
6341
  const variant2 = product.variants[0];
6335
6342
  if (variant2.productId !== product.id) throw new Error("Foreign variant");
6336
6343
  const groups = product.sellingPlanGroups;
6337
6344
  const required = groups.map((group) => group.requiresSellingPlan);
6338
6345
  if (required.some((flag) => flag !== required[0])) throw new Error("Conflicting requirement");
6339
- const plans = typeof groups[0]?.id === "number" ? readPostPurchaseLegacyPlans(groups[0], variant2.id) : readPostPurchaseModernPlans(groups, variant2.sellingPlanAllocations);
6346
+ const plans = hasLegacyPlanGroups(product) ? readPostPurchaseLegacyPlans(groups[0], variant2.id) : readPostPurchaseModernPlans(groups, variant2.sellingPlanAllocations);
6340
6347
  const unique = /* @__PURE__ */ new Map();
6341
6348
  for (const plan of plans) {
6342
6349
  const previous = unique.get(plan.id);
@@ -6349,8 +6356,7 @@ var projectPostPurchasePlanCatalog = (normalized, report) => {
6349
6356
  discountPercentage: postPurchasePlanDiscountPercentage(variant2.price, plan.adjustment)
6350
6357
  })),
6351
6358
  productId: product.id,
6352
- // REB-25048: a v2 product flags the requirement on itself and carries no selling plan groups
6353
- requiresSellingPlan: (required[0] ?? false) || product.requiresSellingPlan === true,
6359
+ requiresSellingPlan: (required[0] ?? false) || requiresOwnSellingPlan(product),
6354
6360
  variantId: variant2.id
6355
6361
  });
6356
6362
  } catch {
@@ -6903,7 +6909,7 @@ var oneTimeUnavailable = (normalized, allowCollection, quantity3) => {
6903
6909
  return "Only fixed one-time configuration is supported";
6904
6910
  const product = data[0];
6905
6911
  const variant2 = product.variants[0];
6906
- if (product.productGroupVariants.length || product.requiresSellingPlan === true || product.sellingPlanGroups?.some((group) => group.requiresSellingPlan))
6912
+ if (product.productGroupVariants.length || requiresOwnSellingPlan(product) || product.sellingPlanGroups?.some((group) => group.requiresSellingPlan))
6907
6913
  return "A one-time variant without product groups or a required selling plan is required";
6908
6914
  if (!postPurchaseVariantAvailable(variant2)) return VARIANT_UNAVAILABLE;
6909
6915
  if (variant2.productId !== product.id) throw new Error("Product variant identity mismatch");
@@ -7574,7 +7580,7 @@ var reportUnreadableStsLine = (product, field, report) => {
7574
7580
  };
7575
7581
  var postPurchaseStsLine = (normalized, product, lines, variantId, report) => {
7576
7582
  if (!product.sellingPlanGroups?.length || product.productGroupVariants.length) return void 0;
7577
- const modern = typeof product.sellingPlanGroups[0].id !== "number";
7583
+ const modern = !hasLegacyPlanGroups(product);
7578
7584
  for (const [index, variant2] of product.variants.entries()) {
7579
7585
  const matched = lines.filter((line) => line.sellingPlanId === void 0 && line.variantId === variant2.id);
7580
7586
  const data = [{ ...product, variants: [variant2] }];
@@ -7582,7 +7588,7 @@ var postPurchaseStsLine = (normalized, product, lines, variantId, report) => {
7582
7588
  const unread = [];
7583
7589
  if (projectPostPurchasePlanCatalog({ ...normalized, data }, (event) => unread.push(event))?.plans.length)
7584
7590
  return { data, line: matched[0] };
7585
- const field = modern && !PostPurchasePlanAllocations.safeParse(variant2.sellingPlanAllocations).success ? `variants.${index}.sellingPlanAllocations` : unread.length ? "sellingPlanGroups" : void 0;
7591
+ const field = modern && !PostPurchasePlanAllocations.safeParse(variant2.sellingPlanAllocations).success ? `variants.${index}.sellingPlanAllocations` : !unread.length ? void 0 : variant2.productId === product.id ? "sellingPlanGroups" : `variants.${index}.productId`;
7586
7592
  if (report && field) reportUnreadableStsLine(product, field, report);
7587
7593
  }
7588
7594
  }
@@ -8024,7 +8030,7 @@ var eligibility = (normalized, product, excluded) => {
8024
8030
  if (product.productGroupVariants.length) {
8025
8031
  const group = readPostPurchaseGroup(product, normalized.effective, excluded);
8026
8032
  if (!group.entries.length) return void 0;
8027
- return group.entries.map(({ product: option }) => postPurchaseMemberEligibility(normalized, option)).some(Boolean);
8033
+ return group.entries.map(({ product: option }) => eligibility(normalized, option)).some(Boolean);
8028
8034
  }
8029
8035
  if (!product.variants.length) return false;
8030
8036
  const variants = projectPostPurchaseVariantCatalog(product, normalized.effective).variants;
@@ -1,6 +1,9 @@
1
1
  import { PostPurchasePlanCatalog } from '../schema/postPurchasePlanCatalog';
2
2
  import type { normalizePostPurchaseProduct } from '../server/normalizePostPurchaseProduct';
3
3
  import type { Reporter } from '../server/shared';
4
+ type Product = ReturnType<typeof normalizePostPurchaseProduct>['data'][number];
5
+ /** v1 selling-plan groups carry numeric ids and their plans on the group; modern ones key plans per variant. */
6
+ export declare const hasLegacyPlanGroups: ({ sellingPlanGroups }: Pick<Product, "sellingPlanGroups">) => boolean;
4
7
  /**
5
8
  * Optional inspection data survives unsupported preparation without changing its purchase authority. Each plan
6
9
  * carries its own display saving on this variant's price, so the switch label needs no client maths.
@@ -12,3 +15,4 @@ import type { Reporter } from '../server/shared';
12
15
  * not a second fault: each drop was already reported, so it answers null without another report.
13
16
  */
14
17
  export declare const projectPostPurchasePlanCatalog: (normalized: ReturnType<typeof normalizePostPurchaseProduct>, report?: Reporter) => PostPurchasePlanCatalog | null;
18
+ export {};
@@ -0,0 +1,14 @@
1
+ type Requiring = {
2
+ requiresSellingPlan?: boolean | null;
3
+ sellingPlanGroups?: unknown[];
4
+ };
5
+ /**
6
+ * REB-25048: a v2 product flags `requires_selling_plan` on itself rather than on its selling plan groups. It is
7
+ * never sold one-time, and a product that also has groups is offered subscription-only. Legacy read only the first
8
+ * group's flag, so under Product Type `both` it dropped such a product where the rebuild offers it subscription-only
9
+ * (accepted deviation, connscoding on npm-rebuy #117: neither sells it one-time).
10
+ */
11
+ export declare const requiresOwnSellingPlan: (product: Requiring) => boolean;
12
+ /** Requires a selling plan with no group to supply one: no purchasable mode is left, so eligibility drops it. */
13
+ export declare const requiresUnsuppliedSellingPlan: (product: Requiring) => boolean;
14
+ export {};
@@ -17,7 +17,9 @@ export declare const stsAllowed: ({ effective, original }: Pick<Normalized, "eff
17
17
  * plan; (2) it sits on exactly one one-time line, since two make the refunded quantity ambiguous; (3) a grouped
18
18
  * product is never an STS member; (4) the bound variant is the purchased line's, not the product's selected
19
19
  * variant, and subscription is the only mode. The first such variant in catalog order wins, unless `variantId`
20
- * names one.
20
+ * names one. Two more differences from legacy are accepted (connscoding, npm-rebuy #109): a subscription line
21
+ * beside a one-time line of the same variant still gets STS, where legacy's first match on the variant offered
22
+ * none; and the quantity is fixed at the whole one-time line, where legacy let the buyer change it.
21
23
  *
22
24
  * `report` hears a candidate (a purchased, in-stock variant on exactly one one-time line) whose plan data cannot be
23
25
  * read, since it then silently switches nothing: a modern selling-plan variant whose `sellingPlanAllocations` is
@@ -28,12 +28,12 @@ export type UpstreamFetch = (path: string, params: Record<string, string>, optio
28
28
  /**
29
29
  * A drift signal the orchestrators emit when a per-item payload salvage drops something: a malformed
30
30
  * offer product (or a post-purchase data-source product, `product`, named by id and dotted path), an
31
- * invalid/unknown section stubbed out, an unreadable rule verdict, a shop-config
32
- * entry the shared schema inerted (`shopConfig`), unreadable selectable-gift milestones
33
- * (`giftMilestones` — the widget's gifts are then kept), or a post-purchase product's malformed selected review
34
- * metafield (`reviews` — the reviews are then omitted; it names the product and the field, never the value). Distinct from a hard {@link UpstreamError} — the
35
- * request still succeeds (degraded), so this is the only trace that an upstream contract moved. Optional
36
- * on {@link ServerContext}; the host (rebuy-api) wires it to its logger.
31
+ * invalid/unknown section stubbed out, an unreadable rule verdict, a shop-config entry the shared schema
32
+ * inerted (`shopConfig`), unreadable selectable-gift milestones (`giftMilestones` — the widget's gifts are
33
+ * then kept), or a post-purchase product's malformed selected review metafield (`reviews` — the reviews are
34
+ * then omitted; it names the product and the field, never the value). Distinct from a hard
35
+ * {@link UpstreamError} — the request still succeeds (degraded), so this is the only trace that an upstream
36
+ * contract moved. Optional on {@link ServerContext}; the host (rebuy-api) wires it to its logger.
37
37
  */
38
38
  export type ServerDrift = {
39
39
  detail: string;
@@ -55,10 +55,19 @@ export declare const isEmptyObject: (x: unknown) => boolean;
55
55
  export type ServerContext = {
56
56
  fetchUpstream: UpstreamFetch;
57
57
  host: string;
58
- /** Buyer request IP forwarded to the ads engine (the checkout worker can't read it; rebuy-api extracts it). Without it DSPs see one datacenter IP for all traffic — geo/IVT-flagging risk. Monetize only. */
58
+ /**
59
+ * Buyer request IP forwarded to the ads engine (the checkout worker can't read it; rebuy-api extracts it).
60
+ * Without it DSPs see one datacenter IP for all traffic — geo/IVT-flagging risk. Monetize only.
61
+ */
59
62
  ipAddress?: string;
60
63
  /** Optional sink for {@link ServerDrift} — a degraded-but-successful payload salvage. */
61
64
  reportDrift?: (event: ServerDrift) => void;
65
+ /**
66
+ * The checkout extension's Shopify session token (the bare JWT, no `Bearer ` prefix), as the host received
67
+ * it. Forwarded unread to admin-api's B2B availability check, which verifies it and binds the shop and the
68
+ * company location to the buyer it names (REB-25081). Never logged. B2B data-source filtering only.
69
+ */
70
+ sessionToken?: string;
62
71
  /** Browser user-agent forwarded to the ads engine (the checkout worker can't read it). Monetize only. */
63
72
  userAgent?: string;
64
73
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rebuy/rebuy",
3
- "version": "3.57.0",
3
+ "version": "3.59.0",
4
4
  "description": "Shared zod schemas, legacy-to-CAB widget transforms, and server orchestrators for Rebuy's Shopify consumers (rebuy-api, admin-nextjs, rebuy-shopify-extensions)",
5
5
  "license": "MIT",
6
6
  "author": "Rebuy, Inc.",