@blamejs/core 0.7.1 → 0.7.18
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 +423 -389
- package/README.md +150 -149
- package/bin/blamejs.js +0 -0
- package/index.js +308 -282
- package/lib/api-key.js +660 -672
- package/lib/api-snapshot.js +338 -338
- package/lib/app-shutdown.js +385 -385
- package/lib/app.js +365 -365
- package/lib/archive.js +250 -250
- package/lib/atomic-file.js +544 -544
- package/lib/audit-chain.js +177 -177
- package/lib/audit-sign.js +344 -344
- package/lib/audit-tools.js +677 -677
- package/lib/audit.js +766 -766
- package/lib/auth/jwt.js +311 -311
- package/lib/auth/lockout.js +436 -436
- package/lib/auth/oauth.js +721 -721
- package/lib/auth/passkey.js +181 -181
- package/lib/auth/password.js +594 -594
- package/lib/backup/bundle.js +217 -217
- package/lib/backup/crypto.js +176 -176
- package/lib/backup/index.js +515 -515
- package/lib/backup/manifest.js +282 -282
- package/lib/break-glass.js +1338 -1338
- package/lib/bundler.js +441 -441
- package/lib/cache-redis.js +256 -266
- package/lib/cache.js +1206 -1211
- package/lib/canonical-json.js +115 -115
- package/lib/chain-writer.js +234 -234
- package/lib/cli-helpers.js +206 -206
- package/lib/cli.js +2334 -2334
- package/lib/cluster-provider-db.js +317 -317
- package/lib/cluster-storage.js +226 -226
- package/lib/cluster.js +703 -703
- package/lib/codepoint-class.js +196 -0
- package/lib/config-drift.js +301 -301
- package/lib/consent.js +222 -222
- package/lib/constants.js +191 -191
- package/lib/cookies.js +315 -315
- package/lib/credential-hash.js +322 -322
- package/lib/crypto.js +266 -266
- package/lib/csv.js +275 -286
- package/lib/db-declare-row-policy.js +267 -267
- package/lib/db-declare-view.js +420 -421
- package/lib/db-query.js +406 -406
- package/lib/db-schema.js +319 -319
- package/lib/db.js +1288 -1288
- package/lib/deprecate.js +222 -222
- package/lib/dev.js +335 -335
- package/lib/dual-control.js +473 -473
- package/lib/error-page.js +420 -420
- package/lib/external-db-migrate.js +441 -441
- package/lib/external-db.js +1061 -1061
- package/lib/file-type.js +273 -273
- package/lib/file-upload.js +1136 -0
- package/lib/forms.js +422 -422
- package/lib/framework-error.js +293 -202
- package/lib/framework-schema.js +717 -717
- package/lib/gate-contract.js +971 -0
- package/lib/guard-all.js +405 -0
- package/lib/guard-archive.js +739 -0
- package/lib/guard-csv.js +816 -0
- package/lib/guard-email.js +744 -0
- package/lib/guard-filename.js +724 -0
- package/lib/guard-html.js +976 -0
- package/lib/guard-json.js +729 -0
- package/lib/guard-markdown.js +586 -0
- package/lib/guard-svg.js +976 -0
- package/lib/guard-xml.js +405 -0
- package/lib/guard-yaml.js +529 -0
- package/lib/handlers.js +350 -350
- package/lib/http-client-cookie-jar.js +508 -508
- package/lib/http-client.js +1195 -1195
- package/lib/i18n.js +878 -878
- package/lib/jobs.js +185 -185
- package/lib/log-stream-cloudwatch.js +369 -369
- package/lib/log-stream-local.js +146 -146
- package/lib/log-stream-otlp-grpc.js +410 -410
- package/lib/log-stream-otlp.js +286 -286
- package/lib/log-stream-syslog.js +302 -302
- package/lib/log-stream-webhook.js +199 -199
- package/lib/log-stream.js +330 -330
- package/lib/log.js +500 -500
- package/lib/mail-bounce.js +528 -528
- package/lib/mail-dkim.js +369 -362
- package/lib/mail.js +981 -962
- package/lib/metrics.js +683 -683
- package/lib/middleware/api-encrypt.js +936 -573
- package/lib/middleware/attach-user.js +157 -157
- package/lib/middleware/body-parser.js +1170 -1091
- package/lib/middleware/bot-guard.js +178 -178
- package/lib/middleware/compression.js +452 -452
- package/lib/middleware/cors.js +314 -314
- package/lib/middleware/csp-nonce.js +348 -348
- package/lib/middleware/csrf-protect.js +316 -316
- package/lib/middleware/db-role-for.js +264 -269
- package/lib/middleware/health.js +392 -392
- package/lib/middleware/index.js +79 -79
- package/lib/middleware/rate-limit.js +358 -358
- package/lib/middleware/request-id.js +61 -61
- package/lib/middleware/request-log.js +168 -168
- package/lib/middleware/require-auth.js +104 -104
- package/lib/middleware/security-headers.js +116 -116
- package/lib/middleware/sse.js +166 -166
- package/lib/migrations.js +383 -383
- package/lib/mtls-ca.js +518 -518
- package/lib/mtls-engine-default.js +481 -481
- package/lib/network-dns.js +632 -632
- package/lib/network-heartbeat.js +290 -290
- package/lib/network-nts.js +574 -574
- package/lib/network-proxy.js +265 -265
- package/lib/network-tls.js +328 -328
- package/lib/network.js +233 -233
- package/lib/notify.js +612 -614
- package/lib/ntp-check.js +229 -229
- package/lib/numeric-bounds.js +111 -91
- package/lib/object-store/azure-blob-bucket-ops.js +349 -349
- package/lib/object-store/azure-blob.js +488 -451
- package/lib/object-store/gcs-bucket-ops.js +351 -351
- package/lib/object-store/gcs.js +519 -479
- package/lib/object-store/http-put.js +153 -153
- package/lib/object-store/index.js +197 -197
- package/lib/object-store/sigv4-bucket-ops.js +1092 -1092
- package/lib/object-store/sigv4.js +903 -855
- package/lib/observability.js +151 -151
- package/lib/otel-export.js +269 -269
- package/lib/pagination.js +464 -464
- package/lib/parsers/index.js +80 -80
- package/lib/parsers/safe-env.js +642 -642
- package/lib/parsers/safe-ini.js +292 -292
- package/lib/parsers/safe-toml.js +784 -784
- package/lib/parsers/safe-xml.js +390 -390
- package/lib/parsers/safe-yaml.js +1015 -1015
- package/lib/permissions.js +708 -708
- package/lib/pqc-agent.js +87 -87
- package/lib/pqc-gate.js +279 -279
- package/lib/protobuf-encoder.js +190 -190
- package/lib/protocol-dispatcher.js +161 -161
- package/lib/pubsub-redis.js +167 -177
- package/lib/pubsub.js +429 -429
- package/lib/queue-local.js +476 -476
- package/lib/queue-redis.js +745 -752
- package/lib/queue-sqs.js +319 -319
- package/lib/queue.js +695 -695
- package/lib/redis-client.js +519 -489
- package/lib/request-helpers.js +340 -336
- package/lib/restore-bundle.js +237 -237
- package/lib/restore-rollback.js +259 -259
- package/lib/restore.js +409 -409
- package/lib/retry.js +376 -376
- package/lib/router.js +748 -748
- package/lib/safe-async.js +735 -735
- package/lib/safe-buffer.js +237 -237
- package/lib/safe-json.js +541 -541
- package/lib/safe-schema.js +1266 -1266
- package/lib/safe-url.js +159 -159
- package/lib/scheduler.js +706 -706
- package/lib/security-assert.js +373 -373
- package/lib/seeders.js +618 -630
- package/lib/session.js +478 -478
- package/lib/slug.js +269 -269
- package/lib/ssrf-guard.js +401 -401
- package/lib/static.js +879 -114
- package/lib/storage.js +471 -471
- package/lib/subject.js +281 -281
- package/lib/template.js +791 -791
- package/lib/testing.js +798 -798
- package/lib/time.js +310 -310
- package/lib/totp.js +302 -302
- package/lib/tracing.js +494 -494
- package/lib/uuid.js +132 -132
- package/lib/validate-opts.js +340 -270
- package/lib/vault/index.js +308 -308
- package/lib/vault/rotate.js +784 -784
- package/lib/vault/wrap.js +296 -296
- package/lib/vendor/noble-ciphers.cjs +9 -9
- package/lib/webhook.js +595 -598
- package/lib/websocket.js +1048 -1048
- package/package.json +77 -77
- package/sbom.cyclonedx.json +7 -7
package/lib/uuid.js
CHANGED
|
@@ -1,132 +1,132 @@
|
|
|
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 C = require("./constants");
|
|
32
|
-
var { generateBytes } = require("./crypto");
|
|
33
|
-
|
|
34
|
-
// Canonical UUID layout: 8-4-4-4-12 hex digits, version nibble at byte
|
|
35
|
-
// 6 high-nibble, variant bits at byte 8 high two bits (must be 10).
|
|
36
|
-
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;
|
|
37
|
-
// Loose form for `isValid` shape-only check — accepts any version 1-8 and
|
|
38
|
-
// any variant top-2-bit value. Operators wanting strict version+variant
|
|
39
|
-
// gating use `parse()`.
|
|
40
|
-
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;
|
|
41
|
-
|
|
42
|
-
// RFC 4122 §4.1 byte counts and field positions. UUID is 16 bytes; the
|
|
43
|
-
// canonical hex form is 32 chars with dashes between the time-low (4 B),
|
|
44
|
-
// time-mid (2 B), time-hi+version (2 B), clock-seq+variant (2 B) and
|
|
45
|
-
// node (6 B) fields. Maximum length of the canonical form is 36 chars.
|
|
46
|
-
var UUID_BYTE_LEN = C.BYTES.bytes(16);
|
|
47
|
-
var UUID_STR_MAX_LEN = 36;
|
|
48
|
-
// Hex-string slice offsets (each pair = 1 byte); routed through C.BYTES
|
|
49
|
-
// so the framework's byte math stays in one place.
|
|
50
|
-
var HEX_TIME_LOW_END = C.BYTES.bytes(8); // chars 0..8 (bytes 0-3)
|
|
51
|
-
var HEX_TIME_MID_END = C.BYTES.bytes(12); // chars 8..12 (bytes 4-5)
|
|
52
|
-
var HEX_TIME_HI_VER_END = C.BYTES.bytes(16); // chars 12..16 (bytes 6-7)
|
|
53
|
-
var HEX_CLOCK_SEQ_END = C.BYTES.bytes(20); // chars 16..20 (bytes 8-9)
|
|
54
|
-
var HEX_NODE_END = C.BYTES.bytes(32); // chars 20..32 (bytes 10-15)
|
|
55
|
-
// Byte-index positions for version + variant manipulation. Variant
|
|
56
|
-
// index value (8) is routed through C.BYTES so every byte literal in
|
|
57
|
-
// the file routes through one helper.
|
|
58
|
-
var BYTE_VERSION_IDX = 6;
|
|
59
|
-
var BYTE_VARIANT_IDX = C.BYTES.bytes(8);
|
|
60
|
-
|
|
61
|
-
function _bytesToString(bytes) {
|
|
62
|
-
var hex = bytes.toString("hex");
|
|
63
|
-
return hex.slice(0, HEX_TIME_LOW_END) + "-" +
|
|
64
|
-
hex.slice(HEX_TIME_LOW_END, HEX_TIME_MID_END) + "-" +
|
|
65
|
-
hex.slice(HEX_TIME_MID_END, HEX_TIME_HI_VER_END) + "-" +
|
|
66
|
-
hex.slice(HEX_TIME_HI_VER_END, HEX_CLOCK_SEQ_END) + "-" +
|
|
67
|
-
hex.slice(HEX_CLOCK_SEQ_END, HEX_NODE_END);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function v4() {
|
|
71
|
-
var b = generateBytes(UUID_BYTE_LEN);
|
|
72
|
-
// version = 4 (0100): high nibble of byte 6
|
|
73
|
-
b[BYTE_VERSION_IDX] = (b[BYTE_VERSION_IDX] & 0x0f) | 0x40;
|
|
74
|
-
// variant = RFC 4122 (10xx): top two bits of byte 8
|
|
75
|
-
b[BYTE_VARIANT_IDX] = (b[BYTE_VARIANT_IDX] & 0x3f) | 0x80;
|
|
76
|
-
return _bytesToString(b);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function v7(opts) {
|
|
80
|
-
// RFC 9562 §5.7 layout:
|
|
81
|
-
// bytes 0-5 : 48-bit big-endian Unix timestamp in milliseconds
|
|
82
|
-
// bytes 6-7 : version nibble (7) + 12 bits random_a
|
|
83
|
-
// bytes 8-15 : variant bits + 62 bits random_b
|
|
84
|
-
var ms = (opts && typeof opts.now === "number") ? opts.now : Date.now();
|
|
85
|
-
var b = generateBytes(UUID_BYTE_LEN);
|
|
86
|
-
// 48-bit ms timestamp (big-endian) into bytes 0-5.
|
|
87
|
-
// ms can exceed 2^32 (we're in 2026, ms is ~1.78e12), so split via
|
|
88
|
-
// Math.floor + unsigned shift instead of relying on 32-bit bit-ops.
|
|
89
|
-
var msHi = Math.floor(ms / 0x100000000);
|
|
90
|
-
var msLo = ms >>> 0;
|
|
91
|
-
b[0] = (msHi >> 8) & 0xff;
|
|
92
|
-
b[1] = msHi & 0xff;
|
|
93
|
-
b[2] = (msLo >>> 24) & 0xff;
|
|
94
|
-
b[3] = (msLo >>> 16) & 0xff;
|
|
95
|
-
b[4] = (msLo >>> 8) & 0xff;
|
|
96
|
-
b[5] = msLo & 0xff;
|
|
97
|
-
// version = 7 (0111) in high nibble of byte 6, random_a in low nibble + byte 7
|
|
98
|
-
b[BYTE_VERSION_IDX] = (b[BYTE_VERSION_IDX] & 0x0f) | 0x70;
|
|
99
|
-
// variant = RFC 4122 (10xx) in top two bits of byte 8
|
|
100
|
-
b[BYTE_VARIANT_IDX] = (b[BYTE_VARIANT_IDX] & 0x3f) | 0x80;
|
|
101
|
-
return _bytesToString(b);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function parse(str) {
|
|
105
|
-
if (typeof str !== "string") return { ok: false, reason: "not-a-string" };
|
|
106
|
-
// Length cap before regex — RFC 4122 canonical form is exactly 36
|
|
107
|
-
// chars; capping defends the regex engine against pathological-length
|
|
108
|
-
// inputs even though UUID_RE is anchored.
|
|
109
|
-
if (str.length > UUID_STR_MAX_LEN) return { ok: false, reason: "malformed" };
|
|
110
|
-
if (!UUID_RE.test(str)) return { ok: false, reason: "malformed" };
|
|
111
|
-
var hex = str.replace(/-/g, "");
|
|
112
|
-
var bytes = Buffer.from(hex, "hex");
|
|
113
|
-
// Version is the high nibble of byte 6.
|
|
114
|
-
var version = (bytes[BYTE_VERSION_IDX] >> 4) & 0x0f;
|
|
115
|
-
// Variant: top two bits of byte 8 must be 10 for RFC 4122 / 9562.
|
|
116
|
-
var variant = (bytes[BYTE_VARIANT_IDX] >> 6) & 0x03;
|
|
117
|
-
if (variant !== 0b10) return { ok: false, reason: "bad-variant" };
|
|
118
|
-
return { ok: true, version: version, bytes: bytes };
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function isValid(str) {
|
|
122
|
-
if (typeof str !== "string") return false;
|
|
123
|
-
if (str.length > UUID_STR_MAX_LEN) return false;
|
|
124
|
-
return UUID_LOOSE_RE.test(str);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
module.exports = {
|
|
128
|
-
v4: v4,
|
|
129
|
-
v7: v7,
|
|
130
|
-
parse: parse,
|
|
131
|
-
isValid: isValid,
|
|
132
|
-
};
|
|
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 C = require("./constants");
|
|
32
|
+
var { generateBytes } = require("./crypto");
|
|
33
|
+
|
|
34
|
+
// Canonical UUID layout: 8-4-4-4-12 hex digits, version nibble at byte
|
|
35
|
+
// 6 high-nibble, variant bits at byte 8 high two bits (must be 10).
|
|
36
|
+
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;
|
|
37
|
+
// Loose form for `isValid` shape-only check — accepts any version 1-8 and
|
|
38
|
+
// any variant top-2-bit value. Operators wanting strict version+variant
|
|
39
|
+
// gating use `parse()`.
|
|
40
|
+
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;
|
|
41
|
+
|
|
42
|
+
// RFC 4122 §4.1 byte counts and field positions. UUID is 16 bytes; the
|
|
43
|
+
// canonical hex form is 32 chars with dashes between the time-low (4 B),
|
|
44
|
+
// time-mid (2 B), time-hi+version (2 B), clock-seq+variant (2 B) and
|
|
45
|
+
// node (6 B) fields. Maximum length of the canonical form is 36 chars.
|
|
46
|
+
var UUID_BYTE_LEN = C.BYTES.bytes(16);
|
|
47
|
+
var UUID_STR_MAX_LEN = 36;
|
|
48
|
+
// Hex-string slice offsets (each pair = 1 byte); routed through C.BYTES
|
|
49
|
+
// so the framework's byte math stays in one place.
|
|
50
|
+
var HEX_TIME_LOW_END = C.BYTES.bytes(8); // chars 0..8 (bytes 0-3)
|
|
51
|
+
var HEX_TIME_MID_END = C.BYTES.bytes(12); // chars 8..12 (bytes 4-5)
|
|
52
|
+
var HEX_TIME_HI_VER_END = C.BYTES.bytes(16); // chars 12..16 (bytes 6-7)
|
|
53
|
+
var HEX_CLOCK_SEQ_END = C.BYTES.bytes(20); // chars 16..20 (bytes 8-9)
|
|
54
|
+
var HEX_NODE_END = C.BYTES.bytes(32); // chars 20..32 (bytes 10-15)
|
|
55
|
+
// Byte-index positions for version + variant manipulation. Variant
|
|
56
|
+
// index value (8) is routed through C.BYTES so every byte literal in
|
|
57
|
+
// the file routes through one helper.
|
|
58
|
+
var BYTE_VERSION_IDX = 6;
|
|
59
|
+
var BYTE_VARIANT_IDX = C.BYTES.bytes(8);
|
|
60
|
+
|
|
61
|
+
function _bytesToString(bytes) {
|
|
62
|
+
var hex = bytes.toString("hex");
|
|
63
|
+
return hex.slice(0, HEX_TIME_LOW_END) + "-" +
|
|
64
|
+
hex.slice(HEX_TIME_LOW_END, HEX_TIME_MID_END) + "-" +
|
|
65
|
+
hex.slice(HEX_TIME_MID_END, HEX_TIME_HI_VER_END) + "-" +
|
|
66
|
+
hex.slice(HEX_TIME_HI_VER_END, HEX_CLOCK_SEQ_END) + "-" +
|
|
67
|
+
hex.slice(HEX_CLOCK_SEQ_END, HEX_NODE_END);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function v4() {
|
|
71
|
+
var b = generateBytes(UUID_BYTE_LEN);
|
|
72
|
+
// version = 4 (0100): high nibble of byte 6
|
|
73
|
+
b[BYTE_VERSION_IDX] = (b[BYTE_VERSION_IDX] & 0x0f) | 0x40;
|
|
74
|
+
// variant = RFC 4122 (10xx): top two bits of byte 8
|
|
75
|
+
b[BYTE_VARIANT_IDX] = (b[BYTE_VARIANT_IDX] & 0x3f) | 0x80;
|
|
76
|
+
return _bytesToString(b);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function v7(opts) {
|
|
80
|
+
// RFC 9562 §5.7 layout:
|
|
81
|
+
// bytes 0-5 : 48-bit big-endian Unix timestamp in milliseconds
|
|
82
|
+
// bytes 6-7 : version nibble (7) + 12 bits random_a
|
|
83
|
+
// bytes 8-15 : variant bits + 62 bits random_b
|
|
84
|
+
var ms = (opts && typeof opts.now === "number") ? opts.now : Date.now();
|
|
85
|
+
var b = generateBytes(UUID_BYTE_LEN);
|
|
86
|
+
// 48-bit ms timestamp (big-endian) into bytes 0-5.
|
|
87
|
+
// ms can exceed 2^32 (we're in 2026, ms is ~1.78e12), so split via
|
|
88
|
+
// Math.floor + unsigned shift instead of relying on 32-bit bit-ops.
|
|
89
|
+
var msHi = Math.floor(ms / 0x100000000);
|
|
90
|
+
var msLo = ms >>> 0;
|
|
91
|
+
b[0] = (msHi >> 8) & 0xff;
|
|
92
|
+
b[1] = msHi & 0xff;
|
|
93
|
+
b[2] = (msLo >>> 24) & 0xff;
|
|
94
|
+
b[3] = (msLo >>> 16) & 0xff;
|
|
95
|
+
b[4] = (msLo >>> 8) & 0xff;
|
|
96
|
+
b[5] = msLo & 0xff;
|
|
97
|
+
// version = 7 (0111) in high nibble of byte 6, random_a in low nibble + byte 7
|
|
98
|
+
b[BYTE_VERSION_IDX] = (b[BYTE_VERSION_IDX] & 0x0f) | 0x70;
|
|
99
|
+
// variant = RFC 4122 (10xx) in top two bits of byte 8
|
|
100
|
+
b[BYTE_VARIANT_IDX] = (b[BYTE_VARIANT_IDX] & 0x3f) | 0x80;
|
|
101
|
+
return _bytesToString(b);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function parse(str) {
|
|
105
|
+
if (typeof str !== "string") return { ok: false, reason: "not-a-string" };
|
|
106
|
+
// Length cap before regex — RFC 4122 canonical form is exactly 36
|
|
107
|
+
// chars; capping defends the regex engine against pathological-length
|
|
108
|
+
// inputs even though UUID_RE is anchored.
|
|
109
|
+
if (str.length > UUID_STR_MAX_LEN) return { ok: false, reason: "malformed" };
|
|
110
|
+
if (!UUID_RE.test(str)) return { ok: false, reason: "malformed" };
|
|
111
|
+
var hex = str.replace(/-/g, "");
|
|
112
|
+
var bytes = Buffer.from(hex, "hex");
|
|
113
|
+
// Version is the high nibble of byte 6.
|
|
114
|
+
var version = (bytes[BYTE_VERSION_IDX] >> 4) & 0x0f;
|
|
115
|
+
// Variant: top two bits of byte 8 must be 10 for RFC 4122 / 9562.
|
|
116
|
+
var variant = (bytes[BYTE_VARIANT_IDX] >> 6) & 0x03;
|
|
117
|
+
if (variant !== 0b10) return { ok: false, reason: "bad-variant" };
|
|
118
|
+
return { ok: true, version: version, bytes: bytes };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function isValid(str) {
|
|
122
|
+
if (typeof str !== "string") return false;
|
|
123
|
+
if (str.length > UUID_STR_MAX_LEN) return false;
|
|
124
|
+
return UUID_LOOSE_RE.test(str);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
module.exports = {
|
|
128
|
+
v4: v4,
|
|
129
|
+
v7: v7,
|
|
130
|
+
parse: parse,
|
|
131
|
+
isValid: isValid,
|
|
132
|
+
};
|