@glion/util-uid 0.18.0
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/LICENSE +21 -0
- package/README.md +47 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/invariant.d.ts +12 -0
- package/dist/invariant.d.ts.map +1 -0
- package/dist/uid.d.ts +34 -0
- package/dist/uid.d.ts.map +1 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Rethink Health
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# @glion/util-uid
|
|
2
|
+
|
|
3
|
+
Time-ordered, HL7v2-safe unique IDs.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
`@glion/util-uid` generates short, sortable, HL7v2-safe unique IDs. Use them for MSH-10 message control IDs, order numbers, or any field that needs a unique identifier.
|
|
8
|
+
|
|
9
|
+
- **Fits MSH-10.** IDs are 20 characters — a standard ULID is 26 and does not fit.
|
|
10
|
+
- **Sorts by time.** IDs start with a timestamp, so sorting IDs sorts by creation time.
|
|
11
|
+
- **Safe characters only.** Digits and uppercase letters, minus I, L, O, and U: no HL7 delimiters, easy to read aloud, hard to mistype.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @glion/util-uid
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Use
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { uid } from "@glion/util-uid";
|
|
23
|
+
|
|
24
|
+
const controlId = uid(); // e.g. for MSH-10
|
|
25
|
+
// "01J9Z6M8QKT5W3XA9C0D" — 20 characters, sorts by generation time
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Need a branded ID? Compose it: `"MKE" + uid({ size: 17 })`.
|
|
29
|
+
|
|
30
|
+
## API
|
|
31
|
+
|
|
32
|
+
### `uid(options?)`
|
|
33
|
+
|
|
34
|
+
Generates a time-ordered unique identifier.
|
|
35
|
+
|
|
36
|
+
| Parameter | Type | Default | Description |
|
|
37
|
+
| -------------- | -------- | ------- | -------------------------------- |
|
|
38
|
+
| `options.size` | `number` | `20` | Total length of the generated ID |
|
|
39
|
+
|
|
40
|
+
The time part needs 10 characters: keep `size >= 11`, or the ID degrades to a pure-random tail (unique, but not time-ordered). `size` must be a positive integer (`RangeError` otherwise). Per-millisecond uniqueness rests entirely on the random tail, so prefer the full default width when volumes are high.
|
|
41
|
+
|
|
42
|
+
## Part of Glion
|
|
43
|
+
|
|
44
|
+
`@glion/util-uid` is part of **[Glion]**, the application framework for HL7v2. See the [Glion README] for the full package catalog and architecture.
|
|
45
|
+
|
|
46
|
+
[Glion]: https://github.com/rethinkhealth/glion#readme
|
|
47
|
+
[Glion README]: https://github.com/rethinkhealth/glion#readme
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,YAAY,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
//#region src/invariant.ts
|
|
2
|
+
/**
|
|
3
|
+
* Assertion primitives for this package's own internal invariants — bugs in
|
|
4
|
+
* OUR arithmetic, never domain outcomes (a NAK is an `AckException`; an
|
|
5
|
+
* invariant failure must never masquerade as one).
|
|
6
|
+
*/
|
|
7
|
+
/** Thrown when an internal invariant is violated — always a bug; report it. */
|
|
8
|
+
var InvariantError = class extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(`@glion/util-uid internal invariant violated: ${message} — this is a bug, please report it`);
|
|
11
|
+
this.name = "InvariantError";
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
/** Assert `condition`; the `asserts` signature also narrows types for tsc. */
|
|
15
|
+
function invariant(condition, message) {
|
|
16
|
+
if (!condition) throw new InvariantError(message);
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/uid.ts
|
|
20
|
+
/**
|
|
21
|
+
* Time-ordered unique IDs for HL7v2 identifier fields — the ULID idea
|
|
22
|
+
* resized to a 20-character default that fits MSH-10, the tightest common
|
|
23
|
+
* ST field (a standard 26-character ULID cannot fit).
|
|
24
|
+
* Stateless: fresh randomness every call, the same semantics as the ULID
|
|
25
|
+
* reference implementation's default `ulid()`.
|
|
26
|
+
*
|
|
27
|
+
* @module
|
|
28
|
+
*/
|
|
29
|
+
const MAX_LENGTH = 20;
|
|
30
|
+
const TIME_LENGTH = 10;
|
|
31
|
+
const ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
32
|
+
/**
|
|
33
|
+
* Encode `value` as exactly `length` Crockford base32 characters,
|
|
34
|
+
* zero-padded. Throws when `value` is not a non-negative integer below
|
|
35
|
+
* `32 ** length` — exported for its tests, not part of the package surface.
|
|
36
|
+
*/
|
|
37
|
+
function encodeCrockford(value, length) {
|
|
38
|
+
invariant(Number.isInteger(value) && value >= 0, `${value} is not encodable — the encoder takes non-negative integers`);
|
|
39
|
+
invariant(value < 32 ** length, `${value} does not fit ${length} base32 characters`);
|
|
40
|
+
let out = "";
|
|
41
|
+
let rest = value;
|
|
42
|
+
for (let i = 0; i < length; i++) {
|
|
43
|
+
out = ALPHABET[rest % 32] + out;
|
|
44
|
+
rest = Math.floor(rest / 32);
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* `length` Crockford characters of fresh randomness — exported for its
|
|
50
|
+
* tests, not part of the package surface.
|
|
51
|
+
*/
|
|
52
|
+
function randomChars(length) {
|
|
53
|
+
const bytes = new Uint8Array(length);
|
|
54
|
+
crypto.getRandomValues(bytes);
|
|
55
|
+
let out = "";
|
|
56
|
+
for (const byte of bytes) out += ALPHABET[byte % 32];
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Generate a time-ordered unique ID: timestamp + randomness, `size`
|
|
61
|
+
* characters total (default 20 — fits MSH-10's ST limit). IDs sort
|
|
62
|
+
* lexicographically by millisecond; same-millisecond IDs are unique but
|
|
63
|
+
* unordered. Keep `size >= 11`: the timestamp needs 10 characters, and
|
|
64
|
+
* per-millisecond uniqueness rests on what remains. Need a branded ID?
|
|
65
|
+
* Compose it: `"MKE" + uid({ size: 17 })`.
|
|
66
|
+
*/
|
|
67
|
+
function uid(options = {}) {
|
|
68
|
+
const { size = MAX_LENGTH } = options;
|
|
69
|
+
if (!(Number.isInteger(size) && size > 0)) throw new RangeError(`uid size must be a positive integer, got ${size}`);
|
|
70
|
+
if (size <= TIME_LENGTH) return randomChars(size);
|
|
71
|
+
return encodeCrockford(Date.now(), TIME_LENGTH) + randomChars(size - TIME_LENGTH);
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { uid };
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/invariant.ts","../src/uid.ts"],"sourcesContent":["/**\n * Assertion primitives for this package's own internal invariants — bugs in\n * OUR arithmetic, never domain outcomes (a NAK is an `AckException`; an\n * invariant failure must never masquerade as one).\n */\n\n/** Thrown when an internal invariant is violated — always a bug; report it. */\nexport class InvariantError extends Error {\n constructor(message: string) {\n super(\n `@glion/util-uid internal invariant violated: ${message} — this is a bug, please report it`\n );\n this.name = \"InvariantError\";\n }\n}\n\n/** Assert `condition`; the `asserts` signature also narrows types for tsc. */\nexport function invariant(\n condition: unknown,\n message: string\n): asserts condition {\n if (!condition) {\n throw new InvariantError(message);\n }\n}\n","/**\n * Time-ordered unique IDs for HL7v2 identifier fields — the ULID idea\n * resized to a 20-character default that fits MSH-10, the tightest common\n * ST field (a standard 26-character ULID cannot fit).\n * Stateless: fresh randomness every call, the same semantics as the ULID\n * reference implementation's default `ulid()`.\n *\n * @module\n */\n\nimport { invariant } from \"./invariant\";\n\n// Default budget: 20 characters — MSH-10's ST limit, the tightest common\n// HL7v2 identifier field.\nconst MAX_LENGTH = 20;\n\n// Characters the millisecond timestamp occupies. One base32 character is\n// 5 bits, so 10 characters hold 50 — every timestamp until the year 10889,\n// the same horizon as a standard ULID.\nconst TIME_LENGTH = 10;\n\n// Crockford base32 (https://www.crockford.com/base32.html): 0-9 plus the\n// uppercase alphabet minus I, L, O (read back as 1 and 0 by humans) and U\n// (accidental profanity). Index N encodes value N, so equal-length encodings\n// sort lexicographically in numeric order — what makes the IDs time-sortable\n// as plain strings. No HL7 delimiters, nothing legacy engines trip over.\n// Exported for its tests, not part of the package surface.\nexport const ALPHABET = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\n\n/**\n * Encode `value` as exactly `length` Crockford base32 characters,\n * zero-padded. Throws when `value` is not a non-negative integer below\n * `32 ** length` — exported for its tests, not part of the package surface.\n */\nexport function encodeCrockford(value: number, length: number): string {\n // A value that does not fit would be truncated into a valid-LOOKING ID\n // that silently stops sorting (and can collide). Loud beats silent for\n // our own arithmetic — same rationale as unframe's assertInvariant.\n invariant(\n Number.isInteger(value) && value >= 0,\n `${value} is not encodable — the encoder takes non-negative integers`\n );\n invariant(\n value < 32 ** length,\n `${value} does not fit ${length} base32 characters`\n );\n let out = \"\";\n let rest = value;\n for (let i = 0; i < length; i++) {\n // Plain base conversion, like toString(16) with a custom alphabet:\n // `rest % 32` is the lowest base32 digit, prepending puts high digits\n // first — so larger values sort later as strings.\n out = ALPHABET[rest % 32] + out;\n rest = Math.floor(rest / 32);\n }\n // The loop always runs `length` times; once `rest` hits 0 it emits \"0\"s.\n // That left-padding is load-bearing: \"2\" < \"10\" numerically but not\n // lexicographically — constant width keeps string order = numeric order.\n return out;\n}\n\n/**\n * `length` Crockford characters of fresh randomness — exported for its\n * tests, not part of the package surface.\n */\nexport function randomChars(length: number): string {\n // One random byte per character. A byte spans 256 values and 256 is a\n // whole multiple of 32, so `byte % 32` is exactly uniform over the\n // alphabet — 5 bits of randomness per character, no bias, and no bit\n // arithmetic to combine draws.\n const bytes = new Uint8Array(length);\n crypto.getRandomValues(bytes);\n let out = \"\";\n for (const byte of bytes) {\n out += ALPHABET[byte % 32];\n }\n return out;\n}\n\nexport interface UidOptions {\n size?: number;\n}\n\n/**\n * Generate a time-ordered unique ID: timestamp + randomness, `size`\n * characters total (default 20 — fits MSH-10's ST limit). IDs sort\n * lexicographically by millisecond; same-millisecond IDs are unique but\n * unordered. Keep `size >= 11`: the timestamp needs 10 characters, and\n * per-millisecond uniqueness rests on what remains. Need a branded ID?\n * Compose it: `\"MKE\" + uid({ size: 17 })`.\n */\nexport function uid(options: UidOptions = {}): string {\n const { size = MAX_LENGTH } = options;\n // Boundary validation, not an internal invariant: a bad `size` is the\n // caller's bug, so it gets a native RangeError, never InvariantError.\n // Unchecked, NaN would silently emit a bare timestamp with ZERO\n // randomness (Uint8Array(NaN) has length 0) — colliding IDs that look\n // perfectly valid.\n if (!(Number.isInteger(size) && size > 0)) {\n throw new RangeError(`uid size must be a positive integer, got ${size}`);\n }\n if (size <= TIME_LENGTH) {\n // Too narrow for a timestamp: unique, but not time-sortable.\n return randomChars(size);\n }\n\n const timestamp = encodeCrockford(Date.now(), TIME_LENGTH);\n const random = randomChars(size - TIME_LENGTH);\n return timestamp + random;\n}\n"],"mappings":";;;;;;;AAOA,IAAa,iBAAb,cAAoC,MAAM;CACxC,YAAY,SAAiB;AAC3B,QACE,gDAAgD,QAAQ,oCACzD;AACD,OAAK,OAAO;;;;AAKhB,SAAgB,UACd,WACA,SACmB;AACnB,KAAI,CAAC,UACH,OAAM,IAAI,eAAe,QAAQ;;;;;;;;;;;;;ACRrC,MAAM,aAAa;AAKnB,MAAM,cAAc;AAQpB,MAAa,WAAW;;;;;;AAOxB,SAAgB,gBAAgB,OAAe,QAAwB;AAIrE,WACE,OAAO,UAAU,MAAM,IAAI,SAAS,GACpC,GAAG,MAAM,6DACV;AACD,WACE,QAAQ,MAAM,QACd,GAAG,MAAM,gBAAgB,OAAO,oBACjC;CACD,IAAI,MAAM;CACV,IAAI,OAAO;AACX,MAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK;AAI/B,QAAM,SAAS,OAAO,MAAM;AAC5B,SAAO,KAAK,MAAM,OAAO,GAAG;;AAK9B,QAAO;;;;;;AAOT,SAAgB,YAAY,QAAwB;CAKlD,MAAM,QAAQ,IAAI,WAAW,OAAO;AACpC,QAAO,gBAAgB,MAAM;CAC7B,IAAI,MAAM;AACV,MAAK,MAAM,QAAQ,MACjB,QAAO,SAAS,OAAO;AAEzB,QAAO;;;;;;;;;;AAeT,SAAgB,IAAI,UAAsB,EAAE,EAAU;CACpD,MAAM,EAAE,OAAO,eAAe;AAM9B,KAAI,EAAE,OAAO,UAAU,KAAK,IAAI,OAAO,GACrC,OAAM,IAAI,WAAW,4CAA4C,OAAO;AAE1E,KAAI,QAAQ,YAEV,QAAO,YAAY,KAAK;AAK1B,QAFkB,gBAAgB,KAAK,KAAK,EAAE,YAE9B,GADD,YAAY,OAAO,YACT"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assertion primitives for this package's own internal invariants — bugs in
|
|
3
|
+
* OUR arithmetic, never domain outcomes (a NAK is an `AckException`; an
|
|
4
|
+
* invariant failure must never masquerade as one).
|
|
5
|
+
*/
|
|
6
|
+
/** Thrown when an internal invariant is violated — always a bug; report it. */
|
|
7
|
+
export declare class InvariantError extends Error {
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
}
|
|
10
|
+
/** Assert `condition`; the `asserts` signature also narrows types for tsc. */
|
|
11
|
+
export declare function invariant(condition: unknown, message: string): asserts condition;
|
|
12
|
+
//# sourceMappingURL=invariant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invariant.d.ts","sourceRoot":"","sources":["../src/invariant.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,+EAA+E;AAC/E,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAM5B;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CACvB,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,CAInB"}
|
package/dist/uid.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time-ordered unique IDs for HL7v2 identifier fields — the ULID idea
|
|
3
|
+
* resized to a 20-character default that fits MSH-10, the tightest common
|
|
4
|
+
* ST field (a standard 26-character ULID cannot fit).
|
|
5
|
+
* Stateless: fresh randomness every call, the same semantics as the ULID
|
|
6
|
+
* reference implementation's default `ulid()`.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
export declare const ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
11
|
+
/**
|
|
12
|
+
* Encode `value` as exactly `length` Crockford base32 characters,
|
|
13
|
+
* zero-padded. Throws when `value` is not a non-negative integer below
|
|
14
|
+
* `32 ** length` — exported for its tests, not part of the package surface.
|
|
15
|
+
*/
|
|
16
|
+
export declare function encodeCrockford(value: number, length: number): string;
|
|
17
|
+
/**
|
|
18
|
+
* `length` Crockford characters of fresh randomness — exported for its
|
|
19
|
+
* tests, not part of the package surface.
|
|
20
|
+
*/
|
|
21
|
+
export declare function randomChars(length: number): string;
|
|
22
|
+
export interface UidOptions {
|
|
23
|
+
size?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Generate a time-ordered unique ID: timestamp + randomness, `size`
|
|
27
|
+
* characters total (default 20 — fits MSH-10's ST limit). IDs sort
|
|
28
|
+
* lexicographically by millisecond; same-millisecond IDs are unique but
|
|
29
|
+
* unordered. Keep `size >= 11`: the timestamp needs 10 characters, and
|
|
30
|
+
* per-millisecond uniqueness rests on what remains. Need a branded ID?
|
|
31
|
+
* Compose it: `"MKE" + uid({ size: 17 })`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function uid(options?: UidOptions): string;
|
|
34
|
+
//# sourceMappingURL=uid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uid.d.ts","sourceRoot":"","sources":["../src/uid.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmBH,eAAO,MAAM,QAAQ,qCAAqC,CAAC;AAE3D;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAyBrE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAYlD;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,GAAG,CAAC,OAAO,GAAE,UAAe,GAAG,MAAM,CAkBpD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@glion/util-uid",
|
|
3
|
+
"version": "0.18.0",
|
|
4
|
+
"description": "Time-ordered unique IDs for HL7v2 — the ULID idea resized to a 20-character default that fits MSH-10 and other ST identifier fields",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"health",
|
|
7
|
+
"healthcare",
|
|
8
|
+
"hl7",
|
|
9
|
+
"hl7v2",
|
|
10
|
+
"nodejs",
|
|
11
|
+
"typescript",
|
|
12
|
+
"uid",
|
|
13
|
+
"ulid"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://glion.dev",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"author": {
|
|
18
|
+
"name": "Melek Somai",
|
|
19
|
+
"email": "melek@rethinkhealth.io"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/rethinkhealth/glion.git",
|
|
24
|
+
"directory": "packages/util-uid"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"type": "module",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "25.6.0",
|
|
39
|
+
"@vitest/coverage-v8": "4.1.11",
|
|
40
|
+
"publint": "0.3.18",
|
|
41
|
+
"tsdown": "0.21.10",
|
|
42
|
+
"typescript": "6.0.3",
|
|
43
|
+
"vitest": "4.1.11",
|
|
44
|
+
"@glion/check-readme": "0.18.0",
|
|
45
|
+
"@glion/testing": "0.18.0",
|
|
46
|
+
"@glion/tsconfig": "0.18.0"
|
|
47
|
+
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=22"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsdown && tsc --emitDeclarationOnly",
|
|
53
|
+
"check-types": "tsc --noEmit && tsc --noEmit -p tests/tsconfig.json",
|
|
54
|
+
"check:readme": "glion-check-readme",
|
|
55
|
+
"test": "vitest run",
|
|
56
|
+
"test:coverage": "vitest run --coverage",
|
|
57
|
+
"test:watch": "vitest",
|
|
58
|
+
"publint": "publint --strict"
|
|
59
|
+
}
|
|
60
|
+
}
|