@blamejs/blamejs-shop 0.0.129 → 0.1.1

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.
Files changed (127) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/lib/admin.js +275 -9
  4. package/lib/affiliates.js +4 -3
  5. package/lib/analytics.js +3 -2
  6. package/lib/api-keys.js +1 -1
  7. package/lib/assembly-instructions.js +2 -1
  8. package/lib/auto-replenish.js +4 -3
  9. package/lib/backorder.js +2 -1
  10. package/lib/business-hours.js +8 -1
  11. package/lib/carrier-accounts.js +1 -1
  12. package/lib/carrier-rates.js +1 -1
  13. package/lib/cart-abandonment.js +3 -2
  14. package/lib/cart-bulk-ops.js +2 -1
  15. package/lib/cart-recovery.js +5 -4
  16. package/lib/cart.js +6 -2
  17. package/lib/catalog-drafts.js +1 -1
  18. package/lib/click-and-collect.js +3 -2
  19. package/lib/clickstream.js +4 -3
  20. package/lib/config.js +2 -1
  21. package/lib/cookie-consent.js +2 -1
  22. package/lib/credit-limits.js +2 -1
  23. package/lib/currency-display.js +2 -1
  24. package/lib/customer-activity.js +3 -2
  25. package/lib/customer-impersonation.js +3 -3
  26. package/lib/customer-merge.js +4 -3
  27. package/lib/customer-portal.js +4 -4
  28. package/lib/customer-risk-profile.js +2 -1
  29. package/lib/customer-segments.js +2 -1
  30. package/lib/customer-surveys.js +6 -3
  31. package/lib/delivery-estimate.js +2 -2
  32. package/lib/demand-forecast.js +2 -1
  33. package/lib/discount-analytics.js +2 -2
  34. package/lib/dunning.js +4 -1
  35. package/lib/email-warmup.js +6 -1
  36. package/lib/email.js +1 -8
  37. package/lib/error-log.js +3 -2
  38. package/lib/event-log.js +3 -2
  39. package/lib/fraud-screen.js +3 -1
  40. package/lib/fulfillment-sla.js +3 -1
  41. package/lib/index.js +11 -3
  42. package/lib/inventory-allocations.js +3 -0
  43. package/lib/inventory-snapshots.js +2 -1
  44. package/lib/invoice-renderer.js +2 -1
  45. package/lib/line-gift-wrap.js +6 -1
  46. package/lib/live-chat.js +2 -1
  47. package/lib/loyalty-redemption.js +2 -1
  48. package/lib/newsletter.js +6 -1
  49. package/lib/operator-activity-feed.js +4 -3
  50. package/lib/operator-sessions.js +7 -7
  51. package/lib/order-exchanges.js +1 -0
  52. package/lib/order-timeline.js +2 -1
  53. package/lib/payment-retries.js +2 -1
  54. package/lib/payment.js +5 -4
  55. package/lib/pixel-events.js +6 -5
  56. package/lib/preorder.js +2 -1
  57. package/lib/print-queue.js +2 -1
  58. package/lib/product-compare.js +2 -1
  59. package/lib/product-qa.js +2 -1
  60. package/lib/push-notifications.js +6 -5
  61. package/lib/recently-viewed.js +7 -2
  62. package/lib/recommendations.js +7 -2
  63. package/lib/referral-leaderboard.js +2 -1
  64. package/lib/refund-automation.js +1 -1
  65. package/lib/refund-policy.js +1 -1
  66. package/lib/reorder-reminders.js +2 -1
  67. package/lib/reorder-thresholds.js +2 -1
  68. package/lib/robots-config.js +1 -0
  69. package/lib/sales-reports.js +17 -14
  70. package/lib/sales-tax-filings.js +2 -1
  71. package/lib/save-for-later.js +2 -1
  72. package/lib/search-suggestions.js +1 -1
  73. package/lib/shipping-insurance.js +2 -1
  74. package/lib/shipping-labels.js +3 -2
  75. package/lib/shipping-zones.js +1 -0
  76. package/lib/shrinkage-report.js +9 -8
  77. package/lib/sms-dispatcher.js +6 -5
  78. package/lib/stock-alerts.js +1 -1
  79. package/lib/stock-receipts.js +2 -1
  80. package/lib/store-credit.js +2 -1
  81. package/lib/storefront-forms.js +1 -1
  82. package/lib/storefront.js +93 -112
  83. package/lib/subscription-analytics.js +7 -2
  84. package/lib/subscription-controls.js +9 -8
  85. package/lib/subscription-gifts.js +2 -1
  86. package/lib/subscriptions.js +2 -0
  87. package/lib/support-tickets.js +4 -4
  88. package/lib/tax-cert-renewals.js +2 -1
  89. package/lib/tax-remittance.js +2 -1
  90. package/lib/theme-assets.js +1 -1
  91. package/lib/vendor/MANIFEST.json +2 -2
  92. package/lib/vendor/blamejs/CHANGELOG.md +16 -0
  93. package/lib/vendor/blamejs/README.md +6 -4
  94. package/lib/vendor/blamejs/SECURITY.md +2 -0
  95. package/lib/vendor/blamejs/api-snapshot.json +255 -2
  96. package/lib/vendor/blamejs/index.js +1 -0
  97. package/lib/vendor/blamejs/lib/cose.js +284 -10
  98. package/lib/vendor/blamejs/lib/crypto.js +119 -0
  99. package/lib/vendor/blamejs/lib/did.js +416 -0
  100. package/lib/vendor/blamejs/lib/mdoc.js +122 -0
  101. package/lib/vendor/blamejs/lib/network-dnssec.js +328 -0
  102. package/lib/vendor/blamejs/lib/network.js +1 -0
  103. package/lib/vendor/blamejs/lib/vc.js +231 -33
  104. package/lib/vendor/blamejs/package.json +1 -1
  105. package/lib/vendor/blamejs/release-notes/v0.12.41.json +18 -0
  106. package/lib/vendor/blamejs/release-notes/v0.12.42.json +18 -0
  107. package/lib/vendor/blamejs/release-notes/v0.12.43.json +18 -0
  108. package/lib/vendor/blamejs/release-notes/v0.12.44.json +18 -0
  109. package/lib/vendor/blamejs/release-notes/v0.12.45.json +18 -0
  110. package/lib/vendor/blamejs/release-notes/v0.12.46.json +18 -0
  111. package/lib/vendor/blamejs/release-notes/v0.12.47.json +18 -0
  112. package/lib/vendor/blamejs/release-notes/v0.12.48.json +22 -0
  113. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +47 -2
  114. package/lib/vendor/blamejs/test/layer-0-primitives/cose.test.js +101 -2
  115. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-self-test.test.js +74 -0
  116. package/lib/vendor/blamejs/test/layer-0-primitives/did.test.js +176 -0
  117. package/lib/vendor/blamejs/test/layer-0-primitives/dnssec.test.js +130 -0
  118. package/lib/vendor/blamejs/test/layer-0-primitives/mdoc.test.js +52 -0
  119. package/lib/vendor/blamejs/test/layer-0-primitives/vc.test.js +63 -0
  120. package/lib/vendor-invoices.js +1 -1
  121. package/lib/webhook-receiver.js +8 -2
  122. package/lib/webhook-subscriptions.js +1 -1
  123. package/lib/webhooks.js +6 -5
  124. package/lib/winback-campaigns.js +2 -1
  125. package/lib/wishlist-alerts.js +2 -1
  126. package/lib/wishlist-digest.js +2 -1
  127. package/package.json +1 -1
@@ -98,6 +98,7 @@ function _b() {
98
98
  if (!bShop) bShop = require("./index");
99
99
  return bShop.framework;
100
100
  }
101
+ var C = _b().constants;
101
102
 
102
103
  // ---- constants ----------------------------------------------------------
103
104
 
@@ -124,8 +125,8 @@ var MAX_FUNNEL_STEPS = 16;
124
125
  var MAX_CLEANUP_DAYS = 365 * 5;
125
126
  var MIN_CLEANUP_DAYS = 1;
126
127
 
127
- var ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1000;
128
- var DEFAULT_WINDOW_MS = 30 * 24 * 60 * 60 * 1000;
128
+ var ONE_YEAR_MS = C.TIME.days(365);
129
+ var DEFAULT_WINDOW_MS = C.TIME.days(30);
129
130
 
130
131
  // Raw-PII shapes refused at every write site (mirrors the analytics
131
132
  // guard). A hashed identifier is hex / base64url and never trips
@@ -679,7 +680,7 @@ function create(opts) {
679
680
  throw new TypeError("clickstream.cleanupOlderThan: days must be an integer in [" +
680
681
  MIN_CLEANUP_DAYS + ", " + MAX_CLEANUP_DAYS + "]");
681
682
  }
682
- var cutoff = Date.now() - (days * 24 * 60 * 60 * 1000);
683
+ var cutoff = Date.now() - (days * C.TIME.days(1));
683
684
  var pv = await query(
684
685
  "DELETE FROM clickstream_pageviews WHERE occurred_at < ?1",
685
686
  [cutoff],
package/lib/config.js CHANGED
@@ -31,9 +31,10 @@ function _b() {
31
31
  if (!bShop) bShop = require("./index");
32
32
  return bShop.framework;
33
33
  }
34
+ var C = _b().constants;
34
35
 
35
36
  var KEY_RE = /^[a-z][a-z0-9._]{0,63}$/;
36
- var CACHE_TTL_MS = 30 * 1000;
37
+ var CACHE_TTL_MS = C.TIME.seconds(30);
37
38
  var MAX_VALUE_LEN = 64 * 1024; // 64 KiB — fits even a long jurisdiction table
38
39
 
39
40
  function _validateKey(k) {
@@ -149,6 +149,7 @@ function _b() {
149
149
  if (!bShop) bShop = require("./index");
150
150
  return bShop.framework;
151
151
  }
152
+ var C = _b().constants;
152
153
 
153
154
  // ---- validators --------------------------------------------------------
154
155
 
@@ -572,7 +573,7 @@ function create(opts) {
572
573
  // out the same way an active one does.
573
574
  cleanupOlderThan: async function (days) {
574
575
  _positiveInt(days, "days");
575
- var cutoff = _now() - (days * 86400 * 1000);
576
+ var cutoff = _now() - (days * C.TIME.days(1));
576
577
  // The subquery picks the freshest row for each
577
578
  // `session_id_hash`; the outer DELETE removes every row older
578
579
  // than the cutoff that isn't on that survivor list.
@@ -95,6 +95,7 @@ function _b() {
95
95
  if (!bShop) bShop = require("./index");
96
96
  return bShop.framework;
97
97
  }
98
+ var C = _b().constants;
98
99
 
99
100
  var BILLING_CYCLES = ["weekly", "biweekly", "monthly"];
100
101
  var STATUSES = ["active", "suspended", "closed"];
@@ -106,7 +107,7 @@ var MAX_REF_LEN = 128;
106
107
  // injection cover has no legitimate place in a one-line column.
107
108
  var PRINTABLE_RE = /^[^\x00-\x1f\x7f]*$/;
108
109
 
109
- var MS_PER_DAY = 86400 * 1000;
110
+ var MS_PER_DAY = C.TIME.days(1);
110
111
 
111
112
  // Aging buckets. The boundary days are reported as part of the
112
113
  // agingReport return shape so downstream invoice rendering doesn't
@@ -56,9 +56,10 @@ function _b() {
56
56
  if (!bShop) bShop = require("./index");
57
57
  return bShop.framework;
58
58
  }
59
+ var C = _b().constants;
59
60
 
60
61
  var CURRENCY_RE = /^[A-Z]{3}$/;
61
- var DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;
62
+ var DEFAULT_TTL_MS = C.TIME.days(1);
62
63
  var DEFAULT_SUPPORTED = [
63
64
  "USD", "EUR", "GBP", "JPY", "CAD", "AUD", "CHF",
64
65
  "SEK", "NOK", "DKK", "NZD", "INR", "BRL", "MXN",
@@ -95,6 +95,7 @@ function _b() {
95
95
  if (!bShop) bShop = require("./index");
96
96
  return bShop.framework;
97
97
  }
98
+ var C = _b().constants;
98
99
 
99
100
  // ---- constants ----------------------------------------------------------
100
101
 
@@ -103,7 +104,7 @@ var DEFAULT_LIMIT = 50;
103
104
  var MAX_INACTIVE_LIMIT = 500;
104
105
  var DEFAULT_INACTIVE_LIMIT = 100;
105
106
 
106
- var MS_PER_DAY = 86400000;
107
+ var MS_PER_DAY = C.TIME.days(1);
107
108
  var WINDOW_30D = 30 * MS_PER_DAY;
108
109
  var WINDOW_90D = 90 * MS_PER_DAY;
109
110
  var WINDOW_365D = 365 * MS_PER_DAY;
@@ -111,7 +112,7 @@ var WINDOW_365D = 365 * MS_PER_DAY;
111
112
  // Cache freshness window. summarize() returns the cached row when
112
113
  // computed_at is within this window AND no source has a newer event
113
114
  // than last_activity_at. Same posture as order-timeline's cache.
114
- var CACHE_TTL_MS = 5 * 60 * 1000;
115
+ var CACHE_TTL_MS = C.TIME.minutes(5);
115
116
 
116
117
  // Order-FSM events → canonical English titles. Events not in this
117
118
  // map fall through with the raw event name as the title.
@@ -137,9 +137,9 @@
137
137
 
138
138
  var TOKEN_NAMESPACE = "customer-impersonation-token";
139
139
  var TOKEN_BYTES = 32;
140
- var DEFAULT_TTL_SECONDS = 60 * 60; // 60-minute default
140
+ var DEFAULT_TTL_SECONDS = 60 * 60; // allow:raw-time-literal — seconds value; C.TIME returns ms (60-minute default)
141
141
  var MIN_TTL_SECONDS = 60; // refuse sub-minute
142
- var MAX_TTL_SECONDS = 8 * 60 * 60; // hard ceiling — eight hours
142
+ var MAX_TTL_SECONDS = 8 * 60 * 60; // allow:raw-time-literal — seconds value; C.TIME returns ms (hard ceiling — eight hours)
143
143
  var MAX_REASON_LEN = 280;
144
144
  var MAX_END_REASON_LEN = 280;
145
145
  var MAX_ENDED_BY_LEN = 64;
@@ -348,7 +348,7 @@ function create(opts) {
348
348
  var tokenHash = _b().crypto.namespaceHash(TOKEN_NAMESPACE, plaintext);
349
349
  var id = _b().uuid.v7();
350
350
  var now = _now();
351
- var expiresAt = now + (ttl * 1000);
351
+ var expiresAt = now + (ttl * 1000); // allow:raw-time-literal — ttl is a runtime seconds value; *1000 converts to ms
352
352
 
353
353
  await query(
354
354
  "INSERT INTO impersonations " +
@@ -158,7 +158,7 @@ var DEFAULT_LIST_LIMIT = 50;
158
158
  var MAX_CANDIDATE_LIMIT = 200;
159
159
  var DEFAULT_CAND_LIMIT = 25;
160
160
  var MAX_REASON_LEN = 280;
161
- var ROLLBACK_WINDOW_MS = 7 * 24 * 60 * 60 * 1000;
161
+ var ROLLBACK_WINDOW_MS = _b().constants.TIME.days(7);
162
162
  var DEFAULT_SIMILARITY = 0.85;
163
163
  var MIN_SIMILARITY = 0.50;
164
164
  var MAX_SIMILARITY = 1.00;
@@ -187,6 +187,7 @@ function _b() {
187
187
  if (!bShop) bShop = require("./index");
188
188
  return bShop.framework;
189
189
  }
190
+ var C = _b().constants;
190
191
 
191
192
  // ---- monotonic clock ---------------------------------------------------
192
193
  //
@@ -747,8 +748,8 @@ function create(opts) {
747
748
  var now = _now();
748
749
  if (now - Number(row.executed_at) > ROLLBACK_WINDOW_MS) {
749
750
  var winErr = new Error("customerMerge.rollbackMerge: merge_id " + mergeId +
750
- " executed " + Math.floor((now - Number(row.executed_at)) / (24 * 60 * 60 * 1000)) +
751
- " days ago, past the " + (ROLLBACK_WINDOW_MS / (24 * 60 * 60 * 1000)) +
751
+ " executed " + Math.floor((now - Number(row.executed_at)) / C.TIME.days(1)) +
752
+ " days ago, past the " + (ROLLBACK_WINDOW_MS / C.TIME.days(1)) +
752
753
  "-day rollback window");
753
754
  winErr.code = "CUSTOMER_MERGE_ROLLBACK_WINDOW_EXPIRED";
754
755
  throw winErr;
@@ -75,8 +75,8 @@
75
75
 
76
76
  var TOKEN_NAMESPACE = "customer-portal-token";
77
77
  var TOKEN_BYTES = 32;
78
- var DEFAULT_TTL_SECONDS = 15 * 60;
79
- var MAX_TTL_SECONDS = 60 * 60 * 24; // hard ceiling — one day
78
+ var DEFAULT_TTL_SECONDS = 15 * 60; // allow:raw-time-literal — seconds value; C.TIME returns ms
79
+ var MAX_TTL_SECONDS = 60 * 60 * 24; // allow:raw-time-literal — seconds value; C.TIME returns ms (hard ceiling — one day)
80
80
  var MIN_TTL_SECONDS = 30; // refuse zero / negative / sub-30s
81
81
  var MAX_REASON_LEN = 64;
82
82
  var MAX_UA_CLASS_LEN = 64;
@@ -196,7 +196,7 @@ function create(opts) {
196
196
  var tokenHash = _b().crypto.namespaceHash(TOKEN_NAMESPACE, plaintext);
197
197
  var id = _b().uuid.v7();
198
198
  var now = _now();
199
- var expiresAt = now + (ttl * 1000);
199
+ var expiresAt = now + (ttl * 1000); // allow:raw-time-literal — ttl is a runtime seconds value; *1000 converts to ms
200
200
 
201
201
  await query(
202
202
  "INSERT INTO customer_portal_sessions " +
@@ -338,7 +338,7 @@ function create(opts) {
338
338
  // worker layer can emit a metric.
339
339
  expireOlderThan: async function (seconds) {
340
340
  _seconds(seconds, "seconds");
341
- var threshold = _now() - (seconds * 1000);
341
+ var threshold = _now() - (seconds * 1000); // allow:raw-time-literal — seconds is a runtime seconds value; *1000 converts to ms
342
342
  var r = await query(
343
343
  "UPDATE customer_portal_sessions " +
344
344
  "SET status = 'expired' " +
@@ -120,6 +120,7 @@ function _b() {
120
120
  }
121
121
  return bShop.framework;
122
122
  }
123
+ var C = _b().constants;
123
124
 
124
125
  // ---- constants ----------------------------------------------------------
125
126
 
@@ -149,7 +150,7 @@ var BANDS = Object.freeze({
149
150
  // score (their lifetime count still reflects them). 90 days matches
150
151
  // the typical card-network chargeback-evidence cycle: anything older
151
152
  // has already gone through dispute and is settled.
152
- var RECENT_WINDOW_MS = 90 * 86400 * 1000;
153
+ var RECENT_WINDOW_MS = C.TIME.days(90);
153
154
 
154
155
  // detail_json byte ceiling. Operators routinely embed order ids,
155
156
  // amounts, a few human-readable notes — 8 KiB after JSON-encoding
@@ -113,6 +113,7 @@ function _b() {
113
113
  if (!bShop) bShop = require("./index");
114
114
  return bShop.framework;
115
115
  }
116
+ var C = _b().constants;
116
117
 
117
118
  var DEFAULT_LIMIT = 100;
118
119
  var MAX_LIMIT = 1000;
@@ -398,7 +399,7 @@ function create(opts) {
398
399
  var lastAt = Number(row.last_order_at || 0);
399
400
  var aov = orderCount > 0 ? Math.floor(gross / orderCount) : 0;
400
401
  var refundBps = orderCount > 0 ? Math.floor((refunded * 10000) / orderCount) : 0;
401
- var recencyDays = lastAt > 0 ? Math.floor((nowTs - lastAt) / (24 * 60 * 60 * 1000)) : null;
402
+ var recencyDays = lastAt > 0 ? Math.floor((nowTs - lastAt) / C.TIME.days(1)) : null;
402
403
  out.push({
403
404
  customer_id: row.customer_id,
404
405
  order_count: orderCount,
@@ -73,6 +73,7 @@ function _b() {
73
73
  if (!bShop) bShop = require("./index");
74
74
  return bShop.framework;
75
75
  }
76
+ var C = _b().constants;
76
77
 
77
78
  // ---- constants ----------------------------------------------------------
78
79
 
@@ -579,7 +580,7 @@ function create(opts) {
579
580
  var plaintext = _generateToken();
580
581
  var tokenHash = _hashToken(plaintext);
581
582
  var issuedAt = _now();
582
- var expiresAt = issuedAt + (expiresHours * 60 * 60 * 1000);
583
+ var expiresAt = issuedAt + (expiresHours * C.TIME.hours(1));
583
584
 
584
585
  await query(
585
586
  "INSERT INTO survey_invitations " +
@@ -904,7 +905,8 @@ function create(opts) {
904
905
  out.csat = csatTotal === 0
905
906
  ? { positive_pct: 0, mean: 0, positives: 0, neutrals: 0, negatives: 0 }
906
907
  : {
907
- positive_pct: Math.round((pos / csatTotal) * 1000) / 10,
908
+ positive_pct: Math.round((pos / csatTotal) * 1000) / 10, // allow:raw-time-literal — percentage scaling factor, not a duration
909
+
908
910
  mean: Math.round(primary.mean * 100) / 100,
909
911
  positives: pos,
910
912
  neutrals: neu,
@@ -923,7 +925,8 @@ function create(opts) {
923
925
  ? { mean: 0, agree_pct: 0, agree: 0 }
924
926
  : {
925
927
  mean: Math.round(primary.mean * 100) / 100,
926
- agree_pct: Math.round((cesAgree / primary.count) * 1000) / 10,
928
+ agree_pct: Math.round((cesAgree / primary.count) * 1000) / 10, // allow:raw-time-literal — percentage scaling factor, not a duration
929
+
927
930
  agree: cesAgree,
928
931
  };
929
932
  }
@@ -124,9 +124,9 @@ var POSTAL_RE = /^[A-Za-z0-9][A-Za-z0-9 -]{0,15}$/;
124
124
 
125
125
  var COUNTRY_RE = /^[A-Z]{2}$/;
126
126
 
127
- var MAX_WEIGHT_GRAMS = 1000 * 1000;
127
+ var MAX_WEIGHT_GRAMS = 1000 * 1000; // allow:raw-time-literal — grams (1000 kg), not a duration
128
128
 
129
- var DAY_MS = 24 * 60 * 60 * 1000;
129
+ var DAY_MS = _b().constants.TIME.days(1);
130
130
 
131
131
  // Lazy framework handle — matches the convention every other shop
132
132
  // primitive uses; avoids the require cycle that would arise from
@@ -104,6 +104,7 @@ function _b() {
104
104
  if (!bShop) bShop = require("./index");
105
105
  return bShop.framework;
106
106
  }
107
+ var C = _b().constants;
107
108
 
108
109
  // ---- constants ----------------------------------------------------------
109
110
 
@@ -127,7 +128,7 @@ var MAX_UNITS_SOLD = 1000000000;
127
128
  var DEFAULT_WINDOW_DAYS = 30;
128
129
  var DEFAULT_ALPHA = 0.3;
129
130
 
130
- var DAY_MS = 24 * 60 * 60 * 1000;
131
+ var DAY_MS = C.TIME.days(1);
131
132
 
132
133
  // Weekly-seasonality needs at least two full weeks of history to
133
134
  // avoid claiming a pattern from one cycle. Monthly-seasonality needs
@@ -124,8 +124,8 @@ var MAX_SESSION_LEN = 256;
124
124
  var MAX_TIER_ID_LEN = 128;
125
125
  var MAX_LIMIT = 200;
126
126
 
127
- var ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1000;
128
- var DEFAULT_WINDOW_MS = 30 * 24 * 60 * 60 * 1000;
127
+ var ONE_YEAR_MS = _b().constants.TIME.days(365);
128
+ var DEFAULT_WINDOW_MS = _b().constants.TIME.days(30);
129
129
 
130
130
  // Coupon-code shape — alnum + dot/dash/underscore plus a `:` to
131
131
  // admit the `tier:<id>` convention. Length-capped so a giant string
package/lib/dunning.js CHANGED
@@ -109,6 +109,9 @@ function _b() {
109
109
  if (!bShop) bShop = require("./index");
110
110
  return bShop.framework;
111
111
  }
112
+ // Framework constants (C.TIME duration helpers). Safe at module-eval —
113
+ // the index entry point exposes `framework` before the require cascade.
114
+ var C = _b().constants;
112
115
 
113
116
  // ---- constants ----------------------------------------------------------
114
117
 
@@ -123,7 +126,7 @@ var MAX_SCHEDULE_STEPS = 64;
123
126
  var MAX_CANCEL_ATTEMPTS = 64;
124
127
  var MAX_LIST_LIMIT = 500;
125
128
  var DEFAULT_LIST_LIMIT = 100;
126
- var MS_PER_HOUR = 60 * 60 * 1000;
129
+ var MS_PER_HOUR = C.TIME.hours(1);
127
130
 
128
131
  var SLUG_RE = /^[a-z](?:[a-z0-9-]*[a-z0-9])?$/;
129
132
  var CONTROL_BYTE_RE = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/;
@@ -92,6 +92,11 @@
92
92
 
93
93
  // ---- constants ----------------------------------------------------------
94
94
 
95
+ // `_b()` is a hoisted function declaration (defined below); resolving the
96
+ // framework constants here at module-eval is safe — the index entry point
97
+ // exposes `framework` before the require cascade.
98
+ var C = _b().constants;
99
+
95
100
  var MAX_SLUG_LEN = 80;
96
101
  var MAX_DAILY_TARGETS = 365; // a year of ramp ceiling — operator schedule, not framework
97
102
  var MAX_DAILY_TARGET = 10000000; // 10M sends in one day — well above any reasonable IP ceiling
@@ -100,7 +105,7 @@ var MAX_REASON_LEN = 280;
100
105
  var MAX_LIST_LIMIT = 500;
101
106
  var MAX_DOMAIN_LEN = 253; // DNS hostname cap
102
107
  var MAX_IP_LEN = 45; // IPv6 max textual length
103
- var MS_PER_DAY = 24 * 60 * 60 * 1000;
108
+ var MS_PER_DAY = C.TIME.days(1);
104
109
 
105
110
  var SLUG_RE = /^[a-z0-9][a-z0-9._-]{0,79}$/;
106
111
  // Lowercase domain — IDN punycode + alnum + hyphen + dot, ending in a
package/lib/email.js CHANGED
@@ -32,16 +32,9 @@ function _b() {
32
32
  return bShop.framework;
33
33
  }
34
34
 
35
- var HTML_ESCAPE_MAP = {
36
- "&": "&amp;",
37
- "<": "&lt;",
38
- ">": "&gt;",
39
- "\"": "&quot;",
40
- "'": "&#39;",
41
- };
42
35
  function _htmlEscape(s) {
43
36
  if (s == null) return "";
44
- return String(s).replace(/[&<>"']/g, function (c) { return HTML_ESCAPE_MAP[c]; });
37
+ return _b().template.escapeHtml(String(s));
45
38
  }
46
39
 
47
40
  // Strict {{var}} renderer. Refuses unrecognized placeholders so a
package/lib/error-log.js CHANGED
@@ -71,9 +71,10 @@ function _b() {
71
71
  if (!bShop) bShop = require("./index");
72
72
  return bShop.framework;
73
73
  }
74
+ var C = _b().constants;
74
75
 
75
- var ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1000;
76
- var DEFAULT_WINDOW_MS = 24 * 60 * 60 * 1000; // 24h — the dashboard's default
76
+ var ONE_YEAR_MS = C.TIME.days(365);
77
+ var DEFAULT_WINDOW_MS = C.TIME.days(1); // 24h — the dashboard's default
77
78
 
78
79
  var SESSION_NAMESPACE = "error-log-session";
79
80
 
package/lib/event-log.js CHANGED
@@ -92,6 +92,7 @@ function _b() {
92
92
  if (!bShop) bShop = require("./index");
93
93
  return bShop.framework;
94
94
  }
95
+ var C = _b().constants;
95
96
 
96
97
  // ---- constants ---------------------------------------------------------
97
98
 
@@ -115,7 +116,7 @@ var MAX_TAIL_EVENTS = 500;
115
116
  var DEFAULT_TAIL_EVENTS = 50;
116
117
  var MIN_POLL_MS = 250;
117
118
  var DEFAULT_POLL_MS = 2000;
118
- var MAX_POLL_MS = 60000;
119
+ var MAX_POLL_MS = C.TIME.minutes(1);
119
120
  var MAX_PURGE_DAYS = 3650;
120
121
 
121
122
  // Identifier shapes — kind / subject_kind / actor_kind / source share
@@ -650,7 +651,7 @@ function create(opts) {
650
651
  throw new TypeError("eventLog.purgeOlderThan: days must be an integer in [1, " + MAX_PURGE_DAYS + "]");
651
652
  }
652
653
  var excludeCritical = !!input.exclude_critical;
653
- var cutoff = _now() - days * 86400000;
654
+ var cutoff = _now() - C.TIME.days(days);
654
655
 
655
656
  var sql, params;
656
657
  if (excludeCritical) {
@@ -101,6 +101,7 @@ function _b() {
101
101
  }
102
102
  return bShop.framework;
103
103
  }
104
+ var C = _b().constants;
104
105
 
105
106
  // ---- constants ----------------------------------------------------------
106
107
 
@@ -137,10 +138,11 @@ var WEIGHTS = Object.freeze({
137
138
  });
138
139
 
139
140
  // Thresholds for the heuristic dials.
140
- var VELOCITY_WINDOW_MS = 24 * 60 * 60 * 1000; // 24h lookback
141
+ var VELOCITY_WINDOW_MS = C.TIME.days(1); // 24h lookback
141
142
  var VELOCITY_MAX_OK = 3; // > N triggers
142
143
  var HIGH_VALUE_NEW_THRESH = 50000; // 500.00 minor units
143
144
  var SESSION_FAST_MAX_SEC = 15;
145
+ // allow:raw-time-literal — session-age ceiling in SECONDS (24h); compared against session_age_seconds, C.TIME returns ms
144
146
  var SESSION_OLD_MAX_SEC = 24 * 60 * 60;
145
147
  var LARGE_LINE_COUNT_THRESH = 25;
146
148
  var SCORE_MAX = 100;
@@ -107,6 +107,7 @@ function _b() {
107
107
  if (!bShop) bShop = require("./index");
108
108
  return bShop.framework;
109
109
  }
110
+ var C = _b().constants;
110
111
 
111
112
  // ---- constants ----------------------------------------------------------
112
113
 
@@ -124,7 +125,7 @@ var SLUG_RE = /^[a-z0-9][a-z0-9._-]{0,63}$/;
124
125
  var CUTOFF_RE = /^([01][0-9]|2[0-3]):([0-5][0-9])$/;
125
126
  var TIMEZONE_RE = /^[A-Za-z][A-Za-z0-9+_\-/]{0,63}$/;
126
127
 
127
- var MS_PER_HOUR = 60 * 60 * 1000;
128
+ var MS_PER_HOUR = C.TIME.hours(1);
128
129
  var MS_PER_DAY = 24 * MS_PER_HOUR;
129
130
 
130
131
  var SEVERITY_MINOR_MAX = 24;
@@ -296,6 +297,7 @@ function _clockStart(placedAt, cutoffLocalTime, timezone) {
296
297
  var nextHour = Number(nextByType.hour);
297
298
  var nextMinute = Number(nextByType.minute);
298
299
  var nextSecond = Number(nextByType.second);
300
+ // allow:raw-time-literal — converts a runtime-computed local time-of-day (h/m/s) to ms; not a fixed duration C.TIME can express
299
301
  var localOffsetMs = (nextHour * 3600 + nextMinute * 60 + nextSecond) * 1000;
300
302
  return nextDayMs - localOffsetMs;
301
303
  }
package/lib/index.js CHANGED
@@ -30,8 +30,16 @@ try {
30
30
  throw e;
31
31
  }
32
32
 
33
- module.exports = {
34
- framework: framework,
33
+ // Expose the framework on the exports object up front — before the
34
+ // require cascade below — so a shop module that composes a framework
35
+ // primitive at module-eval time (e.g. `var C = require("./index")
36
+ // .framework.constants` via the `_b()` lazy accessor, used for
37
+ // duration constants) resolves `framework` cleanly while it is itself
38
+ // being required. Without this, `_b()` mid-cascade would see a
39
+ // half-built exports object with no `framework` field.
40
+ module.exports.framework = framework;
41
+
42
+ Object.assign(module.exports, {
35
43
  externaldbD1: require("./externaldb-d1"),
36
44
  r2Bridge: require("./r2-bridge"),
37
45
  catalog: require("./catalog"),
@@ -242,4 +250,4 @@ module.exports = {
242
250
  winbackCampaigns: require("./winback-campaigns"),
243
251
  wishlistDigest: require("./wishlist-digest"),
244
252
  operatorHelpCenter: require("./operator-help-center"),
245
- };
253
+ });
@@ -84,6 +84,7 @@ var ORDER_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
84
84
  var HOLD_ID_RE = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
85
85
  var REASON_RE = /^[\S\s]{1,256}$/;
86
86
  var DEFAULT_TTL = 900; // 15 minutes by default
87
+ // allow:raw-time-literal — TTL ceiling in SECONDS (not ms); C.TIME returns ms
87
88
  var MAX_TTL = 24 * 60 * 60; // 24h ceiling — anything longer is a usage-error smell
88
89
  var MIN_TTL = 1;
89
90
 
@@ -284,6 +285,7 @@ function create(opts) {
284
285
  }
285
286
 
286
287
  var ts = _monotonicTs();
288
+ // allow:raw-time-literal — seconds→ms conversion of a variable TTL count; C.TIME helpers take a fixed duration, not a runtime value
287
289
  var expiresAt = ts + ttlSeconds * 1000;
288
290
  var id = _b().uuid.v7();
289
291
  await query(
@@ -415,6 +417,7 @@ function create(opts) {
415
417
  ", expected 'held'");
416
418
  }
417
419
 
420
+ // allow:raw-time-literal — seconds→ms conversion of a variable TTL count; C.TIME helpers take a fixed duration, not a runtime value
418
421
  var nextExpires = Number(existing.expires_at) + input.additional_ttl_seconds * 1000;
419
422
  await query(
420
423
  "UPDATE inventory_holds SET expires_at = ?1 WHERE id = ?2 AND status = 'held'",
@@ -90,6 +90,7 @@ function _b() {
90
90
  if (!bShop) bShop = require("./index");
91
91
  return bShop.framework;
92
92
  }
93
+ var C = _b().constants;
93
94
 
94
95
  // ---- constants ----------------------------------------------------------
95
96
 
@@ -660,7 +661,7 @@ function create(opts) {
660
661
  // to wipe the snapshot history wholesale call with 0.
661
662
  purgeOlderThan: async function (days) {
662
663
  _days(days);
663
- var cutoff = _now() - (days * 86400000);
664
+ var cutoff = _now() - C.TIME.days(days);
664
665
  // Read the ids first so the return shape can carry both the
665
666
  // count and the ids that were removed (operators occasionally
666
667
  // want to log "purged snapshots: a, b, c" for a compliance
@@ -88,6 +88,7 @@ function _b() {
88
88
  if (!bShop) bShop = require("./index");
89
89
  return bShop.framework;
90
90
  }
91
+ var C = _b().constants;
91
92
 
92
93
  // ---- constants ----------------------------------------------------------
93
94
 
@@ -503,7 +504,7 @@ function create(opts) {
503
504
  var issuer = await _resolveIssuer();
504
505
 
505
506
  var generatedAt = Date.now();
506
- var dueAt = generatedAt + dueDays * 24 * 60 * 60 * 1000;
507
+ var dueAt = generatedAt + C.TIME.days(dueDays);
507
508
 
508
509
  var seq = await _advanceSeries(series);
509
510
  var invoiceNumber = _formatInvoiceNumber(seq, generatedAt);
@@ -68,9 +68,14 @@
68
68
 
69
69
  // ---- constants ----------------------------------------------------------
70
70
 
71
+ // `_b()` is a hoisted function declaration (defined below); resolving the
72
+ // framework constants here at module-eval is safe — the index entry point
73
+ // exposes `framework` before the require cascade.
74
+ var C = _b().constants;
75
+
71
76
  var MAX_MESSAGE_LEN = 500;
72
77
  var MAX_RECIPIENT_LEN = 120;
73
- var MAX_FROM_TO_SPAN = 366 * 24 * 3600 * 1000; // analytics window cap
78
+ var MAX_FROM_TO_SPAN = C.TIME.days(366); // analytics window cap
74
79
 
75
80
  // SKU shape mirrors catalog.js + gift-options.js — alnum + . _ -, ≤
76
81
  // 128 chars, leading char must be alnum so a wrap_sku can never
package/lib/live-chat.js CHANGED
@@ -114,6 +114,7 @@ function _b() {
114
114
  if (!bShop) bShop = require("./index");
115
115
  return bShop.framework;
116
116
  }
117
+ var C = _b().constants;
117
118
 
118
119
  // ---- validators ---------------------------------------------------------
119
120
 
@@ -673,7 +674,7 @@ function create(opts) {
673
674
  }
674
675
  var idleMinutes = _idleMinutes(input.idle_minutes);
675
676
  var ts = _now();
676
- var threshold = ts - idleMinutes * 60 * 1000;
677
+ var threshold = ts - C.TIME.minutes(idleMinutes);
677
678
  var r = await query(
678
679
  "SELECT id FROM chat_sessions " +
679
680
  "WHERE status IN ('queued','assigned','active','waiting') " +
@@ -68,6 +68,7 @@ function _b() {
68
68
  if (!bShop) bShop = require("./index");
69
69
  return bShop.framework;
70
70
  }
71
+ var C = _b().constants;
71
72
 
72
73
  // ---- constants ----------------------------------------------------------
73
74
 
@@ -82,7 +83,7 @@ var MAX_REDEMPTIONS_LIMIT = 200;
82
83
  var MAX_POINT_COST = 100000000;
83
84
  var MAX_PER_CUSTOMER = 100000;
84
85
  var MAX_EXPIRES_DAYS = 3650;
85
- var MS_PER_DAY = 86400000;
86
+ var MS_PER_DAY = C.TIME.days(1);
86
87
 
87
88
  // Slug shape matches the catalog / promo-banners convention — alnum +
88
89
  // hyphen + underscore + dot, leading char alnum, capped length.
package/lib/newsletter.js CHANGED
@@ -48,10 +48,15 @@
48
48
 
49
49
  "use strict";
50
50
 
51
+ // `_b()` is a hoisted function declaration (defined below); resolving the
52
+ // framework constants here at module-eval is safe — the index entry point
53
+ // exposes `framework` before the require cascade.
54
+ var C = _b().constants;
55
+
51
56
  var EMAIL_NAMESPACE = "newsletter-email";
52
57
  var UNSUBSCRIBE_NAMESPACE = "newsletter-unsubscribe";
53
58
  var UNSUBSCRIBE_TOKEN_BYTES = 24;
54
- var UNSUBSCRIBE_TTL_MS = 365 * 24 * 60 * 60 * 1000;
59
+ var UNSUBSCRIBE_TTL_MS = C.TIME.days(365);
55
60
  var MAX_SOURCE_LEN = 64;
56
61
  var SOURCE_RE = /^[a-z0-9][a-z0-9._-]{0,62}[a-z0-9]$/;
57
62
 
@@ -106,19 +106,20 @@ function _b() {
106
106
  if (!bShop) bShop = require("./index");
107
107
  return bShop.framework;
108
108
  }
109
+ var C = _b().constants;
109
110
 
110
111
  // ---- constants ----------------------------------------------------------
111
112
 
112
113
  var MAX_LIMIT = 200;
113
114
  var DEFAULT_LIMIT = 50;
114
115
  var MAX_RECENT_LOGINS = 10;
115
- var ONLINE_WINDOW_MS = 5 * 60 * 1000;
116
- var MS_PER_DAY = 86400000;
116
+ var ONLINE_WINDOW_MS = C.TIME.minutes(5);
117
+ var MS_PER_DAY = C.TIME.days(1);
117
118
 
118
119
  // Cache freshness window. summarizeForOperator returns the cached row
119
120
  // when computed_at is within this window AND no source has a newer
120
121
  // event than last_activity_at. Same posture as customer-activity uses.
121
- var CACHE_TTL_MS = 5 * 60 * 1000;
122
+ var CACHE_TTL_MS = C.TIME.minutes(5);
122
123
 
123
124
  // Order-key for the forOperator() pagination cursor — (occurred_at
124
125
  // DESC, kind DESC). Tuple keeps the cursor monotonic even when two