@jackens/nnn 2024.2.19 → 2024.2.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/nnn.d.ts +220 -21
- package/nnn.js +419 -37
- package/package.json +3 -1
- package/readme.md +193 -186
- package/chartable.d.ts +0 -31
- package/chartable.js +0 -193
- package/eq.d.ts +0 -8
- package/eq.js +0 -83
- package/escape.d.ts +0 -18
- package/escape.js +0 -51
- package/fixTypography.d.ts +0 -8
- package/fixTypography.js +0 -61
- package/h.d.ts +0 -55
- package/h.js +0 -213
- package/has.d.ts +0 -9
- package/has.js +0 -40
- package/is.d.ts +0 -17
- package/is.js +0 -65
- package/jcss.d.ts +0 -33
- package/jcss.js +0 -293
- package/jsOnParse.d.ts +0 -20
- package/jsOnParse.js +0 -85
- package/locale.d.ts +0 -8
- package/locale.js +0 -39
- package/nanolight.d.ts +0 -6
- package/nanolight.js +0 -21
- package/nanolightJs.d.ts +0 -8
- package/nanolightJs.js +0 -29
- package/pick.d.ts +0 -14
- package/pick.js +0 -31
- package/plUral.d.ts +0 -8
- package/plUral.js +0 -39
- package/pro.d.ts +0 -8
- package/pro.js +0 -39
- package/refsInfo.d.ts +0 -11
- package/refsInfo.js +0 -57
- package/uuid1.d.ts +0 -16
- package/uuid1.js +0 -54
package/jsOnParse.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { has } from './has.js'
|
|
2
|
-
import { is } from './is.js'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* `JSON.parse` with “JavaScript turned on”.
|
|
6
|
-
*
|
|
7
|
-
* Objects having *exactly* one property which is present in the `handlers` map, i.e. objects of the form:
|
|
8
|
-
*
|
|
9
|
-
* ```js
|
|
10
|
-
* { "«handlerName»": [«params»] }
|
|
11
|
-
* ```
|
|
12
|
-
*
|
|
13
|
-
* are replaced by the result of call
|
|
14
|
-
*
|
|
15
|
-
* ```js
|
|
16
|
-
* handlers['«handlerName»'](...«params»)
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
export const jsOnParse = (
|
|
20
|
-
/** @type {Partial<Record<PropertyKey, Function>>} */ handlers,
|
|
21
|
-
/** @type {string} */ text
|
|
22
|
-
) => JSON.parse(text, (key, value) => {
|
|
23
|
-
if (is(Object, value)) {
|
|
24
|
-
let isSecondKey = false
|
|
25
|
-
|
|
26
|
-
for (key in value) {
|
|
27
|
-
if (isSecondKey) {
|
|
28
|
-
return value
|
|
29
|
-
}
|
|
30
|
-
isSecondKey = true
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (has(key, handlers) && is(Array, value[key])) {
|
|
34
|
-
// @ts-expect-error
|
|
35
|
-
return handlers[key](...value[key])
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return value
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
export const tests = {
|
|
43
|
-
jsOnParse: (/** @type {import('chai').expect} */ expect) => {
|
|
44
|
-
const handlers = {
|
|
45
|
-
$hello: (/** @type {string} */ name) => `Hello ${name}!`,
|
|
46
|
-
$foo: () => 'bar'
|
|
47
|
-
}
|
|
48
|
-
const actual = jsOnParse(handlers, `[
|
|
49
|
-
{
|
|
50
|
-
"$hello": ["World"]
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"nested": {
|
|
54
|
-
"$hello": ["nested World"]
|
|
55
|
-
},
|
|
56
|
-
"one": 1,
|
|
57
|
-
"two": 2
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
"$foo": []
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
"$foo": ["The parent object does not have exactly one property!"],
|
|
64
|
-
"one": 1,
|
|
65
|
-
"two": 2
|
|
66
|
-
}
|
|
67
|
-
]`)
|
|
68
|
-
const expected = [
|
|
69
|
-
'Hello World!',
|
|
70
|
-
{
|
|
71
|
-
nested: 'Hello nested World!',
|
|
72
|
-
one: 1,
|
|
73
|
-
two: 2
|
|
74
|
-
},
|
|
75
|
-
'bar',
|
|
76
|
-
{
|
|
77
|
-
$foo: ['The parent object does not have exactly one property!'],
|
|
78
|
-
one: 1,
|
|
79
|
-
two: 2
|
|
80
|
-
}
|
|
81
|
-
]
|
|
82
|
-
|
|
83
|
-
expect(actual).to.deep.equal(expected)
|
|
84
|
-
}
|
|
85
|
-
}
|
package/locale.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Language translations helper.
|
|
3
|
-
*/
|
|
4
|
-
export function locale(map: Partial<Record<PropertyKey, Partial<Record<PropertyKey, string>>>>, defaultVersion: string): (text: string, version?: string) => string;
|
|
5
|
-
|
|
6
|
-
export namespace tests {
|
|
7
|
-
function locale(expect: Chai.ExpectStatic): void;
|
|
8
|
-
}
|
package/locale.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { is } from './is.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Language translations helper.
|
|
5
|
-
*/
|
|
6
|
-
export const locale = (
|
|
7
|
-
/** @type {Partial<Record<PropertyKey, Partial<Record<PropertyKey, string>>>>} */ map,
|
|
8
|
-
/** @type {string} */ defaultVersion
|
|
9
|
-
) => (
|
|
10
|
-
/** @type {string} */ text,
|
|
11
|
-
/** @type {string} */ version = defaultVersion
|
|
12
|
-
) => {
|
|
13
|
-
const textV = map?.[version]?.[text]
|
|
14
|
-
const textD = map?.[defaultVersion]?.[text]
|
|
15
|
-
|
|
16
|
-
return is(String, textV) ? textV : is(String, textD) ? textD : text
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const tests = {
|
|
20
|
-
locale: (/** @type {import('chai').expect} */ expect) => {
|
|
21
|
-
const _ = locale({
|
|
22
|
-
default: { Password: 'Hasło' },
|
|
23
|
-
button: { Login: 'Zaloguj' }
|
|
24
|
-
}, 'default')
|
|
25
|
-
|
|
26
|
-
expect(_('Login')).to.deep.equal('Login')
|
|
27
|
-
expect(_('Password')).to.deep.equal('Hasło')
|
|
28
|
-
|
|
29
|
-
expect(_('Undefined text')).to.deep.equal('Undefined text')
|
|
30
|
-
|
|
31
|
-
expect(_('Login', 'button')).to.deep.equal('Zaloguj')
|
|
32
|
-
|
|
33
|
-
expect(_('Password', 'undefined_version')).to.deep.equal('Hasło')
|
|
34
|
-
expect(_('Undefined text', 'undefined_version')).to.deep.equal('Undefined text')
|
|
35
|
-
|
|
36
|
-
expect(_('toString')).to.deep.equal('toString')
|
|
37
|
-
expect(_('toString', 'undefined_version')).to.deep.equal('toString')
|
|
38
|
-
}
|
|
39
|
-
}
|
package/nanolight.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A generic helper for syntax highlighting (see also `nanolightJs`).
|
|
3
|
-
*/
|
|
4
|
-
export function nanolight(pattern: RegExp, highlighters: ((chunk: string, index: number) => import('./h.js').HArgs1)[], code: string): import("./h.js").HArgs1[];
|
|
5
|
-
|
|
6
|
-
export const tests: {};
|
package/nanolight.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A generic helper for syntax highlighting (see also `nanolightJs`).
|
|
3
|
-
*/
|
|
4
|
-
export const nanolight = (
|
|
5
|
-
/** @type {RegExp} */ pattern,
|
|
6
|
-
/** @type {((chunk: string, index: number) => import('./h.js').HArgs1)[]} */ highlighters,
|
|
7
|
-
/** @type {string} */ code
|
|
8
|
-
) => {
|
|
9
|
-
const /** @type {import('./h.js').HArgs1[]} */ result = []
|
|
10
|
-
|
|
11
|
-
code.split(pattern).forEach((chunk, index) => {
|
|
12
|
-
if (chunk != null && chunk !== '') {
|
|
13
|
-
index %= highlighters.length
|
|
14
|
-
result.push(highlighters[index](chunk, index))
|
|
15
|
-
}
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
return result
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const tests = {}
|
package/nanolightJs.d.ts
DELETED
package/nanolightJs.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { h } from './h.js'
|
|
2
|
-
import { nanolight } from './nanolight.js'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* A helper for highlighting JavaScript.
|
|
6
|
-
*/
|
|
7
|
-
// @ts-expect-error
|
|
8
|
-
export const nanolightJs = nanolight.bind(0,
|
|
9
|
-
/('.*?'|".*?"|`[\s\S]*?`)|(\/\/.*?\n|\/\*[\s\S]*?\*\/)|(any|bigint|break|boolean|case|catch|const|continue|debugger|default|delete|do|else|eval|export|extends|false|finally|for|from|function|goto|if|import|in|instanceof|is|keyof|let|NaN|new|number|null|package|return|string|super|switch|symbol|this|throw|true|try|type|typeof|undefined|unknown|var|void|while|with|yield)(?!\w)|([<>=.?:&|!^~*/%+-])|(0x[\dabcdef]+|0o[01234567]+|0b[01]+|\d+(?:\.[\d_]+)?(?:e[+-]?[\d_]+)?)|([$\w]+)(?=\()|([$\wąćęłńóśżźĄĆĘŁŃÓŚŻŹ]+)/,
|
|
10
|
-
[
|
|
11
|
-
chunk => chunk,
|
|
12
|
-
chunk => ['span', { class: 'string' }, chunk],
|
|
13
|
-
chunk => ['span', { class: 'comment' }, chunk],
|
|
14
|
-
chunk => ['span', { class: 'keyword' }, chunk],
|
|
15
|
-
chunk => ['span', { class: 'operator' }, chunk],
|
|
16
|
-
chunk => ['span', { class: 'number' }, chunk],
|
|
17
|
-
chunk => ['span', { class: 'function' }, chunk],
|
|
18
|
-
chunk => ['span', { class: 'literal' }, chunk]
|
|
19
|
-
]
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
export const tests = {
|
|
23
|
-
nanolightJs: (/** @type {import('chai').expect} */ expect) => {
|
|
24
|
-
const codeJs = 'const answerToLifeTheUniverseAndEverything = 42'
|
|
25
|
-
|
|
26
|
-
expect(h('pre', ['code', ...nanolightJs(codeJs)]).outerHTML).to.deep.equal(
|
|
27
|
-
'<pre><code><span class="keyword">const</span> <span class="literal">answerToLifeTheUniverseAndEverything</span> <span class="operator">=</span> <span class="number">42</span></code></pre>')
|
|
28
|
-
}
|
|
29
|
-
}
|
package/pick.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A helper that implements TypeScript’s `Omit` utility type.
|
|
3
|
-
*/
|
|
4
|
-
export const omit: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: T, keys: K) => Omit<T, K[number]>;
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* A helper that implements TypeScript’s `Pick` utility type.
|
|
8
|
-
*/
|
|
9
|
-
export const pick: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: T, keys: K) => Pick<T, K[number]>;
|
|
10
|
-
|
|
11
|
-
export namespace tests {
|
|
12
|
-
function pick(expect: Chai.ExpectStatic): void;
|
|
13
|
-
function omit(expect: Chai.ExpectStatic): void;
|
|
14
|
-
}
|
package/pick.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A helper that implements TypeScript’s `Pick` utility type.
|
|
3
|
-
*
|
|
4
|
-
* @type {<T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: T, keys: K) => Pick<T, K[number]>}
|
|
5
|
-
*/
|
|
6
|
-
export const pick = (/** @type {Partial<Record<PropertyKey, any>>} */ obj, /** @type {any[]} */ keys) =>
|
|
7
|
-
// @ts-expect-error
|
|
8
|
-
Object.fromEntries(Object.entries(obj).filter(([key]) => keys.includes(key)))
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* A helper that implements TypeScript’s `Omit` utility type.
|
|
12
|
-
*
|
|
13
|
-
* @type {<T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: T, keys: K) => Omit<T, K[number]>}
|
|
14
|
-
*/
|
|
15
|
-
export const omit = (/** @type {Partial<Record<PropertyKey, any>>} */ obj, /** @type {any[]} */ keys) =>
|
|
16
|
-
// @ts-expect-error
|
|
17
|
-
Object.fromEntries(Object.entries(obj).filter(([key]) => !keys.includes(key)))
|
|
18
|
-
|
|
19
|
-
export const tests = {
|
|
20
|
-
pick: (/** @type {import('chai').expect} */ expect) => {
|
|
21
|
-
const obj = { a: 42, b: '42', c: 17 }
|
|
22
|
-
|
|
23
|
-
expect(pick(obj, ['a', 'b'])).to.deep.equal({ a: 42, b: '42' })
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
omit: (/** @type {import('chai').expect} */ expect) => {
|
|
27
|
-
const obj = { a: 42, b: '42', c: 17 }
|
|
28
|
-
|
|
29
|
-
expect(omit(obj, ['c'])).to.deep.equal({ a: 42, b: '42' })
|
|
30
|
-
}
|
|
31
|
-
}
|
package/plUral.d.ts
DELETED
package/plUral.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A helper for choosing the correct singular and plural.
|
|
3
|
-
*/
|
|
4
|
-
export const plUral = (
|
|
5
|
-
/** @type {string} */ singular,
|
|
6
|
-
/** @type {string} */ plural2,
|
|
7
|
-
/** @type {string} */ plural5,
|
|
8
|
-
/** @type {number} */ value
|
|
9
|
-
) => {
|
|
10
|
-
const absValue = Math.abs(value)
|
|
11
|
-
const absValueMod10 = absValue % 10
|
|
12
|
-
|
|
13
|
-
return value === 1
|
|
14
|
-
? singular
|
|
15
|
-
: (absValueMod10 === 2 || absValueMod10 === 3 || absValueMod10 === 4) &&
|
|
16
|
-
absValue !== 12 && absValue !== 13 && absValue !== 14
|
|
17
|
-
? plural2
|
|
18
|
-
: plural5
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const tests = {
|
|
22
|
-
plUral: (/** @type {import('chai').expect} */ expect) => {
|
|
23
|
-
// @ts-expect-error
|
|
24
|
-
const auto = plUral.bind(null, 'auto', 'auta', 'aut')
|
|
25
|
-
|
|
26
|
-
expect(auto(0)).to.deep.equal('aut')
|
|
27
|
-
expect(auto(1)).to.deep.equal('auto')
|
|
28
|
-
expect(auto(17)).to.deep.equal('aut')
|
|
29
|
-
expect(auto(42)).to.deep.equal('auta')
|
|
30
|
-
|
|
31
|
-
// @ts-expect-error
|
|
32
|
-
const car = plUral.bind(null, 'car', 'cars', 'cars')
|
|
33
|
-
|
|
34
|
-
expect(car(0)).to.deep.equal('cars')
|
|
35
|
-
expect(car(1)).to.deep.equal('car')
|
|
36
|
-
expect(car(17)).to.deep.equal('cars')
|
|
37
|
-
expect(car(42)).to.deep.equal('cars')
|
|
38
|
-
}
|
|
39
|
-
}
|
package/pro.d.ts
DELETED
package/pro.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A helper that protects calls to nested properties by a `Proxy` that initializes non-existent values with an empty object.
|
|
3
|
-
*/
|
|
4
|
-
// @ts-expect-error
|
|
5
|
-
export const pro = (/** @type {any} */ ref) => new Proxy(ref, {
|
|
6
|
-
get (target, key) {
|
|
7
|
-
return pro(target[key] = target[key] ?? {})
|
|
8
|
-
}
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
export const tests = {
|
|
12
|
-
pro: (/** @type {import('chai').expect} */ expect) => {
|
|
13
|
-
const ref = {}
|
|
14
|
-
|
|
15
|
-
pro(ref).one.two[3][4] = 1234
|
|
16
|
-
|
|
17
|
-
expect(ref).to.deep.equal({ one: { two: { 3: { 4: 1234 } } } })
|
|
18
|
-
|
|
19
|
-
pro(ref).one.two.tree = 123
|
|
20
|
-
|
|
21
|
-
expect(ref).to.deep.equal({ one: { two: { 3: { 4: 1234 }, tree: 123 } } })
|
|
22
|
-
|
|
23
|
-
pro(ref).one.two = undefined
|
|
24
|
-
|
|
25
|
-
expect(ref).to.deep.equal({ one: { two: undefined } })
|
|
26
|
-
|
|
27
|
-
delete pro(ref).one.two
|
|
28
|
-
|
|
29
|
-
expect(ref).to.deep.equal({ one: {} })
|
|
30
|
-
|
|
31
|
-
pro(ref).one.two.three.four
|
|
32
|
-
|
|
33
|
-
expect(ref).to.deep.equal({ one: { two: { three: { four: {} } } } })
|
|
34
|
-
|
|
35
|
-
pro(ref).one.two.three.four = 1234
|
|
36
|
-
|
|
37
|
-
expect(ref).to.deep.equal({ one: { two: { three: { four: 1234 } } } })
|
|
38
|
-
}
|
|
39
|
-
}
|
package/refsInfo.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A helper that provides information about the given `refs`.
|
|
3
|
-
*
|
|
4
|
-
* It returns an array of triples: `[«name», «prototype-name», «array-of-own-property-names»]`.
|
|
5
|
-
*/
|
|
6
|
-
export function refsInfo(...refs: any[]): [string, string, string[]][];
|
|
7
|
-
|
|
8
|
-
export const tests: {
|
|
9
|
-
refsInfo: (expect: Chai.ExpectStatic) => void;
|
|
10
|
-
'refsInfo: browserFingerprint': (expect: Chai.ExpectStatic) => void;
|
|
11
|
-
};
|
package/refsInfo.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { is } from './is.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* A helper that provides information about the given `refs`.
|
|
5
|
-
*
|
|
6
|
-
* It returns an array of triples: `[«name», «prototype-name», «array-of-own-property-names»]`.
|
|
7
|
-
*/
|
|
8
|
-
export const refsInfo = (/** @type {any[]} */ ...refs) => {
|
|
9
|
-
const /** @type {Set<Function>} */ fns = new Set()
|
|
10
|
-
|
|
11
|
-
refs.forEach(ref => {
|
|
12
|
-
while (is(Function, ref) && !fns.has(ref) && `${ref}`.includes('[native code]')) {
|
|
13
|
-
fns.add(ref)
|
|
14
|
-
ref = Object.getPrototypeOf(ref)
|
|
15
|
-
}
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
return Array.from(fns.values()).map(/** @return {[string, string, string[]]} */ fn => [
|
|
19
|
-
fn.name,
|
|
20
|
-
Object.getPrototypeOf(fn)?.name ?? '',
|
|
21
|
-
Object.getOwnPropertyNames(fn.prototype ?? Object.create(null)).sort()
|
|
22
|
-
]).sort((a, b) => -(a[0] < b[0]))
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const tests = {
|
|
26
|
-
refsInfo: (/** @type {import('chai').expect} */ expect) => {
|
|
27
|
-
const info = refsInfo(Array, Function)
|
|
28
|
-
|
|
29
|
-
expect(info.find(([name]) => name === 'Array')?.[2]?.includes('length')).to.be.true
|
|
30
|
-
expect(info.find(([name]) => name === 'Function')?.[2]?.includes('length')).to.be.true
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
'refsInfo: browserFingerprint': (/** @type {import('chai').expect} */ expect) => {
|
|
34
|
-
const browserFingerprint = () => {
|
|
35
|
-
// @ts-expect-error
|
|
36
|
-
const refs = Object.getOwnPropertyNames(window).map(name => window[name])
|
|
37
|
-
const info = refsInfo(...refs)
|
|
38
|
-
const json = JSON.stringify(info)
|
|
39
|
-
const hash = Array(32).fill(0)
|
|
40
|
-
let j = 0
|
|
41
|
-
|
|
42
|
-
for (let i = 0; i < json.length; i++) {
|
|
43
|
-
let charCode = json.charCodeAt(i)
|
|
44
|
-
|
|
45
|
-
while (charCode > 0) {
|
|
46
|
-
hash[j] = hash[j] ^ (charCode & 15)
|
|
47
|
-
charCode >>= 4
|
|
48
|
-
j = (j + 1) & 31
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return hash.map(x => x.toString(16)).join('')
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
console.log(browserFingerprint())
|
|
56
|
-
}
|
|
57
|
-
}
|
package/uuid1.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export const tests: {
|
|
2
|
-
uuid1: (expect: Chai.ExpectStatic) => void;
|
|
3
|
-
'uuid1: node': (expect: Chai.ExpectStatic) => void;
|
|
4
|
-
'uuid1: date': (expect: Chai.ExpectStatic) => void;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* A helper that generates a UUID v1 identifier (with a creation timestamp).
|
|
9
|
-
*
|
|
10
|
-
* - The optional `node` parameter should have the format `/^[0123456789abcdef]+$/`.
|
|
11
|
-
* Its value will be trimmed to last 12 characters and left padded with zeros.
|
|
12
|
-
*/
|
|
13
|
-
export function uuid1({ date, node }?: {
|
|
14
|
-
date?: Date | undefined;
|
|
15
|
-
node?: string | undefined;
|
|
16
|
-
}): string;
|
package/uuid1.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
const ZEROS = '0'.repeat(16)
|
|
2
|
-
let counter = 0
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* A helper that generates a UUID v1 identifier (with a creation timestamp).
|
|
6
|
-
*
|
|
7
|
-
* - The optional `node` parameter should have the format `/^[0123456789abcdef]+$/`.
|
|
8
|
-
* Its value will be trimmed to last 12 characters and left padded with zeros.
|
|
9
|
-
*/
|
|
10
|
-
export const uuid1 = ({
|
|
11
|
-
date = new Date(),
|
|
12
|
-
node = Math.random().toString(16).slice(2)
|
|
13
|
-
} = {}) => {
|
|
14
|
-
const time = ZEROS + (10000 * (+date + 12219292800000)).toString(16)
|
|
15
|
-
|
|
16
|
-
counter = (counter + 1) & 16383
|
|
17
|
-
|
|
18
|
-
return time.slice(-8).concat(
|
|
19
|
-
'-',
|
|
20
|
-
time.slice(-12, -8),
|
|
21
|
-
// @ts-expect-error
|
|
22
|
-
-1,
|
|
23
|
-
time.slice(-15, -12),
|
|
24
|
-
'-',
|
|
25
|
-
(8 | (counter >> 12)).toString(16),
|
|
26
|
-
(ZEROS + (counter & 4095).toString(16)).slice(-3),
|
|
27
|
-
'-',
|
|
28
|
-
(ZEROS + node).slice(-12))
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export const tests = {
|
|
32
|
-
uuid1: (/** @type {import('chai').expect} */ expect) => {
|
|
33
|
-
for (let i = 1; i <= 22136; ++i) {
|
|
34
|
-
const uuid = uuid1()
|
|
35
|
-
|
|
36
|
-
i === 1 && expect(uuid.split('-')[3]).to.deep.equal('8001')
|
|
37
|
-
i === 4095 && expect(uuid.split('-')[3]).to.deep.equal('8fff')
|
|
38
|
-
i === 4096 && expect(uuid.split('-')[3]).to.deep.equal('9000')
|
|
39
|
-
i === 9029 && expect(uuid.split('-')[3]).to.deep.equal('a345')
|
|
40
|
-
i === 13398 && expect(uuid.split('-')[3]).to.deep.equal('b456')
|
|
41
|
-
i === 16384 && expect(uuid.split('-')[3]).to.deep.equal('8000')
|
|
42
|
-
i === 17767 && expect(uuid.split('-')[3]).to.deep.equal('8567')
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
'uuid1: node': (/** @type {import('chai').expect} */ expect) => {
|
|
47
|
-
expect(uuid1({ node: '000123456789abc' }).split('-')[4]).to.deep.equal('123456789abc')
|
|
48
|
-
expect(uuid1({ node: '123456789' }).split('-')[4]).to.deep.equal('000123456789')
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
'uuid1: date': (/** @type {import('chai').expect} */ expect) => {
|
|
52
|
-
expect(uuid1({ date: new Date(323325000000) }).startsWith('c1399400-9a71-11bd')).to.be.true
|
|
53
|
-
}
|
|
54
|
-
}
|