short-unique-id
Advanced tools
Comparing version 4.4.4 to 5.0.0
@@ -1,5 +0,11 @@ | ||
interface ShortUniqueIdRanges { | ||
/** | ||
* @packageDocumentation | ||
**/ | ||
export interface ShortUniqueIdRanges { | ||
[k: string]: [number, number]; | ||
} | ||
declare type defaultDictionaries = 'number' | 'alpha' | 'alpha_lower' | 'alpha_upper' | 'alphanum' | 'alphanum_lower' | 'alphanum_upper' | 'hex'; | ||
export interface ShortUniqueIdRangesMap { | ||
[k: string]: ShortUniqueIdRanges; | ||
} | ||
export type ShortUniqueIdDefaultDictionaries = 'number' | 'alpha' | 'alpha_lower' | 'alpha_upper' | 'alphanum' | 'alphanum_lower' | 'alphanum_upper' | 'hex'; | ||
/** | ||
@@ -14,6 +20,8 @@ * ```js | ||
* ``` | ||
* <br/> | ||
* @see {@link DEFAULT_OPTIONS} | ||
*/ | ||
export interface ShortUniqueIdOptions { | ||
/** User-defined character dictionary */ | ||
dictionary: string[] | defaultDictionaries; | ||
dictionary: string[] | ShortUniqueIdDefaultDictionaries; | ||
/** If true, sequentialUUID use the dictionary in the given order */ | ||
@@ -25,2 +33,4 @@ shuffle: boolean; | ||
length: number; | ||
/** From 0 to infinity, the current value for the sequential UUID counter */ | ||
counter: number; | ||
} | ||
@@ -38,2 +48,3 @@ /** | ||
export declare const DEFAULT_UUID_LENGTH: number; | ||
export declare const DEFAULT_OPTIONS: ShortUniqueIdOptions; | ||
/** | ||
@@ -51,10 +62,10 @@ * Generate random or sequential UUID of any length. | ||
* | ||
* //or Node.js require | ||
* // or Node.js require | ||
* const ShortUniqueId = require('short-unique-id'); | ||
* | ||
* //Instantiate | ||
* // Instantiate | ||
* const uid = new ShortUniqueId(); | ||
* | ||
* // Random UUID | ||
* console.log(uid()); | ||
* console.log(uid.rnd()); | ||
* | ||
@@ -77,3 +88,3 @@ * // Sequential UUID | ||
* // Random UUID | ||
* document.write(uid()); | ||
* document.write(uid.rnd()); | ||
* | ||
@@ -97,3 +108,4 @@ * // Sequential UUID | ||
*/ | ||
export default class ShortUniqueId extends Function { | ||
export default class ShortUniqueId { | ||
/** @hidden */ | ||
static default: typeof ShortUniqueId; | ||
@@ -125,5 +137,6 @@ counter: number; | ||
protected _hex_dict_ranges: ShortUniqueIdRanges; | ||
protected _dict_ranges: ShortUniqueIdRangesMap; | ||
protected log: (...args: any[]) => void; | ||
/** Change the dictionary after initialization. */ | ||
setDictionary: (dictionary: string[] | defaultDictionaries, shuffle?: boolean | undefined) => void; | ||
setDictionary: (dictionary: string[] | ShortUniqueIdDefaultDictionaries, shuffle?: boolean) => void; | ||
seq: () => string; | ||
@@ -135,8 +148,15 @@ /** | ||
sequentialUUID: () => string; | ||
rnd: (uuidLength?: number) => string; | ||
/** | ||
* Generates UUID by creating each part randomly. | ||
* @alias `const uid = new ShortUniqueId(); uid(uuidLength: number);` | ||
* @alias `const uid = new ShortUniqueId(); uid.rnd(uuidLength: number);` | ||
*/ | ||
randomUUID: (uuidLength?: number) => string; | ||
fmt: (format: string, date?: Date) => string; | ||
/** | ||
* Generates custom UUID with the provided format string. | ||
* @alias `const uid = new ShortUniqueId(); uid.fmt(format: string);` | ||
*/ | ||
formattedUUID: (format: string, date?: Date) => string; | ||
/** | ||
* Calculates total number of possible UUIDs. | ||
@@ -152,3 +172,5 @@ * | ||
* | ||
* ![](https://render.githubusercontent.com/render/math?math=%5CHuge%20H=n%5El) | ||
* <div style="background: white; padding: 5px; border-radius: 5px; overflow: hidden;"> | ||
* <img src="https://render.githubusercontent.com/render/math?math=%5CHuge%20H=n%5El"/> | ||
* </div> | ||
* | ||
@@ -171,3 +193,5 @@ * This function returns `H`. | ||
* | ||
* ![](https://render.githubusercontent.com/render/math?math=%5CHuge%20Q(H)%5Capprox%5Csqrt%7B%5Cfrac%7B%5Cpi%7D%7B2%7DH%7D) | ||
* <div style="background: white; padding: 5px; border-radius: 5px; overflow: hidden;"> | ||
* <img src="https://render.githubusercontent.com/render/math?math=%5CHuge%20Q(H)%5Capprox%5Csqrt%7B%5Cfrac%7B%5Cpi%7D%7B2%7DH%7D"/> | ||
* </div> | ||
* | ||
@@ -193,3 +217,5 @@ * This function returns `Q(H)`. | ||
* | ||
* ![](https://render.githubusercontent.com/render/math?math=%5CHuge%20p(r%3B%20H)%5Capprox%5Cfrac%7B%5Csqrt%7B%5Cfrac%7B%5Cpi%7D%7B2%7Dr%7D%7D%7BH%7D) | ||
* <div style="background: white; padding: 5px; border-radius: 5px; overflow: hidden;"> | ||
* <img src="https://render.githubusercontent.com/render/math?math=%5CHuge%20p(r%3B%20H)%5Capprox%5Cfrac%7B%5Csqrt%7B%5Cfrac%7B%5Cpi%7D%7B2%7Dr%7D%7D%7BH%7D"/> | ||
* </div> | ||
* | ||
@@ -219,3 +245,5 @@ * This function returns `p(r; H)`. | ||
* | ||
* ![](https://render.githubusercontent.com/render/math?math=%5CHuge%201-%5Cfrac%7BQ(H)%7D%7BH%7D) | ||
* <div style="background: white; padding: 5px; border-radius: 5px; overflow: hidden;"> | ||
* <img src="https://render.githubusercontent.com/render/math?math=%5CHuge%201-%5Cfrac%7BQ(H)%7D%7BH%7D"/> | ||
* </div> | ||
* | ||
@@ -242,3 +270,3 @@ * (Useful if you need a value to rate the "quality" of the combination of given dictionary | ||
*/ | ||
stamp: (finalLength: number) => string; | ||
stamp: (finalLength: number, date?: Date) => string; | ||
/** | ||
@@ -256,5 +284,8 @@ * Extracts the date embeded in a UUID generated using the `uid.stamp(finalLength);` method. | ||
*/ | ||
parseStamp: (stamp: string) => Date; | ||
parseStamp: (suid: string, format?: string) => Date; | ||
/** | ||
* Set the counter to a specific value. | ||
*/ | ||
setCounter: (counter: number) => void; | ||
constructor(argOptions?: Partial<ShortUniqueIdOptions>); | ||
} | ||
export {}; |
@@ -0,3 +1,6 @@ | ||
"use strict"; | ||
var ShortUniqueId = (() => { | ||
var __defProp = Object.defineProperty; | ||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
var __getOwnPropNames = Object.getOwnPropertyNames; | ||
var __getOwnPropSymbols = Object.getOwnPropertySymbols; | ||
@@ -18,8 +21,19 @@ var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
}; | ||
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); | ||
var __export = (target, all) => { | ||
__markAsModule(target); | ||
for (var name in all) | ||
__defProp(target, name, { get: all[name], enumerable: true }); | ||
}; | ||
var __copyProps = (to, from, except, desc) => { | ||
if (from && typeof from === "object" || typeof from === "function") { | ||
for (let key of __getOwnPropNames(from)) | ||
if (!__hasOwnProp.call(to, key) && key !== except) | ||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
} | ||
return to; | ||
}; | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
var __publicField = (obj, key, value) => { | ||
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); | ||
return value; | ||
}; | ||
@@ -29,2 +43,3 @@ // src/index.ts | ||
__export(src_exports, { | ||
DEFAULT_OPTIONS: () => DEFAULT_OPTIONS, | ||
DEFAULT_UUID_LENGTH: () => DEFAULT_UUID_LENGTH, | ||
@@ -35,3 +50,3 @@ default: () => ShortUniqueId | ||
// package.json | ||
var version = "4.4.4"; | ||
var version = "5.0.0"; | ||
@@ -44,50 +59,66 @@ // src/index.ts | ||
debug: false, | ||
length: DEFAULT_UUID_LENGTH | ||
length: DEFAULT_UUID_LENGTH, | ||
counter: 0 | ||
}; | ||
var _ShortUniqueId = class extends Function { | ||
var _ShortUniqueId = class _ShortUniqueId { | ||
constructor(argOptions = {}) { | ||
super(); | ||
this.dictIndex = 0; | ||
this.dictRange = []; | ||
this.lowerBound = 0; | ||
this.upperBound = 0; | ||
this.dictLength = 0; | ||
this._digit_first_ascii = 48; | ||
this._digit_last_ascii = 58; | ||
this._alpha_lower_first_ascii = 97; | ||
this._alpha_lower_last_ascii = 123; | ||
this._hex_last_ascii = 103; | ||
this._alpha_upper_first_ascii = 65; | ||
this._alpha_upper_last_ascii = 91; | ||
this._number_dict_ranges = { | ||
__publicField(this, "counter"); | ||
__publicField(this, "debug"); | ||
__publicField(this, "dict"); | ||
__publicField(this, "version"); | ||
__publicField(this, "dictIndex", 0); | ||
__publicField(this, "dictRange", []); | ||
__publicField(this, "lowerBound", 0); | ||
__publicField(this, "upperBound", 0); | ||
__publicField(this, "dictLength", 0); | ||
__publicField(this, "uuidLength"); | ||
__publicField(this, "_digit_first_ascii", 48); | ||
__publicField(this, "_digit_last_ascii", 58); | ||
__publicField(this, "_alpha_lower_first_ascii", 97); | ||
__publicField(this, "_alpha_lower_last_ascii", 123); | ||
__publicField(this, "_hex_last_ascii", 103); | ||
__publicField(this, "_alpha_upper_first_ascii", 65); | ||
__publicField(this, "_alpha_upper_last_ascii", 91); | ||
__publicField(this, "_number_dict_ranges", { | ||
digits: [this._digit_first_ascii, this._digit_last_ascii] | ||
}; | ||
this._alpha_dict_ranges = { | ||
}); | ||
__publicField(this, "_alpha_dict_ranges", { | ||
lowerCase: [this._alpha_lower_first_ascii, this._alpha_lower_last_ascii], | ||
upperCase: [this._alpha_upper_first_ascii, this._alpha_upper_last_ascii] | ||
}; | ||
this._alpha_lower_dict_ranges = { | ||
}); | ||
__publicField(this, "_alpha_lower_dict_ranges", { | ||
lowerCase: [this._alpha_lower_first_ascii, this._alpha_lower_last_ascii] | ||
}; | ||
this._alpha_upper_dict_ranges = { | ||
}); | ||
__publicField(this, "_alpha_upper_dict_ranges", { | ||
upperCase: [this._alpha_upper_first_ascii, this._alpha_upper_last_ascii] | ||
}; | ||
this._alphanum_dict_ranges = { | ||
}); | ||
__publicField(this, "_alphanum_dict_ranges", { | ||
digits: [this._digit_first_ascii, this._digit_last_ascii], | ||
lowerCase: [this._alpha_lower_first_ascii, this._alpha_lower_last_ascii], | ||
upperCase: [this._alpha_upper_first_ascii, this._alpha_upper_last_ascii] | ||
}; | ||
this._alphanum_lower_dict_ranges = { | ||
}); | ||
__publicField(this, "_alphanum_lower_dict_ranges", { | ||
digits: [this._digit_first_ascii, this._digit_last_ascii], | ||
lowerCase: [this._alpha_lower_first_ascii, this._alpha_lower_last_ascii] | ||
}; | ||
this._alphanum_upper_dict_ranges = { | ||
}); | ||
__publicField(this, "_alphanum_upper_dict_ranges", { | ||
digits: [this._digit_first_ascii, this._digit_last_ascii], | ||
upperCase: [this._alpha_upper_first_ascii, this._alpha_upper_last_ascii] | ||
}; | ||
this._hex_dict_ranges = { | ||
}); | ||
__publicField(this, "_hex_dict_ranges", { | ||
decDigits: [this._digit_first_ascii, this._digit_last_ascii], | ||
alphaDigits: [this._alpha_lower_first_ascii, this._hex_last_ascii] | ||
}; | ||
this.log = (...args) => { | ||
}); | ||
__publicField(this, "_dict_ranges", { | ||
_number_dict_ranges: this._number_dict_ranges, | ||
_alpha_dict_ranges: this._alpha_dict_ranges, | ||
_alpha_lower_dict_ranges: this._alpha_lower_dict_ranges, | ||
_alpha_upper_dict_ranges: this._alpha_upper_dict_ranges, | ||
_alphanum_dict_ranges: this._alphanum_dict_ranges, | ||
_alphanum_lower_dict_ranges: this._alphanum_lower_dict_ranges, | ||
_alphanum_upper_dict_ranges: this._alphanum_upper_dict_ranges, | ||
_hex_dict_ranges: this._hex_dict_ranges | ||
}); | ||
/* tslint:disable consistent-return */ | ||
__publicField(this, "log", (...args) => { | ||
const finalArgs = [...args]; | ||
@@ -100,4 +131,6 @@ finalArgs[0] = `[short-unique-id] ${args[0]}`; | ||
} | ||
}; | ||
this.setDictionary = (dictionary, shuffle) => { | ||
}); | ||
/* tslint:enable consistent-return */ | ||
/** Change the dictionary after initialization. */ | ||
__publicField(this, "setDictionary", (dictionary, shuffle) => { | ||
let finalDict; | ||
@@ -111,3 +144,3 @@ if (dictionary && Array.isArray(dictionary) && dictionary.length > 1) { | ||
const rangesName = `_${dictionary}_dict_ranges`; | ||
const ranges = this[rangesName]; | ||
const ranges = this._dict_ranges[rangesName]; | ||
Object.keys(ranges).forEach((rangeType) => { | ||
@@ -129,8 +162,12 @@ const rangeTypeKey = rangeType; | ||
this.dictLength = this.dict.length; | ||
this.counter = 0; | ||
}; | ||
this.seq = () => { | ||
this.setCounter(0); | ||
}); | ||
__publicField(this, "seq", () => { | ||
return this.sequentialUUID(); | ||
}; | ||
this.sequentialUUID = () => { | ||
}); | ||
/** | ||
* Generates UUID based on internal counter that's incremented after each ID generation. | ||
* @alias `const uid = new ShortUniqueId(); uid.seq();` | ||
*/ | ||
__publicField(this, "sequentialUUID", () => { | ||
let counterDiv; | ||
@@ -147,4 +184,11 @@ let counterRem; | ||
return id; | ||
}; | ||
this.randomUUID = (uuidLength = this.uuidLength || DEFAULT_UUID_LENGTH) => { | ||
}); | ||
__publicField(this, "rnd", (uuidLength = this.uuidLength || DEFAULT_UUID_LENGTH) => { | ||
return this.randomUUID(uuidLength); | ||
}); | ||
/** | ||
* Generates UUID by creating each part randomly. | ||
* @alias `const uid = new ShortUniqueId(); uid.rnd(uuidLength: number);` | ||
*/ | ||
__publicField(this, "randomUUID", (uuidLength = this.uuidLength || DEFAULT_UUID_LENGTH) => { | ||
let id; | ||
@@ -159,40 +203,230 @@ let randomPartIdx; | ||
for (j = 0; j < uuidLength; j += 1) { | ||
randomPartIdx = parseInt((Math.random() * this.dictLength).toFixed(0), 10) % this.dictLength; | ||
randomPartIdx = parseInt( | ||
(Math.random() * this.dictLength).toFixed(0), | ||
10 | ||
) % this.dictLength; | ||
id += this.dict[randomPartIdx]; | ||
} | ||
return id; | ||
}; | ||
this.availableUUIDs = (uuidLength = this.uuidLength) => { | ||
return parseFloat(Math.pow([...new Set(this.dict)].length, uuidLength).toFixed(0)); | ||
}; | ||
this.approxMaxBeforeCollision = (rounds = this.availableUUIDs(this.uuidLength)) => { | ||
return parseFloat(Math.sqrt(Math.PI / 2 * rounds).toFixed(20)); | ||
}; | ||
this.collisionProbability = (rounds = this.availableUUIDs(this.uuidLength), uuidLength = this.uuidLength) => { | ||
return parseFloat((this.approxMaxBeforeCollision(rounds) / this.availableUUIDs(uuidLength)).toFixed(20)); | ||
}; | ||
this.uniqueness = (rounds = this.availableUUIDs(this.uuidLength)) => { | ||
const score = parseFloat((1 - this.approxMaxBeforeCollision(rounds) / rounds).toFixed(20)); | ||
}); | ||
__publicField(this, "fmt", (format, date) => { | ||
return this.formattedUUID(format, date); | ||
}); | ||
/** | ||
* Generates custom UUID with the provided format string. | ||
* @alias `const uid = new ShortUniqueId(); uid.fmt(format: string);` | ||
*/ | ||
__publicField(this, "formattedUUID", (format, date) => { | ||
const fnMap = { | ||
"$r": this.randomUUID, | ||
"$s": this.sequentialUUID, | ||
"$t": this.stamp | ||
}; | ||
const result = format.replace( | ||
/\$[rs]\d{0,}|\$t0|\$t[1-9]\d{1,}/g, | ||
(m) => { | ||
const fn = m.slice(0, 2); | ||
const len = parseInt(m.slice(2), 10); | ||
if (fn === "$s") { | ||
return fnMap[fn]().padStart(len, "0"); | ||
} | ||
if (fn === "$t" && date) { | ||
return fnMap[fn](len, date); | ||
} | ||
return fnMap[fn](len); | ||
} | ||
); | ||
return result; | ||
}); | ||
/** | ||
* Calculates total number of possible UUIDs. | ||
* | ||
* Given that: | ||
* | ||
* - `H` is the total number of possible UUIDs | ||
* - `n` is the number of unique characters in the dictionary | ||
* - `l` is the UUID length | ||
* | ||
* Then `H` is defined as `n` to the power of `l`: | ||
* | ||
* <div style="background: white; padding: 5px; border-radius: 5px; overflow: hidden;"> | ||
* <img src="https://render.githubusercontent.com/render/math?math=%5CHuge%20H=n%5El"/> | ||
* </div> | ||
* | ||
* This function returns `H`. | ||
*/ | ||
__publicField(this, "availableUUIDs", (uuidLength = this.uuidLength) => { | ||
return parseFloat( | ||
Math.pow([...new Set(this.dict)].length, uuidLength).toFixed(0) | ||
); | ||
}); | ||
/** | ||
* Calculates approximate number of hashes before first collision. | ||
* | ||
* Given that: | ||
* | ||
* - `H` is the total number of possible UUIDs, or in terms of this library, | ||
* the result of running `availableUUIDs()` | ||
* - the expected number of values we have to choose before finding the | ||
* first collision can be expressed as the quantity `Q(H)` | ||
* | ||
* Then `Q(H)` can be approximated as the square root of the product of half | ||
* of pi times `H`: | ||
* | ||
* <div style="background: white; padding: 5px; border-radius: 5px; overflow: hidden;"> | ||
* <img src="https://render.githubusercontent.com/render/math?math=%5CHuge%20Q(H)%5Capprox%5Csqrt%7B%5Cfrac%7B%5Cpi%7D%7B2%7DH%7D"/> | ||
* </div> | ||
* | ||
* This function returns `Q(H)`. | ||
* | ||
* (see [Poisson distribution](https://en.wikipedia.org/wiki/Poisson_distribution)) | ||
*/ | ||
__publicField(this, "approxMaxBeforeCollision", (rounds = this.availableUUIDs(this.uuidLength)) => { | ||
return parseFloat( | ||
Math.sqrt(Math.PI / 2 * rounds).toFixed(20) | ||
); | ||
}); | ||
/** | ||
* Calculates probability of generating duplicate UUIDs (a collision) in a | ||
* given number of UUID generation rounds. | ||
* | ||
* Given that: | ||
* | ||
* - `r` is the maximum number of times that `randomUUID()` will be called, | ||
* or better said the number of _rounds_ | ||
* - `H` is the total number of possible UUIDs, or in terms of this library, | ||
* the result of running `availableUUIDs()` | ||
* | ||
* Then the probability of collision `p(r; H)` can be approximated as the result | ||
* of dividing the square root of the product of half of pi times `r` by `H`: | ||
* | ||
* <div style="background: white; padding: 5px; border-radius: 5px; overflow: hidden;"> | ||
* <img src="https://render.githubusercontent.com/render/math?math=%5CHuge%20p(r%3B%20H)%5Capprox%5Cfrac%7B%5Csqrt%7B%5Cfrac%7B%5Cpi%7D%7B2%7Dr%7D%7D%7BH%7D"/> | ||
* </div> | ||
* | ||
* This function returns `p(r; H)`. | ||
* | ||
* (see [Poisson distribution](https://en.wikipedia.org/wiki/Poisson_distribution)) | ||
* | ||
* (Useful if you are wondering _"If I use this lib and expect to perform at most | ||
* `r` rounds of UUID generations, what is the probability that I will hit a duplicate UUID?"_.) | ||
*/ | ||
__publicField(this, "collisionProbability", (rounds = this.availableUUIDs(this.uuidLength), uuidLength = this.uuidLength) => { | ||
return parseFloat( | ||
(this.approxMaxBeforeCollision(rounds) / this.availableUUIDs(uuidLength)).toFixed(20) | ||
); | ||
}); | ||
/** | ||
* Calculate a "uniqueness" score (from 0 to 1) of UUIDs based on size of | ||
* dictionary and chosen UUID length. | ||
* | ||
* Given that: | ||
* | ||
* - `H` is the total number of possible UUIDs, or in terms of this library, | ||
* the result of running `availableUUIDs()` | ||
* - `Q(H)` is the approximate number of hashes before first collision, | ||
* or in terms of this library, the result of running `approxMaxBeforeCollision()` | ||
* | ||
* Then `uniqueness` can be expressed as the additive inverse of the probability of | ||
* generating a "word" I had previously generated (a duplicate) at any given iteration | ||
* up to the the total number of possible UUIDs expressed as the quotiend of `Q(H)` and `H`: | ||
* | ||
* <div style="background: white; padding: 5px; border-radius: 5px; overflow: hidden;"> | ||
* <img src="https://render.githubusercontent.com/render/math?math=%5CHuge%201-%5Cfrac%7BQ(H)%7D%7BH%7D"/> | ||
* </div> | ||
* | ||
* (Useful if you need a value to rate the "quality" of the combination of given dictionary | ||
* and UUID length. The closer to 1, higher the uniqueness and thus better the quality.) | ||
*/ | ||
__publicField(this, "uniqueness", (rounds = this.availableUUIDs(this.uuidLength)) => { | ||
const score = parseFloat( | ||
(1 - this.approxMaxBeforeCollision(rounds) / rounds).toFixed(20) | ||
); | ||
return score > 1 ? 1 : score < 0 ? 0 : score; | ||
}; | ||
this.getVersion = () => { | ||
}); | ||
/** | ||
* Return the version of this module. | ||
*/ | ||
__publicField(this, "getVersion", () => { | ||
return this.version; | ||
}; | ||
this.stamp = (finalLength) => { | ||
}); | ||
/** | ||
* Generates a UUID with a timestamp that can be extracted using `uid.parseStamp(stampString);`. | ||
* | ||
* ```js | ||
* const uidWithTimestamp = uid.stamp(32); | ||
* console.log(uidWithTimestamp); | ||
* // GDa608f973aRCHLXQYPTbKDbjDeVsSb3 | ||
* | ||
* console.log(uid.parseStamp(uidWithTimestamp)); | ||
* // 2021-05-03T06:24:58.000Z | ||
* ``` | ||
*/ | ||
__publicField(this, "stamp", (finalLength, date) => { | ||
const hexStamp = Math.floor(+(date || /* @__PURE__ */ new Date()) / 1e3).toString(16); | ||
if (typeof finalLength === "number" && finalLength === 0) { | ||
return hexStamp; | ||
} | ||
if (typeof finalLength !== "number" || finalLength < 10) { | ||
throw new Error("Param finalLength must be number greater than 10"); | ||
throw new Error( | ||
[ | ||
"Param finalLength must be a number greater than or equal to 10,", | ||
"or 0 if you want the raw hexadecimal timestamp" | ||
].join("\n") | ||
); | ||
} | ||
const hexStamp = Math.floor(+new Date() / 1e3).toString(16); | ||
const idLength = finalLength - 9; | ||
const rndIdx = Math.round(Math.random() * (idLength > 15 ? 15 : idLength)); | ||
const id = this.randomUUID(idLength); | ||
return `${id.substr(0, rndIdx)}${hexStamp}${id.substr(rndIdx)}${rndIdx.toString(16)}`; | ||
}; | ||
this.parseStamp = (stamp) => { | ||
return `${id.substring(0, rndIdx)}${hexStamp}${id.substring(rndIdx)}${rndIdx.toString(16)}`; | ||
}); | ||
/** | ||
* Extracts the date embeded in a UUID generated using the `uid.stamp(finalLength);` method. | ||
* | ||
* ```js | ||
* const uidWithTimestamp = uid.stamp(32); | ||
* console.log(uidWithTimestamp); | ||
* // GDa608f973aRCHLXQYPTbKDbjDeVsSb3 | ||
* | ||
* console.log(uid.parseStamp(uidWithTimestamp)); | ||
* // 2021-05-03T06:24:58.000Z | ||
* ``` | ||
*/ | ||
__publicField(this, "parseStamp", (suid, format) => { | ||
if (format && !/t0|t[1-9]\d{1,}/.test(format)) { | ||
throw new Error("Cannot extract date from a formated UUID with no timestamp in the format"); | ||
} | ||
const stamp = format ? format.replace( | ||
/\$[rs]\d{0,}|\$t0|\$t[1-9]\d{1,}/g, | ||
(m) => { | ||
const fnMap = { | ||
"$r": (len2) => [...Array(len2)].map(() => "r").join(""), | ||
"$s": (len2) => [...Array(len2)].map(() => "s").join(""), | ||
"$t": (len2) => [...Array(len2)].map(() => "t").join("") | ||
}; | ||
const fn = m.slice(0, 2); | ||
const len = parseInt(m.slice(2), 10); | ||
return fnMap[fn](len); | ||
} | ||
).replace( | ||
/^(.*?)(t{8,})(.*)$/g, | ||
(_m, p1, p2) => { | ||
return suid.substring(p1.length, p1.length + p2.length); | ||
} | ||
) : suid; | ||
if (stamp.length === 8) { | ||
return new Date(parseInt(stamp, 16) * 1e3); | ||
} | ||
if (stamp.length < 10) { | ||
throw new Error("Stamp length invalid"); | ||
} | ||
const rndIdx = parseInt(stamp.substr(stamp.length - 1, 1), 16); | ||
return new Date(parseInt(stamp.substr(rndIdx, 8), 16) * 1e3); | ||
}; | ||
const rndIdx = parseInt(stamp.substring(stamp.length - 1), 16); | ||
return new Date(parseInt(stamp.substring(rndIdx, rndIdx + 8), 16) * 1e3); | ||
}); | ||
/** | ||
* Set the counter to a specific value. | ||
*/ | ||
__publicField(this, "setCounter", (counter) => { | ||
this.counter = counter; | ||
}); | ||
const options = __spreadValues(__spreadValues({}, DEFAULT_OPTIONS), argOptions); | ||
@@ -206,19 +440,38 @@ this.counter = 0; | ||
shuffle, | ||
length | ||
length, | ||
counter | ||
} = options; | ||
this.uuidLength = length; | ||
this.setDictionary(dictionary, shuffle); | ||
this.setCounter(counter); | ||
this.debug = options.debug; | ||
this.log(this.dict); | ||
this.log(`Generator instantiated with Dictionary Size ${this.dictLength}`); | ||
return new Proxy(this, { | ||
apply: (target, that, args) => this.randomUUID(...args) | ||
}); | ||
this.log( | ||
`Generator instantiated with Dictionary Size ${this.dictLength} and counter set to ${this.counter}` | ||
); | ||
this.log = this.log.bind(this); | ||
this.setDictionary = this.setDictionary.bind(this); | ||
this.setCounter = this.setCounter.bind(this); | ||
this.seq = this.seq.bind(this); | ||
this.sequentialUUID = this.sequentialUUID.bind(this); | ||
this.rnd = this.rnd.bind(this); | ||
this.randomUUID = this.randomUUID.bind(this); | ||
this.fmt = this.fmt.bind(this); | ||
this.formattedUUID = this.formattedUUID.bind(this); | ||
this.availableUUIDs = this.availableUUIDs.bind(this); | ||
this.approxMaxBeforeCollision = this.approxMaxBeforeCollision.bind(this); | ||
this.collisionProbability = this.collisionProbability.bind(this); | ||
this.uniqueness = this.uniqueness.bind(this); | ||
this.getVersion = this.getVersion.bind(this); | ||
this.stamp = this.stamp.bind(this); | ||
this.parseStamp = this.parseStamp.bind(this); | ||
return this; | ||
} | ||
}; | ||
/** @hidden */ | ||
__publicField(_ShortUniqueId, "default", _ShortUniqueId); | ||
var ShortUniqueId = _ShortUniqueId; | ||
ShortUniqueId.default = _ShortUniqueId; | ||
return src_exports; | ||
return __toCommonJS(src_exports); | ||
})(); | ||
//# sourceMappingURL=short-unique-id.js.map | ||
'undefined'!=typeof module&&(module.exports=ShortUniqueId.default),'undefined'!=typeof window&&(ShortUniqueId=ShortUniqueId.default); |
@@ -1,2 +0,3 @@ | ||
var ShortUniqueId=(()=>{var h=Object.defineProperty;var _=Object.getOwnPropertySymbols;var m=Object.prototype.hasOwnProperty,f=Object.prototype.propertyIsEnumerable;var g=(r,t,i)=>t in r?h(r,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):r[t]=i,l=(r,t)=>{for(var i in t||(t={}))m.call(t,i)&&g(r,i,t[i]);if(_)for(var i of _(t))f.call(t,i)&&g(r,i,t[i]);return r};var I=r=>h(r,"__esModule",{value:!0});var U=(r,t)=>{I(r);for(var i in t)h(r,i,{get:t[i],enumerable:!0})};var y={};U(y,{DEFAULT_UUID_LENGTH:()=>d,default:()=>n});var b="4.4.4";var d=6,q={dictionary:"alphanum",shuffle:!0,debug:!1,length:d},p=class extends Function{constructor(t={}){super();this.dictIndex=0;this.dictRange=[];this.lowerBound=0;this.upperBound=0;this.dictLength=0;this._digit_first_ascii=48;this._digit_last_ascii=58;this._alpha_lower_first_ascii=97;this._alpha_lower_last_ascii=123;this._hex_last_ascii=103;this._alpha_upper_first_ascii=65;this._alpha_upper_last_ascii=91;this._number_dict_ranges={digits:[this._digit_first_ascii,this._digit_last_ascii]};this._alpha_dict_ranges={lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii],upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]};this._alpha_lower_dict_ranges={lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii]};this._alpha_upper_dict_ranges={upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]};this._alphanum_dict_ranges={digits:[this._digit_first_ascii,this._digit_last_ascii],lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii],upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]};this._alphanum_lower_dict_ranges={digits:[this._digit_first_ascii,this._digit_last_ascii],lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii]};this._alphanum_upper_dict_ranges={digits:[this._digit_first_ascii,this._digit_last_ascii],upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]};this._hex_dict_ranges={decDigits:[this._digit_first_ascii,this._digit_last_ascii],alphaDigits:[this._alpha_lower_first_ascii,this._hex_last_ascii]};this.log=(...t)=>{let i=[...t];if(i[0]=`[short-unique-id] ${t[0]}`,this.debug===!0&&typeof console!="undefined"&&console!==null)return console.log(...i)};this.setDictionary=(t,i)=>{let e;if(t&&Array.isArray(t)&&t.length>1)e=t;else{e=[];let s;this.dictIndex=s=0;let a=`_${t}_dict_ranges`,o=this[a];Object.keys(o).forEach(c=>{let u=c;for(this.dictRange=o[u],this.lowerBound=this.dictRange[0],this.upperBound=this.dictRange[1],this.dictIndex=s=this.lowerBound;this.lowerBound<=this.upperBound?s<this.upperBound:s>this.upperBound;this.dictIndex=this.lowerBound<=this.upperBound?s+=1:s-=1)e.push(String.fromCharCode(this.dictIndex))})}if(i){let s=.5;e=e.sort(()=>Math.random()-s)}this.dict=e,this.dictLength=this.dict.length,this.counter=0};this.seq=()=>this.sequentialUUID();this.sequentialUUID=()=>{let t,i,e="";t=this.counter;do i=t%this.dictLength,t=Math.trunc(t/this.dictLength),e+=this.dict[i];while(t!==0);return this.counter+=1,e};this.randomUUID=(t=this.uuidLength||d)=>{let i,e,s;if(t===null||typeof t=="undefined"||t<1)throw new Error("Invalid UUID Length Provided");let a=t>=0;for(i="",s=0;s<t;s+=1)e=parseInt((Math.random()*this.dictLength).toFixed(0),10)%this.dictLength,i+=this.dict[e];return i};this.availableUUIDs=(t=this.uuidLength)=>parseFloat(Math.pow([...new Set(this.dict)].length,t).toFixed(0));this.approxMaxBeforeCollision=(t=this.availableUUIDs(this.uuidLength))=>parseFloat(Math.sqrt(Math.PI/2*t).toFixed(20));this.collisionProbability=(t=this.availableUUIDs(this.uuidLength),i=this.uuidLength)=>parseFloat((this.approxMaxBeforeCollision(t)/this.availableUUIDs(i)).toFixed(20));this.uniqueness=(t=this.availableUUIDs(this.uuidLength))=>{let i=parseFloat((1-this.approxMaxBeforeCollision(t)/t).toFixed(20));return i>1?1:i<0?0:i};this.getVersion=()=>this.version;this.stamp=t=>{if(typeof t!="number"||t<10)throw new Error("Param finalLength must be number greater than 10");let i=Math.floor(+new Date/1e3).toString(16),e=t-9,s=Math.round(Math.random()*(e>15?15:e)),a=this.randomUUID(e);return`${a.substr(0,s)}${i}${a.substr(s)}${s.toString(16)}`};this.parseStamp=t=>{if(t.length<10)throw new Error("Stamp length invalid");let i=parseInt(t.substr(t.length-1,1),16);return new Date(parseInt(t.substr(i,8),16)*1e3)};let i=l(l({},q),t);this.counter=0,this.debug=!1,this.dict=[],this.version=b;let{dictionary:e,shuffle:s,length:a}=i;return this.uuidLength=a,this.setDictionary(e,s),this.debug=i.debug,this.log(this.dict),this.log(`Generator instantiated with Dictionary Size ${this.dictLength}`),new Proxy(this,{apply:(o,c,u)=>this.randomUUID(...u)})}},n=p;n.default=p;return y;})(); | ||
"use strict";var ShortUniqueId=(()=>{var l=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames,m=Object.getOwnPropertySymbols;var f=Object.prototype.hasOwnProperty,q=Object.prototype.propertyIsEnumerable;var g=(a,t,i)=>t in a?l(a,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):a[t]=i,b=(a,t)=>{for(var i in t||(t={}))f.call(t,i)&&g(a,i,t[i]);if(m)for(var i of m(t))q.call(t,i)&&g(a,i,t[i]);return a};var x=(a,t)=>{for(var i in t)l(a,i,{get:t[i],enumerable:!0})},y=(a,t,i,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of w(t))!f.call(a,r)&&r!==i&&l(a,r,{get:()=>t[r],enumerable:!(s=D(t,r))||s.enumerable});return a};var S=a=>y(l({},"__esModule",{value:!0}),a);var e=(a,t,i)=>(g(a,typeof t!="symbol"?t+"":t,i),i);var v={};x(v,{DEFAULT_OPTIONS:()=>I,DEFAULT_UUID_LENGTH:()=>d,default:()=>p});var U="5.0.0";var d=6,I={dictionary:"alphanum",shuffle:!0,debug:!1,length:d,counter:0},_=class _{constructor(t={}){e(this,"counter");e(this,"debug");e(this,"dict");e(this,"version");e(this,"dictIndex",0);e(this,"dictRange",[]);e(this,"lowerBound",0);e(this,"upperBound",0);e(this,"dictLength",0);e(this,"uuidLength");e(this,"_digit_first_ascii",48);e(this,"_digit_last_ascii",58);e(this,"_alpha_lower_first_ascii",97);e(this,"_alpha_lower_last_ascii",123);e(this,"_hex_last_ascii",103);e(this,"_alpha_upper_first_ascii",65);e(this,"_alpha_upper_last_ascii",91);e(this,"_number_dict_ranges",{digits:[this._digit_first_ascii,this._digit_last_ascii]});e(this,"_alpha_dict_ranges",{lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii],upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]});e(this,"_alpha_lower_dict_ranges",{lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii]});e(this,"_alpha_upper_dict_ranges",{upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]});e(this,"_alphanum_dict_ranges",{digits:[this._digit_first_ascii,this._digit_last_ascii],lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii],upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]});e(this,"_alphanum_lower_dict_ranges",{digits:[this._digit_first_ascii,this._digit_last_ascii],lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii]});e(this,"_alphanum_upper_dict_ranges",{digits:[this._digit_first_ascii,this._digit_last_ascii],upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]});e(this,"_hex_dict_ranges",{decDigits:[this._digit_first_ascii,this._digit_last_ascii],alphaDigits:[this._alpha_lower_first_ascii,this._hex_last_ascii]});e(this,"_dict_ranges",{_number_dict_ranges:this._number_dict_ranges,_alpha_dict_ranges:this._alpha_dict_ranges,_alpha_lower_dict_ranges:this._alpha_lower_dict_ranges,_alpha_upper_dict_ranges:this._alpha_upper_dict_ranges,_alphanum_dict_ranges:this._alphanum_dict_ranges,_alphanum_lower_dict_ranges:this._alphanum_lower_dict_ranges,_alphanum_upper_dict_ranges:this._alphanum_upper_dict_ranges,_hex_dict_ranges:this._hex_dict_ranges});e(this,"log",(...t)=>{let i=[...t];if(i[0]=`[short-unique-id] ${t[0]}`,this.debug===!0&&typeof console<"u"&&console!==null)return console.log(...i)});e(this,"setDictionary",(t,i)=>{let s;if(t&&Array.isArray(t)&&t.length>1)s=t;else{s=[];let r;this.dictIndex=r=0;let o=`_${t}_dict_ranges`,n=this._dict_ranges[o];Object.keys(n).forEach(h=>{let c=h;for(this.dictRange=n[c],this.lowerBound=this.dictRange[0],this.upperBound=this.dictRange[1],this.dictIndex=r=this.lowerBound;this.lowerBound<=this.upperBound?r<this.upperBound:r>this.upperBound;this.dictIndex=this.lowerBound<=this.upperBound?r+=1:r-=1)s.push(String.fromCharCode(this.dictIndex))})}i&&(s=s.sort(()=>Math.random()-.5)),this.dict=s,this.dictLength=this.dict.length,this.setCounter(0)});e(this,"seq",()=>this.sequentialUUID());e(this,"sequentialUUID",()=>{let t,i,s="";t=this.counter;do i=t%this.dictLength,t=Math.trunc(t/this.dictLength),s+=this.dict[i];while(t!==0);return this.counter+=1,s});e(this,"rnd",(t=this.uuidLength||d)=>this.randomUUID(t));e(this,"randomUUID",(t=this.uuidLength||d)=>{let i,s,r;if(t===null||typeof t>"u"||t<1)throw new Error("Invalid UUID Length Provided");let o=t>=0;for(i="",r=0;r<t;r+=1)s=parseInt((Math.random()*this.dictLength).toFixed(0),10)%this.dictLength,i+=this.dict[s];return i});e(this,"fmt",(t,i)=>this.formattedUUID(t,i));e(this,"formattedUUID",(t,i)=>{let s={$r:this.randomUUID,$s:this.sequentialUUID,$t:this.stamp};return t.replace(/\$[rs]\d{0,}|\$t0|\$t[1-9]\d{1,}/g,o=>{let n=o.slice(0,2),h=parseInt(o.slice(2),10);return n==="$s"?s[n]().padStart(h,"0"):n==="$t"&&i?s[n](h,i):s[n](h)})});e(this,"availableUUIDs",(t=this.uuidLength)=>parseFloat(Math.pow([...new Set(this.dict)].length,t).toFixed(0)));e(this,"approxMaxBeforeCollision",(t=this.availableUUIDs(this.uuidLength))=>parseFloat(Math.sqrt(Math.PI/2*t).toFixed(20)));e(this,"collisionProbability",(t=this.availableUUIDs(this.uuidLength),i=this.uuidLength)=>parseFloat((this.approxMaxBeforeCollision(t)/this.availableUUIDs(i)).toFixed(20)));e(this,"uniqueness",(t=this.availableUUIDs(this.uuidLength))=>{let i=parseFloat((1-this.approxMaxBeforeCollision(t)/t).toFixed(20));return i>1?1:i<0?0:i});e(this,"getVersion",()=>this.version);e(this,"stamp",(t,i)=>{let s=Math.floor(+(i||new Date)/1e3).toString(16);if(typeof t=="number"&&t===0)return s;if(typeof t!="number"||t<10)throw new Error(["Param finalLength must be a number greater than or equal to 10,","or 0 if you want the raw hexadecimal timestamp"].join(` | ||
`));let r=t-9,o=Math.round(Math.random()*(r>15?15:r)),n=this.randomUUID(r);return`${n.substring(0,o)}${s}${n.substring(o)}${o.toString(16)}`});e(this,"parseStamp",(t,i)=>{if(i&&!/t0|t[1-9]\d{1,}/.test(i))throw new Error("Cannot extract date from a formated UUID with no timestamp in the format");let s=i?i.replace(/\$[rs]\d{0,}|\$t0|\$t[1-9]\d{1,}/g,o=>{let n={$r:u=>[...Array(u)].map(()=>"r").join(""),$s:u=>[...Array(u)].map(()=>"s").join(""),$t:u=>[...Array(u)].map(()=>"t").join("")},h=o.slice(0,2),c=parseInt(o.slice(2),10);return n[h](c)}).replace(/^(.*?)(t{8,})(.*)$/g,(o,n,h)=>t.substring(n.length,n.length+h.length)):t;if(s.length===8)return new Date(parseInt(s,16)*1e3);if(s.length<10)throw new Error("Stamp length invalid");let r=parseInt(s.substring(s.length-1),16);return new Date(parseInt(s.substring(r,r+8),16)*1e3)});e(this,"setCounter",t=>{this.counter=t});let i=b(b({},I),t);this.counter=0,this.debug=!1,this.dict=[],this.version=U;let{dictionary:s,shuffle:r,length:o,counter:n}=i;return this.uuidLength=o,this.setDictionary(s,r),this.setCounter(n),this.debug=i.debug,this.log(this.dict),this.log(`Generator instantiated with Dictionary Size ${this.dictLength} and counter set to ${this.counter}`),this.log=this.log.bind(this),this.setDictionary=this.setDictionary.bind(this),this.setCounter=this.setCounter.bind(this),this.seq=this.seq.bind(this),this.sequentialUUID=this.sequentialUUID.bind(this),this.rnd=this.rnd.bind(this),this.randomUUID=this.randomUUID.bind(this),this.fmt=this.fmt.bind(this),this.formattedUUID=this.formattedUUID.bind(this),this.availableUUIDs=this.availableUUIDs.bind(this),this.approxMaxBeforeCollision=this.approxMaxBeforeCollision.bind(this),this.collisionProbability=this.collisionProbability.bind(this),this.uniqueness=this.uniqueness.bind(this),this.getVersion=this.getVersion.bind(this),this.stamp=this.stamp.bind(this),this.parseStamp=this.parseStamp.bind(this),this}};e(_,"default",_);var p=_;return S(v);})(); | ||
'undefined'!=typeof module&&(module.exports=ShortUniqueId.default),'undefined'!=typeof window&&(ShortUniqueId=ShortUniqueId.default); |
{ | ||
"name": "short-unique-id", | ||
"version": "4.4.4", | ||
"version": "5.0.0", | ||
"description": "Generate random or sequential UUID of any length", | ||
@@ -31,4 +31,4 @@ "keywords": [ | ||
"test": "ts-node src/test.ts", | ||
"build": "scripty", | ||
"docs": "scripty", | ||
"build": "./scripts/build", | ||
"docs": "./scripts/docs", | ||
"release": "release-it" | ||
@@ -41,3 +41,3 @@ }, | ||
"hooks": { | ||
"after:bump": "scripty" | ||
"after:bump": "./scripts/release" | ||
}, | ||
@@ -55,14 +55,15 @@ "npm": { | ||
"devDependencies": { | ||
"@types/node": "^16.6.1", | ||
"auto-changelog": "^2.3.0", | ||
"esbuild": "^0.12.20", | ||
"refup": "^1.0.0", | ||
"release-it": "^14.11.5", | ||
"scripty": "^2.0.0", | ||
"short-unique-id-typedoc-template": "2.0.4", | ||
"ts-node": "^10.2.0", | ||
"tslib": "^2.3.1", | ||
"typedoc": "^0.20.36", | ||
"typescript": "4.2.2" | ||
"@types/node": "^20.3.2", | ||
"auto-changelog": "^2.4.0", | ||
"esbuild": "^0.18.10", | ||
"refup": "^1.1.0", | ||
"release-it": "^15.11.0", | ||
"ts-node": "^10.9.1", | ||
"tslib": "^2.6.0", | ||
"typedoc": "^0.24.8", | ||
"typedoc-plugin-extras": "^2.3.3", | ||
"typedoc-plugin-rename-defaults": "^0.6.5", | ||
"typedoc-plugin-script-inject": "^1.0.0", | ||
"typescript": "^5.1.6" | ||
} | ||
} |
@@ -8,3 +8,3 @@ # Short Unique ID (UUID) Generating Library | ||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> | ||
[![9 Contributors](https://img.shields.io/badge/all_contributors-8-purple.svg)](#contributors) | ||
[![12 Contributors](https://img.shields.io/badge/all_contributors-12-purple.svg)](#contributors) | ||
<!-- ALL-CONTRIBUTORS-BADGE:END --> | ||
@@ -14,3 +14,3 @@ | ||
Tiny (4.6kB minified) no-dependency library for generating random or sequential UUID of any length | ||
Tiny (6.7kB minified) no-dependency library for generating random or sequential UUID of any length | ||
with exceptionally minuscule probabilies of duplicate IDs. | ||
@@ -20,6 +20,14 @@ | ||
const uid = new ShortUniqueId({ length: 10 }); | ||
uid(); // p0ZoB1FwH6 | ||
uid(); // mSjGCTfn8w | ||
uid(); // yt4Xx5nHMB | ||
uid.rnd(); // p0ZoB1FwH6 | ||
uid.rnd(); // mSjGCTfn8w | ||
uid.rnd(); // yt4Xx5nHMB | ||
// ... | ||
// or | ||
const { randomUUID } = new ShortUniqueId({ length: 10 }); | ||
randomUUID(); // e8Civ0HoDy | ||
randomUUID(); // iPjiGoHXAK | ||
randomUUID(); // n528gSMwTN | ||
// ... | ||
``` | ||
@@ -60,3 +68,4 @@ | ||
This project is open to updates by its users, I ensure that PRs are relevant to the community. | ||
This project is part of the [Open Collective](https://opencollective.com/simplyhexagonal) project [Simply Hexagonal](https://simplyhexagonal.org) | ||
and is open to updates by its users, we ensure that PRs are relevant to the community. | ||
In other words, if you find a bug or want a new feature, please help us by becoming one of the | ||
@@ -73,6 +82,13 @@ [contributors](#contributors-) ✌️ ! See the [contributing section](#contributing). | ||
## 📣 v4 Notice | ||
## 📣 v5 Notice | ||
### New Features 🥳 | ||
In order to improve security compliance we have removed the ability to use a ShortUniqueId as a | ||
function, i.e. `const uid = new ShortUniqueId(); uid();` is no longer supported. | ||
If you plan to upgrade to v5 make sure to refactor `uid();` to `uid.rnd();` in your code beforehand. | ||
For more information regarding this decision you can view [issue #53](https://github.com/simplyhexagonal/short-unique-id/issues/53). | ||
### Features | ||
The ability to generate UUIDs that contain a timestamp which can be extracted: | ||
@@ -121,3 +137,3 @@ | ||
const uid = new ShortUniqueId({ | ||
dictionary: 'hex', // the default | ||
dictionary: 'hex', | ||
}); | ||
@@ -135,6 +151,18 @@ | ||
Ability to use custom formatting. | ||
Where `$r` is random UUID, `$s` is sequential UUID, and `$t` is timestamp UUID: | ||
```js | ||
const timestamp = new Date('2023-01-29T03:21:21.000Z'); | ||
const result = uid.formattedUUID('Time: $t0 ID: $s2-$r4', timestamp); // timestamp is optional | ||
console.log(result); | ||
// Time: 63d5e631 ID: 0b-aaab | ||
``` | ||
### Use in CLI | ||
```sh | ||
$ npm install -g short-unique-id | ||
$ npm install --global short-unique-id | ||
@@ -145,6 +173,8 @@ $ suid -h | ||
# node short-unique-id [OPTION] | ||
# | ||
# Options: | ||
# -l, --length=ARG character length of the uid to generate. | ||
# -s, --stamp include timestamp in uid (must be used with --length (-l) of 10 or more). | ||
# -t, --timestamp=ARG custom timestamp to parse (must be used along with -s, --stamp, -f, or --format). | ||
# -f, --format=ARG string representing custom format to generate id with. | ||
# -p, --parse=ARG extract timestamp from stamped uid (ARG). | ||
@@ -160,5 +190,2 @@ # -d, --dictionaryJson=ARG json file with dictionary array. | ||
```js | ||
// Deno (web module) Import | ||
import ShortUniqueId from 'https://esm.sh/short-unique-id'; | ||
// ES6 / TypeScript Import | ||
@@ -169,2 +196,5 @@ import ShortUniqueId from 'short-unique-id'; | ||
const ShortUniqueId = require('short-unique-id'); | ||
// Deno (web module) Import | ||
import ShortUniqueId from 'https://esm.sh/short-unique-id'; | ||
``` | ||
@@ -179,3 +209,3 @@ | ||
// Random UUID | ||
console.log(uid()); | ||
console.log(uid.rnd()); | ||
@@ -186,2 +216,18 @@ // Sequential UUID | ||
alternatively using destructuring assignment: | ||
```js | ||
// Instantiate and destructure (long method name recommended for code readability) | ||
const { randomUUID, sequentialUUID } = new ShortUniqueId(); | ||
// Random UUID | ||
console.log(randomUUID()); | ||
// Sequential UUID | ||
console.log(sequentialUUID()); | ||
``` | ||
_NOTE:_ we made sure to use `bind()` on all ShortUniqueId methods to ensure that any options | ||
passed when creating the instance will be respected by the destructured methods. | ||
### Use in browser | ||
@@ -199,3 +245,3 @@ | ||
// Random UUID | ||
document.write(uid()); | ||
document.write(uid.rnd()); | ||
@@ -257,9 +303,13 @@ // Sequential UUID | ||
![image depicting over 12000 weekly npm downloads](https://raw.githubusercontent.com/jeanlescure/short-unique-id/main/assets/weekly-downloads.png) | ||
![image depicting over 100000 weekly cdn hits](https://raw.githubusercontent.com/jeanlescure/short-unique-id/main/assets/weekly-cdn-hits.png) | ||
![image depicting over 200000 weekly npm downloads](https://raw.githubusercontent.com/jeanlescure/short-unique-id/main/assets/weekly-downloads.png) | ||
![image depicting over 16000000 weekly cdn hits](https://raw.githubusercontent.com/jeanlescure/short-unique-id/main/assets/weekly-cdn-hits.png) | ||
Since this package is now reporting 12k+ npm weekly downloads and 100k+ weekly cdn hits, | ||
Since this package is now reporting 200k+ npm weekly downloads and 16M+ weekly cdn hits, | ||
we've gone ahead and re-written the whole of it in TypeScript and made sure to package | ||
dist modules compatible with Deno, Node.js and all major Browsers. | ||
## Sponsors | ||
- [Clever Synapse](https://cleversynapse.com) | ||
## Development | ||
@@ -336,3 +386,3 @@ | ||
Copyright (c) 2018-2021 [Short Unique ID Contributors](https://github.com/jeanlescure/short-unique-id/#contributors-).<br/> | ||
Copyright (c) 2018-2023 [Short Unique ID Contributors](https://github.com/jeanlescure/short-unique-id/#contributors-).<br/> | ||
Licensed under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
90765
798
374
12
9