UNPKG

uzid

Version:

A simple library for generating unique IDs based on a timestamp and random characters

102 lines 3.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Uzid = void 0; class Uzid { constructor(options = {}) { this.chars = "0123456789abcdefghijklmnopqrstuvwxyz"; this.prefix = options.prefix || ""; this.base = options.base || 36; this.length = options.length ?? 4; if (options.precision && options.precision !== "ms") { throw new Error('Precision must be "ms" if specified'); } this.precision = options.precision; if (this.base !== 36 && this.base !== 62) { throw new Error("Base must be either 36 or 62"); } if (typeof this.length !== "number" || !Number.isInteger(this.length) || this.length < 0 || this.length > 20) { throw new Error("Length must be a non-negative integer between 0 and 20"); } this.chars += this.base === 62 ? "ABCDEFGHIJKLMNOPQRSTUVWXYZ" : ""; } toBaseString(num, base) { if (base === 36) return num.toString(36); if (num === 0) return "0"; let out = ""; let n = num; while (n > 0) { out = this.chars[n % base] + out; n = Math.floor(n / base); } return out; } fromBaseString(str, base) { if (base === 36) return parseInt(str, 36); let out = 0; for (let i = 0; i < str.length; i++) { const char = str[i]; const value = this.chars.indexOf(char); if (value === -1) { throw new Error(`Invalid character '${char}' for base ${base}`); } out = out * base + value; } return out; } single() { const ts = Math.floor(Date.now() / (this.precision === "ms" ? 1 : 1000)); return this.prefix + this.toBaseString(ts, this.base) + this.random(); } generate(count) { return count === undefined ? this.single() : this.multiple(count); } verify(id) { if (typeof id !== "string" || id.length === 0 || !id.startsWith(this.prefix)) return false; const withoutPrefix = id.slice(this.prefix.length); if (withoutPrefix.length === 0) return false; for (let i = 0; i < withoutPrefix.length; i++) { if (!this.chars.includes(withoutPrefix[i])) return false; } const randomPart = this.length === 0 ? "" : withoutPrefix.slice(-this.length); if (randomPart.length !== this.length) return false; const timestampPart = this.length === 0 ? withoutPrefix : withoutPrefix.slice(0, -this.length); try { return !isNaN(new Date(this.fromBaseString(timestampPart, this.base) * (this.precision === "ms" ? 1 : 1000)).getTime()); } catch { return false; } } random() { let s = ""; for (let i = 0; i < this.length; i++) { s += this.chars[Math.floor(Math.random() * this.chars.length)]; } return s; } multiple(count) { if (!Number.isInteger(count) || count < 2) { throw new Error("Count must be a positive integer greater than 1"); } const ids = new Set(); while (ids.size < count) { ids.add(this.single()); } return Array.from(ids).sort(); } } exports.Uzid = Uzid; //# sourceMappingURL=index.js.map