@blamejs/blamejs-shop 0.1.12 → 0.1.14
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/CHANGELOG.md +4 -0
- package/lib/address-validation.js +8 -12
- package/lib/addresses.js +4 -8
- package/lib/admin.js +22 -26
- package/lib/affiliates.js +18 -24
- package/lib/analytics.js +4 -9
- package/lib/announcement-bar.js +7 -11
- package/lib/api-keys.js +15 -21
- package/lib/assembly-instructions.js +9 -13
- package/lib/auto-discount.js +3 -7
- package/lib/auto-replenish.js +5 -9
- package/lib/backorder.js +5 -9
- package/lib/banner-ab-tests.js +11 -15
- package/lib/barcodes.js +5 -9
- package/lib/bin-locations.js +4 -8
- package/lib/blog-articles.js +13 -17
- package/lib/bundles.js +6 -10
- package/lib/business-hours.js +3 -7
- package/lib/captcha-gate.js +5 -11
- package/lib/carrier-accounts.js +16 -22
- package/lib/carrier-rates.js +7 -13
- package/lib/cart-abandonment.js +9 -13
- package/lib/cart-bulk-ops.js +9 -13
- package/lib/cart-recovery.js +9 -13
- package/lib/cart.js +7 -11
- package/lib/catalog-drafts.js +8 -10
- package/lib/catalog-import.js +3 -7
- package/lib/catalog.js +13 -20
- package/lib/category-navigation.js +3 -7
- package/lib/checkout.js +3 -7
- package/lib/click-and-collect.js +7 -11
- package/lib/clickstream.js +9 -13
- package/lib/cms-blocks.js +5 -9
- package/lib/code-minter.js +5 -9
- package/lib/collections.js +10 -18
- package/lib/compliance-export.js +5 -9
- package/lib/config.js +3 -7
- package/lib/consent-ledger.js +5 -12
- package/lib/cookie-consent.js +6 -13
- package/lib/cost-layers.js +6 -10
- package/lib/coupon-stacking.js +2 -6
- package/lib/credit-limits.js +5 -9
- package/lib/currency-display.js +6 -10
- package/lib/currency-rounding.js +4 -8
- package/lib/customer-activity.js +6 -10
- package/lib/customer-impersonation.js +11 -18
- package/lib/customer-import.js +9 -13
- package/lib/customer-merge.js +9 -12
- package/lib/customer-notes.js +18 -22
- package/lib/customer-portal.js +10 -17
- package/lib/customer-risk-profile.js +5 -20
- package/lib/customer-roles.js +5 -9
- package/lib/customer-segments.js +7 -11
- package/lib/customer-surveys.js +10 -14
- package/lib/customers.js +10 -14
- package/lib/cycle-counting.js +5 -9
- package/lib/damage-photos.js +6 -10
- package/lib/delivery-estimate.js +8 -15
- package/lib/demand-forecast.js +7 -11
- package/lib/discount-allocation.js +6 -10
- package/lib/discount-analytics.js +8 -12
- package/lib/dispute-resolution.js +4 -8
- package/lib/dropship-forwarding.js +7 -11
- package/lib/dunning.js +6 -10
- package/lib/email-ab-tests.js +5 -9
- package/lib/email-campaigns.js +8 -12
- package/lib/email-engagement-score.js +4 -19
- package/lib/email-suppressions.js +7 -14
- package/lib/email-templates.js +4 -8
- package/lib/email-warmup.js +6 -13
- package/lib/email.js +5 -9
- package/lib/error-log.js +3 -8
- package/lib/event-log.js +7 -11
- package/lib/experiments.js +5 -9
- package/lib/externaldb-d1.js +2 -6
- package/lib/fraud-screen.js +10 -29
- package/lib/fulfillment-sla.js +5 -9
- package/lib/geolocation.js +2 -6
- package/lib/gift-card-ledger.js +6 -10
- package/lib/gift-options.js +4 -8
- package/lib/gift-registry.js +7 -11
- package/lib/giftcards.js +9 -13
- package/lib/inventory-alerts.js +4 -8
- package/lib/inventory-allocations.js +3 -7
- package/lib/inventory-audits.js +5 -9
- package/lib/inventory-locations.js +3 -7
- package/lib/inventory-receive.js +7 -11
- package/lib/inventory-snapshots.js +11 -15
- package/lib/inventory-writeoffs.js +6 -10
- package/lib/invoice-renderer.js +6 -10
- package/lib/knowledge-base.js +14 -18
- package/lib/line-gift-wrap.js +8 -15
- package/lib/live-chat.js +11 -18
- package/lib/locale-router.js +3 -7
- package/lib/loyalty-earn-rules.js +4 -8
- package/lib/loyalty-redemption.js +5 -9
- package/lib/loyalty.js +4 -8
- package/lib/mailing-audiences.js +5 -9
- package/lib/marketing-budget.js +6 -10
- package/lib/metered-usage.js +4 -8
- package/lib/newsletter.js +14 -24
- package/lib/notifications.js +5 -9
- package/lib/operator-activity-feed.js +6 -10
- package/lib/operator-approvals.js +4 -8
- package/lib/operator-audit-log.js +5 -9
- package/lib/operator-help-center.js +13 -17
- package/lib/operator-inbox.js +8 -12
- package/lib/operator-roles.js +4 -8
- package/lib/operator-sessions.js +12 -18
- package/lib/order-escalation.js +6 -10
- package/lib/order-exchanges.js +4 -8
- package/lib/order-export.js +10 -14
- package/lib/order-notes.js +14 -20
- package/lib/order-ratings.js +5 -9
- package/lib/order-tags.js +7 -11
- package/lib/order-timeline.js +10 -14
- package/lib/order-tracking.js +5 -9
- package/lib/order.js +11 -15
- package/lib/packing-slips.js +7 -11
- package/lib/payment-methods.js +5 -9
- package/lib/payment-retries.js +6 -10
- package/lib/payment.js +257 -13
- package/lib/pick-lists.js +5 -9
- package/lib/pixel-events.js +6 -10
- package/lib/plan-changes.js +4 -8
- package/lib/preorder.js +5 -9
- package/lib/price-display.js +7 -11
- package/lib/pricing.js +2 -6
- package/lib/print-on-demand.js +27 -31
- package/lib/print-queue.js +6 -10
- package/lib/print-receipts.js +6 -10
- package/lib/product-bulk-ops.js +4 -8
- package/lib/product-compare.js +7 -11
- package/lib/product-import.js +11 -15
- package/lib/product-qa.js +10 -17
- package/lib/promo-banners.js +13 -17
- package/lib/promo-bundles.js +7 -11
- package/lib/purchase-orders.js +7 -13
- package/lib/push-notifications.js +12 -16
- package/lib/pwa-manifest.js +7 -11
- package/lib/quantity-discounts.js +8 -12
- package/lib/quotes.js +5 -12
- package/lib/r2-bridge.js +2 -6
- package/lib/recently-viewed.js +6 -14
- package/lib/recommendations.js +7 -15
- package/lib/referral-leaderboard.js +5 -9
- package/lib/referrals.js +8 -12
- package/lib/refund-automation.js +5 -10
- package/lib/refund-policy.js +4 -9
- package/lib/reorder-reminders.js +8 -12
- package/lib/reorder-thresholds.js +5 -9
- package/lib/return-labels.js +6 -10
- package/lib/returns.js +10 -14
- package/lib/reviews.js +8 -15
- package/lib/robots-config.js +5 -10
- package/lib/sales-reports.js +7 -11
- package/lib/sales-tax-filings.js +10 -14
- package/lib/save-for-later.js +8 -12
- package/lib/search-facets.js +15 -22
- package/lib/search-ranking.js +4 -8
- package/lib/search-suggestions.js +8 -16
- package/lib/search-synonyms.js +9 -15
- package/lib/seller-signup.js +9 -16
- package/lib/shipping-insurance.js +6 -10
- package/lib/shipping-labels.js +6 -10
- package/lib/shipping-zones.js +2 -9
- package/lib/shrinkage-report.js +9 -13
- package/lib/sidebar-widgets.js +8 -12
- package/lib/site-redirects.js +4 -11
- package/lib/sitemap-generator.js +5 -9
- package/lib/smart-restocking.js +3 -7
- package/lib/sms-dispatcher.js +13 -17
- package/lib/split-shipments.js +6 -10
- package/lib/stock-alerts.js +10 -19
- package/lib/stock-receipts.js +14 -18
- package/lib/stock-transfers.js +8 -12
- package/lib/store-credit.js +6 -9
- package/lib/storefront-dashboards.js +4 -8
- package/lib/storefront-forms.js +10 -14
- package/lib/storefront-pages.js +5 -9
- package/lib/storefront.js +46 -50
- package/lib/subscription-analytics.js +14 -22
- package/lib/subscription-billing.js +9 -13
- package/lib/subscription-controls.js +6 -9
- package/lib/subscription-gifts.js +12 -15
- package/lib/subscriptions.js +5 -9
- package/lib/suggestion-box.js +10 -14
- package/lib/support-tickets.js +18 -25
- package/lib/tax-cert-renewals.js +7 -10
- package/lib/tax-exempt.js +5 -9
- package/lib/tax-rates.js +6 -13
- package/lib/tax-remittance.js +6 -9
- package/lib/tenants.js +6 -13
- package/lib/theme-assets.js +5 -10
- package/lib/theme.js +3 -7
- package/lib/tier-benefits.js +4 -8
- package/lib/translations.js +7 -14
- package/lib/trust-badges.js +9 -14
- package/lib/variants.js +9 -16
- package/lib/vendor/MANIFEST.json +2 -2
- package/lib/vendor/blamejs/CHANGELOG.md +4 -0
- package/lib/vendor/blamejs/README.md +2 -1
- package/lib/vendor/blamejs/api-snapshot.json +39 -2
- package/lib/vendor/blamejs/index.js +2 -0
- package/lib/vendor/blamejs/lib/content-digest.js +189 -0
- package/lib/vendor/blamejs/lib/structured-fields.js +362 -0
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.12.53.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.12.54.json +18 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +11 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/content-digest.test.js +87 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/structured-fields-codec.test.js +171 -0
- package/lib/vendor-invoices.js +8 -15
- package/lib/vendors.js +6 -12
- package/lib/webhook-receiver.js +13 -24
- package/lib/webhook-subscriptions.js +9 -16
- package/lib/webhooks.js +17 -20
- package/lib/winback-campaigns.js +8 -11
- package/lib/wishlist-alerts.js +9 -12
- package/lib/wishlist-digest.js +9 -12
- package/lib/wishlist-sharing.js +13 -17
- package/lib/wishlist.js +7 -14
- package/package.json +1 -1
|
@@ -105,12 +105,8 @@
|
|
|
105
105
|
* @related b.uuid, b.guardUuid, b.crypto.namespaceHash, b.safeUrl, b.template.escapeHtml
|
|
106
106
|
*/
|
|
107
107
|
|
|
108
|
-
var
|
|
109
|
-
|
|
110
|
-
if (!bShop) bShop = require("./index");
|
|
111
|
-
return bShop.framework;
|
|
112
|
-
}
|
|
113
|
-
var C = _b().constants;
|
|
108
|
+
var b = require("./vendor/blamejs");
|
|
109
|
+
var C = b.constants;
|
|
114
110
|
|
|
115
111
|
// ---- constants ----------------------------------------------------------
|
|
116
112
|
|
|
@@ -185,7 +181,7 @@ function _id(s, label) {
|
|
|
185
181
|
|
|
186
182
|
function _uuid(s, label) {
|
|
187
183
|
try {
|
|
188
|
-
return
|
|
184
|
+
return b.guardUuid.sanitize(s, { profile: "strict" });
|
|
189
185
|
} catch (e) {
|
|
190
186
|
throw new TypeError("assembly-instructions: " + label + " - " + (e && e.message || "invalid UUID"));
|
|
191
187
|
}
|
|
@@ -199,7 +195,7 @@ function _sessionId(s) {
|
|
|
199
195
|
}
|
|
200
196
|
|
|
201
197
|
function _hashSession(s) {
|
|
202
|
-
return
|
|
198
|
+
return b.crypto.namespaceHash(SESSION_NAMESPACE, s);
|
|
203
199
|
}
|
|
204
200
|
|
|
205
201
|
// content_url is HTTPS-only - PDFs / videos / external_link rows all
|
|
@@ -211,7 +207,7 @@ function _contentUrl(s) {
|
|
|
211
207
|
throw new TypeError("assembly-instructions: content_url must be a non-empty string <= " + MAX_URL_LEN + " chars");
|
|
212
208
|
}
|
|
213
209
|
try {
|
|
214
|
-
|
|
210
|
+
b.safeUrl.parse(s, { allowedProtocols: ["https:"] });
|
|
215
211
|
} catch (e) {
|
|
216
212
|
throw new TypeError("assembly-instructions: content_url - " + (e && e.message || "https-only URL required"));
|
|
217
213
|
}
|
|
@@ -258,7 +254,7 @@ function _days(n) {
|
|
|
258
254
|
// order-detail page can render the markdown variant without composing
|
|
259
255
|
// a separate renderer.
|
|
260
256
|
function _esc(s) {
|
|
261
|
-
return
|
|
257
|
+
return b.template.escapeHtml(s);
|
|
262
258
|
}
|
|
263
259
|
|
|
264
260
|
function _renderMarkdown(src) {
|
|
@@ -316,7 +312,7 @@ function create(opts) {
|
|
|
316
312
|
void catalog;
|
|
317
313
|
var query = opts.query;
|
|
318
314
|
if (!query) {
|
|
319
|
-
query = function (sql, params) { return
|
|
315
|
+
query = function (sql, params) { return b.externalDb.query(sql, params); };
|
|
320
316
|
}
|
|
321
317
|
|
|
322
318
|
function _shapeInstruction(row) {
|
|
@@ -435,7 +431,7 @@ function create(opts) {
|
|
|
435
431
|
}
|
|
436
432
|
|
|
437
433
|
var ts = _now();
|
|
438
|
-
var id =
|
|
434
|
+
var id = b.uuid.v7({ now: ts });
|
|
439
435
|
await query(
|
|
440
436
|
"INSERT INTO product_instructions " +
|
|
441
437
|
"(id, sku, kind, content_url, content_markdown, locale, version, published, archived_at, created_at, updated_at) " +
|
|
@@ -566,7 +562,7 @@ function create(opts) {
|
|
|
566
562
|
var customerId = hasCustomer ? _uuid(input.customer_id, "customer_id") : null;
|
|
567
563
|
var sessionHash = hasSession ? _hashSession(_sessionId(input.session_id)) : null;
|
|
568
564
|
var occurredAt = input.occurred_at == null ? _now() : _epochMs(input.occurred_at, "occurred_at");
|
|
569
|
-
var id =
|
|
565
|
+
var id = b.uuid.v7({ now: _now() });
|
|
570
566
|
await query(
|
|
571
567
|
"INSERT INTO product_instruction_views " +
|
|
572
568
|
"(id, instruction_id, order_id, customer_id, session_id_hash, occurred_at) " +
|
package/lib/auto-discount.js
CHANGED
|
@@ -216,11 +216,7 @@ var ALLOWED_PATCH_COLUMNS = Object.freeze([
|
|
|
216
216
|
"active",
|
|
217
217
|
]);
|
|
218
218
|
|
|
219
|
-
var
|
|
220
|
-
function _b() {
|
|
221
|
-
if (!bShop) bShop = require("./index");
|
|
222
|
-
return bShop.framework;
|
|
223
|
-
}
|
|
219
|
+
var b = require("./vendor/blamejs");
|
|
224
220
|
|
|
225
221
|
// ---- validators ---------------------------------------------------------
|
|
226
222
|
|
|
@@ -595,7 +591,7 @@ function create(opts) {
|
|
|
595
591
|
opts = opts || {};
|
|
596
592
|
var query = opts.query;
|
|
597
593
|
if (!query) {
|
|
598
|
-
query = function (sql, params) { return
|
|
594
|
+
query = function (sql, params) { return b.externalDb.query(sql, params); };
|
|
599
595
|
}
|
|
600
596
|
var catalog = opts.catalog || null;
|
|
601
597
|
var customerSegments = opts.customerSegments || null;
|
|
@@ -1055,7 +1051,7 @@ function create(opts) {
|
|
|
1055
1051
|
throw new TypeError("autoDiscount.recordApplication: rule_slug " + JSON.stringify(slug) + " not found");
|
|
1056
1052
|
}
|
|
1057
1053
|
|
|
1058
|
-
var id =
|
|
1054
|
+
var id = b.uuid.v7();
|
|
1059
1055
|
await query(
|
|
1060
1056
|
"INSERT INTO auto_discount_applications (id, rule_slug, order_id, customer_id, savings_minor, applied_at) " +
|
|
1061
1057
|
"VALUES (?1, ?2, ?3, ?4, ?5, ?6)",
|
package/lib/auto-replenish.js
CHANGED
|
@@ -86,12 +86,8 @@
|
|
|
86
86
|
* the typed reason, not a drop.
|
|
87
87
|
*/
|
|
88
88
|
|
|
89
|
-
var
|
|
90
|
-
|
|
91
|
-
if (!bShop) bShop = require("./index");
|
|
92
|
-
return bShop.framework;
|
|
93
|
-
}
|
|
94
|
-
var C = _b().constants;
|
|
89
|
+
var b = require("./vendor/blamejs");
|
|
90
|
+
var C = b.constants;
|
|
95
91
|
|
|
96
92
|
// ---- constants ----------------------------------------------------------
|
|
97
93
|
|
|
@@ -305,7 +301,7 @@ function create(opts) {
|
|
|
305
301
|
|
|
306
302
|
var query = opts.query;
|
|
307
303
|
if (!query) {
|
|
308
|
-
query = function (sql, params) { return
|
|
304
|
+
query = function (sql, params) { return b.externalDb.query(sql, params); };
|
|
309
305
|
}
|
|
310
306
|
|
|
311
307
|
async function _getPolicyRaw(slug) {
|
|
@@ -347,7 +343,7 @@ function create(opts) {
|
|
|
347
343
|
// Execute the per-policy aggregation + compose. Returns the run row
|
|
348
344
|
// (already inserted) so tickReplenishment can collect summaries.
|
|
349
345
|
async function _runPolicyOnce(policy, now) {
|
|
350
|
-
var runId =
|
|
346
|
+
var runId = b.uuid.v7();
|
|
351
347
|
var runRow = {
|
|
352
348
|
id: runId,
|
|
353
349
|
policy_slug: policy.slug,
|
|
@@ -824,7 +820,7 @@ function create(opts) {
|
|
|
824
820
|
JSON.stringify(policySlug) + " not found");
|
|
825
821
|
}
|
|
826
822
|
var runRow = {
|
|
827
|
-
id:
|
|
823
|
+
id: b.uuid.v7(),
|
|
828
824
|
policy_slug: policySlug,
|
|
829
825
|
po_id: poId,
|
|
830
826
|
qty_proposed: qtyProposed,
|
package/lib/backorder.js
CHANGED
|
@@ -77,12 +77,8 @@
|
|
|
77
77
|
* the real catalog created at boot.
|
|
78
78
|
*/
|
|
79
79
|
|
|
80
|
-
var
|
|
81
|
-
|
|
82
|
-
if (!bShop) bShop = require("./index");
|
|
83
|
-
return bShop.framework;
|
|
84
|
-
}
|
|
85
|
-
var C = _b().constants;
|
|
80
|
+
var b = require("./vendor/blamejs");
|
|
81
|
+
var C = b.constants;
|
|
86
82
|
|
|
87
83
|
// ---- constants ----------------------------------------------------------
|
|
88
84
|
|
|
@@ -97,7 +93,7 @@ var BACKORDER_STATUSES = Object.freeze(["pending", "fulfilled", "cancelled"]);
|
|
|
97
93
|
|
|
98
94
|
function _uuid(s, label) {
|
|
99
95
|
try {
|
|
100
|
-
return
|
|
96
|
+
return b.guardUuid.sanitize(s, { profile: "strict" });
|
|
101
97
|
} catch (e) {
|
|
102
98
|
throw new TypeError("backorder: " + label + " — " + (e && e.message || "invalid UUID"));
|
|
103
99
|
}
|
|
@@ -149,7 +145,7 @@ function create(opts) {
|
|
|
149
145
|
var catalog = opts.catalog;
|
|
150
146
|
var query = opts.query;
|
|
151
147
|
if (!query) {
|
|
152
|
-
query = function (sql, params) { return
|
|
148
|
+
query = function (sql, params) { return b.externalDb.query(sql, params); };
|
|
153
149
|
}
|
|
154
150
|
|
|
155
151
|
// Read the per-SKU config row. Returns null on miss so callers can
|
|
@@ -273,7 +269,7 @@ function create(opts) {
|
|
|
273
269
|
}
|
|
274
270
|
}
|
|
275
271
|
|
|
276
|
-
var id =
|
|
272
|
+
var id = b.uuid.v7();
|
|
277
273
|
var ts = _now();
|
|
278
274
|
try {
|
|
279
275
|
await query(
|
package/lib/banner-ab-tests.js
CHANGED
|
@@ -134,11 +134,7 @@ var ZERO_WIDTH_RE = new RegExp(
|
|
|
134
134
|
"[\\u200B-\\u200F\\u202A-\\u202E\\u2060-\\u2064\\u2066-\\u2069\\uFEFF\\u061C]"
|
|
135
135
|
);
|
|
136
136
|
|
|
137
|
-
var
|
|
138
|
-
function _b() {
|
|
139
|
-
if (!bShop) bShop = require("./index");
|
|
140
|
-
return bShop.framework;
|
|
141
|
-
}
|
|
137
|
+
var b = require("./vendor/blamejs");
|
|
142
138
|
|
|
143
139
|
// ---- monotonic clock ----------------------------------------------------
|
|
144
140
|
//
|
|
@@ -325,7 +321,7 @@ function create(opts) {
|
|
|
325
321
|
opts = opts || {};
|
|
326
322
|
var query = opts.query;
|
|
327
323
|
if (!query) {
|
|
328
|
-
query = function (sql, params) { return
|
|
324
|
+
query = function (sql, params) { return b.externalDb.query(sql, params); };
|
|
329
325
|
}
|
|
330
326
|
// Optional `promoBanners` handle. When supplied, defineTest verifies
|
|
331
327
|
// each variant's banner_slug references an existing, non-archived
|
|
@@ -335,13 +331,13 @@ function create(opts) {
|
|
|
335
331
|
var promo = opts.promoBanners || null;
|
|
336
332
|
|
|
337
333
|
function _hashSession(sessionId) {
|
|
338
|
-
return
|
|
334
|
+
return b.crypto.namespaceHash(SESSION_NAMESPACE, sessionId);
|
|
339
335
|
}
|
|
340
336
|
|
|
341
337
|
function _assignVariant(testSlug, sessionHash, variants) {
|
|
342
338
|
var cw = 0;
|
|
343
339
|
for (var i = 0; i < variants.length; i += 1) cw += variants[i].weight;
|
|
344
|
-
var keyHash =
|
|
340
|
+
var keyHash = b.crypto.namespaceHash(ASSIGN_NAMESPACE, testSlug + ":" + sessionHash);
|
|
345
341
|
var bucket = _modCumulativeWeight(keyHash, cw);
|
|
346
342
|
var acc = 0;
|
|
347
343
|
for (var j = 0; j < variants.length; j += 1) {
|
|
@@ -520,7 +516,7 @@ function create(opts) {
|
|
|
520
516
|
|
|
521
517
|
var sessionHash = _hashSession(input.session_id);
|
|
522
518
|
var variant = _assignVariant(test.slug, sessionHash, test.variants);
|
|
523
|
-
var id =
|
|
519
|
+
var id = b.uuid.v7();
|
|
524
520
|
await query(
|
|
525
521
|
"INSERT INTO banner_ab_test_events " +
|
|
526
522
|
"(id, test_slug, variant_slug, session_id_hash, event_kind, value, occurred_at) " +
|
|
@@ -595,13 +591,13 @@ function create(opts) {
|
|
|
595
591
|
}
|
|
596
592
|
for (var i = 0; i < countRows.length; i += 1) {
|
|
597
593
|
var cr = countRows[i];
|
|
598
|
-
var
|
|
599
|
-
if (!
|
|
594
|
+
var bv = byVariant[cr.variant_slug];
|
|
595
|
+
if (!bv) continue;
|
|
600
596
|
var n = Number(cr.n);
|
|
601
|
-
if (cr.event_kind === "impression")
|
|
602
|
-
else if (cr.event_kind === "click")
|
|
603
|
-
else
|
|
604
|
-
if (cr.event_kind === "conversion")
|
|
597
|
+
if (cr.event_kind === "impression") bv.impressions = n;
|
|
598
|
+
else if (cr.event_kind === "click") bv.clicks = n;
|
|
599
|
+
else bv.conversions = n;
|
|
600
|
+
if (cr.event_kind === "conversion") bv.conversion_value = Number(cr.value_sum);
|
|
605
601
|
}
|
|
606
602
|
for (var d = 0; d < distinctRows.length; d += 1) {
|
|
607
603
|
var dr = distinctRows[d];
|
package/lib/barcodes.js
CHANGED
|
@@ -44,11 +44,7 @@
|
|
|
44
44
|
* var svg = await bc.renderSvg({ sku: "WIDGET-A" });
|
|
45
45
|
*/
|
|
46
46
|
|
|
47
|
-
var
|
|
48
|
-
function _b() {
|
|
49
|
-
if (!bShop) bShop = require("./index");
|
|
50
|
-
return bShop.framework;
|
|
51
|
-
}
|
|
47
|
+
var b = require("./vendor/blamejs");
|
|
52
48
|
|
|
53
49
|
var KINDS = ["upc_a", "ean_13", "code_128", "gtin_14"];
|
|
54
50
|
|
|
@@ -367,7 +363,7 @@ function _renderSvg(modules, label, opts) {
|
|
|
367
363
|
}
|
|
368
364
|
var labelXml = "";
|
|
369
365
|
if (label) {
|
|
370
|
-
var safe =
|
|
366
|
+
var safe = b.template.escapeHtml(String(label));
|
|
371
367
|
labelXml = "<text x=\"" + (totalW / 2).toFixed(3) + "\" y=\"" + (heightPx - 2) +
|
|
372
368
|
"\" font-family=\"monospace\" font-size=\"10\" text-anchor=\"middle\" fill=\"#000\">" + safe + "</text>";
|
|
373
369
|
}
|
|
@@ -387,7 +383,7 @@ function create(opts) {
|
|
|
387
383
|
var catalog = opts.catalog;
|
|
388
384
|
var query = opts.query;
|
|
389
385
|
if (!query) {
|
|
390
|
-
query = function (sql, params) { return
|
|
386
|
+
query = function (sql, params) { return b.externalDb.query(sql, params); };
|
|
391
387
|
}
|
|
392
388
|
|
|
393
389
|
async function _verifySku(sku) {
|
|
@@ -399,7 +395,7 @@ function create(opts) {
|
|
|
399
395
|
}
|
|
400
396
|
|
|
401
397
|
async function _assignRow(sku, kind, value) {
|
|
402
|
-
var id =
|
|
398
|
+
var id = b.uuid.v7();
|
|
403
399
|
var ts = _now();
|
|
404
400
|
try {
|
|
405
401
|
await query(
|
|
@@ -590,7 +586,7 @@ function create(opts) {
|
|
|
590
586
|
}
|
|
591
587
|
ownerCompany = input.owner_company;
|
|
592
588
|
}
|
|
593
|
-
var id =
|
|
589
|
+
var id = b.uuid.v7();
|
|
594
590
|
var ts = _now();
|
|
595
591
|
await query(
|
|
596
592
|
"INSERT INTO barcode_ranges (id, kind, prefix, next_value, max_value, owner_company, created_at) " +
|
package/lib/bin-locations.js
CHANGED
|
@@ -106,11 +106,7 @@ var CONDITIONS = Object.freeze([
|
|
|
106
106
|
// operator has not used an `{` or beyond as a leading byte.
|
|
107
107
|
var NO_ASSIGN_SORT_KEY = "";
|
|
108
108
|
|
|
109
|
-
var
|
|
110
|
-
function _b() {
|
|
111
|
-
if (!bShop) bShop = require("./index");
|
|
112
|
-
return bShop.framework;
|
|
113
|
-
}
|
|
109
|
+
var b = require("./vendor/blamejs");
|
|
114
110
|
|
|
115
111
|
// ---- monotonic clock ---------------------------------------------------
|
|
116
112
|
//
|
|
@@ -280,7 +276,7 @@ function create(opts) {
|
|
|
280
276
|
opts = opts || {};
|
|
281
277
|
var query = opts.query;
|
|
282
278
|
if (!query) {
|
|
283
|
-
query = function (sql, params) { return
|
|
279
|
+
query = function (sql, params) { return b.externalDb.query(sql, params); };
|
|
284
280
|
}
|
|
285
281
|
|
|
286
282
|
// inventoryLocations is optional — when wired, every assign /
|
|
@@ -394,7 +390,7 @@ function create(opts) {
|
|
|
394
390
|
"INSERT INTO bin_assignments (id, sku, location_code, bin_label, " +
|
|
395
391
|
"aisle, shelf, level, is_primary, assigned_at, archived_at) " +
|
|
396
392
|
"VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, NULL)",
|
|
397
|
-
[
|
|
393
|
+
[b.uuid.v7(), sku, locCode, binLabel,
|
|
398
394
|
aisle, shelf, level, isPrimary ? 1 : 0, now],
|
|
399
395
|
);
|
|
400
396
|
} catch (e) {
|
|
@@ -704,7 +700,7 @@ function create(opts) {
|
|
|
704
700
|
// input order.
|
|
705
701
|
var expectedSorted = expected.slice().sort();
|
|
706
702
|
var actualSorted = actual.slice().sort();
|
|
707
|
-
var id =
|
|
703
|
+
var id = b.uuid.v7();
|
|
708
704
|
await query(
|
|
709
705
|
"INSERT INTO bin_audits (id, location_code, bin_label, audited_by, " +
|
|
710
706
|
"expected_skus_json, actual_skus_json, variance_json, occurred_at) " +
|
package/lib/blog-articles.js
CHANGED
|
@@ -167,11 +167,7 @@ var ZERO_WIDTH_RE = new RegExp(
|
|
|
167
167
|
"[\\u200B-\\u200F\\u202A-\\u202E\\u2060-\\u2064\\u2066-\\u2069\\uFEFF\\u061C]"
|
|
168
168
|
);
|
|
169
169
|
|
|
170
|
-
var
|
|
171
|
-
function _b() {
|
|
172
|
-
if (!bShop) bShop = require("./index");
|
|
173
|
-
return bShop.framework;
|
|
174
|
-
}
|
|
170
|
+
var b = require("./vendor/blamejs");
|
|
175
171
|
|
|
176
172
|
// ---- monotonic clock ---------------------------------------------------
|
|
177
173
|
//
|
|
@@ -323,7 +319,7 @@ function _heroImageUrl(s) {
|
|
|
323
319
|
return s;
|
|
324
320
|
}
|
|
325
321
|
try {
|
|
326
|
-
|
|
322
|
+
b.safeUrl.parse(s, { allowedProtocols: ["https:"] });
|
|
327
323
|
} catch (e) {
|
|
328
324
|
throw new TypeError("blogArticles: hero_image_url — " + (e && e.message || "must be https:// or a /-rooted absolute path"));
|
|
329
325
|
}
|
|
@@ -423,7 +419,7 @@ function _hydrateRow(r) {
|
|
|
423
419
|
// byte is HTML-escaped before it reaches the `<article>` of the page.
|
|
424
420
|
|
|
425
421
|
function _esc(s) {
|
|
426
|
-
return
|
|
422
|
+
return b.template.escapeHtml(s);
|
|
427
423
|
}
|
|
428
424
|
|
|
429
425
|
function _safeLinkUrl(url) {
|
|
@@ -435,7 +431,7 @@ function _safeLinkUrl(url) {
|
|
|
435
431
|
return url;
|
|
436
432
|
}
|
|
437
433
|
try {
|
|
438
|
-
|
|
434
|
+
b.safeUrl.parse(url, { allowedProtocols: ["https:"] });
|
|
439
435
|
} catch (_e) {
|
|
440
436
|
return null;
|
|
441
437
|
}
|
|
@@ -573,7 +569,7 @@ function create(opts) {
|
|
|
573
569
|
opts = opts || {};
|
|
574
570
|
var query = opts.query;
|
|
575
571
|
if (!query) {
|
|
576
|
-
query = function (sql, params) { return
|
|
572
|
+
query = function (sql, params) { return b.externalDb.query(sql, params); };
|
|
577
573
|
}
|
|
578
574
|
// `customers` is reserved for future cross-primitive composition
|
|
579
575
|
// (e.g. byline -> customer-of-record lookups). The factory accepts
|
|
@@ -598,7 +594,7 @@ function create(opts) {
|
|
|
598
594
|
throw new TypeError("blogArticles." + label + ": cursor must be an opaque string or null");
|
|
599
595
|
}
|
|
600
596
|
try {
|
|
601
|
-
var state =
|
|
597
|
+
var state = b.pagination.decodeCursor(cursor, cursorSecret);
|
|
602
598
|
if (JSON.stringify(state.orderKey) !== JSON.stringify(LIST_ORDER_KEY)) {
|
|
603
599
|
throw new TypeError("blogArticles." + label + ": cursor orderKey mismatch");
|
|
604
600
|
}
|
|
@@ -612,7 +608,7 @@ function create(opts) {
|
|
|
612
608
|
function _encodeNext(rows, limit) {
|
|
613
609
|
var last = rows[rows.length - 1];
|
|
614
610
|
if (!last || rows.length < limit) return null;
|
|
615
|
-
return
|
|
611
|
+
return b.pagination.encodeCursor({
|
|
616
612
|
orderKey: LIST_ORDER_KEY,
|
|
617
613
|
vals: [Number(last.published_at), last.slug],
|
|
618
614
|
forward: true,
|
|
@@ -705,11 +701,11 @@ function create(opts) {
|
|
|
705
701
|
var idx = 1;
|
|
706
702
|
|
|
707
703
|
if (cursorVals) {
|
|
708
|
-
var
|
|
709
|
-
var
|
|
704
|
+
var pPublished = idx;
|
|
705
|
+
var pSlug = idx + 1;
|
|
710
706
|
where.push(
|
|
711
|
-
"(published_at < ?" +
|
|
712
|
-
"(published_at = ?" +
|
|
707
|
+
"(published_at < ?" + pPublished + " OR " +
|
|
708
|
+
"(published_at = ?" + pPublished + " AND slug < ?" + pSlug + "))"
|
|
713
709
|
);
|
|
714
710
|
params.push(cursorVals[0], cursorVals[1]);
|
|
715
711
|
idx += 2;
|
|
@@ -1064,13 +1060,13 @@ function create(opts) {
|
|
|
1064
1060
|
}
|
|
1065
1061
|
var sessionHash = null;
|
|
1066
1062
|
if (input.session_id != null) {
|
|
1067
|
-
sessionHash =
|
|
1063
|
+
sessionHash = b.crypto.namespaceHash(VIEW_NAMESPACE, _sessionIdRaw(input.session_id));
|
|
1068
1064
|
}
|
|
1069
1065
|
var ts = _now();
|
|
1070
1066
|
await query(
|
|
1071
1067
|
"INSERT INTO blog_article_views (id, slug, session_id_hash, occurred_at) " +
|
|
1072
1068
|
"VALUES (?1, ?2, ?3, ?4)",
|
|
1073
|
-
[
|
|
1069
|
+
[b.uuid.v7(), slug, sessionHash, ts],
|
|
1074
1070
|
);
|
|
1075
1071
|
await query(
|
|
1076
1072
|
"UPDATE blog_articles SET view_count = view_count + 1 WHERE slug = ?1",
|
package/lib/bundles.js
CHANGED
|
@@ -50,11 +50,7 @@
|
|
|
50
50
|
* an `extraReferenceCheck` callback to the factory.
|
|
51
51
|
*/
|
|
52
52
|
|
|
53
|
-
var
|
|
54
|
-
function _b() {
|
|
55
|
-
if (!bShop) bShop = require("./index");
|
|
56
|
-
return bShop.framework;
|
|
57
|
-
}
|
|
53
|
+
var b = require("./vendor/blamejs");
|
|
58
54
|
|
|
59
55
|
// SKU shape is shared with the catalog primitive — same alphabet, same
|
|
60
56
|
// length cap. Component lookup goes through the catalog, so the two
|
|
@@ -109,7 +105,7 @@ function create(opts) {
|
|
|
109
105
|
opts = opts || {};
|
|
110
106
|
var query = opts.query;
|
|
111
107
|
if (!query) {
|
|
112
|
-
query = function (sql, params) { return
|
|
108
|
+
query = function (sql, params) { return b.externalDb.query(sql, params); };
|
|
113
109
|
}
|
|
114
110
|
var catalog = opts.catalog;
|
|
115
111
|
if (!catalog || !catalog.variants || typeof catalog.variants.bySku !== "function") {
|
|
@@ -305,7 +301,7 @@ function create(opts) {
|
|
|
305
301
|
throw new TypeError("bundles.listBundles: cursor must be an opaque string or null");
|
|
306
302
|
}
|
|
307
303
|
try {
|
|
308
|
-
var state =
|
|
304
|
+
var state = b.pagination.decodeCursor(input.cursor, cursorSecret);
|
|
309
305
|
if (JSON.stringify(state.orderKey) !== JSON.stringify(BUNDLE_ORDER_KEY)) {
|
|
310
306
|
throw new TypeError("bundles.listBundles: cursor orderKey mismatch");
|
|
311
307
|
}
|
|
@@ -328,7 +324,7 @@ function create(opts) {
|
|
|
328
324
|
var last = r.rows[r.rows.length - 1];
|
|
329
325
|
var next = null;
|
|
330
326
|
if (last && r.rows.length === limit) {
|
|
331
|
-
next =
|
|
327
|
+
next = b.pagination.encodeCursor({
|
|
332
328
|
orderKey: BUNDLE_ORDER_KEY,
|
|
333
329
|
vals: [last.updated_at, last.bundle_sku],
|
|
334
330
|
forward: true,
|
|
@@ -472,8 +468,8 @@ function create(opts) {
|
|
|
472
468
|
// Allow-list defense even though the column name is a literal —
|
|
473
469
|
// a future refactor that introduces a dynamic patch key path
|
|
474
470
|
// can't widen the surface to an attacker-controlled column.
|
|
475
|
-
|
|
476
|
-
sets.push(
|
|
471
|
+
b.safeSql.assertOneOf(col, ALLOWED_BUNDLE_COLUMNS);
|
|
472
|
+
sets.push(b.safeSql.quoteIdentifier(col, "sqlite") + " = ?" + (idx++));
|
|
477
473
|
params.push(val);
|
|
478
474
|
}
|
|
479
475
|
if (patch.title !== undefined) {
|
package/lib/business-hours.js
CHANGED
|
@@ -69,12 +69,8 @@
|
|
|
69
69
|
* @related shop.deliveryEstimate
|
|
70
70
|
*/
|
|
71
71
|
|
|
72
|
-
var
|
|
73
|
-
|
|
74
|
-
if (!bShop) bShop = require("./index");
|
|
75
|
-
return bShop.framework;
|
|
76
|
-
}
|
|
77
|
-
var C = _b().constants;
|
|
72
|
+
var b = require("./vendor/blamejs");
|
|
73
|
+
var C = b.constants;
|
|
78
74
|
|
|
79
75
|
var MAX_SLUG_LEN = 64;
|
|
80
76
|
var SLUG_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
@@ -369,7 +365,7 @@ function create(opts) {
|
|
|
369
365
|
opts = opts || {};
|
|
370
366
|
var query = opts.query;
|
|
371
367
|
if (!query) {
|
|
372
|
-
query = function (sql, params) { return
|
|
368
|
+
query = function (sql, params) { return b.externalDb.query(sql, params); };
|
|
373
369
|
}
|
|
374
370
|
|
|
375
371
|
function _hydrateSchedule(row) {
|
package/lib/captcha-gate.js
CHANGED
|
@@ -175,14 +175,8 @@ var ALLOWED_PATCH_COLUMNS = Object.freeze([
|
|
|
175
175
|
"active",
|
|
176
176
|
]);
|
|
177
177
|
|
|
178
|
-
//
|
|
179
|
-
|
|
180
|
-
// importing `./index` at module-eval time.
|
|
181
|
-
var bShop;
|
|
182
|
-
function _b() {
|
|
183
|
-
if (!bShop) bShop = require("./index");
|
|
184
|
-
return bShop.framework;
|
|
185
|
-
}
|
|
178
|
+
// Framework handle (the vendored blamejs); index.js re-exports this as .framework.
|
|
179
|
+
var b = require("./vendor/blamejs");
|
|
186
180
|
|
|
187
181
|
// ---- validators --------------------------------------------------------
|
|
188
182
|
|
|
@@ -258,7 +252,7 @@ function _secretKeyRaw(s) {
|
|
|
258
252
|
}
|
|
259
253
|
|
|
260
254
|
function _hashSecret(normalizedSecret) {
|
|
261
|
-
return
|
|
255
|
+
return b.crypto.namespaceHash(SECRET_HASH_NAMESPACE, normalizedSecret);
|
|
262
256
|
}
|
|
263
257
|
|
|
264
258
|
function _thresholdScore(n, kind) {
|
|
@@ -368,7 +362,7 @@ function _optionalSessionId(s) {
|
|
|
368
362
|
}
|
|
369
363
|
|
|
370
364
|
function _hashSession(rawSessionId) {
|
|
371
|
-
return
|
|
365
|
+
return b.crypto.namespaceHash("captcha-session", rawSessionId);
|
|
372
366
|
}
|
|
373
367
|
|
|
374
368
|
function _tsBound(n, label) {
|
|
@@ -443,7 +437,7 @@ function create(opts) {
|
|
|
443
437
|
opts = opts || {};
|
|
444
438
|
var query = opts.query;
|
|
445
439
|
if (!query) {
|
|
446
|
-
query = function (sql, params) { return
|
|
440
|
+
query = function (sql, params) { return b.externalDb.query(sql, params); };
|
|
447
441
|
}
|
|
448
442
|
|
|
449
443
|
async function _getProviderRow(slug) {
|
package/lib/carrier-accounts.js
CHANGED
|
@@ -99,7 +99,10 @@ var CARRIERS = Object.freeze([
|
|
|
99
99
|
|
|
100
100
|
var STATUSES = Object.freeze(["active", "disabled", "rotating"]);
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
// Framework handle (the vendored blamejs); index.js re-exports this as .framework.
|
|
103
|
+
var b = require("./vendor/blamejs");
|
|
104
|
+
|
|
105
|
+
var ROTATION_GRACE_MS = b.constants.TIME.days(1);
|
|
103
106
|
|
|
104
107
|
var NS_ACCOUNT_NUMBER = "carrier-account-account-number";
|
|
105
108
|
var NS_API_KEY = "carrier-account-api-key";
|
|
@@ -141,15 +144,6 @@ var API_KEY_RE = /^[\x21-\x7e]+$/;
|
|
|
141
144
|
|
|
142
145
|
var OPERATION_RE = /^[a-z0-9][a-z0-9._:-]{0,63}$/;
|
|
143
146
|
|
|
144
|
-
// Lazy framework handle — matches the pattern used by every other shop
|
|
145
|
-
// primitive; avoids the require cycle that would arise from importing
|
|
146
|
-
// `./index` at module-eval time.
|
|
147
|
-
var bShop;
|
|
148
|
-
function _b() {
|
|
149
|
-
if (!bShop) bShop = require("./index");
|
|
150
|
-
return bShop.framework;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
147
|
// ---- monotonic clock ---------------------------------------------------
|
|
154
148
|
//
|
|
155
149
|
// Operator-driven rotations + disables can land in the same millisecond
|
|
@@ -169,7 +163,7 @@ function _now() {
|
|
|
169
163
|
// ---- validators --------------------------------------------------------
|
|
170
164
|
|
|
171
165
|
function _uuid(s, label) {
|
|
172
|
-
try { return
|
|
166
|
+
try { return b.guardUuid.sanitize(s, { profile: "strict" }); }
|
|
173
167
|
catch (e) {
|
|
174
168
|
throw new TypeError("carrier-accounts: " + label + " — " +
|
|
175
169
|
(e && e.message || "invalid UUID"));
|
|
@@ -328,21 +322,21 @@ function _shipFromAddress(a) {
|
|
|
328
322
|
// Node built-in `base64url` encoding) instead of the polynomial-
|
|
329
323
|
// ReDoS-shaped `.replace(/=+$/, "")` strip.
|
|
330
324
|
function _generateSecret() {
|
|
331
|
-
var buf =
|
|
332
|
-
return
|
|
325
|
+
var buf = b.crypto.generateBytes(SECRET_BYTE_LEN);
|
|
326
|
+
return b.crypto.toBase64Url(buf);
|
|
333
327
|
}
|
|
334
328
|
|
|
335
329
|
function _hashAccountNumber(plain) {
|
|
336
|
-
return
|
|
330
|
+
return b.crypto.namespaceHash(NS_ACCOUNT_NUMBER, plain);
|
|
337
331
|
}
|
|
338
332
|
function _hashApiKey(plain) {
|
|
339
|
-
return
|
|
333
|
+
return b.crypto.namespaceHash(NS_API_KEY, plain);
|
|
340
334
|
}
|
|
341
335
|
function _hashApiSecret(plain) {
|
|
342
|
-
return
|
|
336
|
+
return b.crypto.namespaceHash(NS_API_SECRET, plain);
|
|
343
337
|
}
|
|
344
338
|
function _hashMeterNumber(plain) {
|
|
345
|
-
return
|
|
339
|
+
return b.crypto.namespaceHash(NS_METER_NUMBER, plain);
|
|
346
340
|
}
|
|
347
341
|
|
|
348
342
|
// ---- percentile --------------------------------------------------------
|
|
@@ -362,7 +356,7 @@ function create(opts) {
|
|
|
362
356
|
opts = opts || {};
|
|
363
357
|
var query = opts.query;
|
|
364
358
|
if (!query) {
|
|
365
|
-
query = function (sql, params) { return
|
|
359
|
+
query = function (sql, params) { return b.externalDb.query(sql, params); };
|
|
366
360
|
}
|
|
367
361
|
|
|
368
362
|
async function _getRaw(id) {
|
|
@@ -475,7 +469,7 @@ function create(opts) {
|
|
|
475
469
|
[hashAN, normAcct, hashAK, hashAS, hashMN, addrJson, now, id],
|
|
476
470
|
);
|
|
477
471
|
} else {
|
|
478
|
-
id =
|
|
472
|
+
id = b.uuid.v7();
|
|
479
473
|
await query(
|
|
480
474
|
"INSERT INTO carrier_accounts " +
|
|
481
475
|
"(id, carrier, account_label, account_number_hash, " +
|
|
@@ -667,7 +661,7 @@ function create(opts) {
|
|
|
667
661
|
if (current.status === "disabled") return { ok: false, reason: "disabled" };
|
|
668
662
|
|
|
669
663
|
var supplied = _hashApiKey(input.plaintext_key);
|
|
670
|
-
var live =
|
|
664
|
+
var live = b.crypto.timingSafeEqual(current.api_key_hash, supplied);
|
|
671
665
|
if (live) {
|
|
672
666
|
return { ok: true, matched: "live", account_id: id };
|
|
673
667
|
}
|
|
@@ -689,7 +683,7 @@ function create(opts) {
|
|
|
689
683
|
(now - rotatedAt) <= ROTATION_GRACE_MS;
|
|
690
684
|
|
|
691
685
|
if (prev != null && withinGrace) {
|
|
692
|
-
var matchedPrev =
|
|
686
|
+
var matchedPrev = b.crypto.timingSafeEqual(prev, supplied);
|
|
693
687
|
if (matchedPrev) {
|
|
694
688
|
return { ok: true, matched: "previous", account_id: id,
|
|
695
689
|
grace_expires_at: rotatedAt + ROTATION_GRACE_MS };
|
|
@@ -719,7 +713,7 @@ function create(opts) {
|
|
|
719
713
|
throw miss;
|
|
720
714
|
}
|
|
721
715
|
var ts = _now();
|
|
722
|
-
var rowId =
|
|
716
|
+
var rowId = b.uuid.v7();
|
|
723
717
|
await query(
|
|
724
718
|
"INSERT INTO carrier_usage_log (id, account_id, operation, " +
|
|
725
719
|
"success, ms_elapsed, occurred_at) VALUES (?1, ?2, ?3, ?4, ?5, ?6)",
|