From d382fa8e4bafe93d4dfb409c3f9b9b45d4992cd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 12:05:29 +0000 Subject: [PATCH 1/4] deps: bump @cldmv/fix-headers from 1.3.7 to 1.3.9 in the patch group Bumps the patch group with 1 update: [@cldmv/fix-headers](https://github.com/CLDMV/fix-headers). Updates `@cldmv/fix-headers` from 1.3.7 to 1.3.9 - [Release notes](https://github.com/CLDMV/fix-headers/releases) - [Commits](https://github.com/CLDMV/fix-headers/compare/v1.3.7...v1.3.9) --- updated-dependencies: - dependency-name: "@cldmv/fix-headers" dependency-version: 1.3.9 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3c79089..bd65b4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,9 +84,9 @@ } }, "node_modules/@cldmv/fix-headers": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@cldmv/fix-headers/-/fix-headers-1.3.7.tgz", - "integrity": "sha512-n8dzZVzYb1W1RiXr4hXD3ZiEfI/r3WN8ibPZGaaKgGOYD1aT5fUBXt+wr0lpLi8aiRprzvQi55u0kafRdUip/Q==", + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/@cldmv/fix-headers/-/fix-headers-1.3.9.tgz", + "integrity": "sha512-gBosC62dn7OG3oFDM4VYrRDkeDeF7mpxvwKt/3Vs6s+76eodALh0L2AhGvytkS+bmjFwOEmaYtYR+FZbDWz7tw==", "dev": true, "license": "Apache-2.0", "dependencies": { From 2863dc1b40591d8e1d93f2a3853640825547ff48 Mon Sep 17 00:00:00 2001 From: "cldmv-bot[bot]" <230771808+cldmv-bot[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 12:07:30 +0000 Subject: [PATCH 2/4] chore: bump version to 1.1.8 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index bd65b4e..4198bff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cldmv/uuid", - "version": "1.1.7", + "version": "1.1.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@cldmv/uuid", - "version": "1.1.7", + "version": "1.1.8", "license": "Apache-2.0", "devDependencies": { "@cldmv/fix-headers": "^1.2.2", diff --git a/package.json b/package.json index 7665aae..61c8c57 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cldmv/uuid", - "version": "1.1.7", + "version": "1.1.8", "description": "Extended RFC 4122 and RFC 9562 UUID implementation with custom variant structures, issuer-based identification, and timestamp variants", "main": "./index.cjs", "module": "./index.mjs", From f9a458dbc198150302cdefa2118b1d910ce42007 Mon Sep 17 00:00:00 2001 From: Shinrai Date: Mon, 17 Aug 2026 07:11:26 -0700 Subject: [PATCH 3/4] feat(browser): make UUID generation zero-node-builtin for browser bundlers The static `import crypto from "crypto"` in uuid.mjs and every RFC/timestamp version file made the package unbundlable for browser targets (esbuild platform:"browser" fails to resolve "crypto"), and the internal Buffer-based representation would still throw ReferenceError at runtime even past that. Splits crypto/hex/hash access into isomorphic node+browser module pairs (./rng, ./bytes, ./hash) selected via the package's "browser" export condition, self-referenced from within the package. Node keeps its native Buffer/crypto-backed fast paths; the browser variants use globalThis.crypto.getRandomValues and hand-rolled MD5/SHA-1 (crypto.subtle is async, which would break v3/v5's synchronous API). The internal UUID buffer representation moves from Buffer to plain Uint8Array so it works in both runtimes. versions/timestamp/*, versions/issuer/*, and entropy-sources.mjs are dead code never imported by uuid.mjs and were left untouched. Verified against RFC 1321 (MD5) / FIPS 180-1 (SHA-1) test vectors, node:crypto cross-checks, and an actual headless-Chromium run confirming zero Buffer/ node:crypto references and correct output (including the standard v3/v5 DNS namespace vectors). Fixes #21 --- package.json | 24 +++ src/lib/bit-utils.mjs | 34 ++-- src/lib/bytes-browser.mjs | 68 +++++++ src/lib/bytes.mjs | 46 +++++ src/lib/hash-browser.mjs | 217 +++++++++++++++++++++++ src/lib/hash.mjs | 39 ++++ src/lib/rng-browser.mjs | 28 +++ src/lib/rng.mjs | 27 +++ src/lib/validators.mjs | 28 +-- src/lib/versions/rfc/v1.mjs | 12 +- src/lib/versions/rfc/v35.mjs | 14 +- src/lib/versions/rfc/v4.mjs | 6 +- src/lib/versions/rfc/v6.mjs | 12 +- src/lib/versions/rfc/v7.mjs | 4 +- src/lib/versions/rfc/v8.mjs | 4 +- src/uuid.mjs | 47 ++--- tests/browser-modules.test.vitest.mjs | 127 +++++++++++++ tests/validators.test.vitest.mjs | 8 +- types/index.d.mts | 33 ++-- types/src/lib/bit-utils.d.mts | 62 +++---- types/src/lib/bit-utils.d.mts.map | 2 +- types/src/lib/bytes-browser.d.mts | 20 +++ types/src/lib/bytes-browser.d.mts.map | 1 + types/src/lib/bytes.d.mts | 37 ++++ types/src/lib/bytes.d.mts.map | 1 + types/src/lib/constants.d.mts | 6 +- types/src/lib/hash-browser.d.mts | 15 ++ types/src/lib/hash-browser.d.mts.map | 1 + types/src/lib/hash.d.mts | 15 ++ types/src/lib/hash.d.mts.map | 1 + types/src/lib/rng-browser.d.mts | 22 +++ types/src/lib/rng-browser.d.mts.map | 1 + types/src/lib/rng.d.mts | 7 + types/src/lib/rng.d.mts.map | 1 + types/src/lib/validators.d.mts | 22 +-- types/src/lib/validators.d.mts.map | 2 +- types/src/lib/versions/rfc/v1.d.mts.map | 2 +- types/src/lib/versions/rfc/v35.d.mts.map | 2 +- types/src/lib/versions/rfc/v6.d.mts.map | 2 +- types/src/uuid.d.mts | 48 ++--- types/src/uuid.d.mts.map | 2 +- 41 files changed, 874 insertions(+), 176 deletions(-) create mode 100644 src/lib/bytes-browser.mjs create mode 100644 src/lib/bytes.mjs create mode 100644 src/lib/hash-browser.mjs create mode 100644 src/lib/hash.mjs create mode 100644 src/lib/rng-browser.mjs create mode 100644 src/lib/rng.mjs create mode 100644 tests/browser-modules.test.vitest.mjs create mode 100644 types/src/lib/bytes-browser.d.mts create mode 100644 types/src/lib/bytes-browser.d.mts.map create mode 100644 types/src/lib/bytes.d.mts create mode 100644 types/src/lib/bytes.d.mts.map create mode 100644 types/src/lib/hash-browser.d.mts create mode 100644 types/src/lib/hash-browser.d.mts.map create mode 100644 types/src/lib/hash.d.mts create mode 100644 types/src/lib/hash.d.mts.map create mode 100644 types/src/lib/rng-browser.d.mts create mode 100644 types/src/lib/rng-browser.d.mts.map create mode 100644 types/src/lib/rng.d.mts create mode 100644 types/src/lib/rng.d.mts.map diff --git a/package.json b/package.json index 61c8c57..fc3f8e1 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,30 @@ }, "import": "./dist/uuid.mjs" }, + "./rng": { + "uuid-dev": { + "browser": "./src/lib/rng-browser.mjs", + "import": "./src/lib/rng.mjs" + }, + "browser": "./dist/lib/rng-browser.mjs", + "import": "./dist/lib/rng.mjs" + }, + "./bytes": { + "uuid-dev": { + "browser": "./src/lib/bytes-browser.mjs", + "import": "./src/lib/bytes.mjs" + }, + "browser": "./dist/lib/bytes-browser.mjs", + "import": "./dist/lib/bytes.mjs" + }, + "./hash": { + "uuid-dev": { + "browser": "./src/lib/hash-browser.mjs", + "import": "./src/lib/hash.mjs" + }, + "browser": "./dist/lib/hash-browser.mjs", + "import": "./dist/lib/hash.mjs" + }, "./package.json": "./package.json" }, "type": "module", diff --git a/src/lib/bit-utils.mjs b/src/lib/bit-utils.mjs index 9f767e4..2f773bd 100644 --- a/src/lib/bit-utils.mjs +++ b/src/lib/bit-utils.mjs @@ -24,7 +24,7 @@ export class BitUtils { /** * Set specific bits in a buffer - * @param {Buffer} buffer - Target buffer + * @param {Uint8Array} buffer - Target buffer * @param {number} startBit - Starting bit position (0-based) * @param {number} bitCount - Number of bits to set * @param {number|BigInt} value - Value to set @@ -58,7 +58,7 @@ export class BitUtils { /** * Get specific bits from a buffer - * @param {Buffer} buffer - Source buffer + * @param {Uint8Array} buffer - Source buffer * @param {number} startBit - Starting bit position (0-based) * @param {number} bitCount - Number of bits to get * @returns {BigInt} The extracted value as BigInt @@ -82,7 +82,7 @@ export class BitUtils { /** * Get specific bits from a buffer as a regular number (for values <= 32 bits) - * @param {Buffer} buffer - Source buffer + * @param {Uint8Array} buffer - Source buffer * @param {number} startBit - Starting bit position (0-based) * @param {number} bitCount - Number of bits to get (max 32) * @returns {number} The extracted value as number @@ -96,7 +96,7 @@ export class BitUtils { /** * Clear specific bits in a buffer - * @param {Buffer} buffer - Target buffer + * @param {Uint8Array} buffer - Target buffer * @param {number} startBit - Starting bit position (0-based) * @param {number} bitCount - Number of bits to clear */ @@ -106,7 +106,7 @@ export class BitUtils { /** * Toggle specific bits in a buffer - * @param {Buffer} buffer - Target buffer + * @param {Uint8Array} buffer - Target buffer * @param {number} startBit - Starting bit position (0-based) * @param {number} bitCount - Number of bits to toggle */ @@ -123,11 +123,11 @@ export class BitUtils { * Create a bit mask for specific bit positions * @param {number} totalBits - Total number of bits in the mask * @param {Array} bitPositions - Array of bit positions to set - * @returns {Buffer} Buffer containing the bit mask + * @returns {Uint8Array} Buffer containing the bit mask */ static createBitMask(totalBits, bitPositions) { const byteCount = Math.ceil(totalBits / 8); - const mask = Buffer.alloc(byteCount, 0); + const mask = new Uint8Array(byteCount); for (const bitPos of bitPositions) { if (bitPos < 0 || bitPos >= totalBits) { @@ -144,8 +144,8 @@ export class BitUtils { /** * Apply a bit mask to a buffer (AND operation) - * @param {Buffer} buffer - Target buffer to modify - * @param {Buffer} mask - Bit mask to apply + * @param {Uint8Array} buffer - Target buffer to modify + * @param {Uint8Array} mask - Bit mask to apply */ static applyMask(buffer, mask) { if (buffer.length !== mask.length) { @@ -159,8 +159,8 @@ export class BitUtils { /** * Apply an inverted bit mask to a buffer (clear masked bits) - * @param {Buffer} buffer - Target buffer to modify - * @param {Buffer} mask - Bit mask to invert and apply + * @param {Uint8Array} buffer - Target buffer to modify + * @param {Uint8Array} mask - Bit mask to invert and apply */ static applyInvertedMask(buffer, mask) { if (buffer.length !== mask.length) { @@ -174,7 +174,7 @@ export class BitUtils { /** * Count the number of set bits in a buffer - * @param {Buffer} buffer - Buffer to count bits in + * @param {Uint8Array} buffer - Buffer to count bits in * @returns {number} Number of set bits */ static countSetBits(buffer) { @@ -191,7 +191,7 @@ export class BitUtils { /** * Convert a buffer to a binary string representation - * @param {Buffer} buffer - Buffer to convert + * @param {Uint8Array} buffer - Buffer to convert * @param {boolean} includeSeparators - Whether to include byte separators * @returns {string} Binary string representation */ @@ -207,7 +207,7 @@ export class BitUtils { * Convert a binary string to a buffer * @param {string} binaryString - Binary string (without separators) * @param {number} byteCount - Expected number of bytes - * @returns {Buffer} Resulting buffer + * @returns {Uint8Array} Resulting buffer */ static fromBinaryString(binaryString, byteCount) { const cleanBinary = binaryString.replace(/\s/g, ""); // Remove any spaces @@ -216,7 +216,7 @@ export class BitUtils { throw new Error(`Binary string length ${cleanBinary.length} doesn't match expected ${byteCount * 8} bits`); } - const buffer = Buffer.alloc(byteCount); + const buffer = new Uint8Array(byteCount); for (let i = 0; i < byteCount; i++) { const byteString = cleanBinary.slice(i * 8, (i + 1) * 8); buffer[i] = parseInt(byteString, 2); @@ -227,7 +227,7 @@ export class BitUtils { /** * Validate that a bit position is within valid range for a buffer - * @param {Buffer} buffer - Buffer to validate against + * @param {Uint8Array} buffer - Buffer to validate against * @param {number} bitPosition - Bit position to validate * @throws {Error} If bit position is invalid */ @@ -240,7 +240,7 @@ export class BitUtils { /** * Get a human-readable representation of specific bit fields - * @param {Buffer} buffer - Buffer to analyze + * @param {Uint8Array} buffer - Buffer to analyze * @param {Object} fieldDefinitions - Object mapping field names to {start, length} definitions * @returns {Object} Object with field names as keys and their values */ diff --git a/src/lib/bytes-browser.mjs b/src/lib/bytes-browser.mjs new file mode 100644 index 0000000..2a14280 --- /dev/null +++ b/src/lib/bytes-browser.mjs @@ -0,0 +1,68 @@ +/** + * @Project: @cldmv/slothlet + * @Filename: /src/lib/bytes-browser.mjs + * @Date: 2026-08-17T00:00:00-08:00 (0) + * @Author: Nate Corcoran + * @Email: + * ----- + * @Last modified by: Nate Corcoran (Shinrai@users.noreply.github.com) + * @Last modified time: 2026-08-17T00:00:00-08:00 (0) + * ----- + * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. + */ + +/** + * Browser hex/byte helpers (selected via the "browser" export condition on ./bytes). + * Pure Uint8Array implementation, no Node Buffer. + * + * Note: unlike Node's Buffer.from(hex, "hex") (which silently stops at the first + * invalid hex character), fromHex() here throws on malformed input. This is a + * deliberate, safety-improving divergence for the browser path only — it never + * changes Node's existing behavior. + */ + +const HEX_CHARS = "0123456789abcdef"; + +/** + * Parse a hex string into bytes. + * @param {string} hex - Hex string (no separators) + * @returns {Uint8Array} Parsed bytes + */ +export function fromHex(hex) { + if (hex.length % 2 !== 0) { + throw new TypeError("Invalid hex string length"); + } + + const out = new Uint8Array(hex.length / 2); + for (let i = 0; i < out.length; i++) { + const byte = parseInt(hex.substr(i * 2, 2), 16); + if (Number.isNaN(byte)) { + throw new TypeError("Invalid hex string"); + } + out[i] = byte; + } + return out; +} + +/** + * Encode bytes as a lowercase hex string. + * @param {Uint8Array} bytes - Bytes to encode + * @returns {string} Hex string + */ +export function toHex(bytes) { + let hex = ""; + for (let i = 0; i < bytes.length; i++) { + hex += HEX_CHARS[(bytes[i] >> 4) & 0xf] + HEX_CHARS[bytes[i] & 0xf]; + } + return hex; +} + +/** + * Return a copy of `bytes` as the runtime's native Buffer-like type. + * There is no Buffer in the browser, so this is a plain Uint8Array copy. + * @param {Uint8Array} bytes - Bytes to wrap + * @returns {Uint8Array} Copy of the bytes + */ +export function toBufferLike(bytes) { + return Uint8Array.from(bytes); +} diff --git a/src/lib/bytes.mjs b/src/lib/bytes.mjs new file mode 100644 index 0000000..f458fb9 --- /dev/null +++ b/src/lib/bytes.mjs @@ -0,0 +1,46 @@ +/** + * @Project: @cldmv/slothlet + * @Filename: /src/lib/bytes.mjs + * @Date: 2026-08-17T00:00:00-08:00 (0) + * @Author: Nate Corcoran + * @Email: + * ----- + * @Last modified by: Nate Corcoran (Shinrai@users.noreply.github.com) + * @Last modified time: 2026-08-17T00:00:00-08:00 (0) + * ----- + * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. + */ + +/** + * Node hex/byte helpers (selected via the "browser" export condition on ./bytes). + * Backed by Node's native Buffer for speed; accepts either a Buffer or a plain + * Uint8Array as input since internal UUID buffers are plain Uint8Array. + */ + +/** + * Parse a hex string into bytes. + * @param {string} hex - Hex string (no separators) + * @returns {Uint8Array} Parsed bytes + */ +export function fromHex(hex) { + return Buffer.from(hex, "hex"); +} + +/** + * Encode bytes as a lowercase hex string. + * @param {Uint8Array} bytes - Bytes to encode + * @returns {string} Hex string + */ +export function toHex(bytes) { + return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("hex"); +} + +/** + * Return a copy of `bytes` as the runtime's native Buffer-like type. + * In Node this is a real Buffer (preserves the pre-existing toBuffer() contract). + * @param {Uint8Array} bytes - Bytes to wrap + * @returns {Buffer} Copy of the bytes as a Buffer + */ +export function toBufferLike(bytes) { + return Buffer.from(bytes); +} diff --git a/src/lib/hash-browser.mjs b/src/lib/hash-browser.mjs new file mode 100644 index 0000000..61b1bb0 --- /dev/null +++ b/src/lib/hash-browser.mjs @@ -0,0 +1,217 @@ +/** + * @Project: @cldmv/slothlet + * @Filename: /src/lib/hash-browser.mjs + * @Date: 2026-08-17T00:00:00-08:00 (0) + * @Author: Nate Corcoran + * @Email: + * ----- + * @Last modified by: Nate Corcoran (Shinrai@users.noreply.github.com) + * @Last modified time: 2026-08-17T00:00:00-08:00 (0) + * ----- + * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. + */ + +/** + * Browser MD5 / SHA-1 (RFC 1321 / FIPS 180-1) + * + * Pure-JS, synchronous digests for UUID v3/v5 namespace hashing in environments + * without Node's `crypto` module. `crypto.subtle.digest` is async and can't + * replace this without breaking the synchronous v3()/v5() API. MD5/SHA-1 are + * used here only as RFC 4122's specified namespace-hash functions, not for + * anything security-sensitive. + */ + +const TEXT_ENCODER = new TextEncoder(); + +/** + * Concatenate namespace bytes with the UTF-8 encoding of `name`. + * @param {Uint8Array} namespaceBytes - 16-byte namespace UUID + * @param {string} name - Name to hash + * @returns {Uint8Array} Combined message + */ +function concatMessage(namespaceBytes, name) { + const nameBytes = TEXT_ENCODER.encode(name); + const combined = new Uint8Array(namespaceBytes.length + nameBytes.length); + combined.set(namespaceBytes, 0); + combined.set(nameBytes, namespaceBytes.length); + return combined; +} + +/** + * Pad a message per the MD5/SHA-1 shared Merkle-Damgard scheme (both use the + * same padding: 0x80, zeros, then a 64-bit length field). + * @param {Uint8Array} message - Message to pad + * @param {boolean} lengthBigEndian - true for SHA-1 (big-endian length), false for MD5 (little-endian length) + * @returns {Uint8Array} Padded message, a multiple of 64 bytes + */ +function padMessage(message, lengthBigEndian) { + const msgLen = message.length; + const withOne = msgLen + 1; + const padLen = (56 - (withOne % 64) + 64) % 64; + const totalLen = withOne + padLen + 8; + const padded = new Uint8Array(totalLen); + padded.set(message, 0); + padded[msgLen] = 0x80; + + const bitLen = BigInt(msgLen) * 8n; + const view = new DataView(padded.buffer); + if (lengthBigEndian) { + view.setBigUint64(totalLen - 8, bitLen, false); + } else { + view.setBigUint64(totalLen - 8, bitLen, true); + } + + return padded; +} + +function rotl32(x, n) { + return ((x << n) | (x >>> (32 - n))) >>> 0; +} + +// MD5 per-round shift amounts (RFC 1321 Section 3.4) +const MD5_SHIFTS = [ + 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, + 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 +]; + +// MD5 per-round additive constants: K[i] = floor(abs(sin(i + 1)) * 2^32) (RFC 1321 Section 3.4) +const MD5_K = new Uint32Array(64); +for (let i = 0; i < 64; i++) { + MD5_K[i] = Math.floor(Math.abs(Math.sin(i + 1)) * 4294967296) >>> 0; +} + +/** + * Compute an MD5 digest (RFC 1321). + * @param {Uint8Array} namespaceBytes - Namespace UUID bytes + * @param {string} name - Name to hash + * @returns {Uint8Array} 16-byte digest + */ +export function md5(namespaceBytes, name) { + const padded = padMessage(concatMessage(namespaceBytes, name), false); + const view = new DataView(padded.buffer); + + let a0 = 0x67452301; + let b0 = 0xefcdab89; + let c0 = 0x98badcfe; + let d0 = 0x10325476; + + const M = new Uint32Array(16); + for (let chunkStart = 0; chunkStart < padded.length; chunkStart += 64) { + for (let i = 0; i < 16; i++) { + M[i] = view.getUint32(chunkStart + i * 4, true); + } + + let a = a0; + let b = b0; + let c = c0; + let d = d0; + + for (let i = 0; i < 64; i++) { + let f, g; + if (i < 16) { + f = (b & c) | (~b & d); + g = i; + } else if (i < 32) { + f = (d & b) | (~d & c); + g = (5 * i + 1) % 16; + } else if (i < 48) { + f = b ^ c ^ d; + g = (3 * i + 5) % 16; + } else { + f = c ^ (b | ~d); + g = (7 * i) % 16; + } + + f = (f + a + MD5_K[i] + M[g]) >>> 0; + a = d; + d = c; + c = b; + b = (b + rotl32(f, MD5_SHIFTS[i])) >>> 0; + } + + a0 = (a0 + a) >>> 0; + b0 = (b0 + b) >>> 0; + c0 = (c0 + c) >>> 0; + d0 = (d0 + d) >>> 0; + } + + const digest = new Uint8Array(16); + const digestView = new DataView(digest.buffer); + digestView.setUint32(0, a0, true); + digestView.setUint32(4, b0, true); + digestView.setUint32(8, c0, true); + digestView.setUint32(12, d0, true); + return digest; +} + +/** + * Compute a SHA-1 digest (FIPS 180-1 / RFC 3174). + * @param {Uint8Array} namespaceBytes - Namespace UUID bytes + * @param {string} name - Name to hash + * @returns {Uint8Array} 20-byte digest + */ +export function sha1(namespaceBytes, name) { + const padded = padMessage(concatMessage(namespaceBytes, name), true); + const view = new DataView(padded.buffer); + + let h0 = 0x67452301; + let h1 = 0xefcdab89; + let h2 = 0x98badcfe; + let h3 = 0x10325476; + let h4 = 0xc3d2e1f0; + + const w = new Uint32Array(80); + for (let chunkStart = 0; chunkStart < padded.length; chunkStart += 64) { + for (let i = 0; i < 16; i++) { + w[i] = view.getUint32(chunkStart + i * 4, false); + } + for (let i = 16; i < 80; i++) { + w[i] = rotl32(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1); + } + + let a = h0; + let b = h1; + let c = h2; + let d = h3; + let e = h4; + + for (let i = 0; i < 80; i++) { + let f, k; + if (i < 20) { + f = (b & c) | (~b & d); + k = 0x5a827999; + } else if (i < 40) { + f = b ^ c ^ d; + k = 0x6ed9eba1; + } else if (i < 60) { + f = (b & c) | (b & d) | (c & d); + k = 0x8f1bbcdc; + } else { + f = b ^ c ^ d; + k = 0xca62c1d6; + } + + const temp = (rotl32(a, 5) + f + e + k + w[i]) >>> 0; + e = d; + d = c; + c = rotl32(b, 30); + b = a; + a = temp; + } + + h0 = (h0 + a) >>> 0; + h1 = (h1 + b) >>> 0; + h2 = (h2 + c) >>> 0; + h3 = (h3 + d) >>> 0; + h4 = (h4 + e) >>> 0; + } + + const digest = new Uint8Array(20); + const digestView = new DataView(digest.buffer); + digestView.setUint32(0, h0, false); + digestView.setUint32(4, h1, false); + digestView.setUint32(8, h2, false); + digestView.setUint32(12, h3, false); + digestView.setUint32(16, h4, false); + return digest; +} diff --git a/src/lib/hash.mjs b/src/lib/hash.mjs new file mode 100644 index 0000000..a7be3fb --- /dev/null +++ b/src/lib/hash.mjs @@ -0,0 +1,39 @@ +/** + * @Project: @cldmv/slothlet + * @Filename: /src/lib/hash.mjs + * @Date: 2026-08-17T00:00:00-08:00 (0) + * @Author: Nate Corcoran + * @Email: + * ----- + * @Last modified by: Nate Corcoran (Shinrai@users.noreply.github.com) + * @Last modified time: 2026-08-17T00:00:00-08:00 (0) + * ----- + * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. + */ + +/** + * Node MD5/SHA-1 (selected via the "browser" export condition on ./hash). + * Used only for RFC 4122 v3/v5 namespace hashing, not for anything security-sensitive. + */ + +import crypto from "crypto"; + +/** + * Compute an MD5 digest of namespaceBytes || utf8(name). + * @param {Uint8Array} namespaceBytes - Namespace UUID bytes + * @param {string} name - Name to hash + * @returns {Uint8Array} 16-byte digest + */ +export function md5(namespaceBytes, name) { + return crypto.createHash("md5").update(namespaceBytes).update(name, "utf8").digest(); +} + +/** + * Compute a SHA-1 digest of namespaceBytes || utf8(name). + * @param {Uint8Array} namespaceBytes - Namespace UUID bytes + * @param {string} name - Name to hash + * @returns {Uint8Array} 20-byte digest + */ +export function sha1(namespaceBytes, name) { + return crypto.createHash("sha1").update(namespaceBytes).update(name, "utf8").digest(); +} diff --git a/src/lib/rng-browser.mjs b/src/lib/rng-browser.mjs new file mode 100644 index 0000000..8309112 --- /dev/null +++ b/src/lib/rng-browser.mjs @@ -0,0 +1,28 @@ +/** + * @Project: @cldmv/slothlet + * @Filename: /src/lib/rng-browser.mjs + * @Date: 2026-08-17T00:00:00-08:00 (0) + * @Author: Nate Corcoran + * @Email: + * ----- + * @Last modified by: Nate Corcoran (Shinrai@users.noreply.github.com) + * @Last modified time: 2026-08-17T00:00:00-08:00 (0) + * ----- + * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. + */ + +/** + * Browser entropy source (selected via the "browser" export condition on ./rng) + */ + +/** + * Generate cryptographically secure random bytes via the Web Crypto API. + * @param {number} byteCount - Number of bytes to generate + * @returns {Uint8Array} Random bytes + */ +export function randomBytes(byteCount) { + if (typeof globalThis.crypto?.getRandomValues !== "function") { + throw new Error("No secure random source available: globalThis.crypto.getRandomValues is missing."); + } + return globalThis.crypto.getRandomValues(new Uint8Array(byteCount)); +} diff --git a/src/lib/rng.mjs b/src/lib/rng.mjs new file mode 100644 index 0000000..93e6671 --- /dev/null +++ b/src/lib/rng.mjs @@ -0,0 +1,27 @@ +/** + * @Project: @cldmv/slothlet + * @Filename: /src/lib/rng.mjs + * @Date: 2026-08-17T00:00:00-08:00 (0) + * @Author: Nate Corcoran + * @Email: + * ----- + * @Last modified by: Nate Corcoran (Shinrai@users.noreply.github.com) + * @Last modified time: 2026-08-17T00:00:00-08:00 (0) + * ----- + * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. + */ + +/** + * Node entropy source (selected via the "browser" export condition on ./rng) + */ + +import crypto from "crypto"; + +/** + * Generate cryptographically secure random bytes. + * @param {number} byteCount - Number of bytes to generate + * @returns {Uint8Array} Random bytes (a Node Buffer, which is a Uint8Array) + */ +export function randomBytes(byteCount) { + return crypto.randomBytes(byteCount); +} diff --git a/src/lib/validators.mjs b/src/lib/validators.mjs index 92d2bec..425fea1 100644 --- a/src/lib/validators.mjs +++ b/src/lib/validators.mjs @@ -20,6 +20,7 @@ import { VARIANT_BITS, SUBVARIANT_TIMESTAMP, SUBVARIANT_ISSUER, ISSUER_CATEGORIES, ISSUER_ID_MASK } from "./constants.mjs"; import { BitUtils } from "./bit-utils.mjs"; +import { toHex } from "@cldmv/uuid/bytes"; /** * Validator class for UUID specification compliance @@ -27,11 +28,11 @@ import { BitUtils } from "./bit-utils.mjs"; class UUIDValidator { /** * Validate complete UUID compliance with custom specification - * @param {Buffer} uuidBuffer - 16-byte UUID buffer + * @param {Uint8Array} uuidBuffer - 16-byte UUID buffer * @returns {Object} Validation results */ static validateCompleteUUID(uuidBuffer) { - if (!Buffer.isBuffer(uuidBuffer) || uuidBuffer.length !== 16) { + if (!(uuidBuffer instanceof Uint8Array) || uuidBuffer.length !== 16) { throw new Error("UUID must be a 16-byte buffer"); } @@ -65,7 +66,7 @@ class UUIDValidator { /** * Validate UUID specific fields - * @param {Buffer} uuidBuffer - UUID buffer + * @param {Uint8Array} uuidBuffer - UUID buffer * @param {Object} results - Results object to populate * @private */ @@ -109,7 +110,7 @@ class UUIDValidator { /** * Validate issuer variant specific requirements - * @param {Buffer} uuidBuffer - UUID buffer + * @param {Uint8Array} uuidBuffer - UUID buffer * @param {Object} results - Results object to populate * @private */ @@ -140,7 +141,7 @@ class UUIDValidator { /** * Validate timestamp variant specific requirements - * @param {Buffer} uuidBuffer - UUID buffer + * @param {Uint8Array} uuidBuffer - UUID buffer * @param {Object} results - Results object to populate * @private */ @@ -193,7 +194,7 @@ class UUIDValidator { /** * Validate bit layout compliance - * @param {Buffer} uuidBuffer - UUID buffer + * @param {Uint8Array} uuidBuffer - UUID buffer * @returns {Object} Bit layout validation results */ static validateBitLayout(uuidBuffer) { @@ -248,7 +249,7 @@ class UUIDValidator { /** * Validate entropy distribution in non-immutable fields - * @param {Buffer} uuidBuffer - UUID buffer + * @param {Uint8Array} uuidBuffer - UUID buffer * @returns {Object} Entropy validation results */ static validateEntropy(uuidBuffer) { @@ -260,7 +261,7 @@ class UUIDValidator { }; // Create mask for immutable fields - const immutableMask = Buffer.alloc(16, 0); + const immutableMask = new Uint8Array(16); // Mark immutable bits (these should not contribute to entropy analysis) const immutableFields = [ @@ -280,7 +281,7 @@ class UUIDValidator { } // Extract entropy bits (non-immutable bits) - const entropyBuffer = Buffer.from(uuidBuffer); + const entropyBuffer = new Uint8Array(uuidBuffer); for (let i = 0; i < 16; i++) { entropyBuffer[i] &= ~immutableMask[i]; // Clear immutable bits } @@ -371,16 +372,15 @@ class UUIDValidator { /** * Generate a comprehensive validation report - * @param {Buffer} uuidBuffer - UUID buffer to validate + * @param {Uint8Array} uuidBuffer - UUID buffer to validate * @returns {Object} Comprehensive validation report */ static generateValidationReport(uuidBuffer) { + const hex = toHex(uuidBuffer); const report = { timestamp: new Date(), - uuid: uuidBuffer.toString("hex"), - uuidString: `${uuidBuffer.toString("hex").slice(0, 8)}-${uuidBuffer.toString("hex").slice(8, 12)}-${uuidBuffer - .toString("hex") - .slice(12, 16)}-${uuidBuffer.toString("hex").slice(16, 20)}-${uuidBuffer.toString("hex").slice(20, 32)}`, + uuid: hex, + uuidString: `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`, overallValid: true, sections: {} }; diff --git a/src/lib/versions/rfc/v1.mjs b/src/lib/versions/rfc/v1.mjs index 1403b63..ba635ea 100644 --- a/src/lib/versions/rfc/v1.mjs +++ b/src/lib/versions/rfc/v1.mjs @@ -17,7 +17,7 @@ * Generates UUIDs based on timestamp and node (MAC address) information. */ -import crypto from "crypto"; +import { randomBytes } from "@cldmv/uuid/rng"; import { stringify } from "./utils.mjs"; /** @@ -62,14 +62,20 @@ export function v1(options = {}) { buf[offset + 7] = ((ticks / 0x10000000000) >>> 0) & 0xff; // clock_seq_hi_and_reserved (8 bits) - const clockseq = options.clockseq !== undefined ? options.clockseq : (crypto.randomBytes(2).readUInt16BE(0) & 0x3fff) | 0; + let clockseq; + if (options.clockseq !== undefined) { + clockseq = options.clockseq; + } else { + const clockseqBytes = randomBytes(2); + clockseq = (((clockseqBytes[0] << 8) | clockseqBytes[1]) & 0x3fff) | 0; + } buf[offset + 8] = ((clockseq >>> 8) | 0x80) & 0xff; // variant 10 // clock_seq_low (8 bits) buf[offset + 9] = clockseq & 0xff; // node (48 bits) - const node = options.node || crypto.randomBytes(6); + const node = options.node || randomBytes(6); for (let i = 0; i < 6; i++) { buf[offset + 10 + i] = node[i]; } diff --git a/src/lib/versions/rfc/v35.mjs b/src/lib/versions/rfc/v35.mjs index 24ad895..941fed3 100644 --- a/src/lib/versions/rfc/v35.mjs +++ b/src/lib/versions/rfc/v35.mjs @@ -18,7 +18,7 @@ * Version 5: SHA-1-based namespace UUID */ -import crypto from "crypto"; +import { md5, sha1 } from "@cldmv/uuid/hash"; import { parse, stringify } from "./utils.mjs"; /** @@ -26,13 +26,13 @@ import { parse, stringify } from "./utils.mjs"; * @param {string} name - Name to hash * @param {string|Uint8Array} namespace - Namespace UUID * @param {number} versionByte - Version byte (0x30 for v3, 0x50 for v5) - * @param {Object} hasher - Crypto hash instance + * @param {Function} hashFn - Isomorphic hash function (md5 or sha1), signature (namespaceBytes, name) * @param {Uint8Array} buf - Optional buffer to write into * @param {number} offset - Optional offset in buffer * @returns {string|Uint8Array} UUID string or buffer * @private */ -function _v35(name, namespace, versionByte, hasher, buf, offset) { +function _v35(name, namespace, versionByte, hashFn, buf, offset) { const _buf = buf || new Uint8Array(16); const _offset = offset || 0; @@ -45,9 +45,7 @@ function _v35(name, namespace, versionByte, hasher, buf, offset) { } // Hash namespace + name - hasher.update(Buffer.from(namespaceBytes)); - hasher.update(name, "utf8"); - const hash = hasher.digest(); + const hash = hashFn(namespaceBytes, name); // Copy first 16 bytes of hash to buffer for (let i = 0; i < 16; i++) { @@ -72,7 +70,7 @@ function _v35(name, namespace, versionByte, hasher, buf, offset) { * @returns {string|Uint8Array} UUID string or buffer */ export function v3(name, namespace, buf, offset) { - return _v35(name, namespace, 0x30, crypto.createHash("md5"), buf, offset); + return _v35(name, namespace, 0x30, md5, buf, offset); } /** @@ -84,5 +82,5 @@ export function v3(name, namespace, buf, offset) { * @returns {string|Uint8Array} UUID string or buffer */ export function v5(name, namespace, buf, offset) { - return _v35(name, namespace, 0x50, crypto.createHash("sha1"), buf, offset); + return _v35(name, namespace, 0x50, sha1, buf, offset); } diff --git a/src/lib/versions/rfc/v4.mjs b/src/lib/versions/rfc/v4.mjs index f3fc63b..84f8e10 100644 --- a/src/lib/versions/rfc/v4.mjs +++ b/src/lib/versions/rfc/v4.mjs @@ -17,7 +17,7 @@ * Generates UUIDs from random or pseudo-random numbers. */ -import crypto from "crypto"; +import { randomBytes } from "@cldmv/uuid/rng"; import { stringify } from "./utils.mjs"; /** @@ -32,9 +32,9 @@ export function v4(options = {}) { const buf = options.buf || new Uint8Array(16); const offset = options.offset || 0; - const randomBytes = options.random || crypto.randomBytes(16); + const randomValues = options.random || randomBytes(16); for (let i = 0; i < 16; i++) { - buf[offset + i] = randomBytes[i]; + buf[offset + i] = randomValues[i]; } // Set version (4 bits in byte 6) diff --git a/src/lib/versions/rfc/v6.mjs b/src/lib/versions/rfc/v6.mjs index 6cdfd00..95fb9b5 100644 --- a/src/lib/versions/rfc/v6.mjs +++ b/src/lib/versions/rfc/v6.mjs @@ -18,7 +18,7 @@ * This is a reordered version of UUID v1 for better database indexing. */ -import crypto from "crypto"; +import { randomBytes } from "@cldmv/uuid/rng"; import { stringify } from "./utils.mjs"; /** @@ -61,11 +61,17 @@ export function v6(options = {}) { buf[offset + 7] = ticks & 0xff; // clock_seq and node (same as v1) - const clockseq = options.clockseq !== undefined ? options.clockseq : (crypto.randomBytes(2).readUInt16BE(0) & 0x3fff) | 0; + let clockseq; + if (options.clockseq !== undefined) { + clockseq = options.clockseq; + } else { + const clockseqBytes = randomBytes(2); + clockseq = (((clockseqBytes[0] << 8) | clockseqBytes[1]) & 0x3fff) | 0; + } buf[offset + 8] = ((clockseq >>> 8) | 0x80) & 0xff; buf[offset + 9] = clockseq & 0xff; - const node = options.node || crypto.randomBytes(6); + const node = options.node || randomBytes(6); for (let i = 0; i < 6; i++) { buf[offset + 10 + i] = node[i]; } diff --git a/src/lib/versions/rfc/v7.mjs b/src/lib/versions/rfc/v7.mjs index 0e5b099..99abab0 100644 --- a/src/lib/versions/rfc/v7.mjs +++ b/src/lib/versions/rfc/v7.mjs @@ -18,7 +18,7 @@ * Optimized for database indexing and distributed systems. */ -import crypto from "crypto"; +import { randomBytes } from "@cldmv/uuid/rng"; import { stringify } from "./utils.mjs"; /** @@ -44,7 +44,7 @@ export function v7(options = {}) { buf[offset + 5] = msecs & 0xff; // ver (4 bits) + rand_a (12 bits) - const randBytes = crypto.randomBytes(10); + const randBytes = randomBytes(10); buf[offset + 6] = (randBytes[0] & 0x0f) | 0x70; // version 7 buf[offset + 7] = randBytes[1]; diff --git a/src/lib/versions/rfc/v8.mjs b/src/lib/versions/rfc/v8.mjs index 2be5c4b..a3007a9 100644 --- a/src/lib/versions/rfc/v8.mjs +++ b/src/lib/versions/rfc/v8.mjs @@ -19,7 +19,7 @@ * correctly; all other bits can be filled with custom data. */ -import crypto from "crypto"; +import { randomBytes } from "@cldmv/uuid/rng"; import { stringify } from "./utils.mjs"; /** @@ -43,7 +43,7 @@ export function v8(options = {}) { const offset = options.offset || 0; // Use custom data if provided, otherwise random - const data = options.data || crypto.randomBytes(16); + const data = options.data || randomBytes(16); // Copy data to buffer for (let i = 0; i < 16; i++) { diff --git a/src/uuid.mjs b/src/uuid.mjs index 370c4d2..2626ea6 100644 --- a/src/uuid.mjs +++ b/src/uuid.mjs @@ -24,7 +24,8 @@ * - issuer ID (bits 79-88): 10-bit issuer identification (Issuer Variant only) */ -import crypto from "crypto"; +import { randomBytes } from "@cldmv/uuid/rng"; +import { toHex, fromHex, toBufferLike } from "@cldmv/uuid/bytes"; import { BitUtils } from "./lib/bit-utils.mjs"; import { VARIANT_BITS, @@ -47,10 +48,10 @@ import * as rfcUuids from "./lib/versions/rfc/index.mjs"; class UUID { /** * Create a new UUID instance - * @param {Buffer|string|null} data - Optional UUID data to parse + * @param {Uint8Array|string|null} data - Optional UUID data to parse */ constructor(data = null) { - this._buffer = Buffer.alloc(16); + this._buffer = new Uint8Array(16); if (data !== null && data !== undefined) { this._parseFromData(data); @@ -59,7 +60,7 @@ class UUID { /** * Parse UUID from existing data - * @param {Buffer|string} data - UUID data to parse + * @param {Uint8Array|string} data - UUID data to parse * @private */ _parseFromData(data) { @@ -69,12 +70,12 @@ class UUID { if (hex.length !== 32) { throw new Error("Invalid UUID string length"); } - this._buffer = Buffer.from(hex, "hex"); - } else if (Buffer.isBuffer(data)) { + this._buffer = fromHex(hex); + } else if (data instanceof Uint8Array) { if (data.length !== 16) { throw new Error("Invalid UUID buffer length"); } - this._buffer = Buffer.from(data); + this._buffer = new Uint8Array(data); } else { throw new Error("Invalid UUID data type"); } @@ -84,7 +85,7 @@ class UUID { * Create a new Issuer Variant UUID * @param {number} issuerID - Issuer ID (0-ISSUER_ID_MASK) * @param {number} version - Version number - * @param {Buffer} entropy - Additional entropy data + * @param {Uint8Array} entropy - Additional entropy data * @returns {UUID} New UUID instance */ static createIssuerVariant(issuerID, version, entropy = null) { @@ -109,7 +110,7 @@ class UUID { // Fill remaining bits with entropy if (!entropy) { - entropy = crypto.randomBytes(16); + entropy = randomBytes(16); } uuid._fillEntropy(entropy); @@ -120,7 +121,7 @@ class UUID { * Create a new Timestamp Variant UUID * @param {number|Date} timestamp - Timestamp value (optional, defaults to Date.now()) * @param {number} version - Version number - * @param {Buffer} entropy - Optional entropy for bits 79-127 + * @param {Uint8Array} entropy - Optional entropy for bits 79-127 * @returns {UUID} New UUID instance */ static createTimestampVariant(timestamp, version, entropy = null) { @@ -160,7 +161,7 @@ class UUID { // Fill entropy bits (79-127) if provided, or generate random entropy if (!entropy) { - entropy = crypto.randomBytes(16); + entropy = randomBytes(16); } // Copy entropy starting from bit 79 (byte 9, bit 7) @@ -189,7 +190,7 @@ class UUID { * Create an issuer-based UUID (short name alias) * @param {number} issuerID - Issuer ID (0-1023) * @param {number} version - Version number - * @param {Buffer} entropy - Additional entropy data + * @param {Uint8Array} entropy - Additional entropy data * @returns {UUID} New UUID instance */ static issuer(issuerID, version, entropy = null) { @@ -200,7 +201,7 @@ class UUID { * Create a timestamp-based UUID (short name alias) * @param {number|Date} timestamp - Timestamp value (optional, defaults to Date.now()) * @param {number} version - Version number - * @param {Buffer} entropy - Optional entropy for bits 79-127 + * @param {Uint8Array} entropy - Optional entropy for bits 79-127 * @returns {UUID} New UUID instance */ static timestamp(timestamp, version, entropy = null) { @@ -211,7 +212,7 @@ class UUID { * Create Timestamp Variant v1 UUID (ultra-short alias) * Subvariant 00 - Timestamp-based identification (seconds precision) * @param {number|Date} timestamp - Timestamp value (optional, defaults to Date.now()) - * @param {Buffer} entropy - Optional entropy for bits 79-127 + * @param {Uint8Array} entropy - Optional entropy for bits 79-127 * @returns {UUID} New UUID instance */ static TA(timestamp, entropy = null) { @@ -222,7 +223,7 @@ class UUID { * Create Issuer Variant v1 UUID (ultra-short alias) * Subvariant 01 - Issuer-based identification * @param {number} issuerID - Issuer ID (0-1023) - * @param {Buffer} entropy - Additional entropy data + * @param {Uint8Array} entropy - Additional entropy data * @returns {UUID} New UUID instance */ static IA(issuerID, entropy = null) { @@ -233,7 +234,7 @@ class UUID { * Create Timestamp Variant v2 UUID (ultra-short alias) * Subvariant 00 - Timestamp-based identification (milliseconds precision) * @param {number|Date} timestamp - Timestamp value (optional, defaults to Date.now()) - * @param {Buffer} entropy - Optional entropy for bits 79-127 + * @param {Uint8Array} entropy - Optional entropy for bits 79-127 * @returns {UUID} New UUID instance */ static TB(timestamp, entropy = null) { @@ -283,7 +284,7 @@ class UUID { /** * Fill remaining bits with entropy while preserving immutable fields - * @param {Buffer} entropy - Entropy data + * @param {Uint8Array} entropy - Entropy data * @private */ _fillEntropy(entropy) { @@ -294,7 +295,7 @@ class UUID { const issuerID = this.getIssuerID(); // Apply entropy to entire buffer - entropy.copy(this._buffer); + this._buffer.set(entropy); // Restore immutable fields with saved values this._setVariant(variant); @@ -523,16 +524,16 @@ class UUID { * @returns {string} UUID string with dashes */ toString() { - const hex = this._buffer.toString("hex"); + const hex = toHex(this._buffer); return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`; } /** * Convert UUID to buffer - * @returns {Buffer} UUID as 16-byte buffer + * @returns {Buffer} UUID as 16-byte buffer (Node); a Uint8Array copy in environments without Buffer */ toBuffer() { - return Buffer.from(this._buffer); + return toBufferLike(this._buffer); } /** @@ -648,7 +649,7 @@ class UUID { /** * Validate a UUID buffer for specification compliance - * @param {Buffer} buffer - UUID buffer to validate + * @param {Uint8Array} buffer - UUID buffer to validate * @returns {Promise} Validation results */ static async validate(buffer) { @@ -658,7 +659,7 @@ class UUID { /** * Generate a complete validation report for a UUID - * @param {Buffer} buffer - UUID buffer to validate + * @param {Uint8Array} buffer - UUID buffer to validate * @returns {Promise} Detailed validation report */ static async validateDetailed(buffer) { diff --git a/tests/browser-modules.test.vitest.mjs b/tests/browser-modules.test.vitest.mjs new file mode 100644 index 0000000..7267704 --- /dev/null +++ b/tests/browser-modules.test.vitest.mjs @@ -0,0 +1,127 @@ +/** + * @Project: @cldmv/uuid + * @Filename: /tests/browser-modules.test.vitest.mjs + * @Date: 2026-08-17T00:00:00-08:00 (0) + * @Author: Nate Corcoran + * @Email: + * ----- + * @Last modified by: Nate Corcoran (Shinrai@users.noreply.github.com) + * @Last modified time: 2026-08-17T00:00:00-08:00 (0) + * ----- + * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. + */ + +/** + * Vitest Test Suite for the browser-variant isomorphic modules (rng-browser, + * bytes-browser, hash-browser). These are only reached at runtime via the + * "browser" export condition, which Node's test run never sets, so they're + * imported here directly by relative path to get real coverage of the logic. + * See https://github.com/CLDMV/uuid/issues/22 for actually running them in a + * real browser end-to-end. + */ + +import { describe, test, expect } from "vitest"; +import crypto from "crypto"; +import { randomBytes as randomBytesBrowser } from "../src/lib/rng-browser.mjs"; +import { fromHex as fromHexBrowser, toHex as toHexBrowser, toBufferLike as toBufferLikeBrowser } from "../src/lib/bytes-browser.mjs"; +import { fromHex as fromHexNode, toHex as toHexNode } from "../src/lib/bytes.mjs"; +import { md5 as md5Browser, sha1 as sha1Browser } from "../src/lib/hash-browser.mjs"; +import { md5 as md5Node, sha1 as sha1Node } from "../src/lib/hash.mjs"; + +describe("rng-browser", () => { + test("returns a Uint8Array of the requested length", () => { + const bytes = randomBytesBrowser(16); + expect(bytes).toBeInstanceOf(Uint8Array); + expect(bytes.length).toBe(16); + }); + + test("returns different values across calls (not deterministic)", () => { + const a = randomBytesBrowser(16); + const b = randomBytesBrowser(16); + expect(Array.from(a)).not.toEqual(Array.from(b)); + }); + + test("throws a clear error when globalThis.crypto.getRandomValues is unavailable", () => { + const original = globalThis.crypto; + // eslint-disable-next-line no-undef + Object.defineProperty(globalThis, "crypto", { value: undefined, configurable: true }); + try { + expect(() => randomBytesBrowser(16)).toThrow(/getRandomValues/); + } finally { + Object.defineProperty(globalThis, "crypto", { value: original, configurable: true }); + } + }); +}); + +describe("bytes-browser", () => { + test("fromHex/toHex round-trip matches the Node implementation", () => { + const samples = ["", "00", "ff", "6ba7b8109dad11d180b400c04fd430c8", "0123456789abcdef"]; + for (const hex of samples) { + const browserBytes = fromHexBrowser(hex); + const nodeBytes = fromHexNode(hex); + expect(Array.from(browserBytes)).toEqual(Array.from(nodeBytes)); + expect(toHexBrowser(browserBytes)).toBe(hex); + expect(toHexBrowser(browserBytes)).toBe(toHexNode(nodeBytes)); + } + }); + + test("fromHex throws on odd-length input", () => { + expect(() => fromHexBrowser("abc")).toThrow(TypeError); + }); + + test("fromHex throws on non-hex characters", () => { + expect(() => fromHexBrowser("zz")).toThrow(TypeError); + }); + + test("toBufferLike returns a Uint8Array copy, not a view", () => { + const source = new Uint8Array([1, 2, 3]); + const copy = toBufferLikeBrowser(source); + expect(Array.from(copy)).toEqual([1, 2, 3]); + copy[0] = 99; + expect(source[0]).toBe(1); + }); +}); + +describe("hash-browser", () => { + // Vectors generated from node:crypto directly (not hand-transcribed) to rule out transcription error. + const md5Vectors = [ + ["", "d41d8cd98f00b204e9800998ecf8427e"], + ["abc", "900150983cd24fb0d6963f7d28e17f72"], + ["message digest", "f96b697d7cb7938d525a2f31aaf161d0"], + ["abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b"] + ]; + + const sha1Vectors = [ + ["", "da39a3ee5e6b4b0d3255bfef95601890afd80709"], + ["abc", "a9993e364706816aba3e25717850c26c9cd0d89d"], + ["abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "84983e441c3bd26ebaae4aa1f95129e5e54670f1"] + ]; + + const empty = new Uint8Array(0); + + test.each(md5Vectors)("md5 matches RFC 1321 vector for %j", (input, expected) => { + expect(toHexBrowser(md5Browser(empty, input))).toBe(expected); + }); + + test.each(sha1Vectors)("sha1 matches FIPS 180-1 vector for %j", (input, expected) => { + expect(toHexBrowser(sha1Browser(empty, input))).toBe(expected); + }); + + test("md5/sha1 match node:crypto across varied and multi-block inputs", () => { + const inputs = ["", "a", "hello world", "x".repeat(1000), "The quick brown fox jumps over the lazy dog"]; + for (const input of inputs) { + const nodeMd5 = crypto.createHash("md5").update(input, "utf8").digest("hex"); + const nodeSha1 = crypto.createHash("sha1").update(input, "utf8").digest("hex"); + expect(toHexBrowser(md5Browser(empty, input))).toBe(nodeMd5); + expect(toHexBrowser(sha1Browser(empty, input))).toBe(nodeSha1); + } + }); + + test("matches the Node hash.mjs implementation given a real namespace", () => { + // RFC 4122 DNS namespace UUID + const ns = fromHexNode("6ba7b8109dad11d180b400c04fd430c8"); + const name = "www.example.com"; + expect(toHexBrowser(md5Browser(ns, name))).toBe(toHexNode(md5Node(ns, name))); + expect(toHexBrowser(sha1Browser(ns, name))).toBe(toHexNode(sha1Node(ns, name))); + }); +}); diff --git a/tests/validators.test.vitest.mjs b/tests/validators.test.vitest.mjs index 4906b40..fa6f8dc 100644 --- a/tests/validators.test.vitest.mjs +++ b/tests/validators.test.vitest.mjs @@ -389,10 +389,12 @@ describe("UUIDValidator", () => { }); test("should skip entropy balance analysis when no mutable bits are available", () => { - const originalAlloc = Buffer.alloc; - const allocSpy = vi.spyOn(Buffer, "alloc").mockImplementation((size) => originalAlloc(size, 0xff)); + const RealUint8Array = Uint8Array; + const allocSpy = vi.spyOn(globalThis, "Uint8Array").mockImplementation(function (arg) { + return new RealUint8Array(arg).fill(0xff); + }); - const result = UUIDValidator.validateEntropy(Buffer.alloc(16, 0)); + const result = UUIDValidator.validateEntropy(new RealUint8Array(16)); expect(result.analysis.bitBalance).toBeUndefined(); expect(result.warnings.includes("All entropy bits are zero")).toBe(false); expect(result.warnings.includes("All entropy bits are one")).toBe(false); diff --git a/types/index.d.mts b/types/index.d.mts index 949ae6f..5189d85 100644 --- a/types/index.d.mts +++ b/types/index.d.mts @@ -1,28 +1,15 @@ -/** - * @Project: @cldmv/uuid - * @Filename: /types/index.d.mts - * @Date: 2026-03-04 21:19:55 -08:00 (1772687995) - * @Author: Nate Corcoran - * @Email: - * ----- - * @Last modified by: Nate Corcoran (Shinrai@users.noreply.github.com) - * @Last modified time: 2026-03-04 21:19:57 -08:00 (1772687997) - * ----- - * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. - */ - export default UUID; export const UUID: typeof import("@cldmv/uuid/main").UUID; export const ISSUER_CATEGORIES: { - UNASSIGNED: number; - DRAFTER_RESERVED: number; - CATEGORY_A_START: number; - CATEGORY_A_END: number; - CATEGORY_B_START: number; - CATEGORY_B_END: number; - SPEC_ORIGINATOR: number; - RFC_EXPANSION_START: number; - RFC_EXPANSION_END: number; + UNASSIGNED: number; + DRAFTER_RESERVED: number; + CATEGORY_A_START: number; + CATEGORY_A_END: number; + CATEGORY_B_START: number; + CATEGORY_B_END: number; + SPEC_ORIGINATOR: number; + RFC_EXPANSION_START: number; + RFC_EXPANSION_END: number; }; export { UUID as uuid }; -//# sourceMappingURL=index.d.mts.map +//# sourceMappingURL=index.d.mts.map \ No newline at end of file diff --git a/types/src/lib/bit-utils.d.mts b/types/src/lib/bit-utils.d.mts index dabf64b..1bcc874 100644 --- a/types/src/lib/bit-utils.d.mts +++ b/types/src/lib/bit-utils.d.mts @@ -1,12 +1,12 @@ /** - * @Project: @cldmv/slothlet + * @Project: @cldmv/uuid * @Filename: /src/lib/bit-utils.mjs * @Date: 2025-12-15T20:33:49-08:00 (1765859629) * @Author: Nate Corcoran * @Email: * ----- - * @Last modified by: Nate Corcoran (Shinrai@users.noreply.github.com) - * @Last modified time: 2026-03-04 21:03:43 -08:00 (1772687023) + * @Last modified by: Shinrai (Shinrai@users.noreply.github.com) + * @Last modified time: 2026-08-08 17:13:20 -07:00 (1786234400) * ----- * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. */ @@ -22,94 +22,94 @@ export class BitUtils { /** * Set specific bits in a buffer - * @param {Buffer} buffer - Target buffer + * @param {Uint8Array} buffer - Target buffer * @param {number} startBit - Starting bit position (0-based) * @param {number} bitCount - Number of bits to set * @param {number|BigInt} value - Value to set */ - static setBits(buffer: Buffer, startBit: number, bitCount: number, value: number | bigint): void; + static setBits(buffer: Uint8Array, startBit: number, bitCount: number, value: number | bigint): void; /** * Get specific bits from a buffer - * @param {Buffer} buffer - Source buffer + * @param {Uint8Array} buffer - Source buffer * @param {number} startBit - Starting bit position (0-based) * @param {number} bitCount - Number of bits to get * @returns {BigInt} The extracted value as BigInt */ - static getBits(buffer: Buffer, startBit: number, bitCount: number): bigint; + static getBits(buffer: Uint8Array, startBit: number, bitCount: number): bigint; /** * Get specific bits from a buffer as a regular number (for values <= 32 bits) - * @param {Buffer} buffer - Source buffer + * @param {Uint8Array} buffer - Source buffer * @param {number} startBit - Starting bit position (0-based) * @param {number} bitCount - Number of bits to get (max 32) * @returns {number} The extracted value as number */ - static getBitsAsNumber(buffer: Buffer, startBit: number, bitCount: number): number; + static getBitsAsNumber(buffer: Uint8Array, startBit: number, bitCount: number): number; /** * Clear specific bits in a buffer - * @param {Buffer} buffer - Target buffer + * @param {Uint8Array} buffer - Target buffer * @param {number} startBit - Starting bit position (0-based) * @param {number} bitCount - Number of bits to clear */ - static clearBits(buffer: Buffer, startBit: number, bitCount: number): void; + static clearBits(buffer: Uint8Array, startBit: number, bitCount: number): void; /** * Toggle specific bits in a buffer - * @param {Buffer} buffer - Target buffer + * @param {Uint8Array} buffer - Target buffer * @param {number} startBit - Starting bit position (0-based) * @param {number} bitCount - Number of bits to toggle */ - static toggleBits(buffer: Buffer, startBit: number, bitCount: number): void; + static toggleBits(buffer: Uint8Array, startBit: number, bitCount: number): void; /** * Create a bit mask for specific bit positions * @param {number} totalBits - Total number of bits in the mask * @param {Array} bitPositions - Array of bit positions to set - * @returns {Buffer} Buffer containing the bit mask + * @returns {Uint8Array} Buffer containing the bit mask */ - static createBitMask(totalBits: number, bitPositions: Array): Buffer; + static createBitMask(totalBits: number, bitPositions: Array): Uint8Array; /** * Apply a bit mask to a buffer (AND operation) - * @param {Buffer} buffer - Target buffer to modify - * @param {Buffer} mask - Bit mask to apply + * @param {Uint8Array} buffer - Target buffer to modify + * @param {Uint8Array} mask - Bit mask to apply */ - static applyMask(buffer: Buffer, mask: Buffer): void; + static applyMask(buffer: Uint8Array, mask: Uint8Array): void; /** * Apply an inverted bit mask to a buffer (clear masked bits) - * @param {Buffer} buffer - Target buffer to modify - * @param {Buffer} mask - Bit mask to invert and apply + * @param {Uint8Array} buffer - Target buffer to modify + * @param {Uint8Array} mask - Bit mask to invert and apply */ - static applyInvertedMask(buffer: Buffer, mask: Buffer): void; + static applyInvertedMask(buffer: Uint8Array, mask: Uint8Array): void; /** * Count the number of set bits in a buffer - * @param {Buffer} buffer - Buffer to count bits in + * @param {Uint8Array} buffer - Buffer to count bits in * @returns {number} Number of set bits */ - static countSetBits(buffer: Buffer): number; + static countSetBits(buffer: Uint8Array): number; /** * Convert a buffer to a binary string representation - * @param {Buffer} buffer - Buffer to convert + * @param {Uint8Array} buffer - Buffer to convert * @param {boolean} includeSeparators - Whether to include byte separators * @returns {string} Binary string representation */ - static toBinaryString(buffer: Buffer, includeSeparators?: boolean): string; + static toBinaryString(buffer: Uint8Array, includeSeparators?: boolean): string; /** * Convert a binary string to a buffer * @param {string} binaryString - Binary string (without separators) * @param {number} byteCount - Expected number of bytes - * @returns {Buffer} Resulting buffer + * @returns {Uint8Array} Resulting buffer */ - static fromBinaryString(binaryString: string, byteCount: number): Buffer; + static fromBinaryString(binaryString: string, byteCount: number): Uint8Array; /** * Validate that a bit position is within valid range for a buffer - * @param {Buffer} buffer - Buffer to validate against + * @param {Uint8Array} buffer - Buffer to validate against * @param {number} bitPosition - Bit position to validate * @throws {Error} If bit position is invalid */ - static validateBitPosition(buffer: Buffer, bitPosition: number): void; + static validateBitPosition(buffer: Uint8Array, bitPosition: number): void; /** * Get a human-readable representation of specific bit fields - * @param {Buffer} buffer - Buffer to analyze + * @param {Uint8Array} buffer - Buffer to analyze * @param {Object} fieldDefinitions - Object mapping field names to {start, length} definitions * @returns {Object} Object with field names as keys and their values */ - static getFieldValues(buffer: Buffer, fieldDefinitions: any): any; + static getFieldValues(buffer: Uint8Array, fieldDefinitions: any): any; } //# sourceMappingURL=bit-utils.d.mts.map \ No newline at end of file diff --git a/types/src/lib/bit-utils.d.mts.map b/types/src/lib/bit-utils.d.mts.map index 0bc72bf..e5b7307 100644 --- a/types/src/lib/bit-utils.d.mts.map +++ b/types/src/lib/bit-utils.d.mts.map @@ -1 +1 @@ -{"version":3,"file":"bit-utils.d.mts","sourceRoot":"","sources":["../../../src/lib/bit-utils.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;GAKG;AAEH;;GAEG;AACH;IACC;;;;;;OAMG;IACH,uBALW,MAAM,YACN,MAAM,YACN,MAAM,SACN,MAAM,SAAO,QA2BvB;IAED;;;;;;OAMG;IACH,uBALW,MAAM,YACN,MAAM,YACN,MAAM,UAkBhB;IAED;;;;;;OAMG;IACH,+BALW,MAAM,YACN,MAAM,YACN,MAAM,GACJ,MAAM,CAOlB;IAED;;;;;OAKG;IACH,yBAJW,MAAM,YACN,MAAM,YACN,MAAM,QAIhB;IAED;;;;;OAKG;IACH,0BAJW,MAAM,YACN,MAAM,YACN,MAAM,QAShB;IAED;;;;;OAKG;IACH,gCAJW,MAAM,gBACN,KAAK,CAAC,MAAM,CAAC,GACX,MAAM,CAiBlB;IAED;;;;OAIG;IACH,yBAHW,MAAM,QACN,MAAM,QAUhB;IAED;;;;OAIG;IACH,iCAHW,MAAM,QACN,MAAM,QAUhB;IAED;;;;OAIG;IACH,4BAHW,MAAM,GACJ,MAAM,CAYlB;IAED;;;;;OAKG;IACH,8BAJW,MAAM,sBACN,OAAO,GACL,MAAM,CAQlB;IAED;;;;;OAKG;IACH,sCAJW,MAAM,aACN,MAAM,GACJ,MAAM,CAgBlB;IAED;;;;;OAKG;IACH,mCAJW,MAAM,eACN,MAAM,QAQhB;IAED;;;;;OAKG;IACH,8BAJW,MAAM,8BAahB;CACD"} \ No newline at end of file +{"version":3,"file":"bit-utils.d.mts","sourceRoot":"","sources":["../../../src/lib/bit-utils.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;GAKG;AAEH;;GAEG;AACH;IACC;;;;;;OAMG;IACH,uBALW,UAAU,YACV,MAAM,YACN,MAAM,SACN,MAAM,SAAO,QA2BvB;IAED;;;;;;OAMG;IACH,uBALW,UAAU,YACV,MAAM,YACN,MAAM,UAkBhB;IAED;;;;;;OAMG;IACH,+BALW,UAAU,YACV,MAAM,YACN,MAAM,GACJ,MAAM,CAOlB;IAED;;;;;OAKG;IACH,yBAJW,UAAU,YACV,MAAM,YACN,MAAM,QAIhB;IAED;;;;;OAKG;IACH,0BAJW,UAAU,YACV,MAAM,YACN,MAAM,QAShB;IAED;;;;;OAKG;IACH,gCAJW,MAAM,gBACN,KAAK,CAAC,MAAM,CAAC,GACX,UAAU,CAiBtB;IAED;;;;OAIG;IACH,yBAHW,UAAU,QACV,UAAU,QAUpB;IAED;;;;OAIG;IACH,iCAHW,UAAU,QACV,UAAU,QAUpB;IAED;;;;OAIG;IACH,4BAHW,UAAU,GACR,MAAM,CAYlB;IAED;;;;;OAKG;IACH,8BAJW,UAAU,sBACV,OAAO,GACL,MAAM,CAQlB;IAED;;;;;OAKG;IACH,sCAJW,MAAM,aACN,MAAM,GACJ,UAAU,CAgBtB;IAED;;;;;OAKG;IACH,mCAJW,UAAU,eACV,MAAM,QAQhB;IAED;;;;;OAKG;IACH,8BAJW,UAAU,8BAapB;CACD"} \ No newline at end of file diff --git a/types/src/lib/bytes-browser.d.mts b/types/src/lib/bytes-browser.d.mts new file mode 100644 index 0000000..2f73e1d --- /dev/null +++ b/types/src/lib/bytes-browser.d.mts @@ -0,0 +1,20 @@ +/** + * Parse a hex string into bytes. + * @param {string} hex - Hex string (no separators) + * @returns {Uint8Array} Parsed bytes + */ +export function fromHex(hex: string): Uint8Array; +/** + * Encode bytes as a lowercase hex string. + * @param {Uint8Array} bytes - Bytes to encode + * @returns {string} Hex string + */ +export function toHex(bytes: Uint8Array): string; +/** + * Return a copy of `bytes` as the runtime's native Buffer-like type. + * There is no Buffer in the browser, so this is a plain Uint8Array copy. + * @param {Uint8Array} bytes - Bytes to wrap + * @returns {Uint8Array} Copy of the bytes + */ +export function toBufferLike(bytes: Uint8Array): Uint8Array; +//# sourceMappingURL=bytes-browser.d.mts.map \ No newline at end of file diff --git a/types/src/lib/bytes-browser.d.mts.map b/types/src/lib/bytes-browser.d.mts.map new file mode 100644 index 0000000..57a651f --- /dev/null +++ b/types/src/lib/bytes-browser.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"bytes-browser.d.mts","sourceRoot":"","sources":["../../../src/lib/bytes-browser.mjs"],"names":[],"mappings":"AAyBA;;;;GAIG;AACH,6BAHW,MAAM,GACJ,UAAU,CAgBtB;AAED;;;;GAIG;AACH,6BAHW,UAAU,GACR,MAAM,CAQlB;AAED;;;;;GAKG;AACH,oCAHW,UAAU,GACR,UAAU,CAItB"} \ No newline at end of file diff --git a/types/src/lib/bytes.d.mts b/types/src/lib/bytes.d.mts new file mode 100644 index 0000000..78b9f65 --- /dev/null +++ b/types/src/lib/bytes.d.mts @@ -0,0 +1,37 @@ +/** + * @Project: @cldmv/slothlet + * @Filename: /src/lib/bytes.mjs + * @Date: 2026-08-17T00:00:00-08:00 (0) + * @Author: Nate Corcoran + * @Email: + * ----- + * @Last modified by: Nate Corcoran (Shinrai@users.noreply.github.com) + * @Last modified time: 2026-08-17T00:00:00-08:00 (0) + * ----- + * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. + */ +/** + * Node hex/byte helpers (selected via the "browser" export condition on ./bytes). + * Backed by Node's native Buffer for speed; accepts either a Buffer or a plain + * Uint8Array as input since internal UUID buffers are plain Uint8Array. + */ +/** + * Parse a hex string into bytes. + * @param {string} hex - Hex string (no separators) + * @returns {Uint8Array} Parsed bytes + */ +export function fromHex(hex: string): Uint8Array; +/** + * Encode bytes as a lowercase hex string. + * @param {Uint8Array} bytes - Bytes to encode + * @returns {string} Hex string + */ +export function toHex(bytes: Uint8Array): string; +/** + * Return a copy of `bytes` as the runtime's native Buffer-like type. + * In Node this is a real Buffer (preserves the pre-existing toBuffer() contract). + * @param {Uint8Array} bytes - Bytes to wrap + * @returns {Buffer} Copy of the bytes as a Buffer + */ +export function toBufferLike(bytes: Uint8Array): Buffer; +//# sourceMappingURL=bytes.d.mts.map \ No newline at end of file diff --git a/types/src/lib/bytes.d.mts.map b/types/src/lib/bytes.d.mts.map new file mode 100644 index 0000000..5e7beb6 --- /dev/null +++ b/types/src/lib/bytes.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"bytes.d.mts","sourceRoot":"","sources":["../../../src/lib/bytes.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;GAIG;AAEH;;;;GAIG;AACH,6BAHW,MAAM,GACJ,UAAU,CAItB;AAED;;;;GAIG;AACH,6BAHW,UAAU,GACR,MAAM,CAIlB;AAED;;;;;GAKG;AACH,oCAHW,UAAU,GACR,MAAM,CAIlB"} \ No newline at end of file diff --git a/types/src/lib/constants.d.mts b/types/src/lib/constants.d.mts index 7f6c447..ee59b69 100644 --- a/types/src/lib/constants.d.mts +++ b/types/src/lib/constants.d.mts @@ -1,12 +1,12 @@ /** - * @Project: @cldmv/slothlet + * @Project: @cldmv/uuid * @Filename: /src/lib/constants.mjs * @Date: 2025-12-15T20:33:49-08:00 (1765859629) * @Author: Nate Corcoran * @Email: * ----- - * @Last modified by: Nate Corcoran (Shinrai@users.noreply.github.com) - * @Last modified time: 2026-03-04 21:03:43 -08:00 (1772687023) + * @Last modified by: Shinrai (Shinrai@users.noreply.github.com) + * @Last modified time: 2026-08-08 17:13:20 -07:00 (1786234400) * ----- * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. */ diff --git a/types/src/lib/hash-browser.d.mts b/types/src/lib/hash-browser.d.mts new file mode 100644 index 0000000..346487b --- /dev/null +++ b/types/src/lib/hash-browser.d.mts @@ -0,0 +1,15 @@ +/** + * Compute an MD5 digest (RFC 1321). + * @param {Uint8Array} namespaceBytes - Namespace UUID bytes + * @param {string} name - Name to hash + * @returns {Uint8Array} 16-byte digest + */ +export function md5(namespaceBytes: Uint8Array, name: string): Uint8Array; +/** + * Compute a SHA-1 digest (FIPS 180-1 / RFC 3174). + * @param {Uint8Array} namespaceBytes - Namespace UUID bytes + * @param {string} name - Name to hash + * @returns {Uint8Array} 20-byte digest + */ +export function sha1(namespaceBytes: Uint8Array, name: string): Uint8Array; +//# sourceMappingURL=hash-browser.d.mts.map \ No newline at end of file diff --git a/types/src/lib/hash-browser.d.mts.map b/types/src/lib/hash-browser.d.mts.map new file mode 100644 index 0000000..b091f09 --- /dev/null +++ b/types/src/lib/hash-browser.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"hash-browser.d.mts","sourceRoot":"","sources":["../../../src/lib/hash-browser.mjs"],"names":[],"mappings":"AAkFA;;;;;GAKG;AACH,oCAJW,UAAU,QACV,MAAM,GACJ,UAAU,CA0DtB;AAED;;;;;GAKG;AACH,qCAJW,UAAU,QACV,MAAM,GACJ,UAAU,CAkEtB"} \ No newline at end of file diff --git a/types/src/lib/hash.d.mts b/types/src/lib/hash.d.mts new file mode 100644 index 0000000..95949a1 --- /dev/null +++ b/types/src/lib/hash.d.mts @@ -0,0 +1,15 @@ +/** + * Compute an MD5 digest of namespaceBytes || utf8(name). + * @param {Uint8Array} namespaceBytes - Namespace UUID bytes + * @param {string} name - Name to hash + * @returns {Uint8Array} 16-byte digest + */ +export function md5(namespaceBytes: Uint8Array, name: string): Uint8Array; +/** + * Compute a SHA-1 digest of namespaceBytes || utf8(name). + * @param {Uint8Array} namespaceBytes - Namespace UUID bytes + * @param {string} name - Name to hash + * @returns {Uint8Array} 20-byte digest + */ +export function sha1(namespaceBytes: Uint8Array, name: string): Uint8Array; +//# sourceMappingURL=hash.d.mts.map \ No newline at end of file diff --git a/types/src/lib/hash.d.mts.map b/types/src/lib/hash.d.mts.map new file mode 100644 index 0000000..80cf3c3 --- /dev/null +++ b/types/src/lib/hash.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"hash.d.mts","sourceRoot":"","sources":["../../../src/lib/hash.mjs"],"names":[],"mappings":"AAoBA;;;;;GAKG;AACH,oCAJW,UAAU,QACV,MAAM,GACJ,UAAU,CAItB;AAED;;;;;GAKG;AACH,qCAJW,UAAU,QACV,MAAM,GACJ,UAAU,CAItB"} \ No newline at end of file diff --git a/types/src/lib/rng-browser.d.mts b/types/src/lib/rng-browser.d.mts new file mode 100644 index 0000000..638f035 --- /dev/null +++ b/types/src/lib/rng-browser.d.mts @@ -0,0 +1,22 @@ +/** + * @Project: @cldmv/slothlet + * @Filename: /src/lib/rng-browser.mjs + * @Date: 2026-08-17T00:00:00-08:00 (0) + * @Author: Nate Corcoran + * @Email: + * ----- + * @Last modified by: Nate Corcoran (Shinrai@users.noreply.github.com) + * @Last modified time: 2026-08-17T00:00:00-08:00 (0) + * ----- + * @Copyright: Copyright (c) 2013-2026 Catalyzed Motivation Inc. All rights reserved. + */ +/** + * Browser entropy source (selected via the "browser" export condition on ./rng) + */ +/** + * Generate cryptographically secure random bytes via the Web Crypto API. + * @param {number} byteCount - Number of bytes to generate + * @returns {Uint8Array} Random bytes + */ +export function randomBytes(byteCount: number): Uint8Array; +//# sourceMappingURL=rng-browser.d.mts.map \ No newline at end of file diff --git a/types/src/lib/rng-browser.d.mts.map b/types/src/lib/rng-browser.d.mts.map new file mode 100644 index 0000000..a925135 --- /dev/null +++ b/types/src/lib/rng-browser.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"rng-browser.d.mts","sourceRoot":"","sources":["../../../src/lib/rng-browser.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;GAEG;AAEH;;;;GAIG;AACH,uCAHW,MAAM,GACJ,UAAU,CAOtB"} \ No newline at end of file diff --git a/types/src/lib/rng.d.mts b/types/src/lib/rng.d.mts new file mode 100644 index 0000000..3e8179b --- /dev/null +++ b/types/src/lib/rng.d.mts @@ -0,0 +1,7 @@ +/** + * Generate cryptographically secure random bytes. + * @param {number} byteCount - Number of bytes to generate + * @returns {Uint8Array} Random bytes (a Node Buffer, which is a Uint8Array) + */ +export function randomBytes(byteCount: number): Uint8Array; +//# sourceMappingURL=rng.d.mts.map \ No newline at end of file diff --git a/types/src/lib/rng.d.mts.map b/types/src/lib/rng.d.mts.map new file mode 100644 index 0000000..e64509c --- /dev/null +++ b/types/src/lib/rng.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"rng.d.mts","sourceRoot":"","sources":["../../../src/lib/rng.mjs"],"names":[],"mappings":"AAmBA;;;;GAIG;AACH,uCAHW,MAAM,GACJ,UAAU,CAItB"} \ No newline at end of file diff --git a/types/src/lib/validators.d.mts b/types/src/lib/validators.d.mts index 9b97918..e6c10af 100644 --- a/types/src/lib/validators.d.mts +++ b/types/src/lib/validators.d.mts @@ -4,43 +4,43 @@ export class UUIDValidator { /** * Validate complete UUID compliance with custom specification - * @param {Buffer} uuidBuffer - 16-byte UUID buffer + * @param {Uint8Array} uuidBuffer - 16-byte UUID buffer * @returns {Object} Validation results */ - static validateCompleteUUID(uuidBuffer: Buffer): any; + static validateCompleteUUID(uuidBuffer: Uint8Array): any; /** * Validate UUID specific fields - * @param {Buffer} uuidBuffer - UUID buffer + * @param {Uint8Array} uuidBuffer - UUID buffer * @param {Object} results - Results object to populate * @private */ private static _validateUUIDFields; /** * Validate issuer variant specific requirements - * @param {Buffer} uuidBuffer - UUID buffer + * @param {Uint8Array} uuidBuffer - UUID buffer * @param {Object} results - Results object to populate * @private */ private static _validateIssuerVariant; /** * Validate timestamp variant specific requirements - * @param {Buffer} uuidBuffer - UUID buffer + * @param {Uint8Array} uuidBuffer - UUID buffer * @param {Object} results - Results object to populate * @private */ private static _validateTimestampVariant; /** * Validate bit layout compliance - * @param {Buffer} uuidBuffer - UUID buffer + * @param {Uint8Array} uuidBuffer - UUID buffer * @returns {Object} Bit layout validation results */ - static validateBitLayout(uuidBuffer: Buffer): any; + static validateBitLayout(uuidBuffer: Uint8Array): any; /** * Validate entropy distribution in non-immutable fields - * @param {Buffer} uuidBuffer - UUID buffer + * @param {Uint8Array} uuidBuffer - UUID buffer * @returns {Object} Entropy validation results */ - static validateEntropy(uuidBuffer: Buffer): any; + static validateEntropy(uuidBuffer: Uint8Array): any; /** * Get issuer category name from issuer ID * @param {number} issuerID - Issuer ID @@ -55,9 +55,9 @@ export class UUIDValidator { static validateIssuerIDMutability(issuerID: number): any; /** * Generate a comprehensive validation report - * @param {Buffer} uuidBuffer - UUID buffer to validate + * @param {Uint8Array} uuidBuffer - UUID buffer to validate * @returns {Object} Comprehensive validation report */ - static generateValidationReport(uuidBuffer: Buffer): any; + static generateValidationReport(uuidBuffer: Uint8Array): any; } //# sourceMappingURL=validators.d.mts.map \ No newline at end of file diff --git a/types/src/lib/validators.d.mts.map b/types/src/lib/validators.d.mts.map index 61e9921..448a46d 100644 --- a/types/src/lib/validators.d.mts.map +++ b/types/src/lib/validators.d.mts.map @@ -1 +1 @@ -{"version":3,"file":"validators.d.mts","sourceRoot":"","sources":["../../../src/lib/validators.mjs"],"names":[],"mappings":"AAuBA;;GAEG;AACH;IACC;;;;OAIG;IACH,wCAHW,MAAM,OAkChB;IAED;;;;;OAKG;IACH,mCAoCC;IAED;;;;;OAKG;IACH,sCAuBC;IAED;;;;;OAKG;IACH,yCA6CC;IAED;;;;OAIG;IACH,qCAHW,MAAM,OAmDhB;IAED;;;;OAIG;IACH,mCAHW,MAAM,OAgFhB;IAED;;;;OAIG;IACH,mCAHW,MAAM,GACJ,MAAM,CAgBlB;IAED;;;;OAIG;IACH,4CAHW,MAAM,OAchB;IAED;;;;OAIG;IACH,4CAHW,MAAM,OAgChB;CACD"} \ No newline at end of file +{"version":3,"file":"validators.d.mts","sourceRoot":"","sources":["../../../src/lib/validators.mjs"],"names":[],"mappings":"AAwBA;;GAEG;AACH;IACC;;;;OAIG;IACH,wCAHW,UAAU,OAkCpB;IAED;;;;;OAKG;IACH,mCAoCC;IAED;;;;;OAKG;IACH,sCAuBC;IAED;;;;;OAKG;IACH,yCA6CC;IAED;;;;OAIG;IACH,qCAHW,UAAU,OAmDpB;IAED;;;;OAIG;IACH,mCAHW,UAAU,OAgFpB;IAED;;;;OAIG;IACH,mCAHW,MAAM,GACJ,MAAM,CAgBlB;IAED;;;;OAIG;IACH,4CAHW,MAAM,OAchB;IAED;;;;OAIG;IACH,4CAHW,UAAU,OA+BpB;CACD"} \ No newline at end of file diff --git a/types/src/lib/versions/rfc/v1.d.mts.map b/types/src/lib/versions/rfc/v1.d.mts.map index 5ffe712..b0d5ca1 100644 --- a/types/src/lib/versions/rfc/v1.d.mts.map +++ b/types/src/lib/versions/rfc/v1.d.mts.map @@ -1 +1 @@ -{"version":3,"file":"v1.d.mts","sourceRoot":"","sources":["../../../../../src/lib/versions/rfc/v1.mjs"],"names":[],"mappings":"AAsBA;;;;;;;;;;GAUG;AACH,6BARG;IAAuB,IAAI;IACH,QAAQ,EAAxB,MAAM;IACU,KAAK,EAArB,MAAM;IACU,KAAK,EAArB,MAAM;IACc,GAAG,EAAvB,UAAU;IACM,MAAM,EAAtB,MAAM;CACd,GAAU,MAAM,GAAC,UAAU,CA8C7B"} \ No newline at end of file +{"version":3,"file":"v1.d.mts","sourceRoot":"","sources":["../../../../../src/lib/versions/rfc/v1.mjs"],"names":[],"mappings":"AAsBA;;;;;;;;;;GAUG;AACH,6BARG;IAAuB,IAAI;IACH,QAAQ,EAAxB,MAAM;IACU,KAAK,EAArB,MAAM;IACU,KAAK,EAArB,MAAM;IACc,GAAG,EAAvB,UAAU;IACM,MAAM,EAAtB,MAAM;CACd,GAAU,MAAM,GAAC,UAAU,CAoD7B"} \ No newline at end of file diff --git a/types/src/lib/versions/rfc/v35.d.mts.map b/types/src/lib/versions/rfc/v35.d.mts.map index 828d509..4c35bd2 100644 --- a/types/src/lib/versions/rfc/v35.d.mts.map +++ b/types/src/lib/versions/rfc/v35.d.mts.map @@ -1 +1 @@ -{"version":3,"file":"v35.d.mts","sourceRoot":"","sources":["../../../../../src/lib/versions/rfc/v35.mjs"],"names":[],"mappings":"AAiEA;;;;;;;GAOG;AACH,yBANW,MAAM,aACN,MAAM,GAAC,UAAU,OACjB,UAAU,UACV,MAAM,GACJ,MAAM,GAAC,UAAU,CAI7B;AAED;;;;;;;GAOG;AACH,yBANW,MAAM,aACN,MAAM,GAAC,UAAU,OACjB,UAAU,UACV,MAAM,GACJ,MAAM,GAAC,UAAU,CAI7B"} \ No newline at end of file +{"version":3,"file":"v35.d.mts","sourceRoot":"","sources":["../../../../../src/lib/versions/rfc/v35.mjs"],"names":[],"mappings":"AA+DA;;;;;;;GAOG;AACH,yBANW,MAAM,aACN,MAAM,GAAC,UAAU,OACjB,UAAU,UACV,MAAM,GACJ,MAAM,GAAC,UAAU,CAI7B;AAED;;;;;;;GAOG;AACH,yBANW,MAAM,aACN,MAAM,GAAC,UAAU,OACjB,UAAU,UACV,MAAM,GACJ,MAAM,GAAC,UAAU,CAI7B"} \ No newline at end of file diff --git a/types/src/lib/versions/rfc/v6.d.mts.map b/types/src/lib/versions/rfc/v6.d.mts.map index 79df866..41435d5 100644 --- a/types/src/lib/versions/rfc/v6.d.mts.map +++ b/types/src/lib/versions/rfc/v6.d.mts.map @@ -1 +1 @@ -{"version":3,"file":"v6.d.mts","sourceRoot":"","sources":["../../../../../src/lib/versions/rfc/v6.mjs"],"names":[],"mappings":"AAuBA;;;;;;;;;;GAUG;AACH,6BARG;IAAuB,IAAI;IACH,QAAQ,EAAxB,MAAM;IACU,KAAK,EAArB,MAAM;IACU,KAAK,EAArB,MAAM;IACc,GAAG,EAAvB,UAAU;IACM,MAAM,EAAtB,MAAM;CACd,GAAU,MAAM,GAAC,UAAU,CAyC7B"} \ No newline at end of file +{"version":3,"file":"v6.d.mts","sourceRoot":"","sources":["../../../../../src/lib/versions/rfc/v6.mjs"],"names":[],"mappings":"AAuBA;;;;;;;;;;GAUG;AACH,6BARG;IAAuB,IAAI;IACH,QAAQ,EAAxB,MAAM;IACU,KAAK,EAArB,MAAM;IACU,KAAK,EAArB,MAAM;IACc,GAAG,EAAvB,UAAU;IACM,MAAM,EAAtB,MAAM;CACd,GAAU,MAAM,GAAC,UAAU,CA+C7B"} \ No newline at end of file diff --git a/types/src/uuid.d.mts b/types/src/uuid.d.mts index 4f3ea1b..ade242c 100644 --- a/types/src/uuid.d.mts +++ b/types/src/uuid.d.mts @@ -6,58 +6,58 @@ export class UUID { * Create a new Issuer Variant UUID * @param {number} issuerID - Issuer ID (0-ISSUER_ID_MASK) * @param {number} version - Version number - * @param {Buffer} entropy - Additional entropy data + * @param {Uint8Array} entropy - Additional entropy data * @returns {UUID} New UUID instance */ - static createIssuerVariant(issuerID: number, version: number, entropy?: Buffer): UUID; + static createIssuerVariant(issuerID: number, version: number, entropy?: Uint8Array): UUID; /** * Create a new Timestamp Variant UUID * @param {number|Date} timestamp - Timestamp value (optional, defaults to Date.now()) * @param {number} version - Version number - * @param {Buffer} entropy - Optional entropy for bits 79-127 + * @param {Uint8Array} entropy - Optional entropy for bits 79-127 * @returns {UUID} New UUID instance */ - static createTimestampVariant(timestamp: number | Date, version: number, entropy?: Buffer): UUID; + static createTimestampVariant(timestamp: number | Date, version: number, entropy?: Uint8Array): UUID; /** * Create an issuer-based UUID (short name alias) * @param {number} issuerID - Issuer ID (0-1023) * @param {number} version - Version number - * @param {Buffer} entropy - Additional entropy data + * @param {Uint8Array} entropy - Additional entropy data * @returns {UUID} New UUID instance */ - static issuer(issuerID: number, version: number, entropy?: Buffer): UUID; + static issuer(issuerID: number, version: number, entropy?: Uint8Array): UUID; /** * Create a timestamp-based UUID (short name alias) * @param {number|Date} timestamp - Timestamp value (optional, defaults to Date.now()) * @param {number} version - Version number - * @param {Buffer} entropy - Optional entropy for bits 79-127 + * @param {Uint8Array} entropy - Optional entropy for bits 79-127 * @returns {UUID} New UUID instance */ - static timestamp(timestamp: number | Date, version: number, entropy?: Buffer): UUID; + static timestamp(timestamp: number | Date, version: number, entropy?: Uint8Array): UUID; /** * Create Timestamp Variant v1 UUID (ultra-short alias) * Subvariant 00 - Timestamp-based identification (seconds precision) * @param {number|Date} timestamp - Timestamp value (optional, defaults to Date.now()) - * @param {Buffer} entropy - Optional entropy for bits 79-127 + * @param {Uint8Array} entropy - Optional entropy for bits 79-127 * @returns {UUID} New UUID instance */ - static TA(timestamp: number | Date, entropy?: Buffer): UUID; + static TA(timestamp: number | Date, entropy?: Uint8Array): UUID; /** * Create Issuer Variant v1 UUID (ultra-short alias) * Subvariant 01 - Issuer-based identification * @param {number} issuerID - Issuer ID (0-1023) - * @param {Buffer} entropy - Additional entropy data + * @param {Uint8Array} entropy - Additional entropy data * @returns {UUID} New UUID instance */ - static IA(issuerID: number, entropy?: Buffer): UUID; + static IA(issuerID: number, entropy?: Uint8Array): UUID; /** * Create Timestamp Variant v2 UUID (ultra-short alias) * Subvariant 00 - Timestamp-based identification (milliseconds precision) * @param {number|Date} timestamp - Timestamp value (optional, defaults to Date.now()) - * @param {Buffer} entropy - Optional entropy for bits 79-127 + * @param {Uint8Array} entropy - Optional entropy for bits 79-127 * @returns {UUID} New UUID instance */ - static TB(timestamp: number | Date, entropy?: Buffer): UUID; + static TB(timestamp: number | Date, entropy?: Uint8Array): UUID; /** * Get the shared issuer registry instance * @returns {Promise} Shared registry instance @@ -87,16 +87,16 @@ export class UUID { static getIssuerInfo(issuerID: number): Promise; /** * Validate a UUID buffer for specification compliance - * @param {Buffer} buffer - UUID buffer to validate + * @param {Uint8Array} buffer - UUID buffer to validate * @returns {Promise} Validation results */ - static validate(buffer: Buffer): Promise; + static validate(buffer: Uint8Array): Promise; /** * Generate a complete validation report for a UUID - * @param {Buffer} buffer - UUID buffer to validate + * @param {Uint8Array} buffer - UUID buffer to validate * @returns {Promise} Detailed validation report */ - static validateDetailed(buffer: Buffer): Promise; + static validateDetailed(buffer: Uint8Array): Promise; /** * Generate a version 1 (timestamp) UUID * @param {Object} options - Optional parameters @@ -179,13 +179,13 @@ export class UUID { static detectVariant(uuid: string | Buffer | UUID): string | number | null; /** * Create a new UUID instance - * @param {Buffer|string|null} data - Optional UUID data to parse + * @param {Uint8Array|string|null} data - Optional UUID data to parse */ - constructor(data?: Buffer | string | null); - _buffer: any; + constructor(data?: Uint8Array | string | null); + _buffer: Uint8Array; /** * Parse UUID from existing data - * @param {Buffer|string} data - UUID data to parse + * @param {Uint8Array|string} data - UUID data to parse * @private */ private _parseFromData; @@ -197,7 +197,7 @@ export class UUID { private _setTimestamp; /** * Fill remaining bits with entropy while preserving immutable fields - * @param {Buffer} entropy - Entropy data + * @param {Uint8Array} entropy - Entropy data * @private */ private _fillEntropy; @@ -287,7 +287,7 @@ export class UUID { toString(): string; /** * Convert UUID to buffer - * @returns {Buffer} UUID as 16-byte buffer + * @returns {Buffer} UUID as 16-byte buffer (Node); a Uint8Array copy in environments without Buffer */ toBuffer(): Buffer; /** diff --git a/types/src/uuid.d.mts.map b/types/src/uuid.d.mts.map index 0f382e2..fdc09fd 100644 --- a/types/src/uuid.d.mts.map +++ b/types/src/uuid.d.mts.map @@ -1 +1 @@ -{"version":3,"file":"uuid.d.mts","sourceRoot":"","sources":["../../src/uuid.mjs"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"uuid.d.mts","sourceRoot":"","sources":["../../src/uuid.mjs"],"names":[],"mappings":"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"} \ No newline at end of file From 95f51d0c4df68b422b8efc26f8dbb64e990bcfc9 Mon Sep 17 00:00:00 2001 From: "cldmv-bot[bot]" <230771808+cldmv-bot[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2026 14:34:33 +0000 Subject: [PATCH 4/4] chore: bump version to 1.2.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4198bff..318f1b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cldmv/uuid", - "version": "1.1.8", + "version": "1.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@cldmv/uuid", - "version": "1.1.8", + "version": "1.2.0", "license": "Apache-2.0", "devDependencies": { "@cldmv/fix-headers": "^1.2.2", diff --git a/package.json b/package.json index fc3f8e1..1e1119e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cldmv/uuid", - "version": "1.1.8", + "version": "1.2.0", "description": "Extended RFC 4122 and RFC 9562 UUID implementation with custom variant structures, issuer-based identification, and timestamp variants", "main": "./index.cjs", "module": "./index.mjs",