@rebuy/rebuy 3.56.3 → 3.57.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/server/classifyPostPurchaseOffer.d.ts +4 -1
- package/dist/server/index.cjs +44 -17
- package/dist/server/index.mjs +44 -17
- package/dist/server/postPurchaseModernPlans.d.ts +5 -0
- package/dist/server/postPurchaseResponseDrift.d.ts +13 -0
- package/dist/server/postPurchaseSts.d.ts +7 -1
- package/package.json +1 -1
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { type z } from 'zod';
|
|
2
2
|
import { type PostPurchaseOfferEligibility, PostPurchaseOfferEligibilityContext, PostPurchaseStsOptions } from '../schema/postPurchaseOfferEligibility';
|
|
3
|
+
import type { Reporter } from '../server/shared';
|
|
3
4
|
export declare const classifyPostPurchaseOffer: (settings: unknown, response: unknown, context: z.input<typeof PostPurchaseOfferEligibilityContext>,
|
|
4
5
|
/** STS opt-in; absent or `{ sts: false }` keeps every pre-STS outcome. */
|
|
5
|
-
options?: PostPurchaseStsOptions
|
|
6
|
+
options?: PostPurchaseStsOptions,
|
|
7
|
+
/** Hears each purchased STS candidate whose plan data cannot be read, once per response (REB-25050). */
|
|
8
|
+
report?: Reporter) => PostPurchaseOfferEligibility;
|
package/dist/server/index.cjs
CHANGED
|
@@ -6172,17 +6172,30 @@ var PostPurchaseProductSettings = PostPurchaseSettings.pick({
|
|
|
6172
6172
|
|
|
6173
6173
|
// src/server/readPostPurchaseProductSource.ts
|
|
6174
6174
|
var import_zod45 = require("zod");
|
|
6175
|
-
|
|
6176
|
-
|
|
6177
|
-
var Identified = import_zod45.z.object({ id: PostPurchaseProductId });
|
|
6175
|
+
|
|
6176
|
+
// src/server/postPurchaseResponseDrift.ts
|
|
6178
6177
|
var heard = /* @__PURE__ */ new WeakMap();
|
|
6179
|
-
var
|
|
6180
|
-
|
|
6178
|
+
var sources = /* @__PURE__ */ new WeakMap();
|
|
6179
|
+
var rememberPostPurchaseProductSource = (product, response, productIndex) => {
|
|
6180
|
+
sources.set(product, { productIndex, response });
|
|
6181
|
+
};
|
|
6182
|
+
var postPurchaseProductSourceOf = (product) => sources.get(product);
|
|
6183
|
+
var reportOncePerResponse = (response, report, events) => {
|
|
6184
|
+
const reporters = heard.get(response) ?? /* @__PURE__ */ new WeakMap();
|
|
6181
6185
|
heard.set(response, reporters);
|
|
6182
|
-
|
|
6183
|
-
reporters.
|
|
6184
|
-
|
|
6186
|
+
const details = reporters.get(report) ?? /* @__PURE__ */ new Set();
|
|
6187
|
+
reporters.set(report, details);
|
|
6188
|
+
for (const event of events) {
|
|
6189
|
+
if (details.has(event.detail)) continue;
|
|
6190
|
+
details.add(event.detail);
|
|
6191
|
+
report(event);
|
|
6192
|
+
}
|
|
6185
6193
|
};
|
|
6194
|
+
|
|
6195
|
+
// src/server/readPostPurchaseProductSource.ts
|
|
6196
|
+
var Envelope = PostPurchaseProductSource.extend({ data: import_zod45.z.array(import_zod45.z.unknown()) });
|
|
6197
|
+
var Product3 = PostPurchaseProductSource.shape.data.element;
|
|
6198
|
+
var Identified = import_zod45.z.object({ id: PostPurchaseProductId });
|
|
6186
6199
|
var readPostPurchaseProductSource = (response, report) => {
|
|
6187
6200
|
const { data, metadata } = Envelope.parse(deepCamelCase(response));
|
|
6188
6201
|
const drift = [];
|
|
@@ -6190,6 +6203,7 @@ var readPostPurchaseProductSource = (response, report) => {
|
|
|
6190
6203
|
const products = data.flatMap((raw, productIndex) => {
|
|
6191
6204
|
const parsed = Product3.safeParse(raw);
|
|
6192
6205
|
if (parsed.success) {
|
|
6206
|
+
rememberPostPurchaseProductSource(parsed.data, response, productIndex);
|
|
6193
6207
|
if (parsed.data.requiresSellingPlan && !parsed.data.sellingPlanGroups.length)
|
|
6194
6208
|
drift.push({
|
|
6195
6209
|
detail: `Dropped post-purchase product ${parsed.data.id}: data.${productIndex}.requiresSellingPlan`,
|
|
@@ -6207,7 +6221,7 @@ var readPostPurchaseProductSource = (response, report) => {
|
|
|
6207
6221
|
});
|
|
6208
6222
|
return [];
|
|
6209
6223
|
});
|
|
6210
|
-
if (report && drift.length
|
|
6224
|
+
if (report && drift.length) reportOncePerResponse(response, report, drift);
|
|
6211
6225
|
return { dropped, metadata, products };
|
|
6212
6226
|
};
|
|
6213
6227
|
|
|
@@ -6353,7 +6367,8 @@ var Groups = import_zod52.z.array(
|
|
|
6353
6367
|
sellingPlans: import_zod52.z.unknown()
|
|
6354
6368
|
})
|
|
6355
6369
|
);
|
|
6356
|
-
var
|
|
6370
|
+
var PostPurchasePlanAllocations = import_zod52.z.array(import_zod52.z.object({ sellingPlanGroupId: import_zod52.z.string().min(1) }));
|
|
6371
|
+
var Allocations = PostPurchasePlanAllocations.default([]);
|
|
6357
6372
|
var Plans = import_zod52.z.array(
|
|
6358
6373
|
PostPurchasePlanOption.pick({ id: true, name: true }).extend({
|
|
6359
6374
|
options: import_zod52.z.array(import_zod52.z.object({ value: import_zod52.z.string().min(1) })).min(1),
|
|
@@ -7624,18 +7639,30 @@ var readPostPurchaseQuantity = ({
|
|
|
7624
7639
|
|
|
7625
7640
|
// src/server/postPurchaseSts.ts
|
|
7626
7641
|
var stsAllowed = ({ effective, original }) => [original, effective].some((config) => config.upgradeToSubscription.allow);
|
|
7627
|
-
var
|
|
7642
|
+
var reportUnreadableStsLine = (product, field, report) => {
|
|
7643
|
+
const source2 = postPurchaseProductSourceOf(product);
|
|
7644
|
+
const path = source2 ? `data.${source2.productIndex}.${field}` : field;
|
|
7645
|
+
const detail = `Unreadable post-purchase STS product ${product.id}: ${path}`;
|
|
7646
|
+
reportOncePerResponse(source2?.response ?? product, report, [{ detail, kind: "product" }]);
|
|
7647
|
+
};
|
|
7648
|
+
var postPurchaseStsLine = (normalized, product, lines, variantId, report) => {
|
|
7628
7649
|
if (!product.sellingPlanGroups?.length || product.productGroupVariants.length) return void 0;
|
|
7629
|
-
|
|
7650
|
+
const modern = typeof product.sellingPlanGroups[0].id !== "number";
|
|
7651
|
+
for (const [index, variant2] of product.variants.entries()) {
|
|
7630
7652
|
const matched = lines.filter((line) => line.sellingPlanId === void 0 && line.variantId === variant2.id);
|
|
7631
7653
|
const data = [{ ...product, variants: [variant2] }];
|
|
7632
|
-
if ((variantId === void 0 || variant2.id === variantId) && matched.length === 1 && postPurchaseVariantAvailable(variant2)
|
|
7633
|
-
|
|
7654
|
+
if ((variantId === void 0 || variant2.id === variantId) && matched.length === 1 && postPurchaseVariantAvailable(variant2)) {
|
|
7655
|
+
const unread = [];
|
|
7656
|
+
if (projectPostPurchasePlanCatalog({ ...normalized, data }, (event) => unread.push(event))?.plans.length)
|
|
7657
|
+
return { data, line: matched[0] };
|
|
7658
|
+
const field = modern && !PostPurchasePlanAllocations.safeParse(variant2.sellingPlanAllocations).success ? `variants.${index}.sellingPlanAllocations` : unread.length ? "sellingPlanGroups" : void 0;
|
|
7659
|
+
if (report && field) reportUnreadableStsLine(product, field, report);
|
|
7660
|
+
}
|
|
7634
7661
|
}
|
|
7635
7662
|
};
|
|
7636
7663
|
var preparePostPurchaseStsView = (widgetId, normalized, product, context, requested, report) => {
|
|
7637
7664
|
const { originalLineItems } = PostPurchaseStsContext.parse(context);
|
|
7638
|
-
const found = postPurchaseStsLine(normalized, product, originalLineItems, requested.variantId);
|
|
7665
|
+
const found = postPurchaseStsLine(normalized, product, originalLineItems, requested.variantId, report);
|
|
7639
7666
|
if (!found) return null;
|
|
7640
7667
|
const whole = found.line.quantity;
|
|
7641
7668
|
if (requested.quantity !== void 0 && requested.quantity !== whole)
|
|
@@ -8097,7 +8124,7 @@ var postPurchaseMemberEligibility = (normalized, product, excluded) => {
|
|
|
8097
8124
|
|
|
8098
8125
|
// src/server/classifyPostPurchaseOffer.ts
|
|
8099
8126
|
var identities = (members) => members.map(({ product, productIndex }) => ({ productId: product.id, productIndex }));
|
|
8100
|
-
var classifyPostPurchaseOffer = (settings, response, context, options2) => {
|
|
8127
|
+
var classifyPostPurchaseOffer = (settings, response, context, options2, report) => {
|
|
8101
8128
|
let unreadable = "context-unreadable";
|
|
8102
8129
|
try {
|
|
8103
8130
|
const trusted = PostPurchaseOfferEligibilityContext.parse(context);
|
|
@@ -8123,7 +8150,7 @@ var classifyPostPurchaseOffer = (settings, response, context, options2) => {
|
|
|
8123
8150
|
PostPurchaseSubscriptionSettings.parse(normalized.effective.subscription);
|
|
8124
8151
|
}
|
|
8125
8152
|
const lines = trusted.originalLineItems;
|
|
8126
|
-
const stsMembers = sts ? members.filter(({ product }) => postPurchaseStsLine(normalized, product, lines)) : [];
|
|
8153
|
+
const stsMembers = sts ? members.filter(({ product }) => postPurchaseStsLine(normalized, product, lines, void 0, report)) : [];
|
|
8127
8154
|
if (stsMembers.length) return { members: identities(stsMembers), mode: "sts", status: "retain" };
|
|
8128
8155
|
const classified = members.map((member) => ({
|
|
8129
8156
|
...member,
|
package/dist/server/index.mjs
CHANGED
|
@@ -6099,17 +6099,30 @@ var PostPurchaseProductSettings = PostPurchaseSettings.pick({
|
|
|
6099
6099
|
|
|
6100
6100
|
// src/server/readPostPurchaseProductSource.ts
|
|
6101
6101
|
import { z as z45 } from "zod";
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
var Identified = z45.object({ id: PostPurchaseProductId });
|
|
6102
|
+
|
|
6103
|
+
// src/server/postPurchaseResponseDrift.ts
|
|
6105
6104
|
var heard = /* @__PURE__ */ new WeakMap();
|
|
6106
|
-
var
|
|
6107
|
-
|
|
6105
|
+
var sources = /* @__PURE__ */ new WeakMap();
|
|
6106
|
+
var rememberPostPurchaseProductSource = (product, response, productIndex) => {
|
|
6107
|
+
sources.set(product, { productIndex, response });
|
|
6108
|
+
};
|
|
6109
|
+
var postPurchaseProductSourceOf = (product) => sources.get(product);
|
|
6110
|
+
var reportOncePerResponse = (response, report, events) => {
|
|
6111
|
+
const reporters = heard.get(response) ?? /* @__PURE__ */ new WeakMap();
|
|
6108
6112
|
heard.set(response, reporters);
|
|
6109
|
-
|
|
6110
|
-
reporters.
|
|
6111
|
-
|
|
6113
|
+
const details = reporters.get(report) ?? /* @__PURE__ */ new Set();
|
|
6114
|
+
reporters.set(report, details);
|
|
6115
|
+
for (const event of events) {
|
|
6116
|
+
if (details.has(event.detail)) continue;
|
|
6117
|
+
details.add(event.detail);
|
|
6118
|
+
report(event);
|
|
6119
|
+
}
|
|
6112
6120
|
};
|
|
6121
|
+
|
|
6122
|
+
// src/server/readPostPurchaseProductSource.ts
|
|
6123
|
+
var Envelope = PostPurchaseProductSource.extend({ data: z45.array(z45.unknown()) });
|
|
6124
|
+
var Product3 = PostPurchaseProductSource.shape.data.element;
|
|
6125
|
+
var Identified = z45.object({ id: PostPurchaseProductId });
|
|
6113
6126
|
var readPostPurchaseProductSource = (response, report) => {
|
|
6114
6127
|
const { data, metadata } = Envelope.parse(deepCamelCase(response));
|
|
6115
6128
|
const drift = [];
|
|
@@ -6117,6 +6130,7 @@ var readPostPurchaseProductSource = (response, report) => {
|
|
|
6117
6130
|
const products = data.flatMap((raw, productIndex) => {
|
|
6118
6131
|
const parsed = Product3.safeParse(raw);
|
|
6119
6132
|
if (parsed.success) {
|
|
6133
|
+
rememberPostPurchaseProductSource(parsed.data, response, productIndex);
|
|
6120
6134
|
if (parsed.data.requiresSellingPlan && !parsed.data.sellingPlanGroups.length)
|
|
6121
6135
|
drift.push({
|
|
6122
6136
|
detail: `Dropped post-purchase product ${parsed.data.id}: data.${productIndex}.requiresSellingPlan`,
|
|
@@ -6134,7 +6148,7 @@ var readPostPurchaseProductSource = (response, report) => {
|
|
|
6134
6148
|
});
|
|
6135
6149
|
return [];
|
|
6136
6150
|
});
|
|
6137
|
-
if (report && drift.length
|
|
6151
|
+
if (report && drift.length) reportOncePerResponse(response, report, drift);
|
|
6138
6152
|
return { dropped, metadata, products };
|
|
6139
6153
|
};
|
|
6140
6154
|
|
|
@@ -6280,7 +6294,8 @@ var Groups = z52.array(
|
|
|
6280
6294
|
sellingPlans: z52.unknown()
|
|
6281
6295
|
})
|
|
6282
6296
|
);
|
|
6283
|
-
var
|
|
6297
|
+
var PostPurchasePlanAllocations = z52.array(z52.object({ sellingPlanGroupId: z52.string().min(1) }));
|
|
6298
|
+
var Allocations = PostPurchasePlanAllocations.default([]);
|
|
6284
6299
|
var Plans = z52.array(
|
|
6285
6300
|
PostPurchasePlanOption.pick({ id: true, name: true }).extend({
|
|
6286
6301
|
options: z52.array(z52.object({ value: z52.string().min(1) })).min(1),
|
|
@@ -7551,18 +7566,30 @@ var readPostPurchaseQuantity = ({
|
|
|
7551
7566
|
|
|
7552
7567
|
// src/server/postPurchaseSts.ts
|
|
7553
7568
|
var stsAllowed = ({ effective, original }) => [original, effective].some((config) => config.upgradeToSubscription.allow);
|
|
7554
|
-
var
|
|
7569
|
+
var reportUnreadableStsLine = (product, field, report) => {
|
|
7570
|
+
const source2 = postPurchaseProductSourceOf(product);
|
|
7571
|
+
const path = source2 ? `data.${source2.productIndex}.${field}` : field;
|
|
7572
|
+
const detail = `Unreadable post-purchase STS product ${product.id}: ${path}`;
|
|
7573
|
+
reportOncePerResponse(source2?.response ?? product, report, [{ detail, kind: "product" }]);
|
|
7574
|
+
};
|
|
7575
|
+
var postPurchaseStsLine = (normalized, product, lines, variantId, report) => {
|
|
7555
7576
|
if (!product.sellingPlanGroups?.length || product.productGroupVariants.length) return void 0;
|
|
7556
|
-
|
|
7577
|
+
const modern = typeof product.sellingPlanGroups[0].id !== "number";
|
|
7578
|
+
for (const [index, variant2] of product.variants.entries()) {
|
|
7557
7579
|
const matched = lines.filter((line) => line.sellingPlanId === void 0 && line.variantId === variant2.id);
|
|
7558
7580
|
const data = [{ ...product, variants: [variant2] }];
|
|
7559
|
-
if ((variantId === void 0 || variant2.id === variantId) && matched.length === 1 && postPurchaseVariantAvailable(variant2)
|
|
7560
|
-
|
|
7581
|
+
if ((variantId === void 0 || variant2.id === variantId) && matched.length === 1 && postPurchaseVariantAvailable(variant2)) {
|
|
7582
|
+
const unread = [];
|
|
7583
|
+
if (projectPostPurchasePlanCatalog({ ...normalized, data }, (event) => unread.push(event))?.plans.length)
|
|
7584
|
+
return { data, line: matched[0] };
|
|
7585
|
+
const field = modern && !PostPurchasePlanAllocations.safeParse(variant2.sellingPlanAllocations).success ? `variants.${index}.sellingPlanAllocations` : unread.length ? "sellingPlanGroups" : void 0;
|
|
7586
|
+
if (report && field) reportUnreadableStsLine(product, field, report);
|
|
7587
|
+
}
|
|
7561
7588
|
}
|
|
7562
7589
|
};
|
|
7563
7590
|
var preparePostPurchaseStsView = (widgetId, normalized, product, context, requested, report) => {
|
|
7564
7591
|
const { originalLineItems } = PostPurchaseStsContext.parse(context);
|
|
7565
|
-
const found = postPurchaseStsLine(normalized, product, originalLineItems, requested.variantId);
|
|
7592
|
+
const found = postPurchaseStsLine(normalized, product, originalLineItems, requested.variantId, report);
|
|
7566
7593
|
if (!found) return null;
|
|
7567
7594
|
const whole = found.line.quantity;
|
|
7568
7595
|
if (requested.quantity !== void 0 && requested.quantity !== whole)
|
|
@@ -8024,7 +8051,7 @@ var postPurchaseMemberEligibility = (normalized, product, excluded) => {
|
|
|
8024
8051
|
|
|
8025
8052
|
// src/server/classifyPostPurchaseOffer.ts
|
|
8026
8053
|
var identities = (members) => members.map(({ product, productIndex }) => ({ productId: product.id, productIndex }));
|
|
8027
|
-
var classifyPostPurchaseOffer = (settings, response, context, options2) => {
|
|
8054
|
+
var classifyPostPurchaseOffer = (settings, response, context, options2, report) => {
|
|
8028
8055
|
let unreadable = "context-unreadable";
|
|
8029
8056
|
try {
|
|
8030
8057
|
const trusted = PostPurchaseOfferEligibilityContext.parse(context);
|
|
@@ -8050,7 +8077,7 @@ var classifyPostPurchaseOffer = (settings, response, context, options2) => {
|
|
|
8050
8077
|
PostPurchaseSubscriptionSettings.parse(normalized.effective.subscription);
|
|
8051
8078
|
}
|
|
8052
8079
|
const lines = trusted.originalLineItems;
|
|
8053
|
-
const stsMembers = sts ? members.filter(({ product }) => postPurchaseStsLine(normalized, product, lines)) : [];
|
|
8080
|
+
const stsMembers = sts ? members.filter(({ product }) => postPurchaseStsLine(normalized, product, lines, void 0, report)) : [];
|
|
8054
8081
|
if (stsMembers.length) return { members: identities(stsMembers), mode: "sts", status: "retain" };
|
|
8055
8082
|
const classified = members.map((member) => ({
|
|
8056
8083
|
...member,
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
1
2
|
import { PostPurchasePlanOption } from '../schema/postPurchasePlanCatalog';
|
|
3
|
+
/** A variant's readable `selling_plan_allocations`; a missing list reads as none here, but STS reports it. */
|
|
4
|
+
export declare const PostPurchasePlanAllocations: z.ZodArray<z.ZodObject<{
|
|
5
|
+
sellingPlanGroupId: z.ZodString;
|
|
6
|
+
}, z.core.$strip>>;
|
|
2
7
|
/**
|
|
3
8
|
* Match allocation groups in product order, then preserve each matching group's plan order. Membership is
|
|
4
9
|
* group-level by design (frozen-branch parity): Shopify allocates every plan of a group to a member variant, and
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Reporter, ServerDrift } from '../server/shared';
|
|
2
|
+
/** Records where a parsed product came from, so drift found about it later still names its response and path. */
|
|
3
|
+
export declare const rememberPostPurchaseProductSource: (product: object, response: object, productIndex: number) => void;
|
|
4
|
+
/** The response and raw `productIndex` a parsed product was read from, when it was read by the product source. */
|
|
5
|
+
export declare const postPurchaseProductSourceOf: (product: object) => {
|
|
6
|
+
productIndex: number;
|
|
7
|
+
response: object;
|
|
8
|
+
} | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Reports each event `report` has not yet heard about `response`, keyed on the `response` object itself: every
|
|
11
|
+
* projection of one request rereads the same object, so a drift is heard once however many projections find it.
|
|
12
|
+
*/
|
|
13
|
+
export declare const reportOncePerResponse: (response: object, report: Reporter, events: ServerDrift[]) => void;
|
|
@@ -18,8 +18,14 @@ export declare const stsAllowed: ({ effective, original }: Pick<Normalized, "eff
|
|
|
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
20
|
* names one.
|
|
21
|
+
*
|
|
22
|
+
* `report` hears a candidate (a purchased, in-stock variant on exactly one one-time line) whose plan data cannot be
|
|
23
|
+
* read, since it then silently switches nothing: a modern selling-plan variant whose `sellingPlanAllocations` is
|
|
24
|
+
* missing or malformed, or plan data the catalog cannot read. Each is a `product` drift naming the product id and
|
|
25
|
+
* the dotted path from the source root, never a value, heard once per response like the source's own drops. A
|
|
26
|
+
* readable variant that simply has no plan, or no candidate at all, stays silent.
|
|
21
27
|
*/
|
|
22
|
-
export declare const postPurchaseStsLine: <T extends Line>(normalized: Normalized, product: Normalized["data"][number], lines: T[], variantId?: number) => {
|
|
28
|
+
export declare const postPurchaseStsLine: <T extends Line>(normalized: Normalized, product: Normalized["data"][number], lines: T[], variantId?: number, report?: Reporter) => {
|
|
23
29
|
data: {
|
|
24
30
|
variants: {
|
|
25
31
|
title: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebuy/rebuy",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.57.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.",
|