@blamejs/core 0.5.7 → 0.5.8

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 CHANGED
@@ -8,6 +8,7 @@ upgrading across more than a few patches at a time.
8
8
 
9
9
  ## v0.5.x
10
10
 
11
+ - **0.5.7** (2026-04-30) — defensive validation + queue closure capture + audit context
11
12
  - **0.5.6** (2026-04-30) — break-glass: trustProxy honored, cache require hoisted
12
13
  - **0.5.5** (2026-04-30) — strict default CSP + IPv6 special-range expansion
13
14
  - **0.5.4** (2026-04-30) — close SSRF DNS-rebinding window with pinned outbound DNS
package/index.js CHANGED
@@ -106,6 +106,7 @@ var forms = require("./lib/forms");
106
106
  var app = require("./lib/app");
107
107
  var jobs = require("./lib/jobs");
108
108
  var breakGlass = require("./lib/break-glass");
109
+ var uuid = require("./lib/uuid");
109
110
  var mail = require("./lib/mail");
110
111
  var mailBounce = require("./lib/mail-bounce");
111
112
  var websocketChannels = require("./lib/websocket-channels");
@@ -208,6 +209,7 @@ module.exports = {
208
209
  createApp: app.createApp,
209
210
  jobs: jobs,
210
211
  breakGlass: breakGlass,
212
+ uuid: uuid,
211
213
  mail: mail,
212
214
  mailBounce: mailBounce,
213
215
  websocketChannels: websocketChannels,
package/lib/uuid.js ADDED
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ /**
3
+ * uuid — RFC 4122 v4 (random) + RFC 9562 v7 (time-ordered).
4
+ *
5
+ * Two flavors:
6
+ *
7
+ * b.uuid.v4() — fully random 128-bit UUID. Standard, portable,
8
+ * the default choice when ordering doesn't matter.
9
+ *
10
+ * b.uuid.v7() — Unix-millisecond timestamp prefix + 74 random
11
+ * bits. Time-ordered (sorts by creation time even
12
+ * lexicographically), ideal as a database PK
13
+ * because B-tree inserts stay near the right edge
14
+ * — no random scattering across the index.
15
+ *
16
+ * b.uuid.parse(str) — { ok, version, bytes }. Validates the canonical
17
+ * 8-4-4-4-12 hex form and the version + variant
18
+ * bits. Returns ok:false (no throw) on bad input.
19
+ *
20
+ * b.uuid.isValid(str) — boolean shorthand. No version/variant check
21
+ * beyond shape — operators who care use parse().
22
+ *
23
+ * All entropy comes from `b.crypto.generateBytes`, which routes through
24
+ * `node:crypto.randomBytes` — same source as `crypto.randomUUID()`.
25
+ *
26
+ * Why ship v7 ourselves? Native `crypto.randomUUID()` only emits v4.
27
+ * v7 is the modern recommendation for any UUID landing in a sortable
28
+ * column (jobs queue, audit chain extensions, anything where insertion
29
+ * order matters for index locality).
30
+ */
31
+ var { generateBytes } = require("./crypto");
32
+
33
+ // Canonical UUID layout: 8-4-4-4-12 hex digits, version nibble at byte
34
+ // 6 high-nibble, variant bits at byte 8 high two bits (must be 10).
35
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-7][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
36
+ // Loose form for `isValid` shape-only check — accepts any version 1-8 and
37
+ // any variant top-2-bit value. Operators wanting strict version+variant
38
+ // gating use `parse()`.
39
+ var UUID_LOOSE_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
40
+
41
+ function _bytesToString(bytes) {
42
+ var hex = bytes.toString("hex");
43
+ return hex.slice(0, 8) + "-" +
44
+ hex.slice(8, 12) + "-" +
45
+ hex.slice(12, 16) + "-" +
46
+ hex.slice(16, 20) + "-" +
47
+ hex.slice(20, 32);
48
+ }
49
+
50
+ function v4() {
51
+ var b = generateBytes(16);
52
+ // version = 4 (0100): high nibble of byte 6
53
+ b[6] = (b[6] & 0x0f) | 0x40;
54
+ // variant = RFC 4122 (10xx): top two bits of byte 8
55
+ b[8] = (b[8] & 0x3f) | 0x80;
56
+ return _bytesToString(b);
57
+ }
58
+
59
+ function v7(opts) {
60
+ // RFC 9562 §5.7 layout:
61
+ // bytes 0-5 : 48-bit big-endian Unix timestamp in milliseconds
62
+ // bytes 6-7 : version nibble (7) + 12 bits random_a
63
+ // bytes 8-15 : variant bits + 62 bits random_b
64
+ var ms = (opts && typeof opts.now === "number") ? opts.now : Date.now();
65
+ var b = generateBytes(16);
66
+ // 48-bit ms timestamp (big-endian) into bytes 0-5
67
+ // ms can exceed 2^32 (we're in 2026, ms is ~1.78e12), so use Math + bit ops carefully
68
+ var msHi = Math.floor(ms / 0x100000000); // top 16 bits live in low 16 of msHi
69
+ var msLo = ms >>> 0; // bottom 32 bits unsigned
70
+ b[0] = (msHi >> 8) & 0xff;
71
+ b[1] = msHi & 0xff;
72
+ b[2] = (msLo >>> 24) & 0xff;
73
+ b[3] = (msLo >>> 16) & 0xff;
74
+ b[4] = (msLo >>> 8) & 0xff;
75
+ b[5] = msLo & 0xff;
76
+ // version = 7 (0111) in high nibble of byte 6, random_a in low nibble + byte 7
77
+ b[6] = (b[6] & 0x0f) | 0x70;
78
+ // variant = RFC 4122 (10xx) in top two bits of byte 8
79
+ b[8] = (b[8] & 0x3f) | 0x80;
80
+ return _bytesToString(b);
81
+ }
82
+
83
+ function parse(str) {
84
+ if (typeof str !== "string") return { ok: false, reason: "not-a-string" };
85
+ if (!UUID_RE.test(str)) return { ok: false, reason: "malformed" };
86
+ var hex = str.replace(/-/g, "");
87
+ var bytes = Buffer.from(hex, "hex");
88
+ // Version is the high nibble of byte 6.
89
+ var version = (bytes[6] >> 4) & 0x0f;
90
+ // Variant: top two bits of byte 8 must be 10 for RFC 4122 / 9562.
91
+ var variant = (bytes[8] >> 6) & 0x03;
92
+ if (variant !== 0b10) return { ok: false, reason: "bad-variant" };
93
+ return { ok: true, version: version, bytes: bytes };
94
+ }
95
+
96
+ function isValid(str) {
97
+ return typeof str === "string" && UUID_LOOSE_RE.test(str);
98
+ }
99
+
100
+ module.exports = {
101
+ v4: v4,
102
+ v7: v7,
103
+ parse: parse,
104
+ isValid: isValid,
105
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/core",
3
- "version": "0.5.7",
3
+ "version": "0.5.8",
4
4
  "description": "The Node framework that owns its stack.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "blamejs contributors",