@rebuy/rebuy 3.60.1 → 3.60.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 +36 -8
- package/dist/index.mjs +36 -8
- package/dist/schema/cabShopConfig.d.ts +11 -6
- package/dist/schema/driftedSmartCart.d.ts +15 -0
- package/dist/schema/smartCart.d.ts +20 -20
- package/dist/schema/user-config.cjs +37 -7
- package/dist/schema/user-config.mjs +37 -7
- package/dist/schema/userConfig.d.ts +6 -6
- package/dist/server/index.cjs +53 -8
- package/dist/server/index.mjs +53 -8
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1212,8 +1212,13 @@ var import_zod2 = require("zod");
|
|
|
1212
1212
|
// src/schema/driftedMarkets.ts
|
|
1213
1213
|
var DRIFTED_MARKETS = Object.freeze({ enabled: false });
|
|
1214
1214
|
|
|
1215
|
+
// src/schema/driftedSmartCart.ts
|
|
1216
|
+
var DRIFTED_SMART_CART_SETTINGS = Object.freeze({});
|
|
1217
|
+
var DRIFTED_SMART_CART = Object.freeze({});
|
|
1218
|
+
|
|
1215
1219
|
// src/schema/smartCart.ts
|
|
1216
1220
|
var import_zod = require("zod");
|
|
1221
|
+
var phpEmptyMapAsAbsent = (value) => Array.isArray(value) && value.length === 0 ? void 0 : value;
|
|
1217
1222
|
var SmartCartTierProduct = import_zod.z.looseObject({
|
|
1218
1223
|
handle: import_zod.z.string().optional(),
|
|
1219
1224
|
id: import_zod.z.coerce.number().optional(),
|
|
@@ -1267,7 +1272,11 @@ var SmartCartTier = import_zod.z.looseObject({
|
|
|
1267
1272
|
* `'50' → 50` and keeps the tier (a numeric-string minimum is a valid threshold, not a data defect).
|
|
1268
1273
|
*/
|
|
1269
1274
|
minimum: import_zod.z.preprocess((value) => value == null ? void 0 : value, import_zod.z.coerce.number().optional()),
|
|
1270
|
-
|
|
1275
|
+
/** An empty map arrives as PHP's `[]` (see {@link phpEmptyMapAsAbsent}) — absent, not a failed tier. */
|
|
1276
|
+
presentmentCurrencies: import_zod.z.preprocess(
|
|
1277
|
+
phpEmptyMapAsAbsent,
|
|
1278
|
+
import_zod.z.looseObject({ enabled: import_zod.z.boolean().optional() }).optional()
|
|
1279
|
+
),
|
|
1271
1280
|
productAmountReachedLabel: import_zod.z.boolean().optional(),
|
|
1272
1281
|
productAmountReachedLabelText: import_zod.z.string().optional(),
|
|
1273
1282
|
productAmountRemainingLabel: import_zod.z.boolean().optional(),
|
|
@@ -1320,16 +1329,35 @@ var SmartCartBar = import_zod.z.looseObject({
|
|
|
1320
1329
|
freeShippingOnSubscription: import_zod.z.boolean().optional(),
|
|
1321
1330
|
geolocationEnabled: import_zod.z.boolean().optional(),
|
|
1322
1331
|
id: import_zod.z.string().optional(),
|
|
1323
|
-
language
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1332
|
+
/** An empty `language` map arrives as PHP's `[]` (see {@link phpEmptyMapAsAbsent}) — absent, not a failed bar. */
|
|
1333
|
+
language: import_zod.z.preprocess(
|
|
1334
|
+
phpEmptyMapAsAbsent,
|
|
1335
|
+
import_zod.z.looseObject({
|
|
1336
|
+
freeShippingReached: import_zod.z.string().optional(),
|
|
1337
|
+
freeShippingRemaining: import_zod.z.string().optional(),
|
|
1338
|
+
giftAreaTitle: import_zod.z.string().optional()
|
|
1339
|
+
}).optional()
|
|
1340
|
+
),
|
|
1328
1341
|
name: import_zod.z.string().optional(),
|
|
1329
1342
|
tiers: import_zod.z.array(SmartCartTier).optional()
|
|
1330
1343
|
});
|
|
1331
1344
|
var SmartCartComponent = import_zod.z.looseObject({
|
|
1332
|
-
|
|
1345
|
+
/**
|
|
1346
|
+
* Every component in the layout is parsed, not just the progress bar, so this field is the blast-radius
|
|
1347
|
+
* boundary (REB-25139): before it caught, b.box's `cart_items` component arriving as `settings: []` failed
|
|
1348
|
+
* the component, the `components` array and the whole config — and `CabUserConfig`'s config-level catch
|
|
1349
|
+
* then silently dropped every progress bar for the shop. Now:
|
|
1350
|
+
*
|
|
1351
|
+
* - PHP's empty-map `[]` reads as absent ({@link phpEmptyMapAsAbsent}) — normal engine vocabulary, no drift.
|
|
1352
|
+
* - Any other unreadable settings (a string, a non-empty array, a bar that fails its schema) `.catch` to the
|
|
1353
|
+
* {@link DRIFTED_SMART_CART_SETTINGS} identity sentinel: that component loses its settings (no bars),
|
|
1354
|
+
* its siblings — and the progress bar, when it is a sibling — still parse, and the server's progress-bar
|
|
1355
|
+
* resolution emits a `shopConfig` drift on seeing the sentinel.
|
|
1356
|
+
*
|
|
1357
|
+
* Bars are not salvaged per element: the only reader takes the first progress-bar component's bars as a
|
|
1358
|
+
* set (one per geo segment), and a drifted bar now costs that component's bars WITH a drift, not the cart.
|
|
1359
|
+
*/
|
|
1360
|
+
settings: import_zod.z.preprocess(phpEmptyMapAsAbsent, import_zod.z.looseObject({ bars: import_zod.z.array(SmartCartBar).optional() }).optional()).catch(DRIFTED_SMART_CART_SETTINGS),
|
|
1333
1361
|
type: import_zod.z.string().optional()
|
|
1334
1362
|
});
|
|
1335
1363
|
var SmartCartConfig = import_zod.z.looseObject({
|
|
@@ -1432,7 +1460,7 @@ var CabShopConfig = import_zod2.z.object({
|
|
|
1432
1460
|
});
|
|
1433
1461
|
var CabUserConfig = import_zod2.z.object({
|
|
1434
1462
|
shop: CabShopConfig,
|
|
1435
|
-
smartCart: SmartCartConfig.nullish().catch(
|
|
1463
|
+
smartCart: SmartCartConfig.nullish().catch(DRIFTED_SMART_CART)
|
|
1436
1464
|
});
|
|
1437
1465
|
|
|
1438
1466
|
// src/schema/metadata.ts
|
package/dist/index.mjs
CHANGED
|
@@ -730,8 +730,13 @@ import { z as z2 } from "zod";
|
|
|
730
730
|
// src/schema/driftedMarkets.ts
|
|
731
731
|
var DRIFTED_MARKETS = Object.freeze({ enabled: false });
|
|
732
732
|
|
|
733
|
+
// src/schema/driftedSmartCart.ts
|
|
734
|
+
var DRIFTED_SMART_CART_SETTINGS = Object.freeze({});
|
|
735
|
+
var DRIFTED_SMART_CART = Object.freeze({});
|
|
736
|
+
|
|
733
737
|
// src/schema/smartCart.ts
|
|
734
738
|
import { z } from "zod";
|
|
739
|
+
var phpEmptyMapAsAbsent = (value) => Array.isArray(value) && value.length === 0 ? void 0 : value;
|
|
735
740
|
var SmartCartTierProduct = z.looseObject({
|
|
736
741
|
handle: z.string().optional(),
|
|
737
742
|
id: z.coerce.number().optional(),
|
|
@@ -785,7 +790,11 @@ var SmartCartTier = z.looseObject({
|
|
|
785
790
|
* `'50' → 50` and keeps the tier (a numeric-string minimum is a valid threshold, not a data defect).
|
|
786
791
|
*/
|
|
787
792
|
minimum: z.preprocess((value) => value == null ? void 0 : value, z.coerce.number().optional()),
|
|
788
|
-
|
|
793
|
+
/** An empty map arrives as PHP's `[]` (see {@link phpEmptyMapAsAbsent}) — absent, not a failed tier. */
|
|
794
|
+
presentmentCurrencies: z.preprocess(
|
|
795
|
+
phpEmptyMapAsAbsent,
|
|
796
|
+
z.looseObject({ enabled: z.boolean().optional() }).optional()
|
|
797
|
+
),
|
|
789
798
|
productAmountReachedLabel: z.boolean().optional(),
|
|
790
799
|
productAmountReachedLabelText: z.string().optional(),
|
|
791
800
|
productAmountRemainingLabel: z.boolean().optional(),
|
|
@@ -838,16 +847,35 @@ var SmartCartBar = z.looseObject({
|
|
|
838
847
|
freeShippingOnSubscription: z.boolean().optional(),
|
|
839
848
|
geolocationEnabled: z.boolean().optional(),
|
|
840
849
|
id: z.string().optional(),
|
|
841
|
-
language
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
850
|
+
/** An empty `language` map arrives as PHP's `[]` (see {@link phpEmptyMapAsAbsent}) — absent, not a failed bar. */
|
|
851
|
+
language: z.preprocess(
|
|
852
|
+
phpEmptyMapAsAbsent,
|
|
853
|
+
z.looseObject({
|
|
854
|
+
freeShippingReached: z.string().optional(),
|
|
855
|
+
freeShippingRemaining: z.string().optional(),
|
|
856
|
+
giftAreaTitle: z.string().optional()
|
|
857
|
+
}).optional()
|
|
858
|
+
),
|
|
846
859
|
name: z.string().optional(),
|
|
847
860
|
tiers: z.array(SmartCartTier).optional()
|
|
848
861
|
});
|
|
849
862
|
var SmartCartComponent = z.looseObject({
|
|
850
|
-
|
|
863
|
+
/**
|
|
864
|
+
* Every component in the layout is parsed, not just the progress bar, so this field is the blast-radius
|
|
865
|
+
* boundary (REB-25139): before it caught, b.box's `cart_items` component arriving as `settings: []` failed
|
|
866
|
+
* the component, the `components` array and the whole config — and `CabUserConfig`'s config-level catch
|
|
867
|
+
* then silently dropped every progress bar for the shop. Now:
|
|
868
|
+
*
|
|
869
|
+
* - PHP's empty-map `[]` reads as absent ({@link phpEmptyMapAsAbsent}) — normal engine vocabulary, no drift.
|
|
870
|
+
* - Any other unreadable settings (a string, a non-empty array, a bar that fails its schema) `.catch` to the
|
|
871
|
+
* {@link DRIFTED_SMART_CART_SETTINGS} identity sentinel: that component loses its settings (no bars),
|
|
872
|
+
* its siblings — and the progress bar, when it is a sibling — still parse, and the server's progress-bar
|
|
873
|
+
* resolution emits a `shopConfig` drift on seeing the sentinel.
|
|
874
|
+
*
|
|
875
|
+
* Bars are not salvaged per element: the only reader takes the first progress-bar component's bars as a
|
|
876
|
+
* set (one per geo segment), and a drifted bar now costs that component's bars WITH a drift, not the cart.
|
|
877
|
+
*/
|
|
878
|
+
settings: z.preprocess(phpEmptyMapAsAbsent, z.looseObject({ bars: z.array(SmartCartBar).optional() }).optional()).catch(DRIFTED_SMART_CART_SETTINGS),
|
|
851
879
|
type: z.string().optional()
|
|
852
880
|
});
|
|
853
881
|
var SmartCartConfig = z.looseObject({
|
|
@@ -950,7 +978,7 @@ var CabShopConfig = z2.object({
|
|
|
950
978
|
});
|
|
951
979
|
var CabUserConfig = z2.object({
|
|
952
980
|
shop: CabShopConfig,
|
|
953
|
-
smartCart: SmartCartConfig.nullish().catch(
|
|
981
|
+
smartCart: SmartCartConfig.nullish().catch(DRIFTED_SMART_CART)
|
|
954
982
|
});
|
|
955
983
|
|
|
956
984
|
// src/schema/metadata.ts
|
|
@@ -59,6 +59,11 @@ export type CabShopConfig = z.infer<typeof CabShopConfig>;
|
|
|
59
59
|
* The lean `/api/v1/user/config` projection `fetchUserConfig` parses. `smartFlows` (schema-required on
|
|
60
60
|
* the full `UserConfig` but read by no CAB path) is dropped; `smartCart` keeps its `.catch()`
|
|
61
61
|
* safety bar so a smart-cart shape drift can never fail apiKey resolution.
|
|
62
|
+
*
|
|
63
|
+
* The catch lands on the {@link DRIFTED_SMART_CART} identity sentinel (no components ⇒ no bars), not
|
|
64
|
+
* `undefined`, so the server's progress-bar resolution can tell a drifted config from a shop with no smart
|
|
65
|
+
* cart (`null`/absent stay `null`/`undefined`) and emit a `shopConfig` drift (REB-25139: this catch used to
|
|
66
|
+
* drop every progress bar for the shop silently).
|
|
62
67
|
*/
|
|
63
68
|
export declare const CabUserConfig: z.ZodObject<{
|
|
64
69
|
shop: z.ZodObject<{
|
|
@@ -95,7 +100,7 @@ export declare const CabUserConfig: z.ZodObject<{
|
|
|
95
100
|
}, z.core.$strip>;
|
|
96
101
|
smartCart: z.ZodCatch<z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
97
102
|
components: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
98
|
-
settings: z.ZodOptional<z.ZodObject<{
|
|
103
|
+
settings: z.ZodCatch<z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
99
104
|
bars: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
100
105
|
countryCodes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
101
106
|
excludeDiscountInSubtotal: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -105,11 +110,11 @@ export declare const CabUserConfig: z.ZodObject<{
|
|
|
105
110
|
freeShippingOnSubscription: z.ZodOptional<z.ZodBoolean>;
|
|
106
111
|
geolocationEnabled: z.ZodOptional<z.ZodBoolean>;
|
|
107
112
|
id: z.ZodOptional<z.ZodString>;
|
|
108
|
-
language: z.ZodOptional<z.ZodObject<{
|
|
113
|
+
language: z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
109
114
|
freeShippingReached: z.ZodOptional<z.ZodString>;
|
|
110
115
|
freeShippingRemaining: z.ZodOptional<z.ZodString>;
|
|
111
116
|
giftAreaTitle: z.ZodOptional<z.ZodString>;
|
|
112
|
-
}, z.core.$loose
|
|
117
|
+
}, z.core.$loose>>>;
|
|
113
118
|
name: z.ZodOptional<z.ZodString>;
|
|
114
119
|
tiers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
115
120
|
allProducts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -141,9 +146,9 @@ export declare const CabUserConfig: z.ZodObject<{
|
|
|
141
146
|
filterOosVariants: z.ZodOptional<z.ZodBoolean>;
|
|
142
147
|
id: z.ZodOptional<z.ZodString>;
|
|
143
148
|
minimum: z.ZodPreprocess<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
144
|
-
presentmentCurrencies: z.ZodOptional<z.ZodObject<{
|
|
149
|
+
presentmentCurrencies: z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
145
150
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
146
|
-
}, z.core.$loose
|
|
151
|
+
}, z.core.$loose>>>;
|
|
147
152
|
productAmountReachedLabel: z.ZodOptional<z.ZodBoolean>;
|
|
148
153
|
productAmountReachedLabelText: z.ZodOptional<z.ZodString>;
|
|
149
154
|
productAmountRemainingLabel: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -161,7 +166,7 @@ export declare const CabUserConfig: z.ZodObject<{
|
|
|
161
166
|
unlockConditionType: z.ZodOptional<z.ZodString>;
|
|
162
167
|
}, z.core.$loose>>>;
|
|
163
168
|
}, z.core.$loose>>>;
|
|
164
|
-
}, z.core.$loose
|
|
169
|
+
}, z.core.$loose>>>>;
|
|
165
170
|
type: z.ZodOptional<z.ZodString>;
|
|
166
171
|
}, z.core.$loose>>>;
|
|
167
172
|
}, z.core.$loose>>>>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity sentinels for the smart-cart salvages (REB-25139), on the {@link file://./driftedMarkets.ts} pattern:
|
|
3
|
+
* the schema's `.catch` returns one of THESE frozen objects, and the server's progress-bar resolution detects the
|
|
4
|
+
* drift by reference and emits a `shopConfig` drift. Both read as "no bars" to every consumer — `settings: {}`
|
|
5
|
+
* carries no `bars`, a config `{}` carries no `components` — so a consumer that never checks identity degrades
|
|
6
|
+
* exactly as it would on a missing field.
|
|
7
|
+
*
|
|
8
|
+
* Deliberately NOT re-exported from `src/schema/index.ts` for the same reason as `DRIFTED_MARKETS`: identity only
|
|
9
|
+
* holds within one bundle, and the comparison lives in `./server` (`server/widgetSettings.ts`), where the
|
|
10
|
+
* `CabUserConfig` parse that produced the value also runs.
|
|
11
|
+
*/
|
|
12
|
+
/** A smart-cart component whose `settings` failed to parse: dropped to no settings, its siblings kept. */
|
|
13
|
+
export declare const DRIFTED_SMART_CART_SETTINGS: Readonly<{}>;
|
|
14
|
+
/** A smart-cart config that failed to parse as a whole (e.g. a non-array `components`): no components. */
|
|
15
|
+
export declare const DRIFTED_SMART_CART: Readonly<{}>;
|
|
@@ -69,9 +69,9 @@ export declare const SmartCartTier: z.ZodObject<{
|
|
|
69
69
|
filterOosVariants: z.ZodOptional<z.ZodBoolean>;
|
|
70
70
|
id: z.ZodOptional<z.ZodString>;
|
|
71
71
|
minimum: z.ZodPreprocess<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
72
|
-
presentmentCurrencies: z.ZodOptional<z.ZodObject<{
|
|
72
|
+
presentmentCurrencies: z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
73
73
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
74
|
-
}, z.core.$loose
|
|
74
|
+
}, z.core.$loose>>>;
|
|
75
75
|
productAmountReachedLabel: z.ZodOptional<z.ZodBoolean>;
|
|
76
76
|
productAmountReachedLabelText: z.ZodOptional<z.ZodString>;
|
|
77
77
|
productAmountRemainingLabel: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -102,11 +102,11 @@ export declare const SmartCartBar: z.ZodObject<{
|
|
|
102
102
|
freeShippingOnSubscription: z.ZodOptional<z.ZodBoolean>;
|
|
103
103
|
geolocationEnabled: z.ZodOptional<z.ZodBoolean>;
|
|
104
104
|
id: z.ZodOptional<z.ZodString>;
|
|
105
|
-
language: z.ZodOptional<z.ZodObject<{
|
|
105
|
+
language: z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
106
106
|
freeShippingReached: z.ZodOptional<z.ZodString>;
|
|
107
107
|
freeShippingRemaining: z.ZodOptional<z.ZodString>;
|
|
108
108
|
giftAreaTitle: z.ZodOptional<z.ZodString>;
|
|
109
|
-
}, z.core.$loose
|
|
109
|
+
}, z.core.$loose>>>;
|
|
110
110
|
name: z.ZodOptional<z.ZodString>;
|
|
111
111
|
tiers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
112
112
|
allProducts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -138,9 +138,9 @@ export declare const SmartCartBar: z.ZodObject<{
|
|
|
138
138
|
filterOosVariants: z.ZodOptional<z.ZodBoolean>;
|
|
139
139
|
id: z.ZodOptional<z.ZodString>;
|
|
140
140
|
minimum: z.ZodPreprocess<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
141
|
-
presentmentCurrencies: z.ZodOptional<z.ZodObject<{
|
|
141
|
+
presentmentCurrencies: z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
142
142
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
143
|
-
}, z.core.$loose
|
|
143
|
+
}, z.core.$loose>>>;
|
|
144
144
|
productAmountReachedLabel: z.ZodOptional<z.ZodBoolean>;
|
|
145
145
|
productAmountReachedLabelText: z.ZodOptional<z.ZodString>;
|
|
146
146
|
productAmountRemainingLabel: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -160,7 +160,7 @@ export declare const SmartCartBar: z.ZodObject<{
|
|
|
160
160
|
}, z.core.$loose>;
|
|
161
161
|
/** A smart-cart layout component; only `type === 'tiered_progress_bar'` carries the bars we render. */
|
|
162
162
|
export declare const SmartCartComponent: z.ZodObject<{
|
|
163
|
-
settings: z.ZodOptional<z.ZodObject<{
|
|
163
|
+
settings: z.ZodCatch<z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
164
164
|
bars: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
165
165
|
countryCodes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
166
166
|
excludeDiscountInSubtotal: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -170,11 +170,11 @@ export declare const SmartCartComponent: z.ZodObject<{
|
|
|
170
170
|
freeShippingOnSubscription: z.ZodOptional<z.ZodBoolean>;
|
|
171
171
|
geolocationEnabled: z.ZodOptional<z.ZodBoolean>;
|
|
172
172
|
id: z.ZodOptional<z.ZodString>;
|
|
173
|
-
language: z.ZodOptional<z.ZodObject<{
|
|
173
|
+
language: z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
174
174
|
freeShippingReached: z.ZodOptional<z.ZodString>;
|
|
175
175
|
freeShippingRemaining: z.ZodOptional<z.ZodString>;
|
|
176
176
|
giftAreaTitle: z.ZodOptional<z.ZodString>;
|
|
177
|
-
}, z.core.$loose
|
|
177
|
+
}, z.core.$loose>>>;
|
|
178
178
|
name: z.ZodOptional<z.ZodString>;
|
|
179
179
|
tiers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
180
180
|
allProducts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -206,9 +206,9 @@ export declare const SmartCartComponent: z.ZodObject<{
|
|
|
206
206
|
filterOosVariants: z.ZodOptional<z.ZodBoolean>;
|
|
207
207
|
id: z.ZodOptional<z.ZodString>;
|
|
208
208
|
minimum: z.ZodPreprocess<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
209
|
-
presentmentCurrencies: z.ZodOptional<z.ZodObject<{
|
|
209
|
+
presentmentCurrencies: z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
210
210
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
211
|
-
}, z.core.$loose
|
|
211
|
+
}, z.core.$loose>>>;
|
|
212
212
|
productAmountReachedLabel: z.ZodOptional<z.ZodBoolean>;
|
|
213
213
|
productAmountReachedLabelText: z.ZodOptional<z.ZodString>;
|
|
214
214
|
productAmountRemainingLabel: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -226,7 +226,7 @@ export declare const SmartCartComponent: z.ZodObject<{
|
|
|
226
226
|
unlockConditionType: z.ZodOptional<z.ZodString>;
|
|
227
227
|
}, z.core.$loose>>>;
|
|
228
228
|
}, z.core.$loose>>>;
|
|
229
|
-
}, z.core.$loose
|
|
229
|
+
}, z.core.$loose>>>>;
|
|
230
230
|
type: z.ZodOptional<z.ZodString>;
|
|
231
231
|
}, z.core.$loose>;
|
|
232
232
|
/**
|
|
@@ -234,12 +234,12 @@ export declare const SmartCartComponent: z.ZodObject<{
|
|
|
234
234
|
* `tiered_progress_bar` component(s) and their bars/tiers. The rest of the onsite
|
|
235
235
|
* smart-cart config (buy-more-save-more, custom templates/CSS, callbacks) is out of
|
|
236
236
|
* scope — `looseObject` preserves-but-ignores it. Parsed under `UserConfig.smartCart`
|
|
237
|
-
*
|
|
238
|
-
* offers / monetize / analytics / gift validation.
|
|
237
|
+
* (`.catch(undefined)`) and `CabUserConfig.smartCart` (`.catch` to a drift sentinel) so a shape
|
|
238
|
+
* drift here can NEVER break apiKey resolution for offers / monetize / analytics / gift validation.
|
|
239
239
|
*/
|
|
240
240
|
export declare const SmartCartConfig: z.ZodObject<{
|
|
241
241
|
components: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
242
|
-
settings: z.ZodOptional<z.ZodObject<{
|
|
242
|
+
settings: z.ZodCatch<z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
243
243
|
bars: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
244
244
|
countryCodes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
245
245
|
excludeDiscountInSubtotal: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -249,11 +249,11 @@ export declare const SmartCartConfig: z.ZodObject<{
|
|
|
249
249
|
freeShippingOnSubscription: z.ZodOptional<z.ZodBoolean>;
|
|
250
250
|
geolocationEnabled: z.ZodOptional<z.ZodBoolean>;
|
|
251
251
|
id: z.ZodOptional<z.ZodString>;
|
|
252
|
-
language: z.ZodOptional<z.ZodObject<{
|
|
252
|
+
language: z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
253
253
|
freeShippingReached: z.ZodOptional<z.ZodString>;
|
|
254
254
|
freeShippingRemaining: z.ZodOptional<z.ZodString>;
|
|
255
255
|
giftAreaTitle: z.ZodOptional<z.ZodString>;
|
|
256
|
-
}, z.core.$loose
|
|
256
|
+
}, z.core.$loose>>>;
|
|
257
257
|
name: z.ZodOptional<z.ZodString>;
|
|
258
258
|
tiers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
259
259
|
allProducts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -285,9 +285,9 @@ export declare const SmartCartConfig: z.ZodObject<{
|
|
|
285
285
|
filterOosVariants: z.ZodOptional<z.ZodBoolean>;
|
|
286
286
|
id: z.ZodOptional<z.ZodString>;
|
|
287
287
|
minimum: z.ZodPreprocess<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
288
|
-
presentmentCurrencies: z.ZodOptional<z.ZodObject<{
|
|
288
|
+
presentmentCurrencies: z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
289
289
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
290
|
-
}, z.core.$loose
|
|
290
|
+
}, z.core.$loose>>>;
|
|
291
291
|
productAmountReachedLabel: z.ZodOptional<z.ZodBoolean>;
|
|
292
292
|
productAmountReachedLabelText: z.ZodOptional<z.ZodString>;
|
|
293
293
|
productAmountRemainingLabel: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -305,7 +305,7 @@ export declare const SmartCartConfig: z.ZodObject<{
|
|
|
305
305
|
unlockConditionType: z.ZodOptional<z.ZodString>;
|
|
306
306
|
}, z.core.$loose>>>;
|
|
307
307
|
}, z.core.$loose>>>;
|
|
308
|
-
}, z.core.$loose
|
|
308
|
+
}, z.core.$loose>>>>;
|
|
309
309
|
type: z.ZodOptional<z.ZodString>;
|
|
310
310
|
}, z.core.$loose>>>;
|
|
311
311
|
}, z.core.$loose>;
|
|
@@ -111,6 +111,13 @@ var ShopConfig = import_zod.z.object({
|
|
|
111
111
|
|
|
112
112
|
// src/schema/smartCart.ts
|
|
113
113
|
var import_zod2 = require("zod");
|
|
114
|
+
|
|
115
|
+
// src/schema/driftedSmartCart.ts
|
|
116
|
+
var DRIFTED_SMART_CART_SETTINGS = Object.freeze({});
|
|
117
|
+
var DRIFTED_SMART_CART = Object.freeze({});
|
|
118
|
+
|
|
119
|
+
// src/schema/smartCart.ts
|
|
120
|
+
var phpEmptyMapAsAbsent = (value) => Array.isArray(value) && value.length === 0 ? void 0 : value;
|
|
114
121
|
var SmartCartTierProduct = import_zod2.z.looseObject({
|
|
115
122
|
handle: import_zod2.z.string().optional(),
|
|
116
123
|
id: import_zod2.z.coerce.number().optional(),
|
|
@@ -164,7 +171,11 @@ var SmartCartTier = import_zod2.z.looseObject({
|
|
|
164
171
|
* `'50' → 50` and keeps the tier (a numeric-string minimum is a valid threshold, not a data defect).
|
|
165
172
|
*/
|
|
166
173
|
minimum: import_zod2.z.preprocess((value) => value == null ? void 0 : value, import_zod2.z.coerce.number().optional()),
|
|
167
|
-
|
|
174
|
+
/** An empty map arrives as PHP's `[]` (see {@link phpEmptyMapAsAbsent}) — absent, not a failed tier. */
|
|
175
|
+
presentmentCurrencies: import_zod2.z.preprocess(
|
|
176
|
+
phpEmptyMapAsAbsent,
|
|
177
|
+
import_zod2.z.looseObject({ enabled: import_zod2.z.boolean().optional() }).optional()
|
|
178
|
+
),
|
|
168
179
|
productAmountReachedLabel: import_zod2.z.boolean().optional(),
|
|
169
180
|
productAmountReachedLabelText: import_zod2.z.string().optional(),
|
|
170
181
|
productAmountRemainingLabel: import_zod2.z.boolean().optional(),
|
|
@@ -217,16 +228,35 @@ var SmartCartBar = import_zod2.z.looseObject({
|
|
|
217
228
|
freeShippingOnSubscription: import_zod2.z.boolean().optional(),
|
|
218
229
|
geolocationEnabled: import_zod2.z.boolean().optional(),
|
|
219
230
|
id: import_zod2.z.string().optional(),
|
|
220
|
-
language
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
231
|
+
/** An empty `language` map arrives as PHP's `[]` (see {@link phpEmptyMapAsAbsent}) — absent, not a failed bar. */
|
|
232
|
+
language: import_zod2.z.preprocess(
|
|
233
|
+
phpEmptyMapAsAbsent,
|
|
234
|
+
import_zod2.z.looseObject({
|
|
235
|
+
freeShippingReached: import_zod2.z.string().optional(),
|
|
236
|
+
freeShippingRemaining: import_zod2.z.string().optional(),
|
|
237
|
+
giftAreaTitle: import_zod2.z.string().optional()
|
|
238
|
+
}).optional()
|
|
239
|
+
),
|
|
225
240
|
name: import_zod2.z.string().optional(),
|
|
226
241
|
tiers: import_zod2.z.array(SmartCartTier).optional()
|
|
227
242
|
});
|
|
228
243
|
var SmartCartComponent = import_zod2.z.looseObject({
|
|
229
|
-
|
|
244
|
+
/**
|
|
245
|
+
* Every component in the layout is parsed, not just the progress bar, so this field is the blast-radius
|
|
246
|
+
* boundary (REB-25139): before it caught, b.box's `cart_items` component arriving as `settings: []` failed
|
|
247
|
+
* the component, the `components` array and the whole config — and `CabUserConfig`'s config-level catch
|
|
248
|
+
* then silently dropped every progress bar for the shop. Now:
|
|
249
|
+
*
|
|
250
|
+
* - PHP's empty-map `[]` reads as absent ({@link phpEmptyMapAsAbsent}) — normal engine vocabulary, no drift.
|
|
251
|
+
* - Any other unreadable settings (a string, a non-empty array, a bar that fails its schema) `.catch` to the
|
|
252
|
+
* {@link DRIFTED_SMART_CART_SETTINGS} identity sentinel: that component loses its settings (no bars),
|
|
253
|
+
* its siblings — and the progress bar, when it is a sibling — still parse, and the server's progress-bar
|
|
254
|
+
* resolution emits a `shopConfig` drift on seeing the sentinel.
|
|
255
|
+
*
|
|
256
|
+
* Bars are not salvaged per element: the only reader takes the first progress-bar component's bars as a
|
|
257
|
+
* set (one per geo segment), and a drifted bar now costs that component's bars WITH a drift, not the cart.
|
|
258
|
+
*/
|
|
259
|
+
settings: import_zod2.z.preprocess(phpEmptyMapAsAbsent, import_zod2.z.looseObject({ bars: import_zod2.z.array(SmartCartBar).optional() }).optional()).catch(DRIFTED_SMART_CART_SETTINGS),
|
|
230
260
|
type: import_zod2.z.string().optional()
|
|
231
261
|
});
|
|
232
262
|
var SmartCartConfig = import_zod2.z.looseObject({
|
|
@@ -87,6 +87,13 @@ var ShopConfig = z.object({
|
|
|
87
87
|
|
|
88
88
|
// src/schema/smartCart.ts
|
|
89
89
|
import { z as z2 } from "zod";
|
|
90
|
+
|
|
91
|
+
// src/schema/driftedSmartCart.ts
|
|
92
|
+
var DRIFTED_SMART_CART_SETTINGS = Object.freeze({});
|
|
93
|
+
var DRIFTED_SMART_CART = Object.freeze({});
|
|
94
|
+
|
|
95
|
+
// src/schema/smartCart.ts
|
|
96
|
+
var phpEmptyMapAsAbsent = (value) => Array.isArray(value) && value.length === 0 ? void 0 : value;
|
|
90
97
|
var SmartCartTierProduct = z2.looseObject({
|
|
91
98
|
handle: z2.string().optional(),
|
|
92
99
|
id: z2.coerce.number().optional(),
|
|
@@ -140,7 +147,11 @@ var SmartCartTier = z2.looseObject({
|
|
|
140
147
|
* `'50' → 50` and keeps the tier (a numeric-string minimum is a valid threshold, not a data defect).
|
|
141
148
|
*/
|
|
142
149
|
minimum: z2.preprocess((value) => value == null ? void 0 : value, z2.coerce.number().optional()),
|
|
143
|
-
|
|
150
|
+
/** An empty map arrives as PHP's `[]` (see {@link phpEmptyMapAsAbsent}) — absent, not a failed tier. */
|
|
151
|
+
presentmentCurrencies: z2.preprocess(
|
|
152
|
+
phpEmptyMapAsAbsent,
|
|
153
|
+
z2.looseObject({ enabled: z2.boolean().optional() }).optional()
|
|
154
|
+
),
|
|
144
155
|
productAmountReachedLabel: z2.boolean().optional(),
|
|
145
156
|
productAmountReachedLabelText: z2.string().optional(),
|
|
146
157
|
productAmountRemainingLabel: z2.boolean().optional(),
|
|
@@ -193,16 +204,35 @@ var SmartCartBar = z2.looseObject({
|
|
|
193
204
|
freeShippingOnSubscription: z2.boolean().optional(),
|
|
194
205
|
geolocationEnabled: z2.boolean().optional(),
|
|
195
206
|
id: z2.string().optional(),
|
|
196
|
-
language
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
207
|
+
/** An empty `language` map arrives as PHP's `[]` (see {@link phpEmptyMapAsAbsent}) — absent, not a failed bar. */
|
|
208
|
+
language: z2.preprocess(
|
|
209
|
+
phpEmptyMapAsAbsent,
|
|
210
|
+
z2.looseObject({
|
|
211
|
+
freeShippingReached: z2.string().optional(),
|
|
212
|
+
freeShippingRemaining: z2.string().optional(),
|
|
213
|
+
giftAreaTitle: z2.string().optional()
|
|
214
|
+
}).optional()
|
|
215
|
+
),
|
|
201
216
|
name: z2.string().optional(),
|
|
202
217
|
tiers: z2.array(SmartCartTier).optional()
|
|
203
218
|
});
|
|
204
219
|
var SmartCartComponent = z2.looseObject({
|
|
205
|
-
|
|
220
|
+
/**
|
|
221
|
+
* Every component in the layout is parsed, not just the progress bar, so this field is the blast-radius
|
|
222
|
+
* boundary (REB-25139): before it caught, b.box's `cart_items` component arriving as `settings: []` failed
|
|
223
|
+
* the component, the `components` array and the whole config — and `CabUserConfig`'s config-level catch
|
|
224
|
+
* then silently dropped every progress bar for the shop. Now:
|
|
225
|
+
*
|
|
226
|
+
* - PHP's empty-map `[]` reads as absent ({@link phpEmptyMapAsAbsent}) — normal engine vocabulary, no drift.
|
|
227
|
+
* - Any other unreadable settings (a string, a non-empty array, a bar that fails its schema) `.catch` to the
|
|
228
|
+
* {@link DRIFTED_SMART_CART_SETTINGS} identity sentinel: that component loses its settings (no bars),
|
|
229
|
+
* its siblings — and the progress bar, when it is a sibling — still parse, and the server's progress-bar
|
|
230
|
+
* resolution emits a `shopConfig` drift on seeing the sentinel.
|
|
231
|
+
*
|
|
232
|
+
* Bars are not salvaged per element: the only reader takes the first progress-bar component's bars as a
|
|
233
|
+
* set (one per geo segment), and a drifted bar now costs that component's bars WITH a drift, not the cart.
|
|
234
|
+
*/
|
|
235
|
+
settings: z2.preprocess(phpEmptyMapAsAbsent, z2.looseObject({ bars: z2.array(SmartCartBar).optional() }).optional()).catch(DRIFTED_SMART_CART_SETTINGS),
|
|
206
236
|
type: z2.string().optional()
|
|
207
237
|
});
|
|
208
238
|
var SmartCartConfig = z2.looseObject({
|
|
@@ -80,7 +80,7 @@ export declare const UserConfig: z.ZodObject<{
|
|
|
80
80
|
}, z.core.$strip>;
|
|
81
81
|
smartCart: z.ZodCatch<z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
82
82
|
components: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
83
|
-
settings: z.ZodOptional<z.ZodObject<{
|
|
83
|
+
settings: z.ZodCatch<z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
84
84
|
bars: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
85
85
|
countryCodes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
86
86
|
excludeDiscountInSubtotal: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -90,11 +90,11 @@ export declare const UserConfig: z.ZodObject<{
|
|
|
90
90
|
freeShippingOnSubscription: z.ZodOptional<z.ZodBoolean>;
|
|
91
91
|
geolocationEnabled: z.ZodOptional<z.ZodBoolean>;
|
|
92
92
|
id: z.ZodOptional<z.ZodString>;
|
|
93
|
-
language: z.ZodOptional<z.ZodObject<{
|
|
93
|
+
language: z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
94
94
|
freeShippingReached: z.ZodOptional<z.ZodString>;
|
|
95
95
|
freeShippingRemaining: z.ZodOptional<z.ZodString>;
|
|
96
96
|
giftAreaTitle: z.ZodOptional<z.ZodString>;
|
|
97
|
-
}, z.core.$loose
|
|
97
|
+
}, z.core.$loose>>>;
|
|
98
98
|
name: z.ZodOptional<z.ZodString>;
|
|
99
99
|
tiers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
100
100
|
allProducts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -126,9 +126,9 @@ export declare const UserConfig: z.ZodObject<{
|
|
|
126
126
|
filterOosVariants: z.ZodOptional<z.ZodBoolean>;
|
|
127
127
|
id: z.ZodOptional<z.ZodString>;
|
|
128
128
|
minimum: z.ZodPreprocess<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
129
|
-
presentmentCurrencies: z.ZodOptional<z.ZodObject<{
|
|
129
|
+
presentmentCurrencies: z.ZodPreprocess<z.ZodOptional<z.ZodObject<{
|
|
130
130
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
131
|
-
}, z.core.$loose
|
|
131
|
+
}, z.core.$loose>>>;
|
|
132
132
|
productAmountReachedLabel: z.ZodOptional<z.ZodBoolean>;
|
|
133
133
|
productAmountReachedLabelText: z.ZodOptional<z.ZodString>;
|
|
134
134
|
productAmountRemainingLabel: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -146,7 +146,7 @@ export declare const UserConfig: z.ZodObject<{
|
|
|
146
146
|
unlockConditionType: z.ZodOptional<z.ZodString>;
|
|
147
147
|
}, z.core.$loose>>>;
|
|
148
148
|
}, z.core.$loose>>>;
|
|
149
|
-
}, z.core.$loose
|
|
149
|
+
}, z.core.$loose>>>>;
|
|
150
150
|
type: z.ZodOptional<z.ZodString>;
|
|
151
151
|
}, z.core.$loose>>>;
|
|
152
152
|
}, z.core.$loose>>>>;
|
package/dist/server/index.cjs
CHANGED
|
@@ -1560,8 +1560,13 @@ var import_zod20 = require("zod");
|
|
|
1560
1560
|
// src/schema/driftedMarkets.ts
|
|
1561
1561
|
var DRIFTED_MARKETS = Object.freeze({ enabled: false });
|
|
1562
1562
|
|
|
1563
|
+
// src/schema/driftedSmartCart.ts
|
|
1564
|
+
var DRIFTED_SMART_CART_SETTINGS = Object.freeze({});
|
|
1565
|
+
var DRIFTED_SMART_CART = Object.freeze({});
|
|
1566
|
+
|
|
1563
1567
|
// src/schema/smartCart.ts
|
|
1564
1568
|
var import_zod19 = require("zod");
|
|
1569
|
+
var phpEmptyMapAsAbsent = (value) => Array.isArray(value) && value.length === 0 ? void 0 : value;
|
|
1565
1570
|
var SmartCartTierProduct = import_zod19.z.looseObject({
|
|
1566
1571
|
handle: import_zod19.z.string().optional(),
|
|
1567
1572
|
id: import_zod19.z.coerce.number().optional(),
|
|
@@ -1615,7 +1620,11 @@ var SmartCartTier = import_zod19.z.looseObject({
|
|
|
1615
1620
|
* `'50' → 50` and keeps the tier (a numeric-string minimum is a valid threshold, not a data defect).
|
|
1616
1621
|
*/
|
|
1617
1622
|
minimum: import_zod19.z.preprocess((value) => value == null ? void 0 : value, import_zod19.z.coerce.number().optional()),
|
|
1618
|
-
|
|
1623
|
+
/** An empty map arrives as PHP's `[]` (see {@link phpEmptyMapAsAbsent}) — absent, not a failed tier. */
|
|
1624
|
+
presentmentCurrencies: import_zod19.z.preprocess(
|
|
1625
|
+
phpEmptyMapAsAbsent,
|
|
1626
|
+
import_zod19.z.looseObject({ enabled: import_zod19.z.boolean().optional() }).optional()
|
|
1627
|
+
),
|
|
1619
1628
|
productAmountReachedLabel: import_zod19.z.boolean().optional(),
|
|
1620
1629
|
productAmountReachedLabelText: import_zod19.z.string().optional(),
|
|
1621
1630
|
productAmountRemainingLabel: import_zod19.z.boolean().optional(),
|
|
@@ -1668,16 +1677,35 @@ var SmartCartBar = import_zod19.z.looseObject({
|
|
|
1668
1677
|
freeShippingOnSubscription: import_zod19.z.boolean().optional(),
|
|
1669
1678
|
geolocationEnabled: import_zod19.z.boolean().optional(),
|
|
1670
1679
|
id: import_zod19.z.string().optional(),
|
|
1671
|
-
language
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1680
|
+
/** An empty `language` map arrives as PHP's `[]` (see {@link phpEmptyMapAsAbsent}) — absent, not a failed bar. */
|
|
1681
|
+
language: import_zod19.z.preprocess(
|
|
1682
|
+
phpEmptyMapAsAbsent,
|
|
1683
|
+
import_zod19.z.looseObject({
|
|
1684
|
+
freeShippingReached: import_zod19.z.string().optional(),
|
|
1685
|
+
freeShippingRemaining: import_zod19.z.string().optional(),
|
|
1686
|
+
giftAreaTitle: import_zod19.z.string().optional()
|
|
1687
|
+
}).optional()
|
|
1688
|
+
),
|
|
1676
1689
|
name: import_zod19.z.string().optional(),
|
|
1677
1690
|
tiers: import_zod19.z.array(SmartCartTier).optional()
|
|
1678
1691
|
});
|
|
1679
1692
|
var SmartCartComponent = import_zod19.z.looseObject({
|
|
1680
|
-
|
|
1693
|
+
/**
|
|
1694
|
+
* Every component in the layout is parsed, not just the progress bar, so this field is the blast-radius
|
|
1695
|
+
* boundary (REB-25139): before it caught, b.box's `cart_items` component arriving as `settings: []` failed
|
|
1696
|
+
* the component, the `components` array and the whole config — and `CabUserConfig`'s config-level catch
|
|
1697
|
+
* then silently dropped every progress bar for the shop. Now:
|
|
1698
|
+
*
|
|
1699
|
+
* - PHP's empty-map `[]` reads as absent ({@link phpEmptyMapAsAbsent}) — normal engine vocabulary, no drift.
|
|
1700
|
+
* - Any other unreadable settings (a string, a non-empty array, a bar that fails its schema) `.catch` to the
|
|
1701
|
+
* {@link DRIFTED_SMART_CART_SETTINGS} identity sentinel: that component loses its settings (no bars),
|
|
1702
|
+
* its siblings — and the progress bar, when it is a sibling — still parse, and the server's progress-bar
|
|
1703
|
+
* resolution emits a `shopConfig` drift on seeing the sentinel.
|
|
1704
|
+
*
|
|
1705
|
+
* Bars are not salvaged per element: the only reader takes the first progress-bar component's bars as a
|
|
1706
|
+
* set (one per geo segment), and a drifted bar now costs that component's bars WITH a drift, not the cart.
|
|
1707
|
+
*/
|
|
1708
|
+
settings: import_zod19.z.preprocess(phpEmptyMapAsAbsent, import_zod19.z.looseObject({ bars: import_zod19.z.array(SmartCartBar).optional() }).optional()).catch(DRIFTED_SMART_CART_SETTINGS),
|
|
1681
1709
|
type: import_zod19.z.string().optional()
|
|
1682
1710
|
});
|
|
1683
1711
|
var SmartCartConfig = import_zod19.z.looseObject({
|
|
@@ -1780,7 +1808,7 @@ var CabShopConfig = import_zod20.z.object({
|
|
|
1780
1808
|
});
|
|
1781
1809
|
var CabUserConfig = import_zod20.z.object({
|
|
1782
1810
|
shop: CabShopConfig,
|
|
1783
|
-
smartCart: SmartCartConfig.nullish().catch(
|
|
1811
|
+
smartCart: SmartCartConfig.nullish().catch(DRIFTED_SMART_CART)
|
|
1784
1812
|
});
|
|
1785
1813
|
|
|
1786
1814
|
// src/schema/widgets/checkout-and-beyond/image.ts
|
|
@@ -6092,9 +6120,26 @@ var dispatchWidgetTransform = (id, normalized, report) => {
|
|
|
6092
6120
|
if (isOfferV1(normalized)) return convertOfferToV2({ id, name: normalized.name, settings: normalized });
|
|
6093
6121
|
return normalized;
|
|
6094
6122
|
};
|
|
6123
|
+
var reportSmartCartDrift = (shop, smartCart, ctx) => {
|
|
6124
|
+
if (smartCart === DRIFTED_SMART_CART) {
|
|
6125
|
+
ctx.reportDrift?.({
|
|
6126
|
+
detail: `smart cart config unreadable (drifted shape) \u2014 every progress bar dropped for ${shop}`,
|
|
6127
|
+
kind: "shopConfig"
|
|
6128
|
+
});
|
|
6129
|
+
return;
|
|
6130
|
+
}
|
|
6131
|
+
const drifted = (smartCart?.components ?? []).filter((entry) => entry.settings === DRIFTED_SMART_CART_SETTINGS);
|
|
6132
|
+
if (drifted.length) {
|
|
6133
|
+
ctx.reportDrift?.({
|
|
6134
|
+
detail: `smart cart component settings unreadable (drifted shape) \u2014 dropped for ${drifted.map((entry) => entry.type ?? "untyped").join(", ")} on ${shop}`,
|
|
6135
|
+
kind: "shopConfig"
|
|
6136
|
+
});
|
|
6137
|
+
}
|
|
6138
|
+
};
|
|
6095
6139
|
var fetchProgressBarContext = async (shop, ctx, prefetched) => {
|
|
6096
6140
|
const config = prefetched === void 0 ? await fetchUserConfig({ shop }, ctx).catch(() => void 0) : prefetched;
|
|
6097
6141
|
if (!config) return {};
|
|
6142
|
+
reportSmartCartDrift(shop, config.smartCart, ctx);
|
|
6098
6143
|
if (config.shop.billingVersion === "v6" && config.shop.activePackages.some((pkg) => pkg.shortName === "")) {
|
|
6099
6144
|
ctx.reportDrift?.({
|
|
6100
6145
|
detail: "shop config active package entry inerted (drifted shape) \u2014 smart-cart entitlement may misgate",
|
package/dist/server/index.mjs
CHANGED
|
@@ -1487,8 +1487,13 @@ import { z as z20 } from "zod";
|
|
|
1487
1487
|
// src/schema/driftedMarkets.ts
|
|
1488
1488
|
var DRIFTED_MARKETS = Object.freeze({ enabled: false });
|
|
1489
1489
|
|
|
1490
|
+
// src/schema/driftedSmartCart.ts
|
|
1491
|
+
var DRIFTED_SMART_CART_SETTINGS = Object.freeze({});
|
|
1492
|
+
var DRIFTED_SMART_CART = Object.freeze({});
|
|
1493
|
+
|
|
1490
1494
|
// src/schema/smartCart.ts
|
|
1491
1495
|
import { z as z19 } from "zod";
|
|
1496
|
+
var phpEmptyMapAsAbsent = (value) => Array.isArray(value) && value.length === 0 ? void 0 : value;
|
|
1492
1497
|
var SmartCartTierProduct = z19.looseObject({
|
|
1493
1498
|
handle: z19.string().optional(),
|
|
1494
1499
|
id: z19.coerce.number().optional(),
|
|
@@ -1542,7 +1547,11 @@ var SmartCartTier = z19.looseObject({
|
|
|
1542
1547
|
* `'50' → 50` and keeps the tier (a numeric-string minimum is a valid threshold, not a data defect).
|
|
1543
1548
|
*/
|
|
1544
1549
|
minimum: z19.preprocess((value) => value == null ? void 0 : value, z19.coerce.number().optional()),
|
|
1545
|
-
|
|
1550
|
+
/** An empty map arrives as PHP's `[]` (see {@link phpEmptyMapAsAbsent}) — absent, not a failed tier. */
|
|
1551
|
+
presentmentCurrencies: z19.preprocess(
|
|
1552
|
+
phpEmptyMapAsAbsent,
|
|
1553
|
+
z19.looseObject({ enabled: z19.boolean().optional() }).optional()
|
|
1554
|
+
),
|
|
1546
1555
|
productAmountReachedLabel: z19.boolean().optional(),
|
|
1547
1556
|
productAmountReachedLabelText: z19.string().optional(),
|
|
1548
1557
|
productAmountRemainingLabel: z19.boolean().optional(),
|
|
@@ -1595,16 +1604,35 @@ var SmartCartBar = z19.looseObject({
|
|
|
1595
1604
|
freeShippingOnSubscription: z19.boolean().optional(),
|
|
1596
1605
|
geolocationEnabled: z19.boolean().optional(),
|
|
1597
1606
|
id: z19.string().optional(),
|
|
1598
|
-
language
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1607
|
+
/** An empty `language` map arrives as PHP's `[]` (see {@link phpEmptyMapAsAbsent}) — absent, not a failed bar. */
|
|
1608
|
+
language: z19.preprocess(
|
|
1609
|
+
phpEmptyMapAsAbsent,
|
|
1610
|
+
z19.looseObject({
|
|
1611
|
+
freeShippingReached: z19.string().optional(),
|
|
1612
|
+
freeShippingRemaining: z19.string().optional(),
|
|
1613
|
+
giftAreaTitle: z19.string().optional()
|
|
1614
|
+
}).optional()
|
|
1615
|
+
),
|
|
1603
1616
|
name: z19.string().optional(),
|
|
1604
1617
|
tiers: z19.array(SmartCartTier).optional()
|
|
1605
1618
|
});
|
|
1606
1619
|
var SmartCartComponent = z19.looseObject({
|
|
1607
|
-
|
|
1620
|
+
/**
|
|
1621
|
+
* Every component in the layout is parsed, not just the progress bar, so this field is the blast-radius
|
|
1622
|
+
* boundary (REB-25139): before it caught, b.box's `cart_items` component arriving as `settings: []` failed
|
|
1623
|
+
* the component, the `components` array and the whole config — and `CabUserConfig`'s config-level catch
|
|
1624
|
+
* then silently dropped every progress bar for the shop. Now:
|
|
1625
|
+
*
|
|
1626
|
+
* - PHP's empty-map `[]` reads as absent ({@link phpEmptyMapAsAbsent}) — normal engine vocabulary, no drift.
|
|
1627
|
+
* - Any other unreadable settings (a string, a non-empty array, a bar that fails its schema) `.catch` to the
|
|
1628
|
+
* {@link DRIFTED_SMART_CART_SETTINGS} identity sentinel: that component loses its settings (no bars),
|
|
1629
|
+
* its siblings — and the progress bar, when it is a sibling — still parse, and the server's progress-bar
|
|
1630
|
+
* resolution emits a `shopConfig` drift on seeing the sentinel.
|
|
1631
|
+
*
|
|
1632
|
+
* Bars are not salvaged per element: the only reader takes the first progress-bar component's bars as a
|
|
1633
|
+
* set (one per geo segment), and a drifted bar now costs that component's bars WITH a drift, not the cart.
|
|
1634
|
+
*/
|
|
1635
|
+
settings: z19.preprocess(phpEmptyMapAsAbsent, z19.looseObject({ bars: z19.array(SmartCartBar).optional() }).optional()).catch(DRIFTED_SMART_CART_SETTINGS),
|
|
1608
1636
|
type: z19.string().optional()
|
|
1609
1637
|
});
|
|
1610
1638
|
var SmartCartConfig = z19.looseObject({
|
|
@@ -1707,7 +1735,7 @@ var CabShopConfig = z20.object({
|
|
|
1707
1735
|
});
|
|
1708
1736
|
var CabUserConfig = z20.object({
|
|
1709
1737
|
shop: CabShopConfig,
|
|
1710
|
-
smartCart: SmartCartConfig.nullish().catch(
|
|
1738
|
+
smartCart: SmartCartConfig.nullish().catch(DRIFTED_SMART_CART)
|
|
1711
1739
|
});
|
|
1712
1740
|
|
|
1713
1741
|
// src/schema/widgets/checkout-and-beyond/image.ts
|
|
@@ -6019,9 +6047,26 @@ var dispatchWidgetTransform = (id, normalized, report) => {
|
|
|
6019
6047
|
if (isOfferV1(normalized)) return convertOfferToV2({ id, name: normalized.name, settings: normalized });
|
|
6020
6048
|
return normalized;
|
|
6021
6049
|
};
|
|
6050
|
+
var reportSmartCartDrift = (shop, smartCart, ctx) => {
|
|
6051
|
+
if (smartCart === DRIFTED_SMART_CART) {
|
|
6052
|
+
ctx.reportDrift?.({
|
|
6053
|
+
detail: `smart cart config unreadable (drifted shape) \u2014 every progress bar dropped for ${shop}`,
|
|
6054
|
+
kind: "shopConfig"
|
|
6055
|
+
});
|
|
6056
|
+
return;
|
|
6057
|
+
}
|
|
6058
|
+
const drifted = (smartCart?.components ?? []).filter((entry) => entry.settings === DRIFTED_SMART_CART_SETTINGS);
|
|
6059
|
+
if (drifted.length) {
|
|
6060
|
+
ctx.reportDrift?.({
|
|
6061
|
+
detail: `smart cart component settings unreadable (drifted shape) \u2014 dropped for ${drifted.map((entry) => entry.type ?? "untyped").join(", ")} on ${shop}`,
|
|
6062
|
+
kind: "shopConfig"
|
|
6063
|
+
});
|
|
6064
|
+
}
|
|
6065
|
+
};
|
|
6022
6066
|
var fetchProgressBarContext = async (shop, ctx, prefetched) => {
|
|
6023
6067
|
const config = prefetched === void 0 ? await fetchUserConfig({ shop }, ctx).catch(() => void 0) : prefetched;
|
|
6024
6068
|
if (!config) return {};
|
|
6069
|
+
reportSmartCartDrift(shop, config.smartCart, ctx);
|
|
6025
6070
|
if (config.shop.billingVersion === "v6" && config.shop.activePackages.some((pkg) => pkg.shortName === "")) {
|
|
6026
6071
|
ctx.reportDrift?.({
|
|
6027
6072
|
detail: "shop config active package entry inerted (drifted shape) \u2014 smart-cart entitlement may misgate",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebuy/rebuy",
|
|
3
|
-
"version": "3.60.
|
|
3
|
+
"version": "3.60.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.",
|