UNPKG

@mhysko/s-uuid

Version:

Translate standard UUID to Base68 format and back

76 lines (75 loc) 2.02 kB
import { v4, validate as validateUuid } from 'uuid'; import { encodings } from './encodings.js'; import Converter from './Converter.js'; class Suuid { uuidFn; #converter; encoding = encodings.BASE58; get length() { return Math.ceil(Math.log(2 ** 128) / Math.log(this.encoding.length)); } constructor(uuidFn = v4) { this.uuidFn = uuidFn; this.#converter = new Converter(encodings.HEX, this.encoding); } generate() { return this.translate(this.uuidFn()); } translate(id) { if (this.isUuid(id)) { return this.fromUuid(id); } return this.toUuid(id); } fromUuid(id) { if (this.isSuuid(id)) { return id; } return this.#converter.encode(this.#sanitize(id)); } toUuid(id) { if (this.isUuid(id)) { return id; } const error = new Error('Invalid ID format'); if (!id) { throw error; } const uu1 = this.#converter.decode(id).padStart(32, '0'); const m = /(\w{8})(\w{4})(\w{4})(\w{4})(\w{12})/.exec(uu1); if (!m) { throw error; } return [m[1], m[2], m[3], m[4], m[5]].join('-'); } validate(id, strict = false) { return this.isUuid(id) || this.isSuuid(id, strict); } isUuid(id) { return validateUuid(id); } isSuuid(id, strict = false) { if (!id || typeof id !== 'string') { return false; } if (id.length > this.length) { return false; } if (!Array.from(new Set(id.split(''))).every(ch => this.encoding.includes(ch))) { return false; } if (strict) { try { return !!this.toUuid(id); } catch { return false; } } return true; } #sanitize(id) { return id.toLowerCase().replace(/-/g, ''); } } export default Suuid;