UNPKG

nanohash

Version:

Generate 64bits-based numeric ids readable as short strings too!

235 lines (234 loc) 8.15 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const generate_1 = __importDefault(require("nanoid/generate")); const fauna = __importStar(require("./fauna")); exports.fauna = fauna; const hashtable_1 = require("./hashtable"); function inverseTable(htable) { return Object.entries(htable).reduce((table, [key, code]) => { table[code] = key; return table; }, {}); } exports.presets = { HUMAN_READABLE_REF: { // Let's you create a short readable folder reference (0/O and 1/I are banned) alphabet: 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789', size: 5 }, SHORT_REF: { // Let's you create a short code similar to youtube (ex: ysX7j1) alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', size: 6 } }; /** * Creates an instance of nanohash based on size and alphabet needs * @example * * ```javascript * const nhash = nanohash({ size: 6, alphabet: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" }) * ``` */ class NanoHash { constructor(options = {}) { this.size = 6; this.maxSize = 9; this.alphabet = exports.presets.SHORT_REF.alphabet; this.prefix = '1'; /** * Generates a unique numeric string ID (reversible to code) * * @returns {NanoHash.ID} * * @example * * const code = nhash.generate() * // output: Xe7ZRY */ this.generate = () => { return this.hash(generate_1.default(this.alphabet, this.size)); }; /** * Generates n iterations of unique numeric string ID (each reversible to code) * * @param {number} [n=10] * @returns {NanoHash.ID[]} * * @example * * ```javascript * const code = nhash.bulk(5) * // output: [ '1075226254449', '1563743314555', '1015201022261', '1271320203729', '1465116152533' ] * ``` */ this.bulk = (n = 10) => { return Array(n) .fill(undefined) .map(this.generate); }; /** * Convert a string code to a numeric string ID (reversible) * * @param {NanoHash.code} code * @returns {NanoHash.ID} * * @example * * ```javascript * const countryID = nhash.hash("France") * // output: 1412710231214 * ``` */ this.hash = (code) => { if (code.length > this.maxSize) throw new Error(`Code cannot be longer than ${this.maxSize}`); let firstNumberAlphabet = '12345678'; return ((firstNumberAlphabet.includes(this.prefix) ? this.prefix : '1') + `${code}` .split('') .map((c) => { try { return this.hashtable[c]; } catch (error) { throw new Error(`The character: ${c} can't be used`); } }) .join('')); }; /** * Returns a code from an ID (made from .hash() or .generate()) * * @param {NanoHash.ID} [id=''] * @returns {NanoHash.code} * * @example * * ```javascript * const countryName = nhash.dehash("1412710231214") * // output: France * ``` */ this.dehash = (id = '') => { return `${id}` .slice(1) .match(/.{1,2}/g) .map((c) => { try { return this.codetable[c]; } catch (error) { throw new Error(`The code: ${c} doesn't exist`); } }) .join(''); }; /** * Returns a code from a Fauna ID (generated by Fauna) * * @param {NanoHash.FaunaID} faunaId * @returns {NanoHash.FaunaCode} * * @example * * ```javascript * const code = nhash.faunaCode("258296287713034771") * // output: эh3ъmöýRt * ``` */ this.faunaCode = (faunaId) => { let id = `${faunaId}`; let firstCharacter = ''; let isOdd = id.length % 2 > 0; if (isOdd) { firstCharacter = id.slice(0, 1); try { firstCharacter = hashtable_1.reversedNumbers[firstCharacter]; } catch (error) { console.error(`Couldn't find ${firstCharacter} in reversedNumbers hash`); } id = id.slice(1); } return (firstCharacter + id .match(/.{1,2}/g) .map((c) => { try { return this.codetable99[c]; } catch (error) { throw new Error(`The code: ${c} doesn't exist`); } }) .join('')); }; /** * Returns a Fauna ID from a code (from .faunaCode()) * * @param {NanoHash.FaunaCode} faunaCode * @returns {NanoHash.FaunaID} * * @example * * ```javascript * const faunaID = nhash.faunaId("эh3ъmöýRt") * // output: 258296287713034771 * ``` */ this.faunaId = (faunaCode) => { let code = `${faunaCode}`; let firstCharacter = ''; let hasSpecialFirstCharacter = code.startsWith('_'); if (hasSpecialFirstCharacter) { firstCharacter = code.slice(0, 2); const reversedNumbersCodeTable = inverseTable(hashtable_1.reversedNumbers); try { firstCharacter = reversedNumbersCodeTable[firstCharacter]; } catch (error) { console.error(`Couldn't find ${firstCharacter} in reversedNumbers hash`); } code = code.slice(2); } return (firstCharacter + code .split('') .map((c) => { try { return hashtable_1.hashtable99[c]; } catch (error) { throw new Error(`The character: ${c} can't be used`); } }) .join('')); }; let { size = exports.presets.SHORT_REF.size, maxSize = 9, hashtable = {}, alphabet = exports.presets.SHORT_REF.alphabet } = options; if (maxSize > 9) { this.maxSize = 9; } if (size > maxSize) { throw new Error(`Size cannot be higher than ${maxSize}`); } this.size = size; this.alphabet = alphabet; this.hashtable = Object.assign(hashtable_1.hashtable, hashtable || {}); this.codetable = inverseTable(this.hashtable); this.hashtable99 = hashtable_1.hashtable99; this.codetable99 = inverseTable(this.hashtable99); } } exports.NanoHash = NanoHash; exports.nanohash = (...args) => new NanoHash(...args);