nhb-toolbox
Version:
A versatile collection of smart, efficient, and reusable utility functions, classes and types for everyday development needs.
156 lines (155 loc) • 5.83 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.uuid = uuid;
exports.decodeUUID = decodeUUID;
exports.isUUIDv1 = isUUIDv1;
exports.isUUIDv2 = isUUIDv2;
exports.isUUIDv3 = isUUIDv3;
exports.isUUIDv4 = isUUIDv4;
exports.isUUIDv5 = isUUIDv5;
exports.isUUIDv6 = isUUIDv6;
exports.isUUIDv7 = isUUIDv7;
exports.isUUIDv8 = isUUIDv8;
const specials_1 = require("../guards/specials");
const core_1 = require("./core");
const helpers_1 = require("./helpers");
const utils_1 = require("./utils");
function uuid(options) {
const { version = 'v4', uppercase = false } = options || {};
switch (version) {
case 'v1': {
const timestamp = (0, helpers_1._uuidTimestamp)().toString(16).padStart(15, '0');
const vTimeHigh = (parseInt(timestamp.slice(0, -12).padStart(3, '0'), 16) | 0x1000)
.toString(16)
.padStart(4, '0');
const clockSeq = (0, helpers_1._clockSeq14)();
const clockSeqHi = ((parseInt(clockSeq.slice(0, 2), 16) & 0x3f) | 0x80)
.toString(16)
.padStart(2, '0');
const raw = timestamp.slice(-8) +
timestamp.slice(-12, -8) +
vTimeHigh +
clockSeqHi +
clockSeq.slice(2) +
(0, helpers_1._randomNode48)();
return (0, helpers_1._formatUUID)(raw, 1, uppercase);
}
case 'v3': {
if ((0, helpers_1._isOptionV3V5)(options)) {
const hash = (0, core_1.md5)(options.namespace + options.name);
return (0, helpers_1._formatUUID)(hash, 3, uppercase);
}
throw new Error('v3 requires valid namespace (uuid) and name!');
}
case 'v4': {
const hex = (0, helpers_1._bytesToRandomHex)(new Uint8Array(16));
return (0, helpers_1._formatUUID)(hex, 4, uppercase);
}
case 'v5': {
if ((0, helpers_1._isOptionV3V5)(options)) {
const hash = (0, core_1.sha1)(options.namespace + options.name).slice(0, 32);
return (0, helpers_1._formatUUID)(hash, 5, uppercase);
}
throw new Error('v5 requires valid namespace (uuid) and name!');
}
case 'v6': {
const timestamp = (0, helpers_1._uuidTimestamp)().toString(16).padStart(15, '0');
const vTimeLow = (parseInt(timestamp.slice(12).padStart(3, '0'), 16) | 0x6000)
.toString(16)
.padStart(4, '0');
const clockSeq = (0, helpers_1._clockSeq14)();
const clockSeqHi = ((parseInt(clockSeq.slice(0, 2), 16) & 0x3f) | 0x80)
.toString(16)
.padStart(2, '0');
const raw = timestamp.slice(0, 8) +
timestamp.slice(8, 12) +
vTimeLow +
clockSeqHi +
clockSeq.slice(2) +
(0, helpers_1._randomNode48)();
return (0, helpers_1._formatUUID)(raw, 6, uppercase);
}
case 'v7': {
const tsHex = Date.now().toString(16).padStart(12, '0');
return (0, helpers_1._formatUUID)(tsHex + (0, utils_1.randomHex)(20), 7, uppercase);
}
case 'v8': {
const ts = BigInt(Date.now());
const bytes = new Uint8Array(16);
let temp = ts;
for (let i = 5; i >= 0; i--) {
bytes[i] = Number(temp & 0xffn);
temp >>= 8n;
}
const hex = (0, helpers_1._bytesToRandomHex)(bytes);
return (0, helpers_1._formatUUID)(hex, 8, uppercase);
}
default:
throw new RangeError('Unsupported UUID version!');
}
}
function decodeUUID(uuid) {
if (!(0, specials_1.isUUID)(uuid))
return null;
const plain = uuid.replace(/-/g, '');
const parts = uuid.toLowerCase().split('-');
const version = parseInt(parts[2][0], 16);
const variantNibble = parseInt(parts[3][0], 16);
let variant = 'RFC4122';
if ((variantNibble & 0b1000) === 0)
variant = 'NCS';
else if ((variantNibble & 0b1100) === 0b1000)
variant = 'RFC4122';
else if ((variantNibble & 0b1110) === 0b1100)
variant = 'Microsoft';
else
variant = 'Future';
const decoded = {
version,
variant,
raw: uuid,
plain,
singleInt: BigInt('0x' + plain),
};
const UUID_EPOCH_DIFF = 122192928000000000n;
if (version === 1 || version === 6) {
let tsHex = parts[2].slice(1) + parts[1] + parts[0];
if (version === 6)
tsHex = parts[0] + parts[1] + parts[2].slice(1);
const unixMs = Number((BigInt('0x' + tsHex) - UUID_EPOCH_DIFF) / 10000n);
decoded.timestamp = unixMs;
decoded.node = parts[4];
return decoded;
}
if (version === 7 || version === 8) {
const tsHex = parts.join('').slice(0, 12);
decoded.variant = version === 7 ? 'RFC4122' : 'Future';
decoded.timestamp = parseInt(tsHex, 16);
return decoded;
}
return decoded;
}
function isUUIDv1(value) {
return (0, helpers_1._checkUUIDVersion)(value, '1');
}
function isUUIDv2(value) {
return (0, helpers_1._checkUUIDVersion)(value, '2');
}
function isUUIDv3(value) {
return (0, helpers_1._checkUUIDVersion)(value, '3');
}
function isUUIDv4(value) {
return (0, helpers_1._checkUUIDVersion)(value, '4');
}
function isUUIDv5(value) {
return (0, helpers_1._checkUUIDVersion)(value, '5');
}
function isUUIDv6(value) {
return (0, helpers_1._checkUUIDVersion)(value, '6');
}
function isUUIDv7(value) {
return (0, helpers_1._checkUUIDVersion)(value, '7');
}
function isUUIDv8(value) {
return (0, helpers_1._checkUUIDVersion)(value, '8');
}