@teleporthq/teleport-shared 0.43.67 → 0.43.68
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/__tests__/utils/discount-engine.ts +1548 -0
- package/__tests__/utils/product-options.ts +2458 -0
- package/__tests__/utils/subscription-access.ts +37 -0
- package/dist/cjs/index.d.ts +9 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +17 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils/cart-currency.d.ts +27 -0
- package/dist/cjs/utils/cart-currency.d.ts.map +1 -0
- package/dist/cjs/utils/cart-currency.js +31 -0
- package/dist/cjs/utils/cart-currency.js.map +1 -0
- package/dist/cjs/utils/cart-line-pricing.d.ts +25 -0
- package/dist/cjs/utils/cart-line-pricing.d.ts.map +1 -0
- package/dist/cjs/utils/cart-line-pricing.js +29 -0
- package/dist/cjs/utils/cart-line-pricing.js.map +1 -0
- package/dist/cjs/utils/discount-engine.d.ts +74 -0
- package/dist/cjs/utils/discount-engine.d.ts.map +1 -0
- package/dist/cjs/utils/discount-engine.js +435 -0
- package/dist/cjs/utils/discount-engine.js.map +1 -0
- package/dist/cjs/utils/product-options.d.ts +25 -0
- package/dist/cjs/utils/product-options.d.ts.map +1 -0
- package/dist/cjs/utils/product-options.js +1155 -0
- package/dist/cjs/utils/product-options.js.map +1 -0
- package/dist/cjs/utils/session-cookie-resolver.d.ts +85 -0
- package/dist/cjs/utils/session-cookie-resolver.d.ts.map +1 -0
- package/dist/cjs/utils/session-cookie-resolver.js +108 -0
- package/dist/cjs/utils/session-cookie-resolver.js.map +1 -0
- package/dist/cjs/utils/subscription-access.d.ts +36 -0
- package/dist/cjs/utils/subscription-access.d.ts.map +1 -0
- package/dist/cjs/utils/subscription-access.js +61 -0
- package/dist/cjs/utils/subscription-access.js.map +1 -0
- package/dist/cjs/utils/table-access.d.ts +114 -0
- package/dist/cjs/utils/table-access.d.ts.map +1 -0
- package/dist/cjs/utils/table-access.js +238 -0
- package/dist/cjs/utils/table-access.js.map +1 -0
- package/dist/cjs/utils/web-push.d.ts +43 -0
- package/dist/cjs/utils/web-push.d.ts.map +1 -0
- package/dist/cjs/utils/web-push.js +62 -0
- package/dist/cjs/utils/web-push.js.map +1 -0
- package/dist/esm/index.d.ts +9 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +9 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils/cart-currency.d.ts +27 -0
- package/dist/esm/utils/cart-currency.d.ts.map +1 -0
- package/dist/esm/utils/cart-currency.js +27 -0
- package/dist/esm/utils/cart-currency.js.map +1 -0
- package/dist/esm/utils/cart-line-pricing.d.ts +25 -0
- package/dist/esm/utils/cart-line-pricing.d.ts.map +1 -0
- package/dist/esm/utils/cart-line-pricing.js +25 -0
- package/dist/esm/utils/cart-line-pricing.js.map +1 -0
- package/dist/esm/utils/discount-engine.d.ts +74 -0
- package/dist/esm/utils/discount-engine.d.ts.map +1 -0
- package/dist/esm/utils/discount-engine.js +431 -0
- package/dist/esm/utils/discount-engine.js.map +1 -0
- package/dist/esm/utils/product-options.d.ts +25 -0
- package/dist/esm/utils/product-options.d.ts.map +1 -0
- package/dist/esm/utils/product-options.js +1151 -0
- package/dist/esm/utils/product-options.js.map +1 -0
- package/dist/esm/utils/session-cookie-resolver.d.ts +85 -0
- package/dist/esm/utils/session-cookie-resolver.d.ts.map +1 -0
- package/dist/esm/utils/session-cookie-resolver.js +103 -0
- package/dist/esm/utils/session-cookie-resolver.js.map +1 -0
- package/dist/esm/utils/subscription-access.d.ts +36 -0
- package/dist/esm/utils/subscription-access.d.ts.map +1 -0
- package/dist/esm/utils/subscription-access.js +57 -0
- package/dist/esm/utils/subscription-access.js.map +1 -0
- package/dist/esm/utils/table-access.d.ts +114 -0
- package/dist/esm/utils/table-access.d.ts.map +1 -0
- package/dist/esm/utils/table-access.js +233 -0
- package/dist/esm/utils/table-access.js.map +1 -0
- package/dist/esm/utils/web-push.d.ts +43 -0
- package/dist/esm/utils/web-push.d.ts.map +1 -0
- package/dist/esm/utils/web-push.js +59 -0
- package/dist/esm/utils/web-push.js.map +1 -0
- package/package.json +3 -3
- package/src/index.ts +16 -0
- package/src/utils/cart-currency.ts +76 -0
- package/src/utils/cart-line-pricing.ts +151 -0
- package/src/utils/discount-engine.ts +437 -0
- package/src/utils/product-options.ts +1150 -0
- package/src/utils/session-cookie-resolver.ts +305 -0
- package/src/utils/subscription-access.ts +59 -0
- package/src/utils/table-access.ts +516 -0
- package/src/utils/web-push.ts +61 -0
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DISCOUNT_CHOICE_CHANGED_EVENT = exports.DISCOUNT_CHOICE_STORAGE_KEY = exports.CUSTOMER_CHANGED_EVENT = exports.DISCOUNTS_REFRESH_EVENT = exports.GIFT_CARD_CHANGED_EVENT = exports.GIFT_CARD_STORAGE_KEY = exports.DISCOUNT_RULES_LIMIT = exports.DISCOUNTS_TABLE = exports.generateDiscountEngineHelperCode = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* The discount engine — vouchers and automatic (code-less) discounts on a cart
|
|
6
|
+
* — as ES5 source for embedding into generated runtime code (the storefront
|
|
7
|
+
* provider, the `cart-get-total` workflow handler) that cannot import from
|
|
8
|
+
* this package.
|
|
9
|
+
*
|
|
10
|
+
* ⚠️ THIRD MIRROR. The same arithmetic exists in teleport-gui as
|
|
11
|
+
* `features/e-commerce/utils/discount-engine/discount-engine.ts` (the
|
|
12
|
+
* editor/canvas copy) and
|
|
13
|
+
* `features/workflows/templates/builders/ecommerce/discount-engine-script.ts`
|
|
14
|
+
* (the copy baked into the checkout workflows, whose text this file carries
|
|
15
|
+
* verbatim). All three must agree to the cent, or the discount the shopper
|
|
16
|
+
* sees, the discount the payment provider charges and the discount stored on
|
|
17
|
+
* the order will differ. `__tests__/utils/discount-engine.ts` runs this copy
|
|
18
|
+
* over a fixture table that is byte-identical with the GUI's parity spec.
|
|
19
|
+
*
|
|
20
|
+
* The rules, in one place:
|
|
21
|
+
* - discounts are taken on the GROSS eligible subtotal, gross unit price
|
|
22
|
+
* rounded per unit before multiplying;
|
|
23
|
+
* - rules stack sequentially on what is left of their eligible lines, each
|
|
24
|
+
* rounding once, clamped to that remainder;
|
|
25
|
+
* - combinable rules price together by priority, a combinable voucher last;
|
|
26
|
+
* an exclusive discount (`stackable: false`, a rule or the voucher) is
|
|
27
|
+
* priced on its own; when several sets save something the shopper's
|
|
28
|
+
* `choice` picks one and every one comes back as `options`, otherwise the
|
|
29
|
+
* set that saves the most wins — a tie going to an exclusive voucher, then
|
|
30
|
+
* exclusive rules by priority, then the combination; a voucher left out is
|
|
31
|
+
* rejected `not-stackable` when it would have applied alone, else for its
|
|
32
|
+
* own reason;
|
|
33
|
+
* - free shipping waives the fee once; a gift-card line is never eligible;
|
|
34
|
+
* - `legacy` reproduces the pre-engine voucher rule for an older checkout.
|
|
35
|
+
*
|
|
36
|
+
* Everything is prefixed `__de` and declared as `var … = function` EXPRESSIONS
|
|
37
|
+
* so the block can be spliced INTO a serialized handler body — the entry-point
|
|
38
|
+
* resolver would otherwise mistake a declared 2-argument function for the
|
|
39
|
+
* handler itself.
|
|
40
|
+
*/
|
|
41
|
+
var generateDiscountEngineHelperCode = function () {
|
|
42
|
+
return [
|
|
43
|
+
'var __deRound2 = function (n) { return Math.round(n * 100) / 100; };',
|
|
44
|
+
'var __deSafe = function (n) {',
|
|
45
|
+
' var x = typeof n === "number" ? n : parseFloat(n);',
|
|
46
|
+
' return isFinite(x) ? x : 0;',
|
|
47
|
+
'};',
|
|
48
|
+
'var __deIsArray = function (v) { return Object.prototype.toString.call(v) === "[object Array]"; };',
|
|
49
|
+
// Per-UNIT gross rounding before multiplying by quantity, as every money
|
|
50
|
+
// rule in the store does.
|
|
51
|
+
'var __deGrossUnit = function (netUnitPrice, taxRatePercent) {',
|
|
52
|
+
' var net = __deSafe(netUnitPrice);',
|
|
53
|
+
' if (taxRatePercent > 0) { return __deRound2(net * (1 + taxRatePercent / 100)); }',
|
|
54
|
+
' return net;',
|
|
55
|
+
'};',
|
|
56
|
+
// TEXT columns holding a JSON array (or, on a document store, a real array).
|
|
57
|
+
// Anything unreadable means "nothing listed", never an exception in a
|
|
58
|
+
// checkout.
|
|
59
|
+
'var __deStringArray = function (raw) {',
|
|
60
|
+
' var source = raw;',
|
|
61
|
+
' if (typeof source === "string") {',
|
|
62
|
+
' if (source === "") { return []; }',
|
|
63
|
+
' try { source = JSON.parse(source); } catch (e) { return []; }',
|
|
64
|
+
' }',
|
|
65
|
+
' if (!__deIsArray(source)) { return []; }',
|
|
66
|
+
' var out = [];',
|
|
67
|
+
' for (var i = 0; i < source.length; i++) {',
|
|
68
|
+
' if (source[i] === null || source[i] === undefined || source[i] === "") { continue; }',
|
|
69
|
+
' out.push(String(source[i]));',
|
|
70
|
+
' }',
|
|
71
|
+
' return out;',
|
|
72
|
+
'};',
|
|
73
|
+
// Booleans arrive differently per driver (true / "t" / 1), so normalise once.
|
|
74
|
+
'var __deBool = function (value, fallback) {',
|
|
75
|
+
' if (typeof value === "boolean") { return value; }',
|
|
76
|
+
' if (typeof value === "number") { return value !== 0; }',
|
|
77
|
+
' if (typeof value === "string") {',
|
|
78
|
+
' var s = value.toLowerCase();',
|
|
79
|
+
' if (s === "true" || s === "t" || s === "1" || s === "yes") { return true; }',
|
|
80
|
+
' if (s === "false" || s === "f" || s === "0" || s === "no") { return false; }',
|
|
81
|
+
' }',
|
|
82
|
+
' return fallback;',
|
|
83
|
+
'};',
|
|
84
|
+
'var __deNullableNumber = function (value) {',
|
|
85
|
+
' if (value === null || value === undefined || value === "") { return null; }',
|
|
86
|
+
' var x = typeof value === "number" ? value : parseFloat(value);',
|
|
87
|
+
' return isFinite(x) ? x : null;',
|
|
88
|
+
'};',
|
|
89
|
+
// Maps a `teleport_vouchers` or `teleport_discounts` row onto the rule shape.
|
|
90
|
+
// `discount_type` is kept as read: a type this build does not know prices as
|
|
91
|
+
// a no-op, never as a percentage.
|
|
92
|
+
'var __deNormalizeRule = function (row, source) {',
|
|
93
|
+
' if (!row || typeof row !== "object") { return null; }',
|
|
94
|
+
' var priority = __deNullableNumber(row.priority);',
|
|
95
|
+
' var code = row.code ? String(row.code) : "";',
|
|
96
|
+
' return {',
|
|
97
|
+
' id: row.id ? String(row.id) : "",',
|
|
98
|
+
' source: source === "voucher" ? "voucher" : "automatic",',
|
|
99
|
+
' code: code,',
|
|
100
|
+
' name: row.name ? String(row.name) : code,',
|
|
101
|
+
' discountType: row.discount_type ? String(row.discount_type) : "percentage",',
|
|
102
|
+
' discountValue: __deSafe(row.discount_value),',
|
|
103
|
+
' appliesToAllProducts: __deBool(row.applies_to_all_products, true),',
|
|
104
|
+
' productIds: __deStringArray(row.product_ids),',
|
|
105
|
+
' categoryIds: __deStringArray(row.category_ids),',
|
|
106
|
+
' minOrderValue: __deNullableNumber(row.min_order_value),',
|
|
107
|
+
' minQuantity: __deNullableNumber(row.min_quantity),',
|
|
108
|
+
' firstOrderOnly: __deBool(row.first_order_only, false),',
|
|
109
|
+
' buyQuantity: __deNullableNumber(row.buy_quantity),',
|
|
110
|
+
' getQuantity: __deNullableNumber(row.get_quantity),',
|
|
111
|
+
' stackable: __deBool(row.stackable, true),',
|
|
112
|
+
' priority: priority === null ? 100 : priority',
|
|
113
|
+
' };',
|
|
114
|
+
'};',
|
|
115
|
+
// Cart lines as `cart-get-items` / the provider hold them: NET prices,
|
|
116
|
+
// categories and the gift-card flag stamped by the add-to-cart node and the
|
|
117
|
+
// provider's hydration. A caller with server product rows overlays those.
|
|
118
|
+
'var __deLinesFromCart = function (cartItems) {',
|
|
119
|
+
' var lines = [];',
|
|
120
|
+
' if (!__deIsArray(cartItems)) { return lines; }',
|
|
121
|
+
' for (var i = 0; i < cartItems.length; i++) {',
|
|
122
|
+
' var item = cartItems[i];',
|
|
123
|
+
' if (!item || typeof item !== "object") { continue; }',
|
|
124
|
+
' lines.push({',
|
|
125
|
+
' productId: item.productId ? String(item.productId) : "",',
|
|
126
|
+
' unitPrice: __deSafe(item.price),',
|
|
127
|
+
' quantity: Math.max(0, Math.floor(__deSafe(item.quantity))),',
|
|
128
|
+
' categoryIds: __deStringArray(item.categoryIds),',
|
|
129
|
+
' isGiftCard: __deBool(item.isGiftCard, false),',
|
|
130
|
+
// A recurring line is billed by the provider at the plan price every
|
|
131
|
+
// cycle, so no discount ever touches it and no gift card pays for it.
|
|
132
|
+
' isRecurring: __deBool(item.isRecurring, false),',
|
|
133
|
+
' isDigital: __deBool(item.isDigital, false)',
|
|
134
|
+
' });',
|
|
135
|
+
' }',
|
|
136
|
+
' return lines;',
|
|
137
|
+
'};',
|
|
138
|
+
'var __deWorkingLines = function (lines, taxRatePercent) {',
|
|
139
|
+
' var working = [];',
|
|
140
|
+
' if (!__deIsArray(lines)) { return working; }',
|
|
141
|
+
' for (var i = 0; i < lines.length; i++) {',
|
|
142
|
+
' var line = lines[i];',
|
|
143
|
+
' if (!line || typeof line !== "object") { continue; }',
|
|
144
|
+
' var quantity = Math.max(0, Math.floor(__deSafe(line.quantity)));',
|
|
145
|
+
' if (quantity === 0) { continue; }',
|
|
146
|
+
' var unitGross = __deGrossUnit(line.unitPrice, taxRatePercent);',
|
|
147
|
+
' working.push({',
|
|
148
|
+
' productId: line.productId ? String(line.productId) : "",',
|
|
149
|
+
' quantity: quantity,',
|
|
150
|
+
' categoryIds: __deIsArray(line.categoryIds) ? line.categoryIds.map(String) : [],',
|
|
151
|
+
' isGiftCard: line.isGiftCard === true,',
|
|
152
|
+
' isRecurring: line.isRecurring === true,',
|
|
153
|
+
' remaining: unitGross * quantity',
|
|
154
|
+
' });',
|
|
155
|
+
' }',
|
|
156
|
+
' return working;',
|
|
157
|
+
'};',
|
|
158
|
+
'var __deCloneLines = function (lines) {',
|
|
159
|
+
' var out = [];',
|
|
160
|
+
' for (var i = 0; i < lines.length; i++) {',
|
|
161
|
+
' var l = lines[i];',
|
|
162
|
+
' out.push({ productId: l.productId, quantity: l.quantity, categoryIds: l.categoryIds, isGiftCard: l.isGiftCard, isRecurring: l.isRecurring, remaining: l.remaining });',
|
|
163
|
+
' }',
|
|
164
|
+
' return out;',
|
|
165
|
+
'};',
|
|
166
|
+
'var __deIsEligible = function (line, rule, legacy) {',
|
|
167
|
+
' if (line.isGiftCard || line.isRecurring) { return false; }',
|
|
168
|
+
' if (rule.appliesToAllProducts) { return true; }',
|
|
169
|
+
' if (rule.productIds.indexOf(line.productId) !== -1) { return true; }',
|
|
170
|
+
' if (legacy) { return false; }',
|
|
171
|
+
' for (var i = 0; i < rule.categoryIds.length; i++) {',
|
|
172
|
+
' if (line.categoryIds.indexOf(rule.categoryIds[i]) !== -1) { return true; }',
|
|
173
|
+
' }',
|
|
174
|
+
' return false;',
|
|
175
|
+
'};',
|
|
176
|
+
'var __deCompareRules = function (a, b) {',
|
|
177
|
+
' if (a.priority !== b.priority) { return a.priority < b.priority ? -1 : 1; }',
|
|
178
|
+
' if (a.name !== b.name) { return a.name < b.name ? -1 : 1; }',
|
|
179
|
+
' if (a.id !== b.id) { return a.id < b.id ? -1 : 1; }',
|
|
180
|
+
' return 0;',
|
|
181
|
+
'};',
|
|
182
|
+
'var __deRejected = function (reason, eligibleProductIds) {',
|
|
183
|
+
' return { rejection: reason, goodsDiscount: 0, shippingDiscount: 0, eligibleProductIds: eligibleProductIds };',
|
|
184
|
+
'};',
|
|
185
|
+
/*
|
|
186
|
+
* Prices one rule against what is left of its eligible lines and, when it
|
|
187
|
+
* applies, takes its amount off those lines. Mirrors `evaluateRule` in the
|
|
188
|
+
* TypeScript twin field for field.
|
|
189
|
+
*/
|
|
190
|
+
'var __deEvaluateRule = function (rule, lines, params) {',
|
|
191
|
+
' var eligible = [];',
|
|
192
|
+
' var eligibleProductIds = [];',
|
|
193
|
+
' var eligibleUnits = 0;',
|
|
194
|
+
' for (var i = 0; i < lines.length; i++) {',
|
|
195
|
+
' if (!__deIsEligible(lines[i], rule, params.legacy)) { continue; }',
|
|
196
|
+
' eligible.push(lines[i]);',
|
|
197
|
+
' eligibleUnits += lines[i].quantity;',
|
|
198
|
+
' if (eligibleProductIds.indexOf(lines[i].productId) === -1) { eligibleProductIds.push(lines[i].productId); }',
|
|
199
|
+
' }',
|
|
200
|
+
' if (!params.legacy) {',
|
|
201
|
+
' if (rule.minOrderValue !== null && params.cartGoodsGross < rule.minOrderValue) { return __deRejected("min-order", eligibleProductIds); }',
|
|
202
|
+
' if (rule.minQuantity !== null && eligibleUnits < rule.minQuantity) { return __deRejected("min-quantity", eligibleProductIds); }',
|
|
203
|
+
' if (rule.firstOrderOnly && params.isFirstOrder !== true) { return __deRejected("first-order", eligibleProductIds); }',
|
|
204
|
+
' }',
|
|
205
|
+
' if (rule.discountType === "free_shipping") {',
|
|
206
|
+
' var waived = __deRound2(Math.max(0, __deSafe(params.shippingPrice)));',
|
|
207
|
+
' if (params.shippingWaived || waived <= 0) { return __deRejected("no-op", eligibleProductIds); }',
|
|
208
|
+
' return { rejection: "", goodsDiscount: 0, shippingDiscount: waived, eligibleProductIds: eligibleProductIds };',
|
|
209
|
+
' }',
|
|
210
|
+
' var base = 0;',
|
|
211
|
+
' for (var b = 0; b < eligible.length; b++) { base += eligible[b].remaining; }',
|
|
212
|
+
' var roundedBase = __deRound2(base);',
|
|
213
|
+
' if (roundedBase <= 0) { return __deRejected("no-op", eligibleProductIds); }',
|
|
214
|
+
' if (rule.discountType === "percentage" || rule.discountType === "fixed") {',
|
|
215
|
+
' var value = Math.max(0, __deSafe(rule.discountValue));',
|
|
216
|
+
' var raw = rule.discountType === "percentage" ? (base * Math.min(value, 100)) / 100 : value;',
|
|
217
|
+
' var amount = Math.min(__deRound2(raw), roundedBase);',
|
|
218
|
+
' if (amount <= 0) { return __deRejected("no-op", eligibleProductIds); }',
|
|
219
|
+
' for (var p = 0; p < eligible.length; p++) {',
|
|
220
|
+
' eligible[p].remaining -= (eligible[p].remaining / base) * amount;',
|
|
221
|
+
' }',
|
|
222
|
+
' return { rejection: "", goodsDiscount: amount, shippingDiscount: 0, eligibleProductIds: eligibleProductIds };',
|
|
223
|
+
' }',
|
|
224
|
+
' if (rule.discountType === "buy_x_get_y" && !params.legacy) {',
|
|
225
|
+
' var buy = Math.floor(__deSafe(rule.buyQuantity));',
|
|
226
|
+
' var get = Math.floor(__deSafe(rule.getQuantity));',
|
|
227
|
+
' if (buy < 1 || get < 1) { return __deRejected("no-op", eligibleProductIds); }',
|
|
228
|
+
' var units = [];',
|
|
229
|
+
' for (var u = 0; u < eligible.length; u++) {',
|
|
230
|
+
' var unitValue = eligible[u].remaining / eligible[u].quantity;',
|
|
231
|
+
' for (var q = 0; q < eligible[u].quantity; q++) {',
|
|
232
|
+
' units.push({ line: eligible[u], value: unitValue, order: units.length });',
|
|
233
|
+
' }',
|
|
234
|
+
' }',
|
|
235
|
+
' units.sort(function (a, b) {',
|
|
236
|
+
' if (a.value !== b.value) { return a.value < b.value ? -1 : 1; }',
|
|
237
|
+
' return a.order - b.order;',
|
|
238
|
+
' });',
|
|
239
|
+
' var freeUnits = Math.floor(units.length / (buy + get)) * get;',
|
|
240
|
+
' var bogo = 0;',
|
|
241
|
+
' for (var f = 0; f < freeUnits; f++) {',
|
|
242
|
+
' bogo += units[f].value;',
|
|
243
|
+
' units[f].line.remaining -= units[f].value;',
|
|
244
|
+
' }',
|
|
245
|
+
' bogo = Math.min(__deRound2(bogo), roundedBase);',
|
|
246
|
+
' if (bogo <= 0) { return __deRejected("no-op", eligibleProductIds); }',
|
|
247
|
+
' return { rejection: "", goodsDiscount: bogo, shippingDiscount: 0, eligibleProductIds: eligibleProductIds };',
|
|
248
|
+
' }',
|
|
249
|
+
' return __deRejected("no-op", eligibleProductIds);',
|
|
250
|
+
'};',
|
|
251
|
+
/*
|
|
252
|
+
* Prices one set of discounts that may share the order, sequentially on a
|
|
253
|
+
* copy of the lines. Mirrors `priceCandidate` in the TypeScript twin.
|
|
254
|
+
*/
|
|
255
|
+
'var __dePriceCandidate = function (candidate, lines, params) {',
|
|
256
|
+
' var working = __deCloneLines(lines);',
|
|
257
|
+
' var applied = [];',
|
|
258
|
+
' var shippingWaived = false;',
|
|
259
|
+
' var automaticGoods = 0;',
|
|
260
|
+
' var automaticShipping = 0;',
|
|
261
|
+
' var voucherGoods = 0;',
|
|
262
|
+
' var voucherShipping = 0;',
|
|
263
|
+
' var holdsVoucher = false;',
|
|
264
|
+
' var voucherApplied = false;',
|
|
265
|
+
' var voucherRejection = "";',
|
|
266
|
+
' var eligibleProductIds = [];',
|
|
267
|
+
' for (var c = 0; c < candidate.length; c++) {',
|
|
268
|
+
' var rule = candidate[c];',
|
|
269
|
+
' var isVoucher = rule.source === "voucher";',
|
|
270
|
+
' var evaluation = __deEvaluateRule(rule, working, {',
|
|
271
|
+
' cartGoodsGross: params.cartGoodsGross, shippingPrice: params.shippingPrice, shippingWaived: shippingWaived, isFirstOrder: params.isFirstOrder, legacy: params.legacy',
|
|
272
|
+
' });',
|
|
273
|
+
' if (isVoucher) { holdsVoucher = true; eligibleProductIds = evaluation.eligibleProductIds; }',
|
|
274
|
+
' if (evaluation.rejection !== "") {',
|
|
275
|
+
' if (isVoucher) { voucherRejection = evaluation.rejection; }',
|
|
276
|
+
' continue;',
|
|
277
|
+
' }',
|
|
278
|
+
' applied.push({ id: rule.id, source: isVoucher ? "voucher" : "automatic", code: isVoucher ? rule.code : "", name: rule.name, goodsDiscount: evaluation.goodsDiscount, shippingDiscount: evaluation.shippingDiscount, eligibleProductIds: evaluation.eligibleProductIds });',
|
|
279
|
+
' if (isVoucher) {',
|
|
280
|
+
' voucherApplied = true;',
|
|
281
|
+
' voucherGoods += evaluation.goodsDiscount;',
|
|
282
|
+
' voucherShipping += evaluation.shippingDiscount;',
|
|
283
|
+
' } else {',
|
|
284
|
+
' automaticGoods += evaluation.goodsDiscount;',
|
|
285
|
+
' automaticShipping += evaluation.shippingDiscount;',
|
|
286
|
+
' }',
|
|
287
|
+
' if (evaluation.shippingDiscount > 0) { shippingWaived = true; }',
|
|
288
|
+
' }',
|
|
289
|
+
' return {',
|
|
290
|
+
' applied: applied,',
|
|
291
|
+
' automaticGoods: automaticGoods,',
|
|
292
|
+
' automaticShipping: automaticShipping,',
|
|
293
|
+
' voucherGoods: voucherGoods,',
|
|
294
|
+
' voucherShipping: voucherShipping,',
|
|
295
|
+
' holdsVoucher: holdsVoucher,',
|
|
296
|
+
' voucherApplied: voucherApplied,',
|
|
297
|
+
' voucherRejection: voucherRejection,',
|
|
298
|
+
' eligibleProductIds: eligibleProductIds,',
|
|
299
|
+
' total: __deRound2(__deRound2(automaticGoods + voucherGoods) + __deRound2(Math.min(params.shippingPrice, automaticShipping + voucherShipping)))',
|
|
300
|
+
' };',
|
|
301
|
+
'};',
|
|
302
|
+
/*
|
|
303
|
+
* THE rule. Mirrors `resolveCartDiscounts`: every set of discounts that may
|
|
304
|
+
* share the order is priced on its own — each exclusive discount alone, the
|
|
305
|
+
* combinable ones together. When several sets save something the shopper's
|
|
306
|
+
* `choice` picks one and every one is offered back as `options`; otherwise
|
|
307
|
+
* the set that saves the most wins, a tie going to the set listed first.
|
|
308
|
+
*/
|
|
309
|
+
'var __deDescribeOption = function (applied) {',
|
|
310
|
+
' var names = [];',
|
|
311
|
+
' for (var d = 0; d < applied.length; d++) { names.push(applied[d].source === "voucher" ? "Code " + applied[d].code : applied[d].name); }',
|
|
312
|
+
' return names.join(", ");',
|
|
313
|
+
'};',
|
|
314
|
+
'var __deResolve = function (input) {',
|
|
315
|
+
' var legacy = input.legacy === true;',
|
|
316
|
+
' var taxRatePercent = __deSafe(input.taxRatePercent);',
|
|
317
|
+
' var lines = __deWorkingLines(input.lines, taxRatePercent);',
|
|
318
|
+
' var shippingPrice = Math.max(0, __deSafe(input.shippingPrice));',
|
|
319
|
+
' var isFirstOrder = input.customer && typeof input.customer.isFirstOrder === "boolean" ? input.customer.isFirstOrder : null;',
|
|
320
|
+
' var cartGoodsGross = 0;',
|
|
321
|
+
' for (var g = 0; g < lines.length; g++) { if (!lines[g].isGiftCard && !lines[g].isRecurring) { cartGoodsGross += lines[g].remaining; } }',
|
|
322
|
+
' cartGoodsGross = __deRound2(cartGoodsGross);',
|
|
323
|
+
' var voucher = input.voucher || null;',
|
|
324
|
+
' var rules = legacy || !__deIsArray(input.rules) ? [] : input.rules.slice().sort(__deCompareRules);',
|
|
325
|
+
' var params = { cartGoodsGross: cartGoodsGross, shippingPrice: shippingPrice, isFirstOrder: isFirstOrder, legacy: legacy };',
|
|
326
|
+
' var candidates = [];',
|
|
327
|
+
' var combination = [];',
|
|
328
|
+
' if (voucher && !legacy && !voucher.stackable) { candidates.push({ key: "voucher", rules: [voucher] }); }',
|
|
329
|
+
' for (var r = 0; r < rules.length; r++) {',
|
|
330
|
+
' if (rules[r].stackable) { combination.push(rules[r]); } else { candidates.push({ key: rules[r].id, rules: [rules[r]] }); }',
|
|
331
|
+
' }',
|
|
332
|
+
' if (voucher && (legacy || voucher.stackable)) { combination.push(voucher); }',
|
|
333
|
+
' candidates.push({ key: "combination", rules: combination });',
|
|
334
|
+
' var priced = [];',
|
|
335
|
+
' for (var k = 0; k < candidates.length; k++) { priced.push({ key: candidates[k].key, pricing: __dePriceCandidate(candidates[k].rules, lines, params) }); }',
|
|
336
|
+
' var winner = priced[0];',
|
|
337
|
+
' for (var w = 1; w < priced.length; w++) { if (priced[w].pricing.total > winner.pricing.total) { winner = priced[w]; } }',
|
|
338
|
+
' var choosable = [];',
|
|
339
|
+
' for (var s = 0; s < priced.length; s++) { if (priced[s].pricing.total > 0) { choosable.push(priced[s]); } }',
|
|
340
|
+
' var options = [];',
|
|
341
|
+
' var choice = "";',
|
|
342
|
+
' if (choosable.length > 1) {',
|
|
343
|
+
' for (var p = 0; p < choosable.length; p++) { if (choosable[p].key === input.choice) { winner = choosable[p]; } }',
|
|
344
|
+
' choice = winner.key;',
|
|
345
|
+
' for (var o = 0; o < choosable.length; o++) {',
|
|
346
|
+
' options.push({ key: choosable[o].key, label: __deDescribeOption(choosable[o].pricing.applied), saving: choosable[o].pricing.total, selected: choosable[o] === winner });',
|
|
347
|
+
' }',
|
|
348
|
+
' }',
|
|
349
|
+
' var best = winner.pricing;',
|
|
350
|
+
' var voucherRejection = best.voucherRejection;',
|
|
351
|
+
' var eligibleProductIds = best.eligibleProductIds;',
|
|
352
|
+
' if (voucher && !best.holdsVoucher) {',
|
|
353
|
+
' var alone = __dePriceCandidate([voucher], lines, params);',
|
|
354
|
+
' voucherRejection = alone.voucherApplied ? "not-stackable" : alone.voucherRejection;',
|
|
355
|
+
' eligibleProductIds = alone.eligibleProductIds;',
|
|
356
|
+
' }',
|
|
357
|
+
' return {',
|
|
358
|
+
' applied: best.applied,',
|
|
359
|
+
' goodsDiscount: __deRound2(best.automaticGoods + best.voucherGoods),',
|
|
360
|
+
' shippingDiscount: __deRound2(Math.min(shippingPrice, best.automaticShipping + best.voucherShipping)),',
|
|
361
|
+
' automaticGoodsDiscount: __deRound2(best.automaticGoods),',
|
|
362
|
+
' automaticShippingDiscount: __deRound2(best.automaticShipping),',
|
|
363
|
+
' voucherGoodsDiscount: __deRound2(best.voucherGoods),',
|
|
364
|
+
' voucherShippingDiscount: __deRound2(best.voucherShipping),',
|
|
365
|
+
' voucherApplied: best.voucherApplied,',
|
|
366
|
+
' voucherRejection: voucherRejection,',
|
|
367
|
+
' eligibleProductIds: eligibleProductIds,',
|
|
368
|
+
' options: options,',
|
|
369
|
+
' choice: choice',
|
|
370
|
+
' };',
|
|
371
|
+
'};',
|
|
372
|
+
// The provider's published minimums, in major units; default 0.50.
|
|
373
|
+
'var __deMinimumCharge = function (currency) {',
|
|
374
|
+
' var table = { USD: 0.5, EUR: 0.5, GBP: 0.3, AUD: 0.5, CAD: 0.5, NZD: 0.5, SGD: 0.5, CHF: 0.5, BRL: 0.5, INR: 0.5, AED: 2, BGN: 1, CZK: 15, DKK: 2.5, HKD: 4, HUF: 175, JPY: 50, MXN: 10, MYR: 2, NOK: 3, PLN: 2, RON: 2, SEK: 3, THB: 10 };',
|
|
375
|
+
' var code = String(currency || "").toUpperCase();',
|
|
376
|
+
' return typeof table[code] === "number" ? table[code] : 0.5;',
|
|
377
|
+
'};',
|
|
378
|
+
// How much of an order a gift card pays. Mirrors `resolveGiftCardTender`.
|
|
379
|
+
'var __deTender = function (input) {',
|
|
380
|
+
' var balance = Math.max(0, __deSafe(input.balance));',
|
|
381
|
+
' var total = Math.max(0, __deRound2(__deSafe(input.total)));',
|
|
382
|
+
// A recurring cart whose first charge is a free trial has nothing for a
|
|
383
|
+
// card to pay, and neither has one whose checkout cannot hand the provider
|
|
384
|
+
// a reduced first charge; otherwise the card pays part of the first charge
|
|
385
|
+
// only, and the provider keeps at least its minimum to collect the payment
|
|
386
|
+
// method that bills every later cycle.
|
|
387
|
+
' var recurringRefused = input.hasRecurringLines && !input.recurringTenderAllowed;',
|
|
388
|
+
' if (input.hasGiftCardLines || input.hasRecurringTrial || recurringRefused || balance <= 0 || total <= 0) { return { applied: 0, amountDue: total }; }',
|
|
389
|
+
' var minimum = __deMinimumCharge(input.currency);',
|
|
390
|
+
' var applied = Math.min(balance, total);',
|
|
391
|
+
' if (input.hasRecurringLines) { applied = Math.min(applied, Math.max(0, __deRound2(total - minimum))); }',
|
|
392
|
+
' var remaining = __deRound2(total - applied);',
|
|
393
|
+
' if (remaining > 0 && remaining < minimum) { applied = Math.max(0, __deRound2(total - minimum)); }',
|
|
394
|
+
' applied = __deRound2(applied);',
|
|
395
|
+
' return { applied: applied, amountDue: __deRound2(total - applied) };',
|
|
396
|
+
'};',
|
|
397
|
+
].join('\n');
|
|
398
|
+
};
|
|
399
|
+
exports.generateDiscountEngineHelperCode = generateDiscountEngineHelperCode;
|
|
400
|
+
/** The automatic-discount rules table the storefront reads. */
|
|
401
|
+
exports.DISCOUNTS_TABLE = 'teleport_discounts';
|
|
402
|
+
/**
|
|
403
|
+
* How many live automatic rules any reader loads — the storefront feed, the
|
|
404
|
+
* place-order workflow and the editor — each ordered the way the engine
|
|
405
|
+
* applies them (priority, name, id), so all three price the same set. The
|
|
406
|
+
* editor refuses a live rule past it.
|
|
407
|
+
*/
|
|
408
|
+
exports.DISCOUNT_RULES_LIMIT = 500;
|
|
409
|
+
/**
|
|
410
|
+
* The applied gift card the checkout keeps beside the cart — display data
|
|
411
|
+
* returned by the Apply Gift Card workflow (`{ id, last4, balance, currency,
|
|
412
|
+
* checkedAt }`), never the full code, never trusted for money. ⚠️
|
|
413
|
+
* `cart-get-total` and `cart-clear` spell the same key out as a literal — a
|
|
414
|
+
* serialized handler has no module scope to import it from.
|
|
415
|
+
*/
|
|
416
|
+
exports.GIFT_CARD_STORAGE_KEY = 'workflow_gift_card';
|
|
417
|
+
/** Broadcast when the applied gift card changes. */
|
|
418
|
+
exports.GIFT_CARD_CHANGED_EVENT = 'teleport:gift-card-changed';
|
|
419
|
+
/**
|
|
420
|
+
* Broadcast by the place-order workflow when the server priced the order
|
|
421
|
+
* differently from the summary, so the provider re-reads rules and customer.
|
|
422
|
+
*/
|
|
423
|
+
exports.DISCOUNTS_REFRESH_EVENT = 'teleport:discounts-refresh';
|
|
424
|
+
/** Broadcast once the checkout page-load workflow has written `customer`. */
|
|
425
|
+
exports.CUSTOMER_CHANGED_EVENT = 'teleport:customer-changed';
|
|
426
|
+
/**
|
|
427
|
+
* The localStorage key holding the set of discounts the shopper chose when
|
|
428
|
+
* several could apply but not together (a `DiscountOption.key`: an exclusive
|
|
429
|
+
* rule's id, `voucher`, or `combination`). ⚠️ `cart-get-total` and `cart-clear`
|
|
430
|
+
* spell the key out as a literal — a serialized handler has no module scope.
|
|
431
|
+
*/
|
|
432
|
+
exports.DISCOUNT_CHOICE_STORAGE_KEY = 'workflow_discount_choice';
|
|
433
|
+
/** Broadcast when the shopper's discount choice changes. */
|
|
434
|
+
exports.DISCOUNT_CHOICE_CHANGED_EVENT = 'teleport:discount-choice-changed';
|
|
435
|
+
//# sourceMappingURL=discount-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discount-engine.js","sourceRoot":"","sources":["../../../src/utils/discount-engine.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACI,IAAM,gCAAgC,GAAG;IAC9C,OAAA;QACE,sEAAsE;QACtE,+BAA+B;QAC/B,sDAAsD;QACtD,+BAA+B;QAC/B,IAAI;QACJ,oGAAoG;QACpG,yEAAyE;QACzE,0BAA0B;QAC1B,+DAA+D;QAC/D,qCAAqC;QACrC,oFAAoF;QACpF,eAAe;QACf,IAAI;QACJ,6EAA6E;QAC7E,sEAAsE;QACtE,YAAY;QACZ,wCAAwC;QACxC,qBAAqB;QACrB,qCAAqC;QACrC,uCAAuC;QACvC,mEAAmE;QACnE,KAAK;QACL,4CAA4C;QAC5C,iBAAiB;QACjB,6CAA6C;QAC7C,0FAA0F;QAC1F,kCAAkC;QAClC,KAAK;QACL,eAAe;QACf,IAAI;QACJ,8EAA8E;QAC9E,6CAA6C;QAC7C,qDAAqD;QACrD,0DAA0D;QAC1D,oCAAoC;QACpC,kCAAkC;QAClC,iFAAiF;QACjF,kFAAkF;QAClF,KAAK;QACL,oBAAoB;QACpB,IAAI;QACJ,6CAA6C;QAC7C,+EAA+E;QAC/E,kEAAkE;QAClE,kCAAkC;QAClC,IAAI;QACJ,8EAA8E;QAC9E,6EAA6E;QAC7E,kCAAkC;QAClC,kDAAkD;QAClD,yDAAyD;QACzD,oDAAoD;QACpD,gDAAgD;QAChD,YAAY;QACZ,uCAAuC;QACvC,6DAA6D;QAC7D,iBAAiB;QACjB,+CAA+C;QAC/C,iFAAiF;QACjF,kDAAkD;QAClD,wEAAwE;QACxE,mDAAmD;QACnD,qDAAqD;QACrD,6DAA6D;QAC7D,wDAAwD;QACxD,4DAA4D;QAC5D,wDAAwD;QACxD,wDAAwD;QACxD,+CAA+C;QAC/C,kDAAkD;QAClD,MAAM;QACN,IAAI;QACJ,uEAAuE;QACvE,4EAA4E;QAC5E,0EAA0E;QAC1E,gDAAgD;QAChD,mBAAmB;QACnB,kDAAkD;QAClD,gDAAgD;QAChD,8BAA8B;QAC9B,0DAA0D;QAC1D,kBAAkB;QAClB,gEAAgE;QAChE,wCAAwC;QACxC,mEAAmE;QACnE,uDAAuD;QACvD,qDAAqD;QACrD,qEAAqE;QACrE,sEAAsE;QACtE,uDAAuD;QACvD,kDAAkD;QAClD,SAAS;QACT,KAAK;QACL,iBAAiB;QACjB,IAAI;QACJ,2DAA2D;QAC3D,qBAAqB;QACrB,gDAAgD;QAChD,4CAA4C;QAC5C,0BAA0B;QAC1B,0DAA0D;QAC1D,sEAAsE;QACtE,uCAAuC;QACvC,oEAAoE;QACpE,oBAAoB;QACpB,gEAAgE;QAChE,2BAA2B;QAC3B,uFAAuF;QACvF,6CAA6C;QAC7C,+CAA+C;QAC/C,uCAAuC;QACvC,SAAS;QACT,KAAK;QACL,mBAAmB;QACnB,IAAI;QACJ,yCAAyC;QACzC,iBAAiB;QACjB,4CAA4C;QAC5C,uBAAuB;QACvB,2KAA2K;QAC3K,KAAK;QACL,eAAe;QACf,IAAI;QACJ,sDAAsD;QACtD,8DAA8D;QAC9D,mDAAmD;QACnD,wEAAwE;QACxE,iCAAiC;QACjC,uDAAuD;QACvD,gFAAgF;QAChF,KAAK;QACL,iBAAiB;QACjB,IAAI;QACJ,0CAA0C;QAC1C,+EAA+E;QAC/E,+DAA+D;QAC/D,uDAAuD;QACvD,aAAa;QACb,IAAI;QACJ,4DAA4D;QAC5D,gHAAgH;QAChH,IAAI;QACJ;;;;WAIG;QACH,yDAAyD;QACzD,sBAAsB;QACtB,gCAAgC;QAChC,0BAA0B;QAC1B,4CAA4C;QAC5C,uEAAuE;QACvE,8BAA8B;QAC9B,yCAAyC;QACzC,iHAAiH;QACjH,KAAK;QACL,yBAAyB;QACzB,8IAA8I;QAC9I,qIAAqI;QACrI,0HAA0H;QAC1H,KAAK;QACL,gDAAgD;QAChD,2EAA2E;QAC3E,qGAAqG;QACrG,mHAAmH;QACnH,KAAK;QACL,iBAAiB;QACjB,gFAAgF;QAChF,uCAAuC;QACvC,+EAA+E;QAC/E,8EAA8E;QAC9E,4DAA4D;QAC5D,iGAAiG;QACjG,0DAA0D;QAC1D,4EAA4E;QAC5E,iDAAiD;QACjD,yEAAyE;QACzE,OAAO;QACP,mHAAmH;QACnH,KAAK;QACL,gEAAgE;QAChE,uDAAuD;QACvD,uDAAuD;QACvD,mFAAmF;QACnF,qBAAqB;QACrB,iDAAiD;QACjD,qEAAqE;QACrE,wDAAwD;QACxD,mFAAmF;QACnF,SAAS;QACT,OAAO;QACP,kCAAkC;QAClC,uEAAuE;QACvE,iCAAiC;QACjC,SAAS;QACT,mEAAmE;QACnE,mBAAmB;QACnB,2CAA2C;QAC3C,+BAA+B;QAC/B,kDAAkD;QAClD,OAAO;QACP,qDAAqD;QACrD,0EAA0E;QAC1E,iHAAiH;QACjH,KAAK;QACL,qDAAqD;QACrD,IAAI;QACJ;;;WAGG;QACH,gEAAgE;QAChE,wCAAwC;QACxC,qBAAqB;QACrB,+BAA+B;QAC/B,2BAA2B;QAC3B,8BAA8B;QAC9B,yBAAyB;QACzB,4BAA4B;QAC5B,6BAA6B;QAC7B,+BAA+B;QAC/B,8BAA8B;QAC9B,gCAAgC;QAChC,gDAAgD;QAChD,8BAA8B;QAC9B,gDAAgD;QAChD,wDAAwD;QACxD,4KAA4K;QAC5K,SAAS;QACT,iGAAiG;QACjG,wCAAwC;QACxC,mEAAmE;QACnE,iBAAiB;QACjB,OAAO;QACP,+QAA+Q;QAC/Q,sBAAsB;QACtB,8BAA8B;QAC9B,iDAAiD;QACjD,uDAAuD;QACvD,cAAc;QACd,mDAAmD;QACnD,yDAAyD;QACzD,OAAO;QACP,qEAAqE;QACrE,KAAK;QACL,YAAY;QACZ,uBAAuB;QACvB,qCAAqC;QACrC,2CAA2C;QAC3C,iCAAiC;QACjC,uCAAuC;QACvC,iCAAiC;QACjC,qCAAqC;QACrC,yCAAyC;QACzC,6CAA6C;QAC7C,oJAAoJ;QACpJ,MAAM;QACN,IAAI;QACJ;;;;;;WAMG;QACH,+CAA+C;QAC/C,mBAAmB;QACnB,2IAA2I;QAC3I,4BAA4B;QAC5B,IAAI;QACJ,sCAAsC;QACtC,uCAAuC;QACvC,wDAAwD;QACxD,8DAA8D;QAC9D,mEAAmE;QACnE,+HAA+H;QAC/H,2BAA2B;QAC3B,2IAA2I;QAC3I,gDAAgD;QAChD,wCAAwC;QACxC,sGAAsG;QACtG,8HAA8H;QAC9H,wBAAwB;QACxB,yBAAyB;QACzB,4GAA4G;QAC5G,4CAA4C;QAC5C,gIAAgI;QAChI,KAAK;QACL,gFAAgF;QAChF,gEAAgE;QAChE,oBAAoB;QACpB,6JAA6J;QAC7J,2BAA2B;QAC3B,2HAA2H;QAC3H,uBAAuB;QACvB,+GAA+G;QAC/G,qBAAqB;QACrB,oBAAoB;QACpB,+BAA+B;QAC/B,sHAAsH;QACtH,0BAA0B;QAC1B,kDAAkD;QAClD,gLAAgL;QAChL,OAAO;QACP,KAAK;QACL,8BAA8B;QAC9B,iDAAiD;QACjD,qDAAqD;QACrD,wCAAwC;QACxC,+DAA+D;QAC/D,yFAAyF;QACzF,oDAAoD;QACpD,KAAK;QACL,YAAY;QACZ,4BAA4B;QAC5B,yEAAyE;QACzE,2GAA2G;QAC3G,8DAA8D;QAC9D,oEAAoE;QACpE,0DAA0D;QAC1D,gEAAgE;QAChE,0CAA0C;QAC1C,yCAAyC;QACzC,6CAA6C;QAC7C,uBAAuB;QACvB,oBAAoB;QACpB,MAAM;QACN,IAAI;QACJ,mEAAmE;QACnE,+CAA+C;QAC/C,+OAA+O;QAC/O,oDAAoD;QACpD,+DAA+D;QAC/D,IAAI;QACJ,0EAA0E;QAC1E,qCAAqC;QACrC,uDAAuD;QACvD,+DAA+D;QAC/D,wEAAwE;QACxE,2EAA2E;QAC3E,2EAA2E;QAC3E,2EAA2E;QAC3E,uCAAuC;QACvC,oFAAoF;QACpF,yJAAyJ;QACzJ,oDAAoD;QACpD,2CAA2C;QAC3C,2GAA2G;QAC3G,gDAAgD;QAChD,qGAAqG;QACrG,kCAAkC;QAClC,wEAAwE;QACxE,IAAI;KACL,CAAC,IAAI,CAAC,IAAI,CAAC;AAnWZ,CAmWY,CAAA;AApWD,QAAA,gCAAgC,oCAoW/B;AAEd,+DAA+D;AAClD,QAAA,eAAe,GAAG,oBAAoB,CAAA;AAEnD;;;;;GAKG;AACU,QAAA,oBAAoB,GAAG,GAAG,CAAA;AAEvC;;;;;;GAMG;AACU,QAAA,qBAAqB,GAAG,oBAAoB,CAAA;AAEzD,oDAAoD;AACvC,QAAA,uBAAuB,GAAG,4BAA4B,CAAA;AAEnE;;;GAGG;AACU,QAAA,uBAAuB,GAAG,4BAA4B,CAAA;AAEnE,6EAA6E;AAChE,QAAA,sBAAsB,GAAG,2BAA2B,CAAA;AAEjE;;;;;GAKG;AACU,QAAA,2BAA2B,GAAG,0BAA0B,CAAA;AAErE,4DAA4D;AAC/C,QAAA,6BAA6B,GAAG,kCAAkC,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Product options as ES5 source, for generated runtime code that cannot import
|
|
3
|
+
* from this package: the data-source product transform, the storefront cart
|
|
4
|
+
* provider, and every workflow script that prices a configuration.
|
|
5
|
+
*
|
|
6
|
+
* ⚠️ THIRD MIRROR. The same rules exist in teleport-gui as
|
|
7
|
+
* `features/e-commerce/utils/product-options/` (the editor/canvas TypeScript)
|
|
8
|
+
* and `features/workflows/templates/builders/ecommerce/product-options-script.ts`
|
|
9
|
+
* (`PRODUCT_OPTIONS_HELPERS`, whose text this function returns verbatim). All
|
|
10
|
+
* three must agree to the cent, or the price on the product page, the price
|
|
11
|
+
* added to the cart and the price stored on the order will differ.
|
|
12
|
+
* `__tests__/utils/product-options.ts` runs this copy over a fixture table that
|
|
13
|
+
* is byte-identical with the GUI's parity spec.
|
|
14
|
+
*
|
|
15
|
+
* The block: `var` / `function` only, names prefixed `__po`; no backticks, no
|
|
16
|
+
* dollar-brace, no backslash, never `params` followed by a dot; no `__po`
|
|
17
|
+
* function with exactly two parameters (the handler-entry resolver in
|
|
18
|
+
* `teleport-plugin-next-workflows/src/nodes/types.ts` picks the first
|
|
19
|
+
* two-parameter declaration); wrapped in the sentinel comments below so an
|
|
20
|
+
* export-time refresh can replace it.
|
|
21
|
+
*/
|
|
22
|
+
export declare const PRODUCT_OPTIONS_HELPERS_OPENING = "/* tq:po-helpers:start v1 */";
|
|
23
|
+
export declare const PRODUCT_OPTIONS_HELPERS_CLOSING = "/* tq:po-helpers:end */";
|
|
24
|
+
export declare const generateProductOptionsHelperCode: () => string;
|
|
25
|
+
//# sourceMappingURL=product-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product-options.d.ts","sourceRoot":"","sources":["../../../src/utils/product-options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,+BAA+B,iCAAiC,CAAA;AAC7E,eAAO,MAAM,+BAA+B,4BAA4B,CAAA;AAExE,eAAO,MAAM,gCAAgC,QAAO,MAqmCtC,CAAA"}
|