@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
@@ -140,16 +140,16 @@
140
140
 
141
141
  var TOKEN_NAMESPACE = "operator-session-token";
142
142
  var TOKEN_BYTES = 32;
143
- var DEFAULT_TTL_SECONDS = 8 * 60 * 60; // 8-hour shift default
143
+ var DEFAULT_TTL_SECONDS = 8 * 60 * 60; // allow:raw-time-literal — TTL stored in seconds; C.TIME returns ms (8-hour shift default)
144
144
  var MIN_TTL_SECONDS = 60; // refuse zero / sub-minute
145
- var MAX_TTL_SECONDS = 60 * 60 * 24; // hard ceiling — one day
145
+ var MAX_TTL_SECONDS = 60 * 60 * 24; // allow:raw-time-literal — TTL stored in seconds; C.TIME returns ms (hard ceiling — one day)
146
146
  var MAX_REASON_LEN = 64;
147
147
  var MAX_UA_CLASS_LEN = 64;
148
148
  var MAX_IP_HASH_LEN = 256;
149
149
  var MIN_IP_HASH_LEN = 1;
150
- var DEFAULT_LOCKOUT_WINDOW = 15 * 60; // 15-minute rolling window
150
+ var DEFAULT_LOCKOUT_WINDOW = 15 * 60; // allow:raw-time-literal — lockout window stored in seconds; C.TIME returns ms (15-minute rolling window)
151
151
  var DEFAULT_LOCKOUT_THRESH = 5; // 5 failures trips lockout
152
- var MAX_LOCKOUT_WINDOW = 24 * 60 * 60; // sanity cap — one day
152
+ var MAX_LOCKOUT_WINDOW = 24 * 60 * 60; // allow:raw-time-literal — lockout window stored in seconds; C.TIME returns ms (sanity cap — one day)
153
153
  var MIN_LOCKOUT_THRESHOLD = 1;
154
154
  var MAX_LOCKOUT_THRESHOLD = 1000;
155
155
 
@@ -344,7 +344,7 @@ function create(opts) {
344
344
  var tokenHash = _b().crypto.namespaceHash(TOKEN_NAMESPACE, plaintext);
345
345
  var id = _b().uuid.v7();
346
346
  var now = _now();
347
- var expiresAt = now + (ttl * 1000);
347
+ var expiresAt = now + (ttl * 1000); // allow:raw-time-literal — ttl is in seconds; * 1000 converts to ms
348
348
 
349
349
  await query(
350
350
  "INSERT INTO operator_sessions " +
@@ -615,7 +615,7 @@ function create(opts) {
615
615
  // emit a metric.
616
616
  expireOlderThan: async function (seconds) {
617
617
  _seconds(seconds, "seconds");
618
- var threshold = _now() - (seconds * 1000);
618
+ var threshold = _now() - (seconds * 1000); // allow:raw-time-literal — seconds arg is in seconds; * 1000 converts to ms
619
619
  var r = await query(
620
620
  "UPDATE operator_sessions " +
621
621
  "SET status = 'expired' " +
@@ -646,7 +646,7 @@ function create(opts) {
646
646
  }
647
647
  var windowSec = _lockoutWindow(lopts.window_seconds);
648
648
  var threshold = _lockoutThreshold(lopts.threshold);
649
- var since = _now() - (windowSec * 1000);
649
+ var since = _now() - (windowSec * 1000); // allow:raw-time-literal — windowSec is in seconds; * 1000 converts to ms
650
650
  var r = await query(
651
651
  "SELECT COUNT(*) AS n FROM operator_failed_logins " +
652
652
  "WHERE ip_hash = ?1 AND occurred_at >= ?2",
@@ -301,6 +301,7 @@ function create(opts) {
301
301
  sku: existing.replacement_sku,
302
302
  variant_id: existing.replacement_variant_id || null,
303
303
  quantity: existing.replacement_qty,
304
+ // allow:raw-time-literal — hold TTL in SECONDS (passed to holdForCart's ttl_seconds); C.TIME returns ms
304
305
  ttl_seconds: input.hold_ttl_seconds || 86400,
305
306
  });
306
307
  }
@@ -101,6 +101,7 @@ function _b() {
101
101
  if (!bShop) bShop = require("./index");
102
102
  return bShop.framework;
103
103
  }
104
+ var C = _b().constants;
104
105
 
105
106
  // ---- constants ----------------------------------------------------------
106
107
 
@@ -113,7 +114,7 @@ var DEFAULT_RECENT_LIMIT = 20;
113
114
  // pathological "no new events but the cache is stale" case still
114
115
  // recomputes after a few minutes — gives the operator dashboard
115
116
  // fresh totals even when the underlying primitives are quiet.
116
- var CACHE_TTL_MS = 5 * 60 * 1000;
117
+ var CACHE_TTL_MS = C.TIME.minutes(5);
117
118
 
118
119
  // BCP-47 shape: 2-3 alpha primary subtag, optional region/script
119
120
  // subtags. Matches the shape gift-options uses for the same purpose.
@@ -133,6 +133,7 @@ function _b() {
133
133
  if (!bShop) bShop = require("./index");
134
134
  return bShop.framework;
135
135
  }
136
+ var C = _b().constants;
136
137
 
137
138
  // ---- constants ----------------------------------------------------------
138
139
 
@@ -146,7 +147,7 @@ var MAX_SCHEDULE_STEPS = 64;
146
147
  var MAX_ATTEMPTS_CAP = 64;
147
148
  var MAX_LIST_LIMIT = 500;
148
149
  var DEFAULT_LIST_LIMIT = 100;
149
- var MS_PER_HOUR = 60 * 60 * 1000;
150
+ var MS_PER_HOUR = C.TIME.hours(1);
150
151
 
151
152
  var SLUG_RE = /^[a-z](?:[a-z0-9-]*[a-z0-9])?$/;
152
153
  var FAILURE_CODE_RE = /^[a-z](?:[a-z0-9_]*[a-z0-9])?$/;
package/lib/payment.js CHANGED
@@ -28,6 +28,7 @@ function _b() {
28
28
  if (!bShop) bShop = require("./index");
29
29
  return bShop.framework;
30
30
  }
31
+ var C = _b().constants;
31
32
 
32
33
  var STRIPE_API_BASE_DEFAULT = "https://api.stripe.com/v1";
33
34
  var STRIPE_WEBHOOK_TOLERANCE = 300; // ± 5 minutes (Stripe default)
@@ -38,7 +39,7 @@ var CURRENCY_RE = /^[a-z]{3}$/; // Stripe wants lowercase ISO 421
38
39
  // expires on the same window — operators who run `cleanupExpired()`
39
40
  // on a daily schedule keep the table small without ever shortening
40
41
  // the replay window below Stripe's own retention.
41
- var IDEMPOTENCY_TTL_MS = 24 * 60 * 60 * 1000;
42
+ var IDEMPOTENCY_TTL_MS = C.TIME.days(1);
42
43
  var IDEMPOTENCY_NAMESPACE = "payment-idempotency-body";
43
44
  var IDEMPOTENT_OPERATIONS = {
44
45
  "payment_intent.create": true,
@@ -124,8 +125,8 @@ async function _verifyWebhook(headers, rawBody, secret, opts) {
124
125
  if (!headerVal) return { ok: false, reason: "no-signature" };
125
126
 
126
127
  var toleranceMs = opts.toleranceSeconds == null
127
- ? STRIPE_WEBHOOK_TOLERANCE * 1000
128
- : opts.toleranceSeconds * 1000;
128
+ ? STRIPE_WEBHOOK_TOLERANCE * 1000 // allow:raw-time-literal — seconds value; *1000 converts to ms
129
+ : opts.toleranceSeconds * 1000; // allow:raw-time-literal — runtime seconds value; *1000 converts to ms
129
130
  if (typeof toleranceMs !== "number" || !isFinite(toleranceMs) || toleranceMs <= 0) {
130
131
  throw new TypeError("payment.verifyWebhook: toleranceSeconds must be a positive number");
131
132
  }
@@ -138,7 +139,7 @@ async function _verifyWebhook(headers, rawBody, secret, opts) {
138
139
  body: rawBody,
139
140
  toleranceMs: toleranceMs,
140
141
  nonceStore: opts.nonceStore || undefined,
141
- _nowMs: opts.now != null ? opts.now * 1000 : undefined,
142
+ _nowMs: opts.now != null ? opts.now * 1000 : undefined, // allow:raw-time-literal — opts.now is a runtime seconds value; *1000 converts to ms
142
143
  });
143
144
  } catch (e) {
144
145
  var code = (e && e.code) || "";
@@ -103,6 +103,7 @@ function _b() {
103
103
  if (!bShop) bShop = require("./index");
104
104
  return bShop.framework;
105
105
  }
106
+ var C = _b().constants;
106
107
 
107
108
  // ---- constants ----------------------------------------------------------
108
109
 
@@ -159,11 +160,11 @@ var PHONE_RAW_RE = /^\+?[0-9 ().\-]{7,32}$/;
159
160
  // request — runaway retries against a permanently-broken provider
160
161
  // credential would otherwise saturate the worker tick.
161
162
  var RETRY_BACKOFF_MS = [
162
- 60 * 1000,
163
- 5 * 60 * 1000,
164
- 30 * 60 * 1000,
165
- 2 * 60 * 60 * 1000,
166
- 12 * 60 * 60 * 1000,
163
+ C.TIME.minutes(1),
164
+ C.TIME.minutes(5),
165
+ C.TIME.minutes(30),
166
+ C.TIME.hours(2),
167
+ C.TIME.hours(12),
167
168
  ];
168
169
 
169
170
  // ---- monotonic clock ---------------------------------------------------
package/lib/preorder.js CHANGED
@@ -108,6 +108,7 @@ function _b() {
108
108
  if (!bShop) bShop = require("./index");
109
109
  return bShop.framework;
110
110
  }
111
+ var C = _b().constants;
111
112
 
112
113
  // ---- constants ----------------------------------------------------------
113
114
 
@@ -116,7 +117,7 @@ var SKU_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
116
117
  var CURRENCY_RE = /^[A-Z]{3}$/;
117
118
  var MAX_COPY_LEN = 2000;
118
119
  var MAX_REASON_LEN = 280;
119
- var DAY_MS = 24 * 60 * 60 * 1000;
120
+ var DAY_MS = C.TIME.days(1);
120
121
 
121
122
  var CAMPAIGN_STATUSES = Object.freeze(["active", "launched", "closed"]);
122
123
  var RESERVATION_STATUSES = Object.freeze(["active", "converted", "cancelled"]);
@@ -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
  // ---- constants ----------------------------------------------------------
118
119
 
@@ -573,7 +574,7 @@ function create(opts) {
573
574
  throw new TypeError("print-queue.cleanupCompleted: input object required");
574
575
  }
575
576
  _hours(input.older_than_hours, "older_than_hours");
576
- var cutoff = _now() - Math.floor(input.older_than_hours * 60 * 60 * 1000);
577
+ var cutoff = _now() - Math.floor(C.TIME.hours(input.older_than_hours));
577
578
  var r = await query(
578
579
  "DELETE FROM print_jobs WHERE status IN ('complete', 'cancelled', 'failed') " +
579
580
  "AND COALESCE(completed_at, failed_at, created_at) < ?1",
@@ -80,6 +80,7 @@ function _b() {
80
80
  if (!bShop) bShop = require("./index");
81
81
  return bShop.framework;
82
82
  }
83
+ var C = _b().constants;
83
84
 
84
85
  // ---- constants ----------------------------------------------------------
85
86
 
@@ -775,7 +776,7 @@ function create(opts) {
775
776
  // dashboard can render the sweep's footprint.
776
777
  cleanupOlderThan: async function (days) {
777
778
  _days(days);
778
- var threshold = _now() - (days * 24 * 60 * 60 * 1000);
779
+ var threshold = _now() - C.TIME.days(days);
779
780
  var lists = await query(
780
781
  "DELETE FROM compare_lists WHERE updated_at < ?1",
781
782
  [threshold],
package/lib/product-qa.js CHANGED
@@ -91,6 +91,7 @@ function _b() {
91
91
  if (!bShop) { bShop = require("./index"); }
92
92
  return bShop.framework;
93
93
  }
94
+ var C = _b().constants;
94
95
 
95
96
  // ---- monotonic clock ---------------------------------------------------
96
97
  //
@@ -689,7 +690,7 @@ function create(opts) {
689
690
  // attached to non-rejected questions.
690
691
  async function cleanupRejected(days) {
691
692
  var d = _cleanupDays(days);
692
- var cutoff = _now() - (d * 24 * 60 * 60 * 1000);
693
+ var cutoff = _now() - C.TIME.days(d);
693
694
 
694
695
  var qDel = await query(
695
696
  "DELETE FROM product_qa_questions WHERE status = 'rejected' AND occurred_at < ?1",
@@ -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
 
@@ -108,11 +109,11 @@ var MAX_PROV_MSG_ID_LEN = 256;
108
109
  // to compute `next_retry_at`; once the schedule is exhausted the row
109
110
  // terminates as failed regardless of the caller's `retry` request.
110
111
  var RETRY_BACKOFF_MS = [
111
- 60 * 1000,
112
- 5 * 60 * 1000,
113
- 30 * 60 * 1000,
114
- 2 * 60 * 60 * 1000,
115
- 12 * 60 * 60 * 1000,
112
+ C.TIME.minutes(1),
113
+ C.TIME.minutes(5),
114
+ C.TIME.minutes(30),
115
+ C.TIME.hours(2),
116
+ C.TIME.hours(12),
116
117
  ];
117
118
 
118
119
  var SLUG_RE = /^[a-z](?:[a-z0-9-]*[a-z0-9])?$/;
@@ -76,10 +76,15 @@
76
76
  * @related b.guardUuid, b.crypto.namespaceHash, b.uuid
77
77
  */
78
78
 
79
+ // `_b()` is a hoisted function declaration (defined below); resolving the
80
+ // framework constants here at module-eval is safe — the index entry point
81
+ // exposes `framework` before the require cascade.
82
+ var C = _b().constants;
83
+
79
84
  var DEFAULT_LIMIT = 20;
80
85
  var MAX_LIMIT = 100;
81
86
  var PER_SUBJECT_CAP = 20;
82
- var DEDUP_WINDOW_MS = 5 * 60 * 1000;
87
+ var DEDUP_WINDOW_MS = C.TIME.minutes(5);
83
88
  var SESSION_NAMESPACE = "recently-viewed-session";
84
89
  var SESSION_ID_RE = /^[A-Za-z0-9_-]{16,64}$/;
85
90
  var RECOMMEND_LIMIT = 10;
@@ -479,7 +484,7 @@ function create(opts) {
479
484
  // shopper population grows.
480
485
  cleanupOlderThan: async function (days) {
481
486
  _days(days);
482
- var threshold = Date.now() - (days * 24 * 60 * 60 * 1000);
487
+ var threshold = Date.now() - C.TIME.days(days);
483
488
  var r = await query(
484
489
  "DELETE FROM recently_viewed WHERE last_viewed_at < ?1",
485
490
  [threshold],
@@ -106,13 +106,18 @@
106
106
  * shop.recentlyViewed, shop.analytics, shop.catalog
107
107
  */
108
108
 
109
+ // `_b()` is a hoisted function declaration (defined below); resolving the
110
+ // framework constants here at module-eval is safe — the index entry point
111
+ // exposes `framework` before the require cascade.
112
+ var C = _b().constants;
113
+
109
114
  var DEFAULT_LIMIT = 8;
110
115
  var MAX_LIMIT = 50;
111
116
  var MAX_CART_PRODUCTS = 50;
112
117
  var DEFAULT_WEIGHT = 100;
113
118
  var MAX_WEIGHT = 1000000;
114
- var ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1000;
115
- var DEFAULT_WINDOW_MS = 30 * 24 * 60 * 60 * 1000;
119
+ var ONE_YEAR_MS = C.TIME.days(365);
120
+ var DEFAULT_WINDOW_MS = C.TIME.days(30);
116
121
  var KINDS = ["product", "cart", "customer", "category"];
117
122
  var EVENT_TYPES = ["impression", "click", "conversion"];
118
123
  var SESSION_NAMESPACE = "recommendations-session";
@@ -83,6 +83,7 @@ function _b() {
83
83
  if (!bShop) bShop = require("./index");
84
84
  return bShop.framework;
85
85
  }
86
+ var C = _b().constants;
86
87
 
87
88
  var TIERS = ["bronze", "silver", "gold", "platinum"];
88
89
 
@@ -100,7 +101,7 @@ var DEFAULT_TIER_BONUS_POINTS = {
100
101
  platinum: 10000,
101
102
  };
102
103
 
103
- var MS_PER_DAY = 24 * 60 * 60 * 1000;
104
+ var MS_PER_DAY = C.TIME.days(1);
104
105
  var ROLLING_WINDOW_DAYS = 90;
105
106
 
106
107
  var MAX_LEADERBOARD_LIMIT = 100;
@@ -122,7 +122,7 @@ var MAX_PRIORITY = 1000000;
122
122
  var MAX_LIST_LIMIT = 200;
123
123
  var MAX_REASONS_PER_RULE = 32;
124
124
  var MAX_CURRENCIES_PER_RULE = 32;
125
- var MS_PER_YEAR = 365 * 24 * 60 * 60 * 1000;
125
+ var MS_PER_YEAR = _b().constants.TIME.days(365);
126
126
 
127
127
  // Slug shape matches coupon-stacking / refund-policy convention.
128
128
  var SLUG_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,79}$/;
@@ -81,7 +81,7 @@ var MAX_STATUS_LEN = 64;
81
81
  var MAX_WINDOW_DAYS = 36500; // ~100 years; refuses absurd values
82
82
  var MAX_PRIORITY = 1000000;
83
83
  var MAX_LIST_LIMIT = 200;
84
- var MS_PER_DAY = 24 * 60 * 60 * 1000;
84
+ var MS_PER_DAY = _b().constants.TIME.days(1);
85
85
 
86
86
  // Slug shape matches coupon-stacking / promo-banners / customer-segments
87
87
  // convention — alnum + hyphen + underscore + dot, leading char alnum,
@@ -101,13 +101,14 @@ function _b() {
101
101
  if (!bShop) bShop = require("./index");
102
102
  return bShop.framework;
103
103
  }
104
+ var C = _b().constants;
104
105
 
105
106
  // ---- constants ----------------------------------------------------------
106
107
 
107
108
  var SKU_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
108
109
  var SLUG_RE = /^[a-z0-9][a-z0-9._-]{0,127}$/;
109
110
  var ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
110
- var DAY_MS = 24 * 60 * 60 * 1000;
111
+ var DAY_MS = C.TIME.days(1);
111
112
  var MAX_INTERVAL_DAYS = 3650; // 10 years — same envelope as supplier lead times; refuses Number.MAX_SAFE_INTEGER typos
112
113
  var MAX_BATCH_SIZE = 500;
113
114
  var DEFAULT_BATCH_SIZE = 100;
@@ -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
  // ---- constants ----------------------------------------------------------
118
119
 
@@ -120,7 +121,7 @@ var SKU_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
120
121
  var CODE_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
121
122
  var SLUG_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;
122
123
  var ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
123
- var DAY_MS = 24 * 60 * 60 * 1000;
124
+ var DAY_MS = C.TIME.days(1);
124
125
  var VELOCITY_WINDOW_DAYS = 30;
125
126
  var MAX_LIMIT = 500;
126
127
  var MAX_LEAD_TIME_DAYS = 3650; // 10 years — high enough to cover any real-world supplier promise; low enough to refuse a Number.MAX_SAFE_INTEGER typo
@@ -91,6 +91,7 @@ var MAX_PATH_LEN = 512;
91
91
  var MAX_PATHS_PER_RULE = 200;
92
92
  var MAX_SITEMAP_URL_LEN = 2048;
93
93
  var MAX_HOST_LEN = 255;
94
+ // allow:raw-time-literal — robots.txt Crawl-delay is a seconds value; C.TIME returns ms
94
95
  var MAX_CRAWL_DELAY = 86400; // 24 h — anything larger is a typo
95
96
  var MAX_PRIORITY = 1000000;
96
97
  var MAX_RULE_ID_LEN = 80;
@@ -101,10 +101,11 @@ function _b() {
101
101
  if (!bShop) bShop = require("./index");
102
102
  return bShop.framework;
103
103
  }
104
+ var C = _b().constants;
104
105
 
105
- var ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1000;
106
- var DEFAULT_WINDOW_MS = 30 * 24 * 60 * 60 * 1000;
107
- var DAY_MS = 24 * 60 * 60 * 1000;
106
+ var ONE_YEAR_MS = C.TIME.days(365);
107
+ var DEFAULT_WINDOW_MS = C.TIME.days(30);
108
+ var DAY_MS = C.TIME.days(1);
108
109
 
109
110
  // Cache TTL by report key. Operator can override per-call via
110
111
  // `cache_ttl_ms`; these are the safe defaults — short enough that a
@@ -112,17 +113,17 @@ var DAY_MS = 24 * 60 * 60 * 1000;
112
113
  // hammering the dashboard doesn't re-scan the orders table on every
113
114
  // keystroke.
114
115
  var DEFAULT_CACHE_TTL_MS = {
115
- revenue_by_day: 60 * 1000,
116
- revenue_by_week: 5 * 60 * 1000,
117
- revenue_by_month: 10 * 60 * 1000,
118
- top_products: 5 * 60 * 1000,
119
- top_customers: 5 * 60 * 1000,
120
- revenue_by_country: 5 * 60 * 1000,
121
- revenue_by_payment: 5 * 60 * 1000,
122
- customer_cohort: 15 * 60 * 1000,
123
- aov: 60 * 1000,
124
- refund_rate: 60 * 1000,
125
- funnel: 60 * 1000,
116
+ revenue_by_day: C.TIME.minutes(1),
117
+ revenue_by_week: C.TIME.minutes(5),
118
+ revenue_by_month: C.TIME.minutes(10),
119
+ top_products: C.TIME.minutes(5),
120
+ top_customers: C.TIME.minutes(5),
121
+ revenue_by_country: C.TIME.minutes(5),
122
+ revenue_by_payment: C.TIME.minutes(5),
123
+ customer_cohort: C.TIME.minutes(15),
124
+ aov: C.TIME.minutes(1),
125
+ refund_rate: C.TIME.minutes(1),
126
+ funnel: C.TIME.minutes(1),
126
127
  };
127
128
 
128
129
  var CACHE_NAMESPACE = "sales-report-cache";
@@ -663,7 +664,9 @@ function create(opts) {
663
664
  // Calendar-month arithmetic on the cohort string. SQLite
664
665
  // can do this natively via the modifier shape
665
666
  // `'YYYY-MM-01', '+N months'`.
667
+ // allow:raw-time-literal — SQL strftime('%s') returns unix seconds; * 1000 converts to ms in SQLite
666
668
  var rangeStartSql = "strftime('%s', ?1 || '-01', '+' || ?2 || ' months') * 1000";
669
+ // allow:raw-time-literal — SQL strftime('%s') returns unix seconds; * 1000 converts to ms in SQLite
667
670
  var rangeEndSql = "strftime('%s', ?1 || '-01', '+' || (?2 + 1) || ' months') * 1000";
668
671
  var rangeRow = await query(
669
672
  "SELECT " + rangeStartSql + " AS rs, " + rangeEndSql + " AS re",
@@ -108,6 +108,7 @@ function _b() {
108
108
  if (!bShop) bShop = require("./index");
109
109
  return bShop.framework;
110
110
  }
111
+ var C = _b().constants;
111
112
 
112
113
  // ---- constants ----------------------------------------------------------
113
114
 
@@ -766,7 +767,7 @@ function create(opts) {
766
767
  }
767
768
  var days = _daysAhead(input.days_ahead);
768
769
  var nowTs = input.now == null ? _now() : _epoch(input.now, "now");
769
- var horizon = nowTs + (days * 24 * 60 * 60 * 1000);
770
+ var horizon = nowTs + C.TIME.days(days);
770
771
 
771
772
  var r = await query(
772
773
  "SELECT * FROM sales_tax_filings " +
@@ -76,6 +76,7 @@ function _b() {
76
76
  if (!bShop) bShop = require("./index");
77
77
  return bShop.framework;
78
78
  }
79
+ var C = _b().constants;
79
80
 
80
81
  function _uuid(s, label) {
81
82
  try { return _b().guardUuid.sanitize(s, { profile: "strict" }); }
@@ -649,7 +650,7 @@ function create(opts) {
649
650
  // cron / scheduled-worker layer can emit a metric.
650
651
  expireOlderThan: async function (days) {
651
652
  _days(days);
652
- var threshold = _now() - (days * 24 * 60 * 60 * 1000);
653
+ var threshold = _now() - C.TIME.days(days);
653
654
  var r = await query(
654
655
  "DELETE FROM save_for_later WHERE saved_at < ?1",
655
656
  [threshold],
@@ -76,7 +76,7 @@ var MAX_PREFIX_LEN = 100;
76
76
  var MAX_DISPLAY_TEXT_LEN = 200;
77
77
  var MAX_LINK_URL_LEN = 2048;
78
78
  var MAX_RESULT_COUNT = 1000000;
79
- var POPULAR_WINDOW_MS = 30 * 24 * 60 * 60 * 1000;
79
+ var POPULAR_WINDOW_MS = _b().constants.TIME.days(30);
80
80
  var FEATURED_STATUSES = ["active", "expired", "draft"];
81
81
  var ALLOWED_FEATURED_COLS = [
82
82
  "prefix", "display_text", "link_url", "priority",
@@ -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
 
@@ -109,7 +110,7 @@ var MAX_NAME_LEN = 200;
109
110
  var MAX_AMOUNT_MINOR = 1000000000; // $10,000,000.00 — sane upper cap
110
111
  var MAX_RATE_BPS = 10000; // 100% — exclusive ceiling
111
112
  var MAX_CLAIM_DAYS = 3650; // 10 years — sane upper cap
112
- var DAY_MS = 24 * 60 * 60 * 1000;
113
+ var DAY_MS = C.TIME.days(1);
113
114
 
114
115
  var CLAIM_TYPES = Object.freeze(["lost", "damaged", "stolen", "not_delivered"]);
115
116
  var INSURANCE_STATUSES = Object.freeze(["active", "cancelled", "expired"]);
@@ -63,6 +63,7 @@ function _b() {
63
63
  if (!bShop) bShop = require("./index");
64
64
  return bShop.framework;
65
65
  }
66
+ var C = _b().constants;
66
67
 
67
68
  // ---- constants ----------------------------------------------------------
68
69
 
@@ -90,7 +91,7 @@ var MAX_CUSTOMS_LINES = 100;
90
91
  var DEFAULT_PENDING_LIMIT = 25;
91
92
  var MAX_PENDING_LIMIT = 200;
92
93
 
93
- var VOID_WINDOW_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
94
+ var VOID_WINDOW_MS = C.TIME.days(30); // 30 days
94
95
 
95
96
  // ---- validators ---------------------------------------------------------
96
97
 
@@ -407,7 +408,7 @@ function create(opts) {
407
408
  // when it forwards the void to the broker.
408
409
  if (ts - row.purchased_at > VOID_WINDOW_MS) {
409
410
  var werr = new Error("shipping-labels.voidLabel: refused — label was purchased more than 30 days ago (" +
410
- Math.floor((ts - row.purchased_at) / 86400000) + " days)");
411
+ Math.floor((ts - row.purchased_at) / C.TIME.days(1)) + " days)");
411
412
  werr.code = "SHIPPING_LABELS_VOID_WINDOW_EXPIRED";
412
413
  throw werr;
413
414
  }
@@ -81,6 +81,7 @@ var REGION_RE = /^[A-Z0-9]{1,3}$/;
81
81
  var MAX_RATES = 256;
82
82
  var MAX_SERVICE_LABEL_LEN = 128;
83
83
 
84
+ // allow:raw-time-literal — grams (1 t), not a duration; the `* 1000` is a mass conversion
84
85
  var MAX_WEIGHT_GRAMS = 1000 * 1000; // 1 t — generous, refuses absurd input
85
86
  var MAX_ORDER_MINOR = 1e12; // 10 billion in the minor unit — generous
86
87
 
@@ -134,10 +134,11 @@ function _b() {
134
134
  if (!bShop) bShop = require("./index");
135
135
  return bShop.framework;
136
136
  }
137
+ var C = _b().constants;
137
138
 
138
139
  // ---- constants ----------------------------------------------------------
139
140
 
140
- var DAY_MS = 24 * 60 * 60 * 1000;
141
+ var DAY_MS = C.TIME.days(1);
141
142
  var TWO_YEARS_MS = 730 * DAY_MS;
142
143
  var MAX_LIMIT = 100;
143
144
  var DEFAULT_LIMIT = 10;
@@ -152,13 +153,13 @@ var CACHE_NAMESPACE = "shrinkage-report-cache";
152
153
  // computation is the heaviest and the operator response time on a
153
154
  // red-flag alert is minutes-not-seconds.
154
155
  var DEFAULT_CACHE_TTL_MS = Object.freeze({
155
- report: 60 * 1000,
156
- top_locations: 5 * 60 * 1000,
157
- top_skus: 5 * 60 * 1000,
158
- category_comparison: 5 * 60 * 1000,
159
- monthly_trend: 10 * 60 * 1000,
160
- reason_pie: 5 * 60 * 1000,
161
- anomalies: 15 * 60 * 1000,
156
+ report: C.TIME.minutes(1),
157
+ top_locations: C.TIME.minutes(5),
158
+ top_skus: C.TIME.minutes(5),
159
+ category_comparison: C.TIME.minutes(5),
160
+ monthly_trend: C.TIME.minutes(10),
161
+ reason_pie: C.TIME.minutes(5),
162
+ anomalies: C.TIME.minutes(15),
162
163
  });
163
164
 
164
165
  // Reason-category mapping. Frozen at module load so the operator-
@@ -66,6 +66,7 @@ function _b() {
66
66
  if (!bShop) bShop = require("./index");
67
67
  return bShop.framework;
68
68
  }
69
+ var C = _b().constants;
69
70
 
70
71
  // ---- constants ----------------------------------------------------------
71
72
 
@@ -95,11 +96,11 @@ var MAX_PROVIDER_REF_LEN = 256;
95
96
  // to compute `next_retry_at`; once the schedule is exhausted the row
96
97
  // terminates as failed regardless of the caller's `retry` request.
97
98
  var RETRY_BACKOFF_MS = [
98
- 60 * 1000,
99
- 5 * 60 * 1000,
100
- 30 * 60 * 1000,
101
- 2 * 60 * 60 * 1000,
102
- 12 * 60 * 60 * 1000,
99
+ C.TIME.minutes(1),
100
+ C.TIME.minutes(5),
101
+ C.TIME.minutes(30),
102
+ C.TIME.hours(2),
103
+ C.TIME.hours(12),
103
104
  ];
104
105
 
105
106
  var SLUG_RE = /^[a-z](?:[a-z0-9-]*[a-z0-9])?$/;
@@ -57,7 +57,7 @@ var TOKEN_NAMESPACE = "stock-alert-token";
57
57
  var TOKEN_BYTES = 24; // 24 raw bytes → 32 base64url chars
58
58
  var TOKEN_LEN = 32;
59
59
  var TOKEN_RE = /^[A-Za-z0-9_-]{32}$/;
60
- var DEFAULT_TTL_MS = 1000 * 60 * 60 * 24 * 90; // 90 days
60
+ var DEFAULT_TTL_MS = _b().constants.TIME.days(90); // 90 days
61
61
  var SKU_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
62
62
  var MAX_LIST_LIMIT = 200;
63
63
  var DEFAULT_LIMIT = 50;
@@ -74,6 +74,7 @@ function _b() {
74
74
  if (!bShop) bShop = require("./index");
75
75
  return bShop.framework;
76
76
  }
77
+ var C = _b().constants;
77
78
 
78
79
  // ---- constants ----------------------------------------------------------
79
80
 
@@ -385,7 +386,7 @@ function create(opts) {
385
386
  var plaintext = _generateToken();
386
387
  var tokenHash = _hashToken(plaintext);
387
388
  var nowTs = _now();
388
- var expiresAt = nowTs + (expiresHours * 60 * 60 * 1000);
389
+ var expiresAt = nowTs + C.TIME.hours(expiresHours);
389
390
 
390
391
  if (existing) {
391
392
  await query(
@@ -65,6 +65,7 @@ function _b() {
65
65
  if (!bShop) bShop = require("./index");
66
66
  return bShop.framework;
67
67
  }
68
+ var C = _b().constants;
68
69
 
69
70
  var KINDS = ["credit", "debit", "expire"];
70
71
  var SOURCES = ["refund", "goodwill", "promotional", "manual", "loyalty_redemption"];
@@ -76,7 +77,7 @@ var MAX_SOURCE_REF_LEN = 128;
76
77
  var PRINTABLE_RE = /^[^\x00-\x1f\x7f]*$/;
77
78
 
78
79
  var MAX_BULK_IDS = 500;
79
- var MS_PER_DAY = 86400 * 1000;
80
+ var MS_PER_DAY = C.TIME.days(1);
80
81
 
81
82
  // ---- validators ---------------------------------------------------------
82
83