@rebuy/rebuy 3.56.2 → 3.56.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +9 -1
- package/dist/index.mjs +9 -1
- package/dist/schema/postPurchaseOfferEligibility.d.ts +19 -1
- package/dist/server/index.cjs +39 -28
- package/dist/server/index.mjs +39 -28
- package/dist/server/normalizePostPurchaseCollection.d.ts +3 -0
- package/dist/server/postPurchaseMemberEligibility.d.ts +11 -5
- package/dist/server/postPurchaseVariantCatalog.d.ts +6 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -206,6 +206,7 @@ __export(src_exports, {
|
|
|
206
206
|
PostPurchaseOfferEligibilityContext: () => PostPurchaseOfferEligibilityContext,
|
|
207
207
|
PostPurchaseOfferPresentation: () => PostPurchaseOfferPresentation,
|
|
208
208
|
PostPurchaseOfferSkipReason: () => PostPurchaseOfferSkipReason,
|
|
209
|
+
PostPurchaseOfferUnavailableReason: () => PostPurchaseOfferUnavailableReason,
|
|
209
210
|
PostPurchaseOptions: () => PostPurchaseOptions,
|
|
210
211
|
PostPurchaseOrderAttributes: () => PostPurchaseOrderAttributes,
|
|
211
212
|
PostPurchaseOrderIdSchema: () => PostPurchaseOrderIdSchema,
|
|
@@ -4792,6 +4793,12 @@ var OfferPreparationResponseSchema = import_zod77.z.object({
|
|
|
4792
4793
|
var import_zod78 = require("zod");
|
|
4793
4794
|
var selection2 = PreparedPostPurchaseProduct.shape.selection;
|
|
4794
4795
|
var PostPurchaseOfferSkipReason = import_zod78.z.enum(["empty", "no-eligible-subscription"]);
|
|
4796
|
+
var PostPurchaseOfferUnavailableReason = import_zod78.z.enum([
|
|
4797
|
+
"catalog-unreadable",
|
|
4798
|
+
"context-unreadable",
|
|
4799
|
+
"eligible-sts",
|
|
4800
|
+
"settings-unreadable"
|
|
4801
|
+
]);
|
|
4795
4802
|
var PostPurchaseOfferEligibilityContext = import_zod78.z.object({
|
|
4796
4803
|
excludedProductIds: PostPurchaseExcludedProductIds,
|
|
4797
4804
|
originalLineItems: import_zod78.z.array(selection2.pick({ productId: true, sellingPlanId: true, variantId: true }))
|
|
@@ -4812,7 +4819,8 @@ var PostPurchaseOfferEligibility = import_zod78.z.discriminatedUnion("status", [
|
|
|
4812
4819
|
status: import_zod78.z.literal("retain")
|
|
4813
4820
|
}),
|
|
4814
4821
|
import_zod78.z.object({ reason: PostPurchaseOfferSkipReason, status: import_zod78.z.literal("skip") }),
|
|
4815
|
-
|
|
4822
|
+
/** The classifier always names a reason; it stays optional so a reasonless answer from before still parses. */
|
|
4823
|
+
import_zod78.z.object({ reason: PostPurchaseOfferUnavailableReason.optional(), status: import_zod78.z.literal("unavailable") })
|
|
4816
4824
|
]);
|
|
4817
4825
|
|
|
4818
4826
|
// src/schema/postPurchaseOfferPresentation.ts
|
package/dist/index.mjs
CHANGED
|
@@ -4313,6 +4313,12 @@ var OfferPreparationResponseSchema = z77.object({
|
|
|
4313
4313
|
import { z as z78 } from "zod";
|
|
4314
4314
|
var selection2 = PreparedPostPurchaseProduct.shape.selection;
|
|
4315
4315
|
var PostPurchaseOfferSkipReason = z78.enum(["empty", "no-eligible-subscription"]);
|
|
4316
|
+
var PostPurchaseOfferUnavailableReason = z78.enum([
|
|
4317
|
+
"catalog-unreadable",
|
|
4318
|
+
"context-unreadable",
|
|
4319
|
+
"eligible-sts",
|
|
4320
|
+
"settings-unreadable"
|
|
4321
|
+
]);
|
|
4316
4322
|
var PostPurchaseOfferEligibilityContext = z78.object({
|
|
4317
4323
|
excludedProductIds: PostPurchaseExcludedProductIds,
|
|
4318
4324
|
originalLineItems: z78.array(selection2.pick({ productId: true, sellingPlanId: true, variantId: true }))
|
|
@@ -4333,7 +4339,8 @@ var PostPurchaseOfferEligibility = z78.discriminatedUnion("status", [
|
|
|
4333
4339
|
status: z78.literal("retain")
|
|
4334
4340
|
}),
|
|
4335
4341
|
z78.object({ reason: PostPurchaseOfferSkipReason, status: z78.literal("skip") }),
|
|
4336
|
-
|
|
4342
|
+
/** The classifier always names a reason; it stays optional so a reasonless answer from before still parses. */
|
|
4343
|
+
z78.object({ reason: PostPurchaseOfferUnavailableReason.optional(), status: z78.literal("unavailable") })
|
|
4337
4344
|
]);
|
|
4338
4345
|
|
|
4339
4346
|
// src/schema/postPurchaseOfferPresentation.ts
|
|
@@ -6772,6 +6779,7 @@ export {
|
|
|
6772
6779
|
PostPurchaseOfferEligibilityContext,
|
|
6773
6780
|
PostPurchaseOfferPresentation,
|
|
6774
6781
|
PostPurchaseOfferSkipReason,
|
|
6782
|
+
PostPurchaseOfferUnavailableReason,
|
|
6775
6783
|
PostPurchaseOptions,
|
|
6776
6784
|
PostPurchaseOrderAttributes,
|
|
6777
6785
|
PostPurchaseOrderIdSchema,
|
|
@@ -3,6 +3,19 @@ export declare const PostPurchaseOfferSkipReason: z.ZodEnum<{
|
|
|
3
3
|
empty: "empty";
|
|
4
4
|
"no-eligible-subscription": "no-eligible-subscription";
|
|
5
5
|
}>;
|
|
6
|
+
/**
|
|
7
|
+
* Why an Offer could not be classified (REB-25054). `eligible-sts` is an STS candidate classified without the STS
|
|
8
|
+
* opt-in; each other reason names what was unreadable: the caller's context, the merchant's settings, or the
|
|
9
|
+
* catalog (the data source's products, or its metadata overrides). An ordinary product reason (sold out,
|
|
10
|
+
* plan-only, no variants, undeclared options) never answers `unavailable`: that member is ineligible instead.
|
|
11
|
+
*/
|
|
12
|
+
export declare const PostPurchaseOfferUnavailableReason: z.ZodEnum<{
|
|
13
|
+
"catalog-unreadable": "catalog-unreadable";
|
|
14
|
+
"context-unreadable": "context-unreadable";
|
|
15
|
+
"eligible-sts": "eligible-sts";
|
|
16
|
+
"settings-unreadable": "settings-unreadable";
|
|
17
|
+
}>;
|
|
18
|
+
export type PostPurchaseOfferUnavailableReason = z.infer<typeof PostPurchaseOfferUnavailableReason>;
|
|
6
19
|
export declare const PostPurchaseOfferEligibilityContext: z.ZodObject<{
|
|
7
20
|
excludedProductIds: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
|
|
8
21
|
originalLineItems: z.ZodArray<z.ZodObject<{
|
|
@@ -49,7 +62,12 @@ export declare const PostPurchaseOfferEligibility: z.ZodDiscriminatedUnion<[z.Zo
|
|
|
49
62
|
}>;
|
|
50
63
|
status: z.ZodLiteral<"skip">;
|
|
51
64
|
}, z.core.$strip>, z.ZodObject<{
|
|
52
|
-
reason: z.ZodOptional<z.
|
|
65
|
+
reason: z.ZodOptional<z.ZodEnum<{
|
|
66
|
+
"catalog-unreadable": "catalog-unreadable";
|
|
67
|
+
"context-unreadable": "context-unreadable";
|
|
68
|
+
"eligible-sts": "eligible-sts";
|
|
69
|
+
"settings-unreadable": "settings-unreadable";
|
|
70
|
+
}>>;
|
|
53
71
|
status: z.ZodLiteral<"unavailable">;
|
|
54
72
|
}, z.core.$strip>], "status">;
|
|
55
73
|
export type PostPurchaseOfferEligibility = z.infer<typeof PostPurchaseOfferEligibility>;
|
package/dist/server/index.cjs
CHANGED
|
@@ -7501,11 +7501,11 @@ var PostPurchaseMemberPointer = PostPurchaseProgressSchema.shape.members.element
|
|
|
7501
7501
|
|
|
7502
7502
|
// src/server/normalizePostPurchaseCollection.ts
|
|
7503
7503
|
var import_zod82 = require("zod");
|
|
7504
|
+
var PostPurchaseProductLimit = import_zod82.z.number().int().positive();
|
|
7504
7505
|
var normalizePostPurchaseCollection = (settings, response, excludedProductIds, report) => {
|
|
7505
7506
|
const { dropped, normalized, products } = normalizePostPurchaseSource(settings, response, report);
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
const cap = limit.parse(normalized.effective.productLimit);
|
|
7507
|
+
PostPurchaseProductLimit.parse(normalized.original.productLimit);
|
|
7508
|
+
const cap = PostPurchaseProductLimit.parse(normalized.effective.productLimit);
|
|
7509
7509
|
const prefix = underPostPurchaseCap(products, cap);
|
|
7510
7510
|
const unread = underPostPurchaseCap(dropped, cap);
|
|
7511
7511
|
if (unread.length && !prefix.length) throw new import_zod82.ZodError(unread.flatMap(({ issues }) => issues));
|
|
@@ -7517,6 +7517,8 @@ var normalizePostPurchaseCollection = (settings, response, excludedProductIds, r
|
|
|
7517
7517
|
};
|
|
7518
7518
|
|
|
7519
7519
|
// src/server/postPurchaseVariantCatalog.ts
|
|
7520
|
+
var PostPurchaseVariantOptionMismatch = class extends Error {
|
|
7521
|
+
};
|
|
7520
7522
|
var projectPostPurchaseVariantCatalog = (product, settings) => {
|
|
7521
7523
|
const options2 = PostPurchaseVariantCatalog.shape.options.parse(product.options === void 0 ? [] : product.options).sort((a, b) => a.position - b.position);
|
|
7522
7524
|
const variants = product.variants.map((variant2) => ({
|
|
@@ -7530,7 +7532,7 @@ var projectPostPurchaseVariantCatalog = (product, settings) => {
|
|
|
7530
7532
|
throw new Error("Ambiguous post-purchase variant catalog");
|
|
7531
7533
|
for (const tuple of tuples) {
|
|
7532
7534
|
if (options2.some(({ position, values: values2 }) => !values2.some((value) => value === tuple[position - 1])) || tuple.some((value, index) => value != null && !options2[index]))
|
|
7533
|
-
throw new
|
|
7535
|
+
throw new PostPurchaseVariantOptionMismatch("Variant option tuple does not match the catalog");
|
|
7534
7536
|
}
|
|
7535
7537
|
return PostPurchaseVariantCatalog.parse({
|
|
7536
7538
|
displayMode: settings.productOptions.variantSelectorDisplayMode,
|
|
@@ -7553,6 +7555,12 @@ var projectPostPurchaseVariantCatalog = (product, settings) => {
|
|
|
7553
7555
|
var import_zod83 = require("zod");
|
|
7554
7556
|
var selection2 = PreparedPostPurchaseProduct.shape.selection;
|
|
7555
7557
|
var PostPurchaseOfferSkipReason = import_zod83.z.enum(["empty", "no-eligible-subscription"]);
|
|
7558
|
+
var PostPurchaseOfferUnavailableReason = import_zod83.z.enum([
|
|
7559
|
+
"catalog-unreadable",
|
|
7560
|
+
"context-unreadable",
|
|
7561
|
+
"eligible-sts",
|
|
7562
|
+
"settings-unreadable"
|
|
7563
|
+
]);
|
|
7556
7564
|
var PostPurchaseOfferEligibilityContext = import_zod83.z.object({
|
|
7557
7565
|
excludedProductIds: PostPurchaseExcludedProductIds,
|
|
7558
7566
|
originalLineItems: import_zod83.z.array(selection2.pick({ productId: true, sellingPlanId: true, variantId: true }))
|
|
@@ -7573,7 +7581,8 @@ var PostPurchaseOfferEligibility = import_zod83.z.discriminatedUnion("status", [
|
|
|
7573
7581
|
status: import_zod83.z.literal("retain")
|
|
7574
7582
|
}),
|
|
7575
7583
|
import_zod83.z.object({ reason: PostPurchaseOfferSkipReason, status: import_zod83.z.literal("skip") }),
|
|
7576
|
-
|
|
7584
|
+
/** The classifier always names a reason; it stays optional so a reasonless answer from before still parses. */
|
|
7585
|
+
import_zod83.z.object({ reason: PostPurchaseOfferUnavailableReason.optional(), status: import_zod83.z.literal("unavailable") })
|
|
7577
7586
|
]);
|
|
7578
7587
|
|
|
7579
7588
|
// src/schema/postPurchaseQuantity.ts
|
|
@@ -8057,14 +8066,13 @@ var preparePostPurchaseCollectionView = (widgetId, settings, response, report, r
|
|
|
8057
8066
|
};
|
|
8058
8067
|
|
|
8059
8068
|
// src/server/postPurchaseMemberEligibility.ts
|
|
8060
|
-
var
|
|
8061
|
-
};
|
|
8062
|
-
var postPurchaseMemberEligibility = (normalized, product, excluded) => {
|
|
8069
|
+
var eligibility = (normalized, product, excluded) => {
|
|
8063
8070
|
if (product.productGroupVariants.length) {
|
|
8064
8071
|
const group = readPostPurchaseGroup(product, normalized.effective, excluded);
|
|
8072
|
+
if (!group.entries.length) return void 0;
|
|
8065
8073
|
return group.entries.map(({ product: option }) => postPurchaseMemberEligibility(normalized, option)).some(Boolean);
|
|
8066
8074
|
}
|
|
8067
|
-
if (!product.variants.length)
|
|
8075
|
+
if (!product.variants.length) return false;
|
|
8068
8076
|
const variants = projectPostPurchaseVariantCatalog(product, normalized.effective).variants;
|
|
8069
8077
|
const catalogs = product.variants.map((variant2) => {
|
|
8070
8078
|
const catalog = projectPostPurchasePlanCatalog({
|
|
@@ -8072,23 +8080,31 @@ var postPurchaseMemberEligibility = (normalized, product, excluded) => {
|
|
|
8072
8080
|
data: [{ ...product, variants: [variant2] }]
|
|
8073
8081
|
});
|
|
8074
8082
|
if (!catalog) throw new Error("Unreadable subscription catalog");
|
|
8075
|
-
if (normalized.effective.productType === "one-time" && product.sellingPlanGroups.some((group) => group.requiresSellingPlan))
|
|
8076
|
-
throw new Error("Unsupported purchase mode");
|
|
8077
8083
|
return catalog;
|
|
8078
8084
|
});
|
|
8079
|
-
if (!variants.some((variant2) => variant2.available))
|
|
8080
|
-
throw new PostPurchaseInventoryUnavailable("Unavailable inventory");
|
|
8081
8085
|
return catalogs.some(
|
|
8082
8086
|
(catalog, index) => variants[index].available && (normalized.effective.productType !== "subscription" && !catalog.requiresSellingPlan || normalized.effective.productType !== "one-time" && catalog.plans.length > 0)
|
|
8083
8087
|
);
|
|
8084
8088
|
};
|
|
8089
|
+
var postPurchaseMemberEligibility = (normalized, product, excluded) => {
|
|
8090
|
+
try {
|
|
8091
|
+
return eligibility(normalized, product, excluded);
|
|
8092
|
+
} catch (error) {
|
|
8093
|
+
if (error instanceof PostPurchaseVariantOptionMismatch) return false;
|
|
8094
|
+
throw error;
|
|
8095
|
+
}
|
|
8096
|
+
};
|
|
8085
8097
|
|
|
8086
8098
|
// src/server/classifyPostPurchaseOffer.ts
|
|
8087
8099
|
var identities = (members) => members.map(({ product, productIndex }) => ({ productId: product.id, productIndex }));
|
|
8088
8100
|
var classifyPostPurchaseOffer = (settings, response, context, options2) => {
|
|
8101
|
+
let unreadable = "context-unreadable";
|
|
8089
8102
|
try {
|
|
8090
8103
|
const trusted = PostPurchaseOfferEligibilityContext.parse(context);
|
|
8091
8104
|
const { sts: stsMode = false } = PostPurchaseStsOptions.parse(options2 ?? {});
|
|
8105
|
+
unreadable = "settings-unreadable";
|
|
8106
|
+
PostPurchaseProductLimit.parse(PostPurchaseProductSettings.parse(deepCamelCase(settings)).productLimit);
|
|
8107
|
+
unreadable = "catalog-unreadable";
|
|
8092
8108
|
const { members, normalized } = normalizePostPurchaseCollection(settings, response);
|
|
8093
8109
|
const configurations = [normalized.original, normalized.effective];
|
|
8094
8110
|
const stsEnabled = configurations.some((config) => config.upgradeToSubscription.allow);
|
|
@@ -8101,33 +8117,28 @@ var classifyPostPurchaseOffer = (settings, response, context, options2) => {
|
|
|
8101
8117
|
))
|
|
8102
8118
|
return { reason: "eligible-sts", status: "unavailable" };
|
|
8103
8119
|
if (normalized.effective.productType !== "one-time" || sts) {
|
|
8104
|
-
|
|
8120
|
+
unreadable = "settings-unreadable";
|
|
8121
|
+
PostPurchaseSubscriptionSettings.parse(normalized.original.subscription);
|
|
8122
|
+
unreadable = "catalog-unreadable";
|
|
8123
|
+
PostPurchaseSubscriptionSettings.parse(normalized.effective.subscription);
|
|
8105
8124
|
}
|
|
8106
8125
|
const lines = trusted.originalLineItems;
|
|
8107
8126
|
const stsMembers = sts ? members.filter(({ product }) => postPurchaseStsLine(normalized, product, lines)) : [];
|
|
8108
8127
|
if (stsMembers.length) return { members: identities(stsMembers), mode: "sts", status: "retain" };
|
|
8109
|
-
const classified = members.map((member) => {
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
eligible: postPurchaseMemberEligibility(normalized, member.product, trusted.excludedProductIds)
|
|
8114
|
-
};
|
|
8115
|
-
} catch (error) {
|
|
8116
|
-
if (error instanceof PostPurchaseInventoryUnavailable && !member.product.productGroupVariants.length && trusted.excludedProductIds.includes(member.product.id))
|
|
8117
|
-
return { ...member, eligible: false };
|
|
8118
|
-
throw error;
|
|
8119
|
-
}
|
|
8120
|
-
});
|
|
8128
|
+
const classified = members.map((member) => ({
|
|
8129
|
+
...member,
|
|
8130
|
+
eligible: postPurchaseMemberEligibility(normalized, member.product, trusted.excludedProductIds)
|
|
8131
|
+
}));
|
|
8121
8132
|
if (!members.length) return { reason: "empty", status: "skip" };
|
|
8122
8133
|
if (stsEnabled) return { reason: "no-eligible-subscription", status: "skip" };
|
|
8123
8134
|
const candidates = classified.filter(
|
|
8124
|
-
({ product }) => product.productGroupVariants.length ?
|
|
8135
|
+
({ eligible, product }) => product.productGroupVariants.length ? eligible !== void 0 : !trusted.excludedProductIds.includes(product.id)
|
|
8125
8136
|
);
|
|
8126
8137
|
if (!candidates.length) return { reason: "empty", status: "skip" };
|
|
8127
8138
|
const retained = candidates.filter(({ eligible }) => eligible);
|
|
8128
8139
|
return retained.length ? { members: identities(retained), status: "retain" } : { reason: "no-eligible-subscription", status: "skip" };
|
|
8129
8140
|
} catch {
|
|
8130
|
-
return { status: "unavailable" };
|
|
8141
|
+
return { reason: unreadable, status: "unavailable" };
|
|
8131
8142
|
}
|
|
8132
8143
|
};
|
|
8133
8144
|
|
package/dist/server/index.mjs
CHANGED
|
@@ -7428,11 +7428,11 @@ var PostPurchaseMemberPointer = PostPurchaseProgressSchema.shape.members.element
|
|
|
7428
7428
|
|
|
7429
7429
|
// src/server/normalizePostPurchaseCollection.ts
|
|
7430
7430
|
import { z as z82, ZodError } from "zod";
|
|
7431
|
+
var PostPurchaseProductLimit = z82.number().int().positive();
|
|
7431
7432
|
var normalizePostPurchaseCollection = (settings, response, excludedProductIds, report) => {
|
|
7432
7433
|
const { dropped, normalized, products } = normalizePostPurchaseSource(settings, response, report);
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
const cap = limit.parse(normalized.effective.productLimit);
|
|
7434
|
+
PostPurchaseProductLimit.parse(normalized.original.productLimit);
|
|
7435
|
+
const cap = PostPurchaseProductLimit.parse(normalized.effective.productLimit);
|
|
7436
7436
|
const prefix = underPostPurchaseCap(products, cap);
|
|
7437
7437
|
const unread = underPostPurchaseCap(dropped, cap);
|
|
7438
7438
|
if (unread.length && !prefix.length) throw new ZodError(unread.flatMap(({ issues }) => issues));
|
|
@@ -7444,6 +7444,8 @@ var normalizePostPurchaseCollection = (settings, response, excludedProductIds, r
|
|
|
7444
7444
|
};
|
|
7445
7445
|
|
|
7446
7446
|
// src/server/postPurchaseVariantCatalog.ts
|
|
7447
|
+
var PostPurchaseVariantOptionMismatch = class extends Error {
|
|
7448
|
+
};
|
|
7447
7449
|
var projectPostPurchaseVariantCatalog = (product, settings) => {
|
|
7448
7450
|
const options2 = PostPurchaseVariantCatalog.shape.options.parse(product.options === void 0 ? [] : product.options).sort((a, b) => a.position - b.position);
|
|
7449
7451
|
const variants = product.variants.map((variant2) => ({
|
|
@@ -7457,7 +7459,7 @@ var projectPostPurchaseVariantCatalog = (product, settings) => {
|
|
|
7457
7459
|
throw new Error("Ambiguous post-purchase variant catalog");
|
|
7458
7460
|
for (const tuple of tuples) {
|
|
7459
7461
|
if (options2.some(({ position, values: values2 }) => !values2.some((value) => value === tuple[position - 1])) || tuple.some((value, index) => value != null && !options2[index]))
|
|
7460
|
-
throw new
|
|
7462
|
+
throw new PostPurchaseVariantOptionMismatch("Variant option tuple does not match the catalog");
|
|
7461
7463
|
}
|
|
7462
7464
|
return PostPurchaseVariantCatalog.parse({
|
|
7463
7465
|
displayMode: settings.productOptions.variantSelectorDisplayMode,
|
|
@@ -7480,6 +7482,12 @@ var projectPostPurchaseVariantCatalog = (product, settings) => {
|
|
|
7480
7482
|
import { z as z83 } from "zod";
|
|
7481
7483
|
var selection2 = PreparedPostPurchaseProduct.shape.selection;
|
|
7482
7484
|
var PostPurchaseOfferSkipReason = z83.enum(["empty", "no-eligible-subscription"]);
|
|
7485
|
+
var PostPurchaseOfferUnavailableReason = z83.enum([
|
|
7486
|
+
"catalog-unreadable",
|
|
7487
|
+
"context-unreadable",
|
|
7488
|
+
"eligible-sts",
|
|
7489
|
+
"settings-unreadable"
|
|
7490
|
+
]);
|
|
7483
7491
|
var PostPurchaseOfferEligibilityContext = z83.object({
|
|
7484
7492
|
excludedProductIds: PostPurchaseExcludedProductIds,
|
|
7485
7493
|
originalLineItems: z83.array(selection2.pick({ productId: true, sellingPlanId: true, variantId: true }))
|
|
@@ -7500,7 +7508,8 @@ var PostPurchaseOfferEligibility = z83.discriminatedUnion("status", [
|
|
|
7500
7508
|
status: z83.literal("retain")
|
|
7501
7509
|
}),
|
|
7502
7510
|
z83.object({ reason: PostPurchaseOfferSkipReason, status: z83.literal("skip") }),
|
|
7503
|
-
|
|
7511
|
+
/** The classifier always names a reason; it stays optional so a reasonless answer from before still parses. */
|
|
7512
|
+
z83.object({ reason: PostPurchaseOfferUnavailableReason.optional(), status: z83.literal("unavailable") })
|
|
7504
7513
|
]);
|
|
7505
7514
|
|
|
7506
7515
|
// src/schema/postPurchaseQuantity.ts
|
|
@@ -7984,14 +7993,13 @@ var preparePostPurchaseCollectionView = (widgetId, settings, response, report, r
|
|
|
7984
7993
|
};
|
|
7985
7994
|
|
|
7986
7995
|
// src/server/postPurchaseMemberEligibility.ts
|
|
7987
|
-
var
|
|
7988
|
-
};
|
|
7989
|
-
var postPurchaseMemberEligibility = (normalized, product, excluded) => {
|
|
7996
|
+
var eligibility = (normalized, product, excluded) => {
|
|
7990
7997
|
if (product.productGroupVariants.length) {
|
|
7991
7998
|
const group = readPostPurchaseGroup(product, normalized.effective, excluded);
|
|
7999
|
+
if (!group.entries.length) return void 0;
|
|
7992
8000
|
return group.entries.map(({ product: option }) => postPurchaseMemberEligibility(normalized, option)).some(Boolean);
|
|
7993
8001
|
}
|
|
7994
|
-
if (!product.variants.length)
|
|
8002
|
+
if (!product.variants.length) return false;
|
|
7995
8003
|
const variants = projectPostPurchaseVariantCatalog(product, normalized.effective).variants;
|
|
7996
8004
|
const catalogs = product.variants.map((variant2) => {
|
|
7997
8005
|
const catalog = projectPostPurchasePlanCatalog({
|
|
@@ -7999,23 +8007,31 @@ var postPurchaseMemberEligibility = (normalized, product, excluded) => {
|
|
|
7999
8007
|
data: [{ ...product, variants: [variant2] }]
|
|
8000
8008
|
});
|
|
8001
8009
|
if (!catalog) throw new Error("Unreadable subscription catalog");
|
|
8002
|
-
if (normalized.effective.productType === "one-time" && product.sellingPlanGroups.some((group) => group.requiresSellingPlan))
|
|
8003
|
-
throw new Error("Unsupported purchase mode");
|
|
8004
8010
|
return catalog;
|
|
8005
8011
|
});
|
|
8006
|
-
if (!variants.some((variant2) => variant2.available))
|
|
8007
|
-
throw new PostPurchaseInventoryUnavailable("Unavailable inventory");
|
|
8008
8012
|
return catalogs.some(
|
|
8009
8013
|
(catalog, index) => variants[index].available && (normalized.effective.productType !== "subscription" && !catalog.requiresSellingPlan || normalized.effective.productType !== "one-time" && catalog.plans.length > 0)
|
|
8010
8014
|
);
|
|
8011
8015
|
};
|
|
8016
|
+
var postPurchaseMemberEligibility = (normalized, product, excluded) => {
|
|
8017
|
+
try {
|
|
8018
|
+
return eligibility(normalized, product, excluded);
|
|
8019
|
+
} catch (error) {
|
|
8020
|
+
if (error instanceof PostPurchaseVariantOptionMismatch) return false;
|
|
8021
|
+
throw error;
|
|
8022
|
+
}
|
|
8023
|
+
};
|
|
8012
8024
|
|
|
8013
8025
|
// src/server/classifyPostPurchaseOffer.ts
|
|
8014
8026
|
var identities = (members) => members.map(({ product, productIndex }) => ({ productId: product.id, productIndex }));
|
|
8015
8027
|
var classifyPostPurchaseOffer = (settings, response, context, options2) => {
|
|
8028
|
+
let unreadable = "context-unreadable";
|
|
8016
8029
|
try {
|
|
8017
8030
|
const trusted = PostPurchaseOfferEligibilityContext.parse(context);
|
|
8018
8031
|
const { sts: stsMode = false } = PostPurchaseStsOptions.parse(options2 ?? {});
|
|
8032
|
+
unreadable = "settings-unreadable";
|
|
8033
|
+
PostPurchaseProductLimit.parse(PostPurchaseProductSettings.parse(deepCamelCase(settings)).productLimit);
|
|
8034
|
+
unreadable = "catalog-unreadable";
|
|
8019
8035
|
const { members, normalized } = normalizePostPurchaseCollection(settings, response);
|
|
8020
8036
|
const configurations = [normalized.original, normalized.effective];
|
|
8021
8037
|
const stsEnabled = configurations.some((config) => config.upgradeToSubscription.allow);
|
|
@@ -8028,33 +8044,28 @@ var classifyPostPurchaseOffer = (settings, response, context, options2) => {
|
|
|
8028
8044
|
))
|
|
8029
8045
|
return { reason: "eligible-sts", status: "unavailable" };
|
|
8030
8046
|
if (normalized.effective.productType !== "one-time" || sts) {
|
|
8031
|
-
|
|
8047
|
+
unreadable = "settings-unreadable";
|
|
8048
|
+
PostPurchaseSubscriptionSettings.parse(normalized.original.subscription);
|
|
8049
|
+
unreadable = "catalog-unreadable";
|
|
8050
|
+
PostPurchaseSubscriptionSettings.parse(normalized.effective.subscription);
|
|
8032
8051
|
}
|
|
8033
8052
|
const lines = trusted.originalLineItems;
|
|
8034
8053
|
const stsMembers = sts ? members.filter(({ product }) => postPurchaseStsLine(normalized, product, lines)) : [];
|
|
8035
8054
|
if (stsMembers.length) return { members: identities(stsMembers), mode: "sts", status: "retain" };
|
|
8036
|
-
const classified = members.map((member) => {
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
eligible: postPurchaseMemberEligibility(normalized, member.product, trusted.excludedProductIds)
|
|
8041
|
-
};
|
|
8042
|
-
} catch (error) {
|
|
8043
|
-
if (error instanceof PostPurchaseInventoryUnavailable && !member.product.productGroupVariants.length && trusted.excludedProductIds.includes(member.product.id))
|
|
8044
|
-
return { ...member, eligible: false };
|
|
8045
|
-
throw error;
|
|
8046
|
-
}
|
|
8047
|
-
});
|
|
8055
|
+
const classified = members.map((member) => ({
|
|
8056
|
+
...member,
|
|
8057
|
+
eligible: postPurchaseMemberEligibility(normalized, member.product, trusted.excludedProductIds)
|
|
8058
|
+
}));
|
|
8048
8059
|
if (!members.length) return { reason: "empty", status: "skip" };
|
|
8049
8060
|
if (stsEnabled) return { reason: "no-eligible-subscription", status: "skip" };
|
|
8050
8061
|
const candidates = classified.filter(
|
|
8051
|
-
({ product }) => product.productGroupVariants.length ?
|
|
8062
|
+
({ eligible, product }) => product.productGroupVariants.length ? eligible !== void 0 : !trusted.excludedProductIds.includes(product.id)
|
|
8052
8063
|
);
|
|
8053
8064
|
if (!candidates.length) return { reason: "empty", status: "skip" };
|
|
8054
8065
|
const retained = candidates.filter(({ eligible }) => eligible);
|
|
8055
8066
|
return retained.length ? { members: identities(retained), status: "retain" } : { reason: "no-eligible-subscription", status: "skip" };
|
|
8056
8067
|
} catch {
|
|
8057
|
-
return { status: "unavailable" };
|
|
8068
|
+
return { reason: unreadable, status: "unavailable" };
|
|
8058
8069
|
}
|
|
8059
8070
|
};
|
|
8060
8071
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
1
2
|
import { PostPurchaseExcludedProductIds } from '../schema/postPurchaseProductCollectionView';
|
|
2
3
|
import type { Reporter } from '../server/shared';
|
|
4
|
+
/** A collection's `productLimit`, original or effective: a positive whole number. */
|
|
5
|
+
export declare const PostPurchaseProductLimit: z.ZodNumber;
|
|
3
6
|
/**
|
|
4
7
|
* Preserve the original capped positions before applying product-wide exclusions. `productLimit` caps raw
|
|
5
8
|
* positions, and a member's `productIndex` is its raw position: a product the schema dropped leaves its slot
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { PostPurchaseExcludedProductIds } from '../schema/postPurchaseProductCollectionView';
|
|
2
2
|
import type { normalizePostPurchaseProduct } from '../server/normalizePostPurchaseProduct';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
type Normalized = ReturnType<typeof normalizePostPurchaseProduct>;
|
|
4
|
+
/**
|
|
5
|
+
* Catalog facts only: preparation still owns defaults, quantity, terms, and presentation. `false` is an ordinary
|
|
6
|
+
* product reason (REB-25054): no available variant, plan-only on a one-time Offer, or option values the product
|
|
7
|
+
* does not declare, for the member or, for a group, every sibling. A sibling with undeclared options leaves its
|
|
8
|
+
* whole group ineligible, as preparation cannot read that group either. `undefined` is a group whose every
|
|
9
|
+
* sibling is excluded, so nothing is left to offer; the group is read before exclusions apply, though, so an
|
|
10
|
+
* excluded sibling with undeclared options still answers `false`. A throw is unreadable data.
|
|
11
|
+
*/
|
|
12
|
+
export declare const postPurchaseMemberEligibility: (normalized: Normalized, product: Normalized["data"][number], excluded?: PostPurchaseExcludedProductIds) => boolean | undefined;
|
|
13
|
+
export {};
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import { PostPurchaseVariantCatalog } from '../schema/postPurchaseVariantCatalog';
|
|
2
2
|
import type { normalizePostPurchaseProduct } from '../server/normalizePostPurchaseProduct';
|
|
3
|
+
/**
|
|
4
|
+
* A variant carries an option value its product does not declare (an optionless product, say): the merchandise is
|
|
5
|
+
* readable but cannot be offered as it stands, so member eligibility leaves it out rather than failing the Offer.
|
|
6
|
+
*/
|
|
7
|
+
export declare class PostPurchaseVariantOptionMismatch extends Error {
|
|
8
|
+
}
|
|
3
9
|
export declare const projectPostPurchaseVariantCatalog: (product: ReturnType<typeof normalizePostPurchaseProduct>["data"][number], settings: ReturnType<typeof normalizePostPurchaseProduct>["effective"]) => PostPurchaseVariantCatalog;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebuy/rebuy",
|
|
3
|
-
"version": "3.56.
|
|
3
|
+
"version": "3.56.3",
|
|
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.",
|