@rebuy/rebuy 3.57.0 → 3.58.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/gwp/index.cjs +2 -2
- package/dist/gwp/index.mjs +2 -2
- package/dist/index.cjs +30 -13
- package/dist/index.mjs +30 -13
- package/dist/schema/offerProduct.d.ts +3 -3
- package/dist/schema/postPurchaseFollowups.d.ts +4 -0
- package/dist/schema/postPurchaseRecovery.d.ts +4 -0
- package/dist/schema/postPurchaseSts.d.ts +25 -1
- package/dist/server/index.cjs +23 -19
- package/dist/server/index.mjs +23 -19
- package/dist/server/postPurchasePlanCatalog.d.ts +4 -0
- package/dist/server/postPurchaseSellingPlanRequirement.d.ts +14 -0
- package/dist/server/postPurchaseSts.d.ts +3 -1
- package/dist/server/shared.d.ts +10 -7
- package/package.json +1 -1
package/dist/gwp/index.cjs
CHANGED
|
@@ -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
|
|
41
|
-
var isUnsupportedType = (type = "") => UNSUPPORTED_RULE_TYPES.includes(type) || type.
|
|
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
|
|
package/dist/gwp/index.mjs
CHANGED
|
@@ -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
|
|
9
|
-
var isUnsupportedType = (type = "") => UNSUPPORTED_RULE_TYPES.includes(type) || type.
|
|
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
|
|
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
|
|
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()).
|
|
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([
|
|
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
|
-
|
|
3338
|
-
|
|
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
|
|
4922
|
-
*
|
|
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
|
|
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
|
|
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()).
|
|
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([
|
|
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
|
-
|
|
2858
|
-
|
|
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
|
|
4442
|
-
*
|
|
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>;
|
package/dist/server/index.cjs
CHANGED
|
@@ -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
|
|
85
|
-
var isUnsupportedType = (type = "") => UNSUPPORTED_RULE_TYPES.includes(type) || type.
|
|
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
|
|
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
|
|
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()).
|
|
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),
|
|
@@ -6192,6 +6192,10 @@ var reportOncePerResponse = (response, report, events) => {
|
|
|
6192
6192
|
}
|
|
6193
6193
|
};
|
|
6194
6194
|
|
|
6195
|
+
// src/server/postPurchaseSellingPlanRequirement.ts
|
|
6196
|
+
var requiresOwnSellingPlan = (product) => product.requiresSellingPlan === true;
|
|
6197
|
+
var requiresUnsuppliedSellingPlan = (product) => requiresOwnSellingPlan(product) && !product.sellingPlanGroups?.length;
|
|
6198
|
+
|
|
6195
6199
|
// src/server/readPostPurchaseProductSource.ts
|
|
6196
6200
|
var Envelope = PostPurchaseProductSource.extend({ data: import_zod45.z.array(import_zod45.z.unknown()) });
|
|
6197
6201
|
var Product3 = PostPurchaseProductSource.shape.data.element;
|
|
@@ -6204,9 +6208,9 @@ var readPostPurchaseProductSource = (response, report) => {
|
|
|
6204
6208
|
const parsed = Product3.safeParse(raw);
|
|
6205
6209
|
if (parsed.success) {
|
|
6206
6210
|
rememberPostPurchaseProductSource(parsed.data, response, productIndex);
|
|
6207
|
-
if (parsed.data
|
|
6211
|
+
if (requiresUnsuppliedSellingPlan(parsed.data))
|
|
6208
6212
|
drift.push({
|
|
6209
|
-
detail: `
|
|
6213
|
+
detail: `Ineligible post-purchase product ${parsed.data.id}: data.${productIndex}.requiresSellingPlan`,
|
|
6210
6214
|
kind: "product"
|
|
6211
6215
|
});
|
|
6212
6216
|
return [{ product: parsed.data, productIndex }];
|
|
@@ -6397,19 +6401,20 @@ var readPostPurchaseModernPlans = (raw, allocations) => {
|
|
|
6397
6401
|
};
|
|
6398
6402
|
|
|
6399
6403
|
// src/server/postPurchasePlanCatalog.ts
|
|
6404
|
+
var hasLegacyPlanGroups = ({ sellingPlanGroups }) => typeof sellingPlanGroups[0]?.id === "number";
|
|
6400
6405
|
var projectPostPurchasePlanCatalog = (normalized, report) => {
|
|
6401
6406
|
const { data } = normalized;
|
|
6402
|
-
if (data.length === 1 && data[0].variants.length > 1) return null;
|
|
6403
6407
|
if (normalized.emptiedByDrop && !data.length) return null;
|
|
6408
|
+
if (data.length === 1 && data[0].variants.length > 1) return null;
|
|
6404
6409
|
try {
|
|
6405
|
-
if (data.length !== 1 || data[0].variants.length !== 1) throw new Error("
|
|
6410
|
+
if (data.length !== 1 || data[0].variants.length !== 1) throw new Error("No single product and variant");
|
|
6406
6411
|
const product = data[0];
|
|
6407
6412
|
const variant2 = product.variants[0];
|
|
6408
6413
|
if (variant2.productId !== product.id) throw new Error("Foreign variant");
|
|
6409
6414
|
const groups = product.sellingPlanGroups;
|
|
6410
6415
|
const required = groups.map((group) => group.requiresSellingPlan);
|
|
6411
6416
|
if (required.some((flag) => flag !== required[0])) throw new Error("Conflicting requirement");
|
|
6412
|
-
const plans =
|
|
6417
|
+
const plans = hasLegacyPlanGroups(product) ? readPostPurchaseLegacyPlans(groups[0], variant2.id) : readPostPurchaseModernPlans(groups, variant2.sellingPlanAllocations);
|
|
6413
6418
|
const unique = /* @__PURE__ */ new Map();
|
|
6414
6419
|
for (const plan of plans) {
|
|
6415
6420
|
const previous = unique.get(plan.id);
|
|
@@ -6422,8 +6427,7 @@ var projectPostPurchasePlanCatalog = (normalized, report) => {
|
|
|
6422
6427
|
discountPercentage: postPurchasePlanDiscountPercentage(variant2.price, plan.adjustment)
|
|
6423
6428
|
})),
|
|
6424
6429
|
productId: product.id,
|
|
6425
|
-
|
|
6426
|
-
requiresSellingPlan: (required[0] ?? false) || product.requiresSellingPlan === true,
|
|
6430
|
+
requiresSellingPlan: (required[0] ?? false) || requiresOwnSellingPlan(product),
|
|
6427
6431
|
variantId: variant2.id
|
|
6428
6432
|
});
|
|
6429
6433
|
} catch {
|
|
@@ -6976,7 +6980,7 @@ var oneTimeUnavailable = (normalized, allowCollection, quantity3) => {
|
|
|
6976
6980
|
return "Only fixed one-time configuration is supported";
|
|
6977
6981
|
const product = data[0];
|
|
6978
6982
|
const variant2 = product.variants[0];
|
|
6979
|
-
if (product.productGroupVariants.length || product
|
|
6983
|
+
if (product.productGroupVariants.length || requiresOwnSellingPlan(product) || product.sellingPlanGroups?.some((group) => group.requiresSellingPlan))
|
|
6980
6984
|
return "A one-time variant without product groups or a required selling plan is required";
|
|
6981
6985
|
if (!postPurchaseVariantAvailable(variant2)) return VARIANT_UNAVAILABLE;
|
|
6982
6986
|
if (variant2.productId !== product.id) throw new Error("Product variant identity mismatch");
|
|
@@ -7647,7 +7651,7 @@ var reportUnreadableStsLine = (product, field, report) => {
|
|
|
7647
7651
|
};
|
|
7648
7652
|
var postPurchaseStsLine = (normalized, product, lines, variantId, report) => {
|
|
7649
7653
|
if (!product.sellingPlanGroups?.length || product.productGroupVariants.length) return void 0;
|
|
7650
|
-
const modern =
|
|
7654
|
+
const modern = !hasLegacyPlanGroups(product);
|
|
7651
7655
|
for (const [index, variant2] of product.variants.entries()) {
|
|
7652
7656
|
const matched = lines.filter((line) => line.sellingPlanId === void 0 && line.variantId === variant2.id);
|
|
7653
7657
|
const data = [{ ...product, variants: [variant2] }];
|
|
@@ -7655,7 +7659,7 @@ var postPurchaseStsLine = (normalized, product, lines, variantId, report) => {
|
|
|
7655
7659
|
const unread = [];
|
|
7656
7660
|
if (projectPostPurchasePlanCatalog({ ...normalized, data }, (event) => unread.push(event))?.plans.length)
|
|
7657
7661
|
return { data, line: matched[0] };
|
|
7658
|
-
const field = modern && !PostPurchasePlanAllocations.safeParse(variant2.sellingPlanAllocations).success ? `variants.${index}.sellingPlanAllocations` : unread.length ? "sellingPlanGroups" :
|
|
7662
|
+
const field = modern && !PostPurchasePlanAllocations.safeParse(variant2.sellingPlanAllocations).success ? `variants.${index}.sellingPlanAllocations` : !unread.length ? void 0 : variant2.productId === product.id ? "sellingPlanGroups" : `variants.${index}.productId`;
|
|
7659
7663
|
if (report && field) reportUnreadableStsLine(product, field, report);
|
|
7660
7664
|
}
|
|
7661
7665
|
}
|
|
@@ -8097,7 +8101,7 @@ var eligibility = (normalized, product, excluded) => {
|
|
|
8097
8101
|
if (product.productGroupVariants.length) {
|
|
8098
8102
|
const group = readPostPurchaseGroup(product, normalized.effective, excluded);
|
|
8099
8103
|
if (!group.entries.length) return void 0;
|
|
8100
|
-
return group.entries.map(({ product: option }) =>
|
|
8104
|
+
return group.entries.map(({ product: option }) => eligibility(normalized, option)).some(Boolean);
|
|
8101
8105
|
}
|
|
8102
8106
|
if (!product.variants.length) return false;
|
|
8103
8107
|
const variants = projectPostPurchaseVariantCatalog(product, normalized.effective).variants;
|
package/dist/server/index.mjs
CHANGED
|
@@ -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
|
|
12
|
-
var isUnsupportedType = (type = "") => UNSUPPORTED_RULE_TYPES.includes(type) || type.
|
|
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
|
|
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
|
|
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()).
|
|
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),
|
|
@@ -6119,6 +6119,10 @@ var reportOncePerResponse = (response, report, events) => {
|
|
|
6119
6119
|
}
|
|
6120
6120
|
};
|
|
6121
6121
|
|
|
6122
|
+
// src/server/postPurchaseSellingPlanRequirement.ts
|
|
6123
|
+
var requiresOwnSellingPlan = (product) => product.requiresSellingPlan === true;
|
|
6124
|
+
var requiresUnsuppliedSellingPlan = (product) => requiresOwnSellingPlan(product) && !product.sellingPlanGroups?.length;
|
|
6125
|
+
|
|
6122
6126
|
// src/server/readPostPurchaseProductSource.ts
|
|
6123
6127
|
var Envelope = PostPurchaseProductSource.extend({ data: z45.array(z45.unknown()) });
|
|
6124
6128
|
var Product3 = PostPurchaseProductSource.shape.data.element;
|
|
@@ -6131,9 +6135,9 @@ var readPostPurchaseProductSource = (response, report) => {
|
|
|
6131
6135
|
const parsed = Product3.safeParse(raw);
|
|
6132
6136
|
if (parsed.success) {
|
|
6133
6137
|
rememberPostPurchaseProductSource(parsed.data, response, productIndex);
|
|
6134
|
-
if (parsed.data
|
|
6138
|
+
if (requiresUnsuppliedSellingPlan(parsed.data))
|
|
6135
6139
|
drift.push({
|
|
6136
|
-
detail: `
|
|
6140
|
+
detail: `Ineligible post-purchase product ${parsed.data.id}: data.${productIndex}.requiresSellingPlan`,
|
|
6137
6141
|
kind: "product"
|
|
6138
6142
|
});
|
|
6139
6143
|
return [{ product: parsed.data, productIndex }];
|
|
@@ -6324,19 +6328,20 @@ var readPostPurchaseModernPlans = (raw, allocations) => {
|
|
|
6324
6328
|
};
|
|
6325
6329
|
|
|
6326
6330
|
// src/server/postPurchasePlanCatalog.ts
|
|
6331
|
+
var hasLegacyPlanGroups = ({ sellingPlanGroups }) => typeof sellingPlanGroups[0]?.id === "number";
|
|
6327
6332
|
var projectPostPurchasePlanCatalog = (normalized, report) => {
|
|
6328
6333
|
const { data } = normalized;
|
|
6329
|
-
if (data.length === 1 && data[0].variants.length > 1) return null;
|
|
6330
6334
|
if (normalized.emptiedByDrop && !data.length) return null;
|
|
6335
|
+
if (data.length === 1 && data[0].variants.length > 1) return null;
|
|
6331
6336
|
try {
|
|
6332
|
-
if (data.length !== 1 || data[0].variants.length !== 1) throw new Error("
|
|
6337
|
+
if (data.length !== 1 || data[0].variants.length !== 1) throw new Error("No single product and variant");
|
|
6333
6338
|
const product = data[0];
|
|
6334
6339
|
const variant2 = product.variants[0];
|
|
6335
6340
|
if (variant2.productId !== product.id) throw new Error("Foreign variant");
|
|
6336
6341
|
const groups = product.sellingPlanGroups;
|
|
6337
6342
|
const required = groups.map((group) => group.requiresSellingPlan);
|
|
6338
6343
|
if (required.some((flag) => flag !== required[0])) throw new Error("Conflicting requirement");
|
|
6339
|
-
const plans =
|
|
6344
|
+
const plans = hasLegacyPlanGroups(product) ? readPostPurchaseLegacyPlans(groups[0], variant2.id) : readPostPurchaseModernPlans(groups, variant2.sellingPlanAllocations);
|
|
6340
6345
|
const unique = /* @__PURE__ */ new Map();
|
|
6341
6346
|
for (const plan of plans) {
|
|
6342
6347
|
const previous = unique.get(plan.id);
|
|
@@ -6349,8 +6354,7 @@ var projectPostPurchasePlanCatalog = (normalized, report) => {
|
|
|
6349
6354
|
discountPercentage: postPurchasePlanDiscountPercentage(variant2.price, plan.adjustment)
|
|
6350
6355
|
})),
|
|
6351
6356
|
productId: product.id,
|
|
6352
|
-
|
|
6353
|
-
requiresSellingPlan: (required[0] ?? false) || product.requiresSellingPlan === true,
|
|
6357
|
+
requiresSellingPlan: (required[0] ?? false) || requiresOwnSellingPlan(product),
|
|
6354
6358
|
variantId: variant2.id
|
|
6355
6359
|
});
|
|
6356
6360
|
} catch {
|
|
@@ -6903,7 +6907,7 @@ var oneTimeUnavailable = (normalized, allowCollection, quantity3) => {
|
|
|
6903
6907
|
return "Only fixed one-time configuration is supported";
|
|
6904
6908
|
const product = data[0];
|
|
6905
6909
|
const variant2 = product.variants[0];
|
|
6906
|
-
if (product.productGroupVariants.length || product
|
|
6910
|
+
if (product.productGroupVariants.length || requiresOwnSellingPlan(product) || product.sellingPlanGroups?.some((group) => group.requiresSellingPlan))
|
|
6907
6911
|
return "A one-time variant without product groups or a required selling plan is required";
|
|
6908
6912
|
if (!postPurchaseVariantAvailable(variant2)) return VARIANT_UNAVAILABLE;
|
|
6909
6913
|
if (variant2.productId !== product.id) throw new Error("Product variant identity mismatch");
|
|
@@ -7574,7 +7578,7 @@ var reportUnreadableStsLine = (product, field, report) => {
|
|
|
7574
7578
|
};
|
|
7575
7579
|
var postPurchaseStsLine = (normalized, product, lines, variantId, report) => {
|
|
7576
7580
|
if (!product.sellingPlanGroups?.length || product.productGroupVariants.length) return void 0;
|
|
7577
|
-
const modern =
|
|
7581
|
+
const modern = !hasLegacyPlanGroups(product);
|
|
7578
7582
|
for (const [index, variant2] of product.variants.entries()) {
|
|
7579
7583
|
const matched = lines.filter((line) => line.sellingPlanId === void 0 && line.variantId === variant2.id);
|
|
7580
7584
|
const data = [{ ...product, variants: [variant2] }];
|
|
@@ -7582,7 +7586,7 @@ var postPurchaseStsLine = (normalized, product, lines, variantId, report) => {
|
|
|
7582
7586
|
const unread = [];
|
|
7583
7587
|
if (projectPostPurchasePlanCatalog({ ...normalized, data }, (event) => unread.push(event))?.plans.length)
|
|
7584
7588
|
return { data, line: matched[0] };
|
|
7585
|
-
const field = modern && !PostPurchasePlanAllocations.safeParse(variant2.sellingPlanAllocations).success ? `variants.${index}.sellingPlanAllocations` : unread.length ? "sellingPlanGroups" :
|
|
7589
|
+
const field = modern && !PostPurchasePlanAllocations.safeParse(variant2.sellingPlanAllocations).success ? `variants.${index}.sellingPlanAllocations` : !unread.length ? void 0 : variant2.productId === product.id ? "sellingPlanGroups" : `variants.${index}.productId`;
|
|
7586
7590
|
if (report && field) reportUnreadableStsLine(product, field, report);
|
|
7587
7591
|
}
|
|
7588
7592
|
}
|
|
@@ -8024,7 +8028,7 @@ var eligibility = (normalized, product, excluded) => {
|
|
|
8024
8028
|
if (product.productGroupVariants.length) {
|
|
8025
8029
|
const group = readPostPurchaseGroup(product, normalized.effective, excluded);
|
|
8026
8030
|
if (!group.entries.length) return void 0;
|
|
8027
|
-
return group.entries.map(({ product: option }) =>
|
|
8031
|
+
return group.entries.map(({ product: option }) => eligibility(normalized, option)).some(Boolean);
|
|
8028
8032
|
}
|
|
8029
8033
|
if (!product.variants.length) return false;
|
|
8030
8034
|
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
|
package/dist/server/shared.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* request still succeeds (degraded), so this is the only trace that an upstream
|
|
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,7 +55,10 @@ export declare const isEmptyObject: (x: unknown) => boolean;
|
|
|
55
55
|
export type ServerContext = {
|
|
56
56
|
fetchUpstream: UpstreamFetch;
|
|
57
57
|
host: string;
|
|
58
|
-
/**
|
|
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;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebuy/rebuy",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.58.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.",
|