@blamejs/blamejs-shop 0.0.128 → 0.1.0

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 (111) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +2 -0
  3. package/lib/admin.js +1 -2
  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 +223 -141
  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 +4 -0
  93. package/lib/vendor/blamejs/README.md +2 -0
  94. package/lib/vendor/blamejs/api-snapshot.json +122 -2
  95. package/lib/vendor/blamejs/index.js +2 -0
  96. package/lib/vendor/blamejs/lib/did.js +367 -0
  97. package/lib/vendor/blamejs/lib/mdoc.js +305 -0
  98. package/lib/vendor/blamejs/package.json +1 -1
  99. package/lib/vendor/blamejs/release-notes/v0.12.40.json +18 -0
  100. package/lib/vendor/blamejs/release-notes/v0.12.41.json +18 -0
  101. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +27 -1
  102. package/lib/vendor/blamejs/test/layer-0-primitives/did.test.js +147 -0
  103. package/lib/vendor/blamejs/test/layer-0-primitives/mdoc.test.js +230 -0
  104. package/lib/vendor-invoices.js +1 -1
  105. package/lib/webhook-receiver.js +8 -2
  106. package/lib/webhook-subscriptions.js +1 -1
  107. package/lib/webhooks.js +6 -5
  108. package/lib/winback-campaigns.js +2 -1
  109. package/lib/wishlist-alerts.js +2 -1
  110. package/lib/wishlist-digest.js +2 -1
  111. package/package.json +1 -1
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+ /**
3
+ * Layer 0 — b.mdoc (ISO 18013-5 mdoc / mDL issuer-data verification).
4
+ * A pure-node mock issuer builds an IssuerSigned structure (COSE_Sign1
5
+ * IssuerAuth over a Tag-24 MobileSecurityObject, with the signer cert in
6
+ * the x5chain header) so the verifier's full path is exercised: COSE
7
+ * signature, MSO validity window, per-element digest matching against
8
+ * the MSO, selective disclosure, and the tamper / expiry / docType /
9
+ * malformed-validity refusal paths. The trust core (COSE_Sign1 + CBOR)
10
+ * is the framework's tested b.cose / b.cbor substrate.
11
+ */
12
+
13
+ var b = require("../../index");
14
+ var helpers = require("../helpers");
15
+ var check = helpers.check;
16
+ var asn1 = require("../../lib/asn1-der");
17
+ var cbor = b.cbor;
18
+ var nodeCrypto = require("node:crypto");
19
+
20
+ var NS = "org.iso.18013.5.1";
21
+ var DOCTYPE = "org.iso.18013.5.1.mDL";
22
+
23
+ function _algId(oid, withNull) {
24
+ return withNull ? asn1.writeSequence([asn1.writeOid(oid), asn1.writeNull()]) : asn1.writeSequence([asn1.writeOid(oid)]);
25
+ }
26
+ function _name(cn) {
27
+ return asn1.writeSequence([asn1.writeSet([asn1.writeSequence([asn1.writeOid("2.5.4.3"), asn1.writeUtf8String(cn)])])]);
28
+ }
29
+ function _utc(d) { return asn1.writeNode(0x17, Buffer.from(d.toISOString().replace(/[-:T]/g, "").slice(2, 14) + "Z", "ascii")); }
30
+
31
+ // Minimal self-signed EC cert (mdoc issuer-data verify reads the key,
32
+ // not an EKU). Returns { certDer, key, pem }.
33
+ function _makeCert(cn) {
34
+ var kp = nodeCrypto.generateKeyPairSync("ec", { namedCurve: "P-256" });
35
+ var spki = kp.publicKey.export({ type: "spki", format: "der" });
36
+ var sa = _algId("1.2.840.10045.4.3.2", false);
37
+ var nm = _name(cn || "mDL Issuer");
38
+ var now = Date.now();
39
+ var tbs = asn1.writeSequence([
40
+ asn1.writeContextExplicit(0, asn1.writeInteger(Buffer.from([2]))),
41
+ asn1.writeInteger(Buffer.from([0x2a])), sa, nm,
42
+ asn1.writeSequence([_utc(new Date(now - 86400000)), _utc(new Date(now + 86400000 * 3650))]),
43
+ nm, spki,
44
+ ]);
45
+ var certDer = asn1.writeSequence([tbs, sa, asn1.writeBitString(nodeCrypto.sign("sha256", tbs, kp.privateKey), 0)]);
46
+ return { certDer: certDer, key: kp.privateKey, pem: new nodeCrypto.X509Certificate(certDer).toString() };
47
+ }
48
+
49
+ // Build an IssuerSigned (CBOR bytes). opts: { elements, validFrom,
50
+ // validUntil, docType, digestAlg } — defaults are a valid mDL.
51
+ async function _makeMdoc(cert, opts) {
52
+ opts = opts || {};
53
+ var elements = opts.elements || [["family_name", "Doe"], ["age_over_18", true], ["given_name", "Jane"]];
54
+ var digestNode = opts.digestNode || "sha256";
55
+ var digestAlg = opts.digestAlg || "SHA-256";
56
+ var now = Date.now();
57
+ var items = [];
58
+ var digests = new Map();
59
+ elements.forEach(function (el, i) {
60
+ var inner = cbor.encode(new Map([
61
+ ["digestID", i], ["random", nodeCrypto.randomBytes(32)],
62
+ ["elementIdentifier", el[0]], ["elementValue", el[1]],
63
+ ]));
64
+ items.push(new cbor.Tag(24, inner));
65
+ digests.set(i, nodeCrypto.createHash(digestNode).update(cbor.encode(new cbor.Tag(24, inner))).digest());
66
+ });
67
+ var validFromMs = opts.validFrom != null ? opts.validFrom : now - 86400000;
68
+ var validUntilMs = opts.validUntil != null ? opts.validUntil : now + 86400000 * 3650;
69
+ var validUntilTag = opts.validUntilRaw !== undefined ? opts.validUntilRaw : new cbor.Tag(0, new Date(validUntilMs).toISOString());
70
+ var mso = new Map([
71
+ ["version", "1.0"], ["digestAlgorithm", digestAlg], ["docType", opts.docType || DOCTYPE],
72
+ ["valueDigests", new Map([[NS, digests]])],
73
+ ["validityInfo", new Map([
74
+ ["signed", new cbor.Tag(0, new Date(now).toISOString())],
75
+ ["validFrom", new cbor.Tag(0, new Date(validFromMs).toISOString())],
76
+ ["validUntil", validUntilTag],
77
+ ])],
78
+ ]);
79
+ var payload = cbor.encode(new cbor.Tag(24, cbor.encode(mso)));
80
+ var signed = await b.cose.sign(payload, { alg: opts.alg || "ES256", privateKey: cert.key, unprotectedHeaders: { 33: cert.certDer } });
81
+ var issuerAuth = cbor.decode(signed, { allowedTags: [18, 24] }).value;
82
+ return cbor.encode(new Map([["nameSpaces", new Map([[NS, items]])], ["issuerAuth", issuerAuth]]));
83
+ }
84
+
85
+ function testSurface() {
86
+ check("b.mdoc.verifyIssuerSigned is a function", typeof b.mdoc.verifyIssuerSigned === "function");
87
+ check("b.mdoc.DIGEST_ALGS has SHA-256", b.mdoc.DIGEST_ALGS["SHA-256"] === "sha256");
88
+ check("b.mdoc.MdocError is a class", typeof b.mdoc.MdocError === "function");
89
+ }
90
+
91
+ async function testRoundTrip() {
92
+ var cert = _makeCert();
93
+ var mdoc = await _makeMdoc(cert);
94
+ var out = await b.mdoc.verifyIssuerSigned(mdoc, { algorithms: ["ES256"], expectedDocType: DOCTYPE });
95
+ check("verify: docType", out.docType === DOCTYPE);
96
+ check("verify: alg reported", out.alg === "ES256");
97
+ check("verify: digestAlgorithm", out.digestAlgorithm === "SHA-256");
98
+ check("verify: disclosed elements extracted", out.namespaces[NS].family_name === "Doe" && out.namespaces[NS].age_over_18 === true && out.namespaces[NS].given_name === "Jane");
99
+ check("verify: validityInfo dates returned", out.validityInfo.validUntil instanceof Date);
100
+ check("verify: signerCert PEM returned", /BEGIN CERTIFICATE/.test(out.signerCert));
101
+
102
+ // chain verify against the self-signed issuer as anchor
103
+ var ok = await b.mdoc.verifyIssuerSigned(mdoc, { algorithms: ["ES256"], trustAnchorsPem: cert.pem });
104
+ check("verify: chain to issuer anchor (string)", ok.docType === DOCTYPE);
105
+ }
106
+
107
+ async function testDigestAndSignatureRefusals() {
108
+ var cert = _makeCert();
109
+ var mdoc = await _makeMdoc(cert);
110
+
111
+ // Tamper a disclosed element's value: re-pack one IssuerSignedItem
112
+ // with a changed value but keep the MSO digest → digest mismatch.
113
+ var top = cbor.decode(mdoc, { allowedTags: [0, 1, 24, 1004] });
114
+ var items = top.get("nameSpaces").get(NS);
115
+ var inner0 = cbor.decode(items[0].value, { allowedTags: [0, 1, 24, 1004] });
116
+ inner0.set("elementValue", "Tampered");
117
+ items[0] = new cbor.Tag(24, cbor.encode(inner0));
118
+ var tampered = cbor.encode(top);
119
+ var e1 = null;
120
+ try { await b.mdoc.verifyIssuerSigned(tampered, { algorithms: ["ES256"] }); } catch (e) { e1 = e; }
121
+ check("verify: tampered element refused (digest-mismatch)", e1 && e1.code === "mdoc/digest-mismatch");
122
+
123
+ // Tamper the COSE signature deterministically (flip a byte in the
124
+ // issuerAuth signature element) → bad-signature.
125
+ var top2 = cbor.decode(mdoc, { allowedTags: [0, 1, 24, 1004] });
126
+ var ia = top2.get("issuerAuth");
127
+ ia[3] = Buffer.from(ia[3]); ia[3][0] ^= 0xff;
128
+ var bad = cbor.encode(top2);
129
+ var e2 = null;
130
+ try { await b.mdoc.verifyIssuerSigned(bad, { algorithms: ["ES256"] }); } catch (e) { e2 = e; }
131
+ check("verify: tampered COSE signature refused", e2 && e2.code === "cose/bad-signature");
132
+
133
+ // A malformed x5chain certificate surfaces a clean error (not raw OpenSSL).
134
+ var top3 = cbor.decode(mdoc, { allowedTags: [0, 1, 24, 1004] });
135
+ top3.get("issuerAuth")[1].set(33, Buffer.from([0x30, 0x03, 0x02, 0x01, 0x01]));
136
+ var e6 = null;
137
+ try { await b.mdoc.verifyIssuerSigned(cbor.encode(top3), { algorithms: ["ES256"] }); } catch (e) { e6 = e; }
138
+ check("verify: malformed x5chain cert refused cleanly", e6 && e6.code === "mdoc/bad-cert");
139
+
140
+ // alg outside allowlist
141
+ var e3 = null;
142
+ try { await b.mdoc.verifyIssuerSigned(mdoc, { algorithms: ["EdDSA"] }); } catch (e) { e3 = e; }
143
+ check("verify: alg outside allowlist refused", e3 && (e3.code === "cose/alg-not-allowed"));
144
+ }
145
+
146
+ async function testValidityAndDocType() {
147
+ var cert = _makeCert();
148
+
149
+ // expired (valid window 10 days ago .. 1 day ago)
150
+ var expired = await _makeMdoc(cert, { validFrom: Date.now() - 86400000 * 10, validUntil: Date.now() - 86400000 });
151
+ var e1 = null;
152
+ try { await b.mdoc.verifyIssuerSigned(expired, { algorithms: ["ES256"] }); } catch (e) { e1 = e; }
153
+ check("verify: expired credential refused", e1 && e1.code === "mdoc/expired");
154
+
155
+ // not yet valid
156
+ var future = await _makeMdoc(cert, { validFrom: Date.now() + 86400000 * 30 });
157
+ var e2 = null;
158
+ try { await b.mdoc.verifyIssuerSigned(future, { algorithms: ["ES256"] }); } catch (e) { e2 = e; }
159
+ check("verify: not-yet-valid credential refused", e2 && e2.code === "mdoc/not-yet-valid");
160
+
161
+ // opts.at within window accepts an otherwise-expired credential
162
+ var ok = await b.mdoc.verifyIssuerSigned(expired, { algorithms: ["ES256"], at: new Date(Date.now() - 86400000 * 2) });
163
+ check("verify: opts.at within window accepts", ok.docType === DOCTYPE);
164
+
165
+ // docType mismatch
166
+ var e3 = null;
167
+ try { await b.mdoc.verifyIssuerSigned(await _makeMdoc(cert), { algorithms: ["ES256"], expectedDocType: "org.iso.18013.5.1.photoID" }); } catch (e) { e3 = e; }
168
+ check("verify: docType mismatch refused", e3 && e3.code === "mdoc/doctype-mismatch");
169
+
170
+ // malformed validUntil (a non-date) fails closed
171
+ var badValidity = await _makeMdoc(cert, { validUntilRaw: new cbor.Tag(0, "not-a-date") });
172
+ var e4 = null;
173
+ try { await b.mdoc.verifyIssuerSigned(badValidity, { algorithms: ["ES256"] }); } catch (e) { e4 = e; }
174
+ check("verify: malformed validUntil refused (fail closed)", e4 && e4.code === "mdoc/bad-validity");
175
+
176
+ // invalid opts.at refused (lesson carried from b.tsa / b.vc)
177
+ var e5 = null;
178
+ try { await b.mdoc.verifyIssuerSigned(await _makeMdoc(cert), { algorithms: ["ES256"], at: new Date("nope") }); } catch (e) { e5 = e; }
179
+ check("verify: invalid opts.at refused", e5 && e5.code === "mdoc/bad-at");
180
+
181
+ // Two signed IssuerSignedItems with the same elementIdentifier (each
182
+ // with a valid MSO digest) is ambiguous → fail closed, not last-wins.
183
+ var dup = await _makeMdoc(cert, { elements: [["family_name", "Doe"], ["family_name", "Roe"]] });
184
+ var e6 = null;
185
+ try { await b.mdoc.verifyIssuerSigned(dup, { algorithms: ["ES256"] }); } catch (e) { e6 = e; }
186
+ check("verify: duplicate elementIdentifier refused", e6 && e6.code === "mdoc/duplicate-element");
187
+ }
188
+
189
+ async function testChainAndInputGuards() {
190
+ var cert = _makeCert();
191
+ var mdoc = await _makeMdoc(cert);
192
+
193
+ // unrelated anchor → untrusted
194
+ var other = _makeCert("Unrelated Root");
195
+ var e1 = null;
196
+ try { await b.mdoc.verifyIssuerSigned(mdoc, { algorithms: ["ES256"], trustAnchorsPem: [other.pem] }); } catch (e) { e1 = e; }
197
+ check("verify: unrelated anchor refused", e1 && e1.code === "mdoc/untrusted-chain");
198
+
199
+ // empty trust-anchor shape refused (no fail-open)
200
+ var e2 = null;
201
+ try { await b.mdoc.verifyIssuerSigned(mdoc, { algorithms: ["ES256"], trustAnchorsPem: [] }); } catch (e) { e2 = e; }
202
+ check("verify: empty trustAnchorsPem refused", e2 && e2.code === "mdoc/bad-trust-anchors");
203
+
204
+ // garbage input → not CBOR / malformed
205
+ var e3 = null;
206
+ try { await b.mdoc.verifyIssuerSigned(Buffer.from([0x00, 0x01]), { algorithms: ["ES256"] }); } catch (e) { e3 = e; }
207
+ check("verify: garbage input refused", e3 && (e3.code === "mdoc/malformed" || e3.code === "mdoc/bad-input" || /cbor/.test(e3.code || "")));
208
+
209
+ // missing algorithms
210
+ var e4 = null;
211
+ try { await b.mdoc.verifyIssuerSigned(mdoc, {}); } catch (e) { e4 = e; }
212
+ check("verify: missing algorithms refused", e4 && e4.code === "mdoc/algorithms-required");
213
+ }
214
+
215
+ async function run() {
216
+ testSurface();
217
+ await testRoundTrip();
218
+ await testDigestAndSignatureRefusals();
219
+ await testValidityAndDocType();
220
+ await testChainAndInputGuards();
221
+ }
222
+
223
+ module.exports = { run: run };
224
+
225
+ if (require.main === module) {
226
+ run().then(
227
+ function () { console.log("[mdoc] OK — " + helpers.getChecks() + " checks passed"); },
228
+ function (e) { console.error("FAIL:", e && e.stack || e); process.exit(1); }
229
+ );
230
+ }
@@ -106,7 +106,7 @@ var INVOICE_STATUSES = Object.freeze([
106
106
 
107
107
  var MAX_DUE_WITHIN_DAYS = 3650; // ~10 years — bound the predicate
108
108
 
109
- var MS_PER_DAY = 24 * 60 * 60 * 1000;
109
+ var MS_PER_DAY = _b().constants.TIME.days(1);
110
110
 
111
111
  // Aging buckets (days past due, inclusive at upper bound). `current`
112
112
  // is anything with due_date >= as_of; the rest are the canonical
@@ -76,16 +76,22 @@
76
76
  * @related b.crypto, b.webhook, b.uuid
77
77
  */
78
78
 
79
+ // `_b()` is a hoisted function declaration (defined below), so resolving
80
+ // the framework constants here at module-eval is safe — the index entry
81
+ // point exposes `framework` before the require cascade.
82
+ var C = _b().constants;
83
+
79
84
  var SECRET_NAMESPACE = "webhook-receiver-secret";
80
85
  var SECRET_BYTE_LEN = 32;
81
86
  // 32 bytes -> 43 chars of base64url (no padding).
82
87
  var SECRET_PLAINTEXT_LEN = 43;
83
88
  var SECRET_PLAINTEXT_RE = /^[A-Za-z0-9_\-]{43}$/;
84
89
 
85
- var ROTATION_GRACE_MS = 24 * 60 * 60 * 1000;
90
+ var ROTATION_GRACE_MS = C.TIME.days(1);
86
91
 
87
92
  var DEFAULT_REPLAY_WINDOW_SECONDS = 300; // 5 min — Stripe-shaped default
88
93
  var MIN_REPLAY_WINDOW_SECONDS = 30; // floor — below this clock skew false-rejects
94
+ // allow:raw-time-literal — replay-window ceiling in SECONDS (24h); C.TIME returns ms
89
95
  var MAX_REPLAY_WINDOW_SECONDS = 86400; // 24 h — anything larger is "no replay defense"
90
96
 
91
97
  var DEFAULT_MAX_BODY_BYTES = 1024 * 1024; // 1 MiB
@@ -933,7 +939,7 @@ function create(opts) {
933
939
  purgeOlderThan: async function (days) {
934
940
  var d = _purgeDays(days);
935
941
  var nowMs = _now();
936
- var cutoff = nowMs - (d * 24 * 60 * 60 * 1000);
942
+ var cutoff = nowMs - C.TIME.days(d);
937
943
  var r = await query(
938
944
  "DELETE FROM webhook_received_events " +
939
945
  "WHERE received_at < ?1 " +
@@ -56,7 +56,7 @@ var MAX_EVENT_TYPES = 64;
56
56
  var MAX_ENDPOINT_URL_LEN = 2048;
57
57
  var SECRET_BYTES = 32;
58
58
  var SECRET_NAMESPACE = "webhook-signing-secret";
59
- var ROTATION_GRACE_MS = 24 * 60 * 60 * 1000;
59
+ var ROTATION_GRACE_MS = _b().constants.TIME.days(1);
60
60
 
61
61
  var WILDCARD_EVENT = "*";
62
62
 
package/lib/webhooks.js CHANGED
@@ -41,6 +41,7 @@ function _b() {
41
41
  if (!bShop) bShop = require("./index");
42
42
  return bShop.framework;
43
43
  }
44
+ var C = _b().constants;
44
45
 
45
46
  var KNOWN_EVENTS = Object.freeze([
46
47
  "order.mark_paid",
@@ -75,7 +76,7 @@ var SECRET_BYTES = 32;
75
76
  //
76
77
  // After the fifth failed attempt the delivery moves to webhook_dlq
77
78
  // for operator investigation — see `_moveToDlq` below.
78
- var BACKOFF_SCHEDULE_S = Object.freeze([60, 300, 1800, 14400, 86400]);
79
+ var BACKOFF_SCHEDULE_S = Object.freeze([60, 300, 1800, 14400, 86400]); // allow:raw-time-literal — seconds values; C.TIME returns ms
79
80
  var MAX_ATTEMPTS = 5;
80
81
 
81
82
  // Window used by the per-endpoint rate-limit sliding count. One
@@ -83,7 +84,7 @@ var MAX_ATTEMPTS = 5;
83
84
  // brick its own delivery feed (the window naturally slides forward),
84
85
  // long enough that bursty fan-out from a single high-volume event
85
86
  // doesn't trip the throttle on a healthy endpoint.
86
- var RATE_WINDOW_MS = 60 * 1000;
87
+ var RATE_WINDOW_MS = C.TIME.minutes(1);
87
88
 
88
89
  function _now() { return Date.now(); }
89
90
 
@@ -254,7 +255,7 @@ function create(opts) {
254
255
  if (!willDlq) {
255
256
  var idx = nextAttempts - 1;
256
257
  if (idx < BACKOFF_SCHEDULE_S.length) {
257
- nextRetryAt = ts + (BACKOFF_SCHEDULE_S[idx] * 1000);
258
+ nextRetryAt = ts + (BACKOFF_SCHEDULE_S[idx] * 1000); // allow:raw-time-literal — schedule entry is a runtime seconds value; *1000 converts to ms
258
259
  }
259
260
  }
260
261
  await query(
@@ -507,12 +508,12 @@ function create(opts) {
507
508
  }
508
509
  var tolMs;
509
510
  if (toleranceSeconds === undefined) {
510
- tolMs = 300 * 1000;
511
+ tolMs = C.TIME.minutes(5);
511
512
  } else {
512
513
  if (typeof toleranceSeconds !== "number" || !isFinite(toleranceSeconds) || toleranceSeconds < 30) {
513
514
  throw new TypeError("webhooks.verifyIncoming: toleranceSeconds must be >= 30");
514
515
  }
515
- tolMs = Math.floor(toleranceSeconds * 1000);
516
+ tolMs = Math.floor(toleranceSeconds * 1000); // allow:raw-time-literal — toleranceSeconds is a runtime seconds value; *1000 converts to ms
516
517
  }
517
518
  return await _b().webhook.verify({
518
519
  alg: "hmac-sha256-stripe",
@@ -102,6 +102,7 @@ function _b() {
102
102
  if (!bShop) bShop = require("./index");
103
103
  return bShop.framework;
104
104
  }
105
+ var C = _b().constants;
105
106
 
106
107
  // ---- constants ----------------------------------------------------------
107
108
 
@@ -109,7 +110,7 @@ var SLUG_RE = /^[a-z0-9][a-z0-9._-]{0,62}[a-z0-9]$|^[a-z0-9]$/;
109
110
  var TEMPLATE_RE = /^[a-z0-9][a-z0-9._-]{0,126}[a-z0-9]$|^[a-z0-9]$/;
110
111
  var MAX_REASON_LEN = 280;
111
112
  var MAX_STEPS = 12;
112
- var DAY_MS = 24 * 60 * 60 * 1000;
113
+ var DAY_MS = C.TIME.days(1);
113
114
 
114
115
  var ENROLLMENT_STATUSES = Object.freeze([
115
116
  "active",
@@ -93,6 +93,7 @@ function _b() {
93
93
  if (!bShop) bShop = require("./index");
94
94
  return bShop.framework;
95
95
  }
96
+ var C = _b().constants;
96
97
 
97
98
  // ---- constants ----------------------------------------------------------
98
99
 
@@ -115,7 +116,7 @@ var DEFAULT_BATCH_SIZE = 500;
115
116
  var MAX_BATCH_SIZE = 5000;
116
117
  var MAX_WEEKLY_CAP = 1000;
117
118
  var MAX_BPS = 10000; // 100% — refuse strictly absurd thresholds
118
- var MS_PER_DAY = 86400000;
119
+ var MS_PER_DAY = C.TIME.days(1);
119
120
  var MS_PER_WEEK = MS_PER_DAY * 7;
120
121
 
121
122
  // Per-(customer, sku, policy) re-fire suppression window. A price drop
@@ -115,6 +115,7 @@ function _b() {
115
115
  if (!bShop) bShop = require("./index");
116
116
  return bShop.framework;
117
117
  }
118
+ var C = _b().constants;
118
119
 
119
120
  // ---- constants ----------------------------------------------------------
120
121
 
@@ -130,7 +131,7 @@ var MAX_LIMIT = 500;
130
131
  var DEFAULT_LIMIT = 50;
131
132
  var MAX_DIGEST_LINES = 200;
132
133
 
133
- var DAY_MS = 24 * 60 * 60 * 1000;
134
+ var DAY_MS = C.TIME.days(1);
134
135
 
135
136
  // ---- html escape (local; vendored blamejs's _htmlEscape is private to
136
137
  // the mail primitive). Same rules — five named entities, no tag/attr
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/blamejs-shop",
3
- "version": "0.0.128",
3
+ "version": "0.1.0",
4
4
  "description": "Open-source framework built on blamejs. Vendored stack, zero npm runtime deps, PQC-first crypto, security-on by default.",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {