@rebuy/rebuy 3.16.1 → 3.16.2
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/cabShopConfig.d.ts +2 -0
- package/dist/server/adsEngine.d.ts +12 -3
- package/dist/server/composeOffer.d.ts +1 -1
- package/dist/server/index.cjs +24 -13
- package/dist/server/index.mjs +24 -13
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1205,7 +1205,15 @@ var CabShopConfig = import_zod2.z.object({
|
|
|
1205
1205
|
*/
|
|
1206
1206
|
markets: import_zod2.z.object({ enabled: import_zod2.z.boolean() }).nullish().catch(DRIFTED_MARKETS).default(() => ({ enabled: false })).transform((markets) => markets ?? { enabled: false }),
|
|
1207
1207
|
monetize: import_zod2.z.object({ publisherKey: import_zod2.z.string().nullable() }).nullish().catch(void 0),
|
|
1208
|
-
shopId: import_zod2.z.number().optional().catch(void 0)
|
|
1208
|
+
shopId: import_zod2.z.number().optional().catch(void 0),
|
|
1209
|
+
/**
|
|
1210
|
+
* The merchant's display name ("Gift Basket Store") — the Monetize header copy reads it.
|
|
1211
|
+
* `.catch()` like its siblings: a missing/drifted name degrades the header to the
|
|
1212
|
+
* myshopify-domain slug (the pre-CAB React fallback), never a parse fail. An empty string is a
|
|
1213
|
+
* VALID parse — the slug fallback for `''` (and whitespace/tag-only names) lives in
|
|
1214
|
+
* composeOffer's `||` chain, not here.
|
|
1215
|
+
*/
|
|
1216
|
+
shopName: import_zod2.z.string().nullish().catch(void 0)
|
|
1209
1217
|
});
|
|
1210
1218
|
var CabUserConfig = import_zod2.z.object({
|
|
1211
1219
|
shop: CabShopConfig,
|
package/dist/index.mjs
CHANGED
|
@@ -919,7 +919,15 @@ var CabShopConfig = z2.object({
|
|
|
919
919
|
*/
|
|
920
920
|
markets: z2.object({ enabled: z2.boolean() }).nullish().catch(DRIFTED_MARKETS).default(() => ({ enabled: false })).transform((markets) => markets ?? { enabled: false }),
|
|
921
921
|
monetize: z2.object({ publisherKey: z2.string().nullable() }).nullish().catch(void 0),
|
|
922
|
-
shopId: z2.number().optional().catch(void 0)
|
|
922
|
+
shopId: z2.number().optional().catch(void 0),
|
|
923
|
+
/**
|
|
924
|
+
* The merchant's display name ("Gift Basket Store") — the Monetize header copy reads it.
|
|
925
|
+
* `.catch()` like its siblings: a missing/drifted name degrades the header to the
|
|
926
|
+
* myshopify-domain slug (the pre-CAB React fallback), never a parse fail. An empty string is a
|
|
927
|
+
* VALID parse — the slug fallback for `''` (and whitespace/tag-only names) lives in
|
|
928
|
+
* composeOffer's `||` chain, not here.
|
|
929
|
+
*/
|
|
930
|
+
shopName: z2.string().nullish().catch(void 0)
|
|
923
931
|
});
|
|
924
932
|
var CabUserConfig = z2.object({
|
|
925
933
|
shop: CabShopConfig,
|
|
@@ -52,6 +52,7 @@ export declare const CabShopConfig: z.ZodObject<{
|
|
|
52
52
|
publisherKey: z.ZodNullable<z.ZodString>;
|
|
53
53
|
}, z.core.$strip>>>>;
|
|
54
54
|
shopId: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
|
|
55
|
+
shopName: z.ZodCatch<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
55
56
|
}, z.core.$strip>;
|
|
56
57
|
export type CabShopConfig = z.infer<typeof CabShopConfig>;
|
|
57
58
|
/**
|
|
@@ -90,6 +91,7 @@ export declare const CabUserConfig: z.ZodObject<{
|
|
|
90
91
|
publisherKey: z.ZodNullable<z.ZodString>;
|
|
91
92
|
}, z.core.$strip>>>>;
|
|
92
93
|
shopId: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
|
|
94
|
+
shopName: z.ZodCatch<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
93
95
|
}, z.core.$strip>;
|
|
94
96
|
smartCart: z.ZodCatch<z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
95
97
|
components: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -31,11 +31,20 @@ export declare const isTestingRequest: (input: MonetizeInput, isProduction: bool
|
|
|
31
31
|
* (total preferred over subtotal). Empty values are omitted.
|
|
32
32
|
*/
|
|
33
33
|
export declare const buildAdsParams: (input: MonetizeInput, publisherKey: string, supplyKey: string, testing: boolean, userAgent?: string, ipAddress?: string) => Record<string, string>;
|
|
34
|
+
/** The engine offers plus the shop's display name (for the header copy), resolved on the same config read. */
|
|
35
|
+
export type AdsEngineResult = {
|
|
36
|
+
offers: AdsEngineOffer[];
|
|
37
|
+
storeName?: string;
|
|
38
|
+
};
|
|
34
39
|
/**
|
|
35
40
|
* Fetch live ad offers from the Rebuy ads engine. Resolves the shop's publisher key server-side (and
|
|
36
|
-
* returns
|
|
41
|
+
* returns no offers when the shop isn't enrolled — no ads, not an error). A non-prod upstream sends the
|
|
37
42
|
* staging supply key; a non-prod/editor/QA-email request is flagged `testing` (excluded from billing).
|
|
38
43
|
* `prefetched` is a caller's already-resolved shop config (inline hydration threads it) — consulted only
|
|
39
|
-
* AFTER the gates below, so a gated-out request still costs zero upstream calls either way.
|
|
44
|
+
* AFTER the gates below, so a gated-out request still costs zero upstream calls either way. `storeName`
|
|
45
|
+
* rides along from the same config read so the card composer never needs its own resolution: absent
|
|
46
|
+
* only before the config read (the country/session gates), present once it happens — including the
|
|
47
|
+
* enrolled-but-keyless return, deliberately, so the shape is uniform after the read (with no offers
|
|
48
|
+
* the name simply goes nowhere).
|
|
40
49
|
*/
|
|
41
|
-
export declare const fetchAdsEngineOffers: (input: MonetizeInput, ctx: ServerContext, prefetched?: CabUserConfig) => Promise<
|
|
50
|
+
export declare const fetchAdsEngineOffers: (input: MonetizeInput, ctx: ServerContext, prefetched?: CabUserConfig) => Promise<AdsEngineResult>;
|
|
@@ -10,4 +10,4 @@ import { type MonetizeInput } from '../server/shared';
|
|
|
10
10
|
* decline pixel (`trackingUrl`) and advances. Parsing through the schema fills defaults and validates
|
|
11
11
|
* the shape.
|
|
12
12
|
*/
|
|
13
|
-
export declare const composeOfferCard: (offer: AdsEngineOffer, input: MonetizeInput) => CABSection | undefined;
|
|
13
|
+
export declare const composeOfferCard: (offer: AdsEngineOffer, input: MonetizeInput, storeName?: string) => CABSection | undefined;
|
package/dist/server/index.cjs
CHANGED
|
@@ -625,7 +625,15 @@ var CabShopConfig = import_zod6.z.object({
|
|
|
625
625
|
*/
|
|
626
626
|
markets: import_zod6.z.object({ enabled: import_zod6.z.boolean() }).nullish().catch(DRIFTED_MARKETS).default(() => ({ enabled: false })).transform((markets) => markets ?? { enabled: false }),
|
|
627
627
|
monetize: import_zod6.z.object({ publisherKey: import_zod6.z.string().nullable() }).nullish().catch(void 0),
|
|
628
|
-
shopId: import_zod6.z.number().optional().catch(void 0)
|
|
628
|
+
shopId: import_zod6.z.number().optional().catch(void 0),
|
|
629
|
+
/**
|
|
630
|
+
* The merchant's display name ("Gift Basket Store") — the Monetize header copy reads it.
|
|
631
|
+
* `.catch()` like its siblings: a missing/drifted name degrades the header to the
|
|
632
|
+
* myshopify-domain slug (the pre-CAB React fallback), never a parse fail. An empty string is a
|
|
633
|
+
* VALID parse — the slug fallback for `''` (and whitespace/tag-only names) lives in
|
|
634
|
+
* composeOffer's `||` chain, not here.
|
|
635
|
+
*/
|
|
636
|
+
shopName: import_zod6.z.string().nullish().catch(void 0)
|
|
629
637
|
});
|
|
630
638
|
var CabUserConfig = import_zod6.z.object({
|
|
631
639
|
shop: CabShopConfig,
|
|
@@ -4060,11 +4068,12 @@ var buildAdsParams = (input, publisherKey, supplyKey, testing, userAgent, ipAddr
|
|
|
4060
4068
|
};
|
|
4061
4069
|
};
|
|
4062
4070
|
var fetchAdsEngineOffers = async (input, ctx, prefetched) => {
|
|
4063
|
-
if (!input.country || !SUPPORTED_COUNTRIES.has(input.country.toUpperCase())) return [];
|
|
4064
|
-
if (!(input.sessionId || input.visitorId)) return [];
|
|
4071
|
+
if (!input.country || !SUPPORTED_COUNTRIES.has(input.country.toUpperCase())) return { offers: [] };
|
|
4072
|
+
if (!(input.sessionId || input.visitorId)) return { offers: [] };
|
|
4065
4073
|
const { shop } = prefetched ?? await fetchUserConfig({ shop: input.shop }, ctx);
|
|
4066
4074
|
const publisherKey = shop.monetize?.publisherKey;
|
|
4067
|
-
|
|
4075
|
+
const storeName = shop.shopName ?? void 0;
|
|
4076
|
+
if (!publisherKey) return { offers: [], storeName };
|
|
4068
4077
|
const isProduction = ctx.host === REBUY_ENGINE_HOST;
|
|
4069
4078
|
const supplyKey = isProduction ? SUPPLY_KEY.production : SUPPLY_KEY.staging;
|
|
4070
4079
|
const upstream = await ctx.fetchUpstream(
|
|
@@ -4079,7 +4088,7 @@ var fetchAdsEngineOffers = async (input, ctx, prefetched) => {
|
|
|
4079
4088
|
),
|
|
4080
4089
|
{ host: adsHost(ctx.host) }
|
|
4081
4090
|
);
|
|
4082
|
-
return AdsEngineResponse.parse(upstream).offers;
|
|
4091
|
+
return { offers: AdsEngineResponse.parse(upstream).offers, storeName };
|
|
4083
4092
|
};
|
|
4084
4093
|
|
|
4085
4094
|
// src/server/composeOffer.ts
|
|
@@ -4120,19 +4129,22 @@ var styled = (value, { align, bold, color, fontSize, href }) => ({
|
|
|
4120
4129
|
},
|
|
4121
4130
|
sectionType: SectionType.text
|
|
4122
4131
|
});
|
|
4123
|
-
var shopName = (shop) => shop.replace(/\.myshopify\.com$/, "") || "store";
|
|
4124
|
-
var headerSections = (input) => [
|
|
4132
|
+
var shopName = (shop, storeName) => storeName?.replace(/<[^>]*>/g, "").trim() || shop.replace(/\.myshopify\.com$/, "") || "store";
|
|
4133
|
+
var headerSections = (input, storeName) => [
|
|
4125
4134
|
{
|
|
4126
4135
|
sections: [
|
|
4127
4136
|
styled("Congratulations!", { bold: true, fontSize: "heading" }),
|
|
4128
|
-
styled(`Your ${shopName(input.shop)} purchase unlocked a bonus:`, {
|
|
4137
|
+
styled(`Your ${shopName(input.shop, storeName)} purchase unlocked a bonus:`, {
|
|
4138
|
+
bold: true,
|
|
4139
|
+
fontSize: "heading"
|
|
4140
|
+
})
|
|
4129
4141
|
],
|
|
4130
4142
|
sectionType: SectionType.layout,
|
|
4131
4143
|
spacing: Spacing.none
|
|
4132
4144
|
},
|
|
4133
4145
|
text(input.orderName ? `Order ${input.orderName} Confirmed` : "Order Confirmed")
|
|
4134
4146
|
];
|
|
4135
|
-
var composeOfferCard = (offer, input) => {
|
|
4147
|
+
var composeOfferCard = (offer, input, storeName) => {
|
|
4136
4148
|
const copy = {
|
|
4137
4149
|
sections: [text(offer.headline), smallText(offer.description)],
|
|
4138
4150
|
sectionType: SectionType.layout,
|
|
@@ -4143,7 +4155,7 @@ var composeOfferCard = (offer, input) => {
|
|
|
4143
4155
|
border: { style: BorderStyle.base },
|
|
4144
4156
|
padding: Spacing.tight,
|
|
4145
4157
|
sections: [
|
|
4146
|
-
...headerSections(input),
|
|
4158
|
+
...headerSections(input, storeName),
|
|
4147
4159
|
offer.image_url ? {
|
|
4148
4160
|
alignment: { horizontal: HorizontalAlignment.start, vertical: VerticalAlignment.middle },
|
|
4149
4161
|
direction: Direction.grid,
|
|
@@ -4221,9 +4233,8 @@ var composeOfferCard = (offer, input) => {
|
|
|
4221
4233
|
|
|
4222
4234
|
// src/server/monetizeOffers.ts
|
|
4223
4235
|
var fetchMonetizeOffers = async (input, ctx, prefetched) => {
|
|
4224
|
-
const
|
|
4225
|
-
|
|
4226
|
-
);
|
|
4236
|
+
const { offers: engineOffers, storeName } = await fetchAdsEngineOffers(input, ctx, prefetched);
|
|
4237
|
+
const composed = engineOffers.map((offer) => composeOfferCard(offer, input, storeName));
|
|
4227
4238
|
const offers = composed.filter((card) => card !== void 0);
|
|
4228
4239
|
if (offers.length < composed.length)
|
|
4229
4240
|
ctx.reportDrift?.({
|
package/dist/server/index.mjs
CHANGED
|
@@ -577,7 +577,15 @@ var CabShopConfig = z6.object({
|
|
|
577
577
|
*/
|
|
578
578
|
markets: z6.object({ enabled: z6.boolean() }).nullish().catch(DRIFTED_MARKETS).default(() => ({ enabled: false })).transform((markets) => markets ?? { enabled: false }),
|
|
579
579
|
monetize: z6.object({ publisherKey: z6.string().nullable() }).nullish().catch(void 0),
|
|
580
|
-
shopId: z6.number().optional().catch(void 0)
|
|
580
|
+
shopId: z6.number().optional().catch(void 0),
|
|
581
|
+
/**
|
|
582
|
+
* The merchant's display name ("Gift Basket Store") — the Monetize header copy reads it.
|
|
583
|
+
* `.catch()` like its siblings: a missing/drifted name degrades the header to the
|
|
584
|
+
* myshopify-domain slug (the pre-CAB React fallback), never a parse fail. An empty string is a
|
|
585
|
+
* VALID parse — the slug fallback for `''` (and whitespace/tag-only names) lives in
|
|
586
|
+
* composeOffer's `||` chain, not here.
|
|
587
|
+
*/
|
|
588
|
+
shopName: z6.string().nullish().catch(void 0)
|
|
581
589
|
});
|
|
582
590
|
var CabUserConfig = z6.object({
|
|
583
591
|
shop: CabShopConfig,
|
|
@@ -4012,11 +4020,12 @@ var buildAdsParams = (input, publisherKey, supplyKey, testing, userAgent, ipAddr
|
|
|
4012
4020
|
};
|
|
4013
4021
|
};
|
|
4014
4022
|
var fetchAdsEngineOffers = async (input, ctx, prefetched) => {
|
|
4015
|
-
if (!input.country || !SUPPORTED_COUNTRIES.has(input.country.toUpperCase())) return [];
|
|
4016
|
-
if (!(input.sessionId || input.visitorId)) return [];
|
|
4023
|
+
if (!input.country || !SUPPORTED_COUNTRIES.has(input.country.toUpperCase())) return { offers: [] };
|
|
4024
|
+
if (!(input.sessionId || input.visitorId)) return { offers: [] };
|
|
4017
4025
|
const { shop } = prefetched ?? await fetchUserConfig({ shop: input.shop }, ctx);
|
|
4018
4026
|
const publisherKey = shop.monetize?.publisherKey;
|
|
4019
|
-
|
|
4027
|
+
const storeName = shop.shopName ?? void 0;
|
|
4028
|
+
if (!publisherKey) return { offers: [], storeName };
|
|
4020
4029
|
const isProduction = ctx.host === REBUY_ENGINE_HOST;
|
|
4021
4030
|
const supplyKey = isProduction ? SUPPLY_KEY.production : SUPPLY_KEY.staging;
|
|
4022
4031
|
const upstream = await ctx.fetchUpstream(
|
|
@@ -4031,7 +4040,7 @@ var fetchAdsEngineOffers = async (input, ctx, prefetched) => {
|
|
|
4031
4040
|
),
|
|
4032
4041
|
{ host: adsHost(ctx.host) }
|
|
4033
4042
|
);
|
|
4034
|
-
return AdsEngineResponse.parse(upstream).offers;
|
|
4043
|
+
return { offers: AdsEngineResponse.parse(upstream).offers, storeName };
|
|
4035
4044
|
};
|
|
4036
4045
|
|
|
4037
4046
|
// src/server/composeOffer.ts
|
|
@@ -4072,19 +4081,22 @@ var styled = (value, { align, bold, color, fontSize, href }) => ({
|
|
|
4072
4081
|
},
|
|
4073
4082
|
sectionType: SectionType.text
|
|
4074
4083
|
});
|
|
4075
|
-
var shopName = (shop) => shop.replace(/\.myshopify\.com$/, "") || "store";
|
|
4076
|
-
var headerSections = (input) => [
|
|
4084
|
+
var shopName = (shop, storeName) => storeName?.replace(/<[^>]*>/g, "").trim() || shop.replace(/\.myshopify\.com$/, "") || "store";
|
|
4085
|
+
var headerSections = (input, storeName) => [
|
|
4077
4086
|
{
|
|
4078
4087
|
sections: [
|
|
4079
4088
|
styled("Congratulations!", { bold: true, fontSize: "heading" }),
|
|
4080
|
-
styled(`Your ${shopName(input.shop)} purchase unlocked a bonus:`, {
|
|
4089
|
+
styled(`Your ${shopName(input.shop, storeName)} purchase unlocked a bonus:`, {
|
|
4090
|
+
bold: true,
|
|
4091
|
+
fontSize: "heading"
|
|
4092
|
+
})
|
|
4081
4093
|
],
|
|
4082
4094
|
sectionType: SectionType.layout,
|
|
4083
4095
|
spacing: Spacing.none
|
|
4084
4096
|
},
|
|
4085
4097
|
text(input.orderName ? `Order ${input.orderName} Confirmed` : "Order Confirmed")
|
|
4086
4098
|
];
|
|
4087
|
-
var composeOfferCard = (offer, input) => {
|
|
4099
|
+
var composeOfferCard = (offer, input, storeName) => {
|
|
4088
4100
|
const copy = {
|
|
4089
4101
|
sections: [text(offer.headline), smallText(offer.description)],
|
|
4090
4102
|
sectionType: SectionType.layout,
|
|
@@ -4095,7 +4107,7 @@ var composeOfferCard = (offer, input) => {
|
|
|
4095
4107
|
border: { style: BorderStyle.base },
|
|
4096
4108
|
padding: Spacing.tight,
|
|
4097
4109
|
sections: [
|
|
4098
|
-
...headerSections(input),
|
|
4110
|
+
...headerSections(input, storeName),
|
|
4099
4111
|
offer.image_url ? {
|
|
4100
4112
|
alignment: { horizontal: HorizontalAlignment.start, vertical: VerticalAlignment.middle },
|
|
4101
4113
|
direction: Direction.grid,
|
|
@@ -4173,9 +4185,8 @@ var composeOfferCard = (offer, input) => {
|
|
|
4173
4185
|
|
|
4174
4186
|
// src/server/monetizeOffers.ts
|
|
4175
4187
|
var fetchMonetizeOffers = async (input, ctx, prefetched) => {
|
|
4176
|
-
const
|
|
4177
|
-
|
|
4178
|
-
);
|
|
4188
|
+
const { offers: engineOffers, storeName } = await fetchAdsEngineOffers(input, ctx, prefetched);
|
|
4189
|
+
const composed = engineOffers.map((offer) => composeOfferCard(offer, input, storeName));
|
|
4179
4190
|
const offers = composed.filter((card) => card !== void 0);
|
|
4180
4191
|
if (offers.length < composed.length)
|
|
4181
4192
|
ctx.reportDrift?.({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebuy/rebuy",
|
|
3
|
-
"version": "3.16.
|
|
3
|
+
"version": "3.16.2",
|
|
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.",
|