├── .editorconfig
├── .github
└── workflows
│ └── test.yml
├── .gitignore
├── .prettierrc
├── .vscode
└── settings.json
├── LICENSE
├── README.md
├── logo.png
├── package-lock.json
├── package.json
├── rollup.config.js
├── source
├── cli.ts
├── constants.ts
├── crockford.ts
├── error.ts
├── index.ts
├── stub.ts
├── types.ts
├── ulid.ts
├── utils.ts
└── uuid.ts
├── test
├── benchmark.js
└── node
│ ├── crockford.spec.ts
│ ├── ulid.spec.ts
│ └── uuid.spec.ts
├── tsconfig.dec.json
├── tsconfig.json
└── vitest.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 4
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 |
11 | jobs:
12 | nodejs:
13 | runs-on: ubuntu-latest
14 | strategy:
15 | matrix:
16 | node-version: [18.x, 22.x]
17 | steps:
18 | - uses: actions/checkout@v2
19 | - name: Node.js specs ${{ matrix.node-version }}
20 | uses: actions/setup-node@v1
21 | with:
22 | node-version: ${{ matrix.node-version }}
23 | - run: npm i
24 | - run: npm run build
25 | - run: npm run test:specs
26 | format:
27 | runs-on: ubuntu-latest
28 | strategy:
29 | matrix:
30 | node-version: [22.x]
31 | steps:
32 | - uses: actions/checkout@v2
33 | - name: Type checks ${{ matrix.node-version }}
34 | uses: actions/setup-node@v1
35 | with:
36 | node-version: ${{ matrix.node-version }}
37 | - run: npm i
38 | - run: npm run test:format
39 | types:
40 | runs-on: ubuntu-latest
41 | strategy:
42 | matrix:
43 | node-version: [22.x]
44 | steps:
45 | - uses: actions/checkout@v2
46 | - name: Type checks ${{ matrix.node-version }}
47 | uses: actions/setup-node@v1
48 | with:
49 | node-version: ${{ matrix.node-version }}
50 | - run: npm i
51 | - run: npm run build
52 | - run: npm run test:types
53 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.log
3 |
4 | node_modules
5 | /dist
6 | coverage
7 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "tabWidth": 4,
4 | "trailingComma": "none",
5 | "arrowParens": "avoid"
6 | }
7 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.preferences.importModuleSpecifierEnding": "js"
3 | }
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Alizain Feerasta
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.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | # Universally Unique Lexicographically Sortable Identifier
11 |
12 | [](https://github.com/ulid/javascript/actions/workflows/test.yml)
13 | [](https://codecov.io/gh/ulid/javascript)
14 | [](https://www.npmjs.com/package/ulid) [](https://www.npmjs.com/package/ulid)
15 |
16 | ULIDs are unique, sortable identifiers that work much in the same way as UUIDs, though with some improvements:
17 |
18 | * Lexicographically sortable
19 | * Canonically encoded as a 26 character string, as opposed to the 36 character UUID
20 | * Uses Crockford's base32 for better efficiency and readability (5 bits per character)
21 | * Monotonic sort order (correctly detects and handles the same millisecond)
22 |
23 | ULIDs also provide:
24 |
25 | * 128-bit compatibility with UUID
26 | * 1.21e+24 unique IDs per millisecond
27 | * Case insensitivity
28 | * No special characters (URL safe)
29 |
30 | UUID can be suboptimal for many uses-cases because:
31 |
32 | - It isn't the most character efficient way of encoding 128 bits of randomness
33 | - UUID v1/v2 is impractical in many environments, as it requires access to a unique, stable MAC address
34 | - UUID v3/v5 requires a unique seed and produces randomly distributed IDs, which can cause fragmentation in many data structures
35 | - UUID v4 provides no other information than randomness which can cause fragmentation in many data structures
36 |
37 | ## Installation
38 |
39 | Install using NPM:
40 |
41 | ```shell
42 | npm install ulid --save
43 | ```
44 |
45 | ### Compatibility
46 |
47 | ULID supports the following environments:
48 |
49 | | Version | NodeJS | Browsers | React-Native | Web Workers | Edge Functions |
50 | |-----------|-----------|---------------|---------------|---------------|-------------------|
51 | | v3 | v18+ | Yes | Yes | Yes | ? |
52 | | v2 | v16+ | Yes | No | No | No |
53 |
54 | Additionally, both ESM and CommonJS entrypoints are provided.
55 |
56 | ## Usage
57 |
58 | To quickly generate a ULID, you can simply import the `ulid` function:
59 |
60 | ```typescript
61 | import { ulid } from "ulid";
62 |
63 | ulid(); // "01ARZ3NDEKTSV4RRFFQ69G5FAV"
64 | ```
65 |
66 | ### Seed Time
67 |
68 | You can also input a seed time which will consistently give you the same string for the time component. This is useful for migrating to ulid.
69 |
70 | ```typescript
71 | ulid(1469918176385) // "01ARYZ6S41TSV4RRFFQ69G5FAV"
72 | ```
73 |
74 | ### Monotonic ULIDs
75 |
76 | To generate monotonically increasing ULIDs, create a monotonic counter with `monotonicFactory`.
77 |
78 | > Note that the same seed time is being passed in for this example to demonstrate its behaviour when generating multiple ULIDs within the same millisecond
79 |
80 | ```typescript
81 | import { monotonicFactory } from "ulid";
82 |
83 | const ulid = monotonicFactory();
84 |
85 | // Strict ordering for the same timestamp, by incrementing the least-significant random bit by 1
86 | ulid(150000); // "000XAL6S41ACTAV9WEVGEMMVR8"
87 | ulid(150000); // "000XAL6S41ACTAV9WEVGEMMVR9"
88 | ulid(150000); // "000XAL6S41ACTAV9WEVGEMMVRA"
89 | ulid(150000); // "000XAL6S41ACTAV9WEVGEMMVRB"
90 | ulid(150000); // "000XAL6S41ACTAV9WEVGEMMVRC"
91 |
92 | // Even if a lower timestamp is passed (or generated), it will preserve sort order
93 | ulid(100000); // "000XAL6S41ACTAV9WEVGEMMVRD"
94 | ```
95 |
96 | ### Pseudo-Random Number Generators
97 |
98 | `ulid` automatically detects a suitable (cryptographically-secure) PRNG. In the browser it will use `crypto.getRandomValues` and on NodeJS it will use `crypto.randomBytes`.
99 |
100 | #### Using `Math.random` (insecure)
101 |
102 | By default, `ulid` will not use `Math.random` to generate random values. You can bypass this limitation by overriding the PRNG:
103 |
104 | ```typescript
105 | const ulid = monotonicFactory(() => Math.random());
106 |
107 | ulid(); // "01BXAVRG61YJ5YSBRM51702F6M"
108 | ```
109 |
110 | ### Validity
111 |
112 | You can verify if a value is a valid ULID by using `isValid`:
113 |
114 | ```typescript
115 | import { isValid } from "ulid";
116 |
117 | isValid("01ARYZ6S41TSV4RRFFQ69G5FAV"); // true
118 | isValid("01ARYZ6S41TSV4RRFFQ69G5FA"); // false
119 | ```
120 |
121 | ### ULID Time
122 |
123 | You can encode and decode ULID timestamps by using `encodeTime` and `decodeTime` respectively:
124 |
125 | ```typescript
126 | import { decodeTime } from "ulid";
127 |
128 | decodeTime("01ARYZ6S41TSV4RRFFQ69G5FAV"); // 1469918176385
129 | ```
130 |
131 | Note that while `decodeTime` works on full ULIDs, `encodeTime` encodes only the _time portion_ of ULIDs:
132 |
133 | ```typescript
134 | import { encodeTime } from "ulid";
135 |
136 | encodeTime(1469918176385); // "01ARYZ6S41"
137 | ```
138 |
139 | ### Tests
140 |
141 | Install dependencies using `npm install` first, and then simply run `npm test` to run the test suite.
142 |
143 | ### CLI
144 |
145 | `ulid` can be used on the command line, either via global install:
146 |
147 | ```shell
148 | npm install -g ulid
149 | ulid
150 | ```
151 |
152 | Or via `npx`:
153 |
154 | ```shell
155 | npx ulid
156 | ```
157 |
158 | You can also generate multiple IDs at the same time:
159 |
160 | ```shell
161 | ulid --count 15
162 | ```
163 |
164 | ## Specification
165 |
166 | You can find the full specification, as well as information regarding implementations in other languages, over at [ulid/spec](https://github.com/ulid/spec).
167 |
168 | ## Performance
169 |
170 | You can test `ulid`'s performance by running `npm run bench`:
171 |
172 | ```
173 | Simple ulid x 56,782 ops/sec ±2.50% (86 runs sampled)
174 | ulid with timestamp x 58,574 ops/sec ±1.80% (87 runs sampled)
175 | Done!
176 | ```
177 |
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ulid/javascript/361eb27b5595c766b85af147df38e3e61eebb529/logo.png
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ulid",
3 | "version": "2.4.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "ulid",
9 | "version": "2.4.0",
10 | "license": "MIT",
11 | "bin": {
12 | "ulid": "dist/cli.js"
13 | },
14 | "devDependencies": {
15 | "@rollup/plugin-alias": "^5.1.1",
16 | "@rollup/plugin-commonjs": "^28.0.3",
17 | "@rollup/plugin-node-resolve": "^16.0.1",
18 | "@rollup/plugin-typescript": "^12.1.2",
19 | "@types/node": "^22.13.10",
20 | "benchmark": "^2.1.4",
21 | "prettier": "^3.5.3",
22 | "rollup": "^4.36.0",
23 | "tslib": "^2.8.1",
24 | "typescript": "^5.8.2",
25 | "vitest": "^3.0.9"
26 | }
27 | },
28 | "node_modules/@esbuild/aix-ppc64": {
29 | "version": "0.25.1",
30 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz",
31 | "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==",
32 | "cpu": [
33 | "ppc64"
34 | ],
35 | "dev": true,
36 | "license": "MIT",
37 | "optional": true,
38 | "os": [
39 | "aix"
40 | ],
41 | "engines": {
42 | "node": ">=18"
43 | }
44 | },
45 | "node_modules/@esbuild/android-arm": {
46 | "version": "0.25.1",
47 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz",
48 | "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==",
49 | "cpu": [
50 | "arm"
51 | ],
52 | "dev": true,
53 | "license": "MIT",
54 | "optional": true,
55 | "os": [
56 | "android"
57 | ],
58 | "engines": {
59 | "node": ">=18"
60 | }
61 | },
62 | "node_modules/@esbuild/android-arm64": {
63 | "version": "0.25.1",
64 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz",
65 | "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==",
66 | "cpu": [
67 | "arm64"
68 | ],
69 | "dev": true,
70 | "license": "MIT",
71 | "optional": true,
72 | "os": [
73 | "android"
74 | ],
75 | "engines": {
76 | "node": ">=18"
77 | }
78 | },
79 | "node_modules/@esbuild/android-x64": {
80 | "version": "0.25.1",
81 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz",
82 | "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==",
83 | "cpu": [
84 | "x64"
85 | ],
86 | "dev": true,
87 | "license": "MIT",
88 | "optional": true,
89 | "os": [
90 | "android"
91 | ],
92 | "engines": {
93 | "node": ">=18"
94 | }
95 | },
96 | "node_modules/@esbuild/darwin-arm64": {
97 | "version": "0.25.1",
98 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz",
99 | "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==",
100 | "cpu": [
101 | "arm64"
102 | ],
103 | "dev": true,
104 | "license": "MIT",
105 | "optional": true,
106 | "os": [
107 | "darwin"
108 | ],
109 | "engines": {
110 | "node": ">=18"
111 | }
112 | },
113 | "node_modules/@esbuild/darwin-x64": {
114 | "version": "0.25.1",
115 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz",
116 | "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==",
117 | "cpu": [
118 | "x64"
119 | ],
120 | "dev": true,
121 | "license": "MIT",
122 | "optional": true,
123 | "os": [
124 | "darwin"
125 | ],
126 | "engines": {
127 | "node": ">=18"
128 | }
129 | },
130 | "node_modules/@esbuild/freebsd-arm64": {
131 | "version": "0.25.1",
132 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz",
133 | "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==",
134 | "cpu": [
135 | "arm64"
136 | ],
137 | "dev": true,
138 | "license": "MIT",
139 | "optional": true,
140 | "os": [
141 | "freebsd"
142 | ],
143 | "engines": {
144 | "node": ">=18"
145 | }
146 | },
147 | "node_modules/@esbuild/freebsd-x64": {
148 | "version": "0.25.1",
149 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz",
150 | "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==",
151 | "cpu": [
152 | "x64"
153 | ],
154 | "dev": true,
155 | "license": "MIT",
156 | "optional": true,
157 | "os": [
158 | "freebsd"
159 | ],
160 | "engines": {
161 | "node": ">=18"
162 | }
163 | },
164 | "node_modules/@esbuild/linux-arm": {
165 | "version": "0.25.1",
166 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz",
167 | "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==",
168 | "cpu": [
169 | "arm"
170 | ],
171 | "dev": true,
172 | "license": "MIT",
173 | "optional": true,
174 | "os": [
175 | "linux"
176 | ],
177 | "engines": {
178 | "node": ">=18"
179 | }
180 | },
181 | "node_modules/@esbuild/linux-arm64": {
182 | "version": "0.25.1",
183 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz",
184 | "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==",
185 | "cpu": [
186 | "arm64"
187 | ],
188 | "dev": true,
189 | "license": "MIT",
190 | "optional": true,
191 | "os": [
192 | "linux"
193 | ],
194 | "engines": {
195 | "node": ">=18"
196 | }
197 | },
198 | "node_modules/@esbuild/linux-ia32": {
199 | "version": "0.25.1",
200 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz",
201 | "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==",
202 | "cpu": [
203 | "ia32"
204 | ],
205 | "dev": true,
206 | "license": "MIT",
207 | "optional": true,
208 | "os": [
209 | "linux"
210 | ],
211 | "engines": {
212 | "node": ">=18"
213 | }
214 | },
215 | "node_modules/@esbuild/linux-loong64": {
216 | "version": "0.25.1",
217 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz",
218 | "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==",
219 | "cpu": [
220 | "loong64"
221 | ],
222 | "dev": true,
223 | "license": "MIT",
224 | "optional": true,
225 | "os": [
226 | "linux"
227 | ],
228 | "engines": {
229 | "node": ">=18"
230 | }
231 | },
232 | "node_modules/@esbuild/linux-mips64el": {
233 | "version": "0.25.1",
234 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz",
235 | "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==",
236 | "cpu": [
237 | "mips64el"
238 | ],
239 | "dev": true,
240 | "license": "MIT",
241 | "optional": true,
242 | "os": [
243 | "linux"
244 | ],
245 | "engines": {
246 | "node": ">=18"
247 | }
248 | },
249 | "node_modules/@esbuild/linux-ppc64": {
250 | "version": "0.25.1",
251 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz",
252 | "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==",
253 | "cpu": [
254 | "ppc64"
255 | ],
256 | "dev": true,
257 | "license": "MIT",
258 | "optional": true,
259 | "os": [
260 | "linux"
261 | ],
262 | "engines": {
263 | "node": ">=18"
264 | }
265 | },
266 | "node_modules/@esbuild/linux-riscv64": {
267 | "version": "0.25.1",
268 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz",
269 | "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==",
270 | "cpu": [
271 | "riscv64"
272 | ],
273 | "dev": true,
274 | "license": "MIT",
275 | "optional": true,
276 | "os": [
277 | "linux"
278 | ],
279 | "engines": {
280 | "node": ">=18"
281 | }
282 | },
283 | "node_modules/@esbuild/linux-s390x": {
284 | "version": "0.25.1",
285 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz",
286 | "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==",
287 | "cpu": [
288 | "s390x"
289 | ],
290 | "dev": true,
291 | "license": "MIT",
292 | "optional": true,
293 | "os": [
294 | "linux"
295 | ],
296 | "engines": {
297 | "node": ">=18"
298 | }
299 | },
300 | "node_modules/@esbuild/linux-x64": {
301 | "version": "0.25.1",
302 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz",
303 | "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==",
304 | "cpu": [
305 | "x64"
306 | ],
307 | "dev": true,
308 | "license": "MIT",
309 | "optional": true,
310 | "os": [
311 | "linux"
312 | ],
313 | "engines": {
314 | "node": ">=18"
315 | }
316 | },
317 | "node_modules/@esbuild/netbsd-arm64": {
318 | "version": "0.25.1",
319 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz",
320 | "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==",
321 | "cpu": [
322 | "arm64"
323 | ],
324 | "dev": true,
325 | "license": "MIT",
326 | "optional": true,
327 | "os": [
328 | "netbsd"
329 | ],
330 | "engines": {
331 | "node": ">=18"
332 | }
333 | },
334 | "node_modules/@esbuild/netbsd-x64": {
335 | "version": "0.25.1",
336 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz",
337 | "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==",
338 | "cpu": [
339 | "x64"
340 | ],
341 | "dev": true,
342 | "license": "MIT",
343 | "optional": true,
344 | "os": [
345 | "netbsd"
346 | ],
347 | "engines": {
348 | "node": ">=18"
349 | }
350 | },
351 | "node_modules/@esbuild/openbsd-arm64": {
352 | "version": "0.25.1",
353 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz",
354 | "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==",
355 | "cpu": [
356 | "arm64"
357 | ],
358 | "dev": true,
359 | "license": "MIT",
360 | "optional": true,
361 | "os": [
362 | "openbsd"
363 | ],
364 | "engines": {
365 | "node": ">=18"
366 | }
367 | },
368 | "node_modules/@esbuild/openbsd-x64": {
369 | "version": "0.25.1",
370 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz",
371 | "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==",
372 | "cpu": [
373 | "x64"
374 | ],
375 | "dev": true,
376 | "license": "MIT",
377 | "optional": true,
378 | "os": [
379 | "openbsd"
380 | ],
381 | "engines": {
382 | "node": ">=18"
383 | }
384 | },
385 | "node_modules/@esbuild/sunos-x64": {
386 | "version": "0.25.1",
387 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz",
388 | "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==",
389 | "cpu": [
390 | "x64"
391 | ],
392 | "dev": true,
393 | "license": "MIT",
394 | "optional": true,
395 | "os": [
396 | "sunos"
397 | ],
398 | "engines": {
399 | "node": ">=18"
400 | }
401 | },
402 | "node_modules/@esbuild/win32-arm64": {
403 | "version": "0.25.1",
404 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz",
405 | "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==",
406 | "cpu": [
407 | "arm64"
408 | ],
409 | "dev": true,
410 | "license": "MIT",
411 | "optional": true,
412 | "os": [
413 | "win32"
414 | ],
415 | "engines": {
416 | "node": ">=18"
417 | }
418 | },
419 | "node_modules/@esbuild/win32-ia32": {
420 | "version": "0.25.1",
421 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz",
422 | "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==",
423 | "cpu": [
424 | "ia32"
425 | ],
426 | "dev": true,
427 | "license": "MIT",
428 | "optional": true,
429 | "os": [
430 | "win32"
431 | ],
432 | "engines": {
433 | "node": ">=18"
434 | }
435 | },
436 | "node_modules/@esbuild/win32-x64": {
437 | "version": "0.25.1",
438 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz",
439 | "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==",
440 | "cpu": [
441 | "x64"
442 | ],
443 | "dev": true,
444 | "license": "MIT",
445 | "optional": true,
446 | "os": [
447 | "win32"
448 | ],
449 | "engines": {
450 | "node": ">=18"
451 | }
452 | },
453 | "node_modules/@jridgewell/sourcemap-codec": {
454 | "version": "1.5.0",
455 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
456 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
457 | "dev": true,
458 | "license": "MIT"
459 | },
460 | "node_modules/@rollup/plugin-alias": {
461 | "version": "5.1.1",
462 | "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.1.tgz",
463 | "integrity": "sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==",
464 | "dev": true,
465 | "license": "MIT",
466 | "engines": {
467 | "node": ">=14.0.0"
468 | },
469 | "peerDependencies": {
470 | "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
471 | },
472 | "peerDependenciesMeta": {
473 | "rollup": {
474 | "optional": true
475 | }
476 | }
477 | },
478 | "node_modules/@rollup/plugin-commonjs": {
479 | "version": "28.0.3",
480 | "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.3.tgz",
481 | "integrity": "sha512-pyltgilam1QPdn+Zd9gaCfOLcnjMEJ9gV+bTw6/r73INdvzf1ah9zLIJBm+kW7R6IUFIQ1YO+VqZtYxZNWFPEQ==",
482 | "dev": true,
483 | "license": "MIT",
484 | "dependencies": {
485 | "@rollup/pluginutils": "^5.0.1",
486 | "commondir": "^1.0.1",
487 | "estree-walker": "^2.0.2",
488 | "fdir": "^6.2.0",
489 | "is-reference": "1.2.1",
490 | "magic-string": "^0.30.3",
491 | "picomatch": "^4.0.2"
492 | },
493 | "engines": {
494 | "node": ">=16.0.0 || 14 >= 14.17"
495 | },
496 | "peerDependencies": {
497 | "rollup": "^2.68.0||^3.0.0||^4.0.0"
498 | },
499 | "peerDependenciesMeta": {
500 | "rollup": {
501 | "optional": true
502 | }
503 | }
504 | },
505 | "node_modules/@rollup/plugin-node-resolve": {
506 | "version": "16.0.1",
507 | "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.1.tgz",
508 | "integrity": "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==",
509 | "dev": true,
510 | "license": "MIT",
511 | "dependencies": {
512 | "@rollup/pluginutils": "^5.0.1",
513 | "@types/resolve": "1.20.2",
514 | "deepmerge": "^4.2.2",
515 | "is-module": "^1.0.0",
516 | "resolve": "^1.22.1"
517 | },
518 | "engines": {
519 | "node": ">=14.0.0"
520 | },
521 | "peerDependencies": {
522 | "rollup": "^2.78.0||^3.0.0||^4.0.0"
523 | },
524 | "peerDependenciesMeta": {
525 | "rollup": {
526 | "optional": true
527 | }
528 | }
529 | },
530 | "node_modules/@rollup/plugin-typescript": {
531 | "version": "12.1.2",
532 | "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.2.tgz",
533 | "integrity": "sha512-cdtSp154H5sv637uMr1a8OTWB0L1SWDSm1rDGiyfcGcvQ6cuTs4MDk2BVEBGysUWago4OJN4EQZqOTl/QY3Jgg==",
534 | "dev": true,
535 | "license": "MIT",
536 | "dependencies": {
537 | "@rollup/pluginutils": "^5.1.0",
538 | "resolve": "^1.22.1"
539 | },
540 | "engines": {
541 | "node": ">=14.0.0"
542 | },
543 | "peerDependencies": {
544 | "rollup": "^2.14.0||^3.0.0||^4.0.0",
545 | "tslib": "*",
546 | "typescript": ">=3.7.0"
547 | },
548 | "peerDependenciesMeta": {
549 | "rollup": {
550 | "optional": true
551 | },
552 | "tslib": {
553 | "optional": true
554 | }
555 | }
556 | },
557 | "node_modules/@rollup/pluginutils": {
558 | "version": "5.1.4",
559 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
560 | "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==",
561 | "dev": true,
562 | "license": "MIT",
563 | "dependencies": {
564 | "@types/estree": "^1.0.0",
565 | "estree-walker": "^2.0.2",
566 | "picomatch": "^4.0.2"
567 | },
568 | "engines": {
569 | "node": ">=14.0.0"
570 | },
571 | "peerDependencies": {
572 | "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
573 | },
574 | "peerDependenciesMeta": {
575 | "rollup": {
576 | "optional": true
577 | }
578 | }
579 | },
580 | "node_modules/@rollup/rollup-android-arm-eabi": {
581 | "version": "4.36.0",
582 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.36.0.tgz",
583 | "integrity": "sha512-jgrXjjcEwN6XpZXL0HUeOVGfjXhPyxAbbhD0BlXUB+abTOpbPiN5Wb3kOT7yb+uEtATNYF5x5gIfwutmuBA26w==",
584 | "cpu": [
585 | "arm"
586 | ],
587 | "dev": true,
588 | "license": "MIT",
589 | "optional": true,
590 | "os": [
591 | "android"
592 | ]
593 | },
594 | "node_modules/@rollup/rollup-android-arm64": {
595 | "version": "4.36.0",
596 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.36.0.tgz",
597 | "integrity": "sha512-NyfuLvdPdNUfUNeYKUwPwKsE5SXa2J6bCt2LdB/N+AxShnkpiczi3tcLJrm5mA+eqpy0HmaIY9F6XCa32N5yzg==",
598 | "cpu": [
599 | "arm64"
600 | ],
601 | "dev": true,
602 | "license": "MIT",
603 | "optional": true,
604 | "os": [
605 | "android"
606 | ]
607 | },
608 | "node_modules/@rollup/rollup-darwin-arm64": {
609 | "version": "4.36.0",
610 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.36.0.tgz",
611 | "integrity": "sha512-JQ1Jk5G4bGrD4pWJQzWsD8I1n1mgPXq33+/vP4sk8j/z/C2siRuxZtaUA7yMTf71TCZTZl/4e1bfzwUmFb3+rw==",
612 | "cpu": [
613 | "arm64"
614 | ],
615 | "dev": true,
616 | "license": "MIT",
617 | "optional": true,
618 | "os": [
619 | "darwin"
620 | ]
621 | },
622 | "node_modules/@rollup/rollup-darwin-x64": {
623 | "version": "4.36.0",
624 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.36.0.tgz",
625 | "integrity": "sha512-6c6wMZa1lrtiRsbDziCmjE53YbTkxMYhhnWnSW8R/yqsM7a6mSJ3uAVT0t8Y/DGt7gxUWYuFM4bwWk9XCJrFKA==",
626 | "cpu": [
627 | "x64"
628 | ],
629 | "dev": true,
630 | "license": "MIT",
631 | "optional": true,
632 | "os": [
633 | "darwin"
634 | ]
635 | },
636 | "node_modules/@rollup/rollup-freebsd-arm64": {
637 | "version": "4.36.0",
638 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.36.0.tgz",
639 | "integrity": "sha512-KXVsijKeJXOl8QzXTsA+sHVDsFOmMCdBRgFmBb+mfEb/7geR7+C8ypAml4fquUt14ZyVXaw2o1FWhqAfOvA4sg==",
640 | "cpu": [
641 | "arm64"
642 | ],
643 | "dev": true,
644 | "license": "MIT",
645 | "optional": true,
646 | "os": [
647 | "freebsd"
648 | ]
649 | },
650 | "node_modules/@rollup/rollup-freebsd-x64": {
651 | "version": "4.36.0",
652 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.36.0.tgz",
653 | "integrity": "sha512-dVeWq1ebbvByI+ndz4IJcD4a09RJgRYmLccwlQ8bPd4olz3Y213uf1iwvc7ZaxNn2ab7bjc08PrtBgMu6nb4pQ==",
654 | "cpu": [
655 | "x64"
656 | ],
657 | "dev": true,
658 | "license": "MIT",
659 | "optional": true,
660 | "os": [
661 | "freebsd"
662 | ]
663 | },
664 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
665 | "version": "4.36.0",
666 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.36.0.tgz",
667 | "integrity": "sha512-bvXVU42mOVcF4le6XSjscdXjqx8okv4n5vmwgzcmtvFdifQ5U4dXFYaCB87namDRKlUL9ybVtLQ9ztnawaSzvg==",
668 | "cpu": [
669 | "arm"
670 | ],
671 | "dev": true,
672 | "license": "MIT",
673 | "optional": true,
674 | "os": [
675 | "linux"
676 | ]
677 | },
678 | "node_modules/@rollup/rollup-linux-arm-musleabihf": {
679 | "version": "4.36.0",
680 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.36.0.tgz",
681 | "integrity": "sha512-JFIQrDJYrxOnyDQGYkqnNBtjDwTgbasdbUiQvcU8JmGDfValfH1lNpng+4FWlhaVIR4KPkeddYjsVVbmJYvDcg==",
682 | "cpu": [
683 | "arm"
684 | ],
685 | "dev": true,
686 | "license": "MIT",
687 | "optional": true,
688 | "os": [
689 | "linux"
690 | ]
691 | },
692 | "node_modules/@rollup/rollup-linux-arm64-gnu": {
693 | "version": "4.36.0",
694 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.36.0.tgz",
695 | "integrity": "sha512-KqjYVh3oM1bj//5X7k79PSCZ6CvaVzb7Qs7VMWS+SlWB5M8p3FqufLP9VNp4CazJ0CsPDLwVD9r3vX7Ci4J56A==",
696 | "cpu": [
697 | "arm64"
698 | ],
699 | "dev": true,
700 | "license": "MIT",
701 | "optional": true,
702 | "os": [
703 | "linux"
704 | ]
705 | },
706 | "node_modules/@rollup/rollup-linux-arm64-musl": {
707 | "version": "4.36.0",
708 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.36.0.tgz",
709 | "integrity": "sha512-QiGnhScND+mAAtfHqeT+cB1S9yFnNQ/EwCg5yE3MzoaZZnIV0RV9O5alJAoJKX/sBONVKeZdMfO8QSaWEygMhw==",
710 | "cpu": [
711 | "arm64"
712 | ],
713 | "dev": true,
714 | "license": "MIT",
715 | "optional": true,
716 | "os": [
717 | "linux"
718 | ]
719 | },
720 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
721 | "version": "4.36.0",
722 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.36.0.tgz",
723 | "integrity": "sha512-1ZPyEDWF8phd4FQtTzMh8FQwqzvIjLsl6/84gzUxnMNFBtExBtpL51H67mV9xipuxl1AEAerRBgBwFNpkw8+Lg==",
724 | "cpu": [
725 | "loong64"
726 | ],
727 | "dev": true,
728 | "license": "MIT",
729 | "optional": true,
730 | "os": [
731 | "linux"
732 | ]
733 | },
734 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
735 | "version": "4.36.0",
736 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.36.0.tgz",
737 | "integrity": "sha512-VMPMEIUpPFKpPI9GZMhJrtu8rxnp6mJR3ZzQPykq4xc2GmdHj3Q4cA+7avMyegXy4n1v+Qynr9fR88BmyO74tg==",
738 | "cpu": [
739 | "ppc64"
740 | ],
741 | "dev": true,
742 | "license": "MIT",
743 | "optional": true,
744 | "os": [
745 | "linux"
746 | ]
747 | },
748 | "node_modules/@rollup/rollup-linux-riscv64-gnu": {
749 | "version": "4.36.0",
750 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.36.0.tgz",
751 | "integrity": "sha512-ttE6ayb/kHwNRJGYLpuAvB7SMtOeQnVXEIpMtAvx3kepFQeowVED0n1K9nAdraHUPJ5hydEMxBpIR7o4nrm8uA==",
752 | "cpu": [
753 | "riscv64"
754 | ],
755 | "dev": true,
756 | "license": "MIT",
757 | "optional": true,
758 | "os": [
759 | "linux"
760 | ]
761 | },
762 | "node_modules/@rollup/rollup-linux-s390x-gnu": {
763 | "version": "4.36.0",
764 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.36.0.tgz",
765 | "integrity": "sha512-4a5gf2jpS0AIe7uBjxDeUMNcFmaRTbNv7NxI5xOCs4lhzsVyGR/0qBXduPnoWf6dGC365saTiwag8hP1imTgag==",
766 | "cpu": [
767 | "s390x"
768 | ],
769 | "dev": true,
770 | "license": "MIT",
771 | "optional": true,
772 | "os": [
773 | "linux"
774 | ]
775 | },
776 | "node_modules/@rollup/rollup-linux-x64-gnu": {
777 | "version": "4.36.0",
778 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.36.0.tgz",
779 | "integrity": "sha512-5KtoW8UWmwFKQ96aQL3LlRXX16IMwyzMq/jSSVIIyAANiE1doaQsx/KRyhAvpHlPjPiSU/AYX/8m+lQ9VToxFQ==",
780 | "cpu": [
781 | "x64"
782 | ],
783 | "dev": true,
784 | "license": "MIT",
785 | "optional": true,
786 | "os": [
787 | "linux"
788 | ]
789 | },
790 | "node_modules/@rollup/rollup-linux-x64-musl": {
791 | "version": "4.36.0",
792 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.36.0.tgz",
793 | "integrity": "sha512-sycrYZPrv2ag4OCvaN5js+f01eoZ2U+RmT5as8vhxiFz+kxwlHrsxOwKPSA8WyS+Wc6Epid9QeI/IkQ9NkgYyQ==",
794 | "cpu": [
795 | "x64"
796 | ],
797 | "dev": true,
798 | "license": "MIT",
799 | "optional": true,
800 | "os": [
801 | "linux"
802 | ]
803 | },
804 | "node_modules/@rollup/rollup-win32-arm64-msvc": {
805 | "version": "4.36.0",
806 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.36.0.tgz",
807 | "integrity": "sha512-qbqt4N7tokFwwSVlWDsjfoHgviS3n/vZ8LK0h1uLG9TYIRuUTJC88E1xb3LM2iqZ/WTqNQjYrtmtGmrmmawB6A==",
808 | "cpu": [
809 | "arm64"
810 | ],
811 | "dev": true,
812 | "license": "MIT",
813 | "optional": true,
814 | "os": [
815 | "win32"
816 | ]
817 | },
818 | "node_modules/@rollup/rollup-win32-ia32-msvc": {
819 | "version": "4.36.0",
820 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.36.0.tgz",
821 | "integrity": "sha512-t+RY0JuRamIocMuQcfwYSOkmdX9dtkr1PbhKW42AMvaDQa+jOdpUYysroTF/nuPpAaQMWp7ye+ndlmmthieJrQ==",
822 | "cpu": [
823 | "ia32"
824 | ],
825 | "dev": true,
826 | "license": "MIT",
827 | "optional": true,
828 | "os": [
829 | "win32"
830 | ]
831 | },
832 | "node_modules/@rollup/rollup-win32-x64-msvc": {
833 | "version": "4.36.0",
834 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.36.0.tgz",
835 | "integrity": "sha512-aRXd7tRZkWLqGbChgcMMDEHjOKudo1kChb1Jt1IfR8cY/KIpgNviLeJy5FUb9IpSuQj8dU2fAYNMPW/hLKOSTw==",
836 | "cpu": [
837 | "x64"
838 | ],
839 | "dev": true,
840 | "license": "MIT",
841 | "optional": true,
842 | "os": [
843 | "win32"
844 | ]
845 | },
846 | "node_modules/@types/estree": {
847 | "version": "1.0.6",
848 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
849 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
850 | "dev": true,
851 | "license": "MIT"
852 | },
853 | "node_modules/@types/node": {
854 | "version": "22.13.10",
855 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz",
856 | "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==",
857 | "dev": true,
858 | "license": "MIT",
859 | "dependencies": {
860 | "undici-types": "~6.20.0"
861 | }
862 | },
863 | "node_modules/@types/resolve": {
864 | "version": "1.20.2",
865 | "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
866 | "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
867 | "dev": true,
868 | "license": "MIT"
869 | },
870 | "node_modules/@vitest/expect": {
871 | "version": "3.0.9",
872 | "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.9.tgz",
873 | "integrity": "sha512-5eCqRItYgIML7NNVgJj6TVCmdzE7ZVgJhruW0ziSQV4V7PvLkDL1bBkBdcTs/VuIz0IxPb5da1IDSqc1TR9eig==",
874 | "dev": true,
875 | "license": "MIT",
876 | "dependencies": {
877 | "@vitest/spy": "3.0.9",
878 | "@vitest/utils": "3.0.9",
879 | "chai": "^5.2.0",
880 | "tinyrainbow": "^2.0.0"
881 | },
882 | "funding": {
883 | "url": "https://opencollective.com/vitest"
884 | }
885 | },
886 | "node_modules/@vitest/mocker": {
887 | "version": "3.0.9",
888 | "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.9.tgz",
889 | "integrity": "sha512-ryERPIBOnvevAkTq+L1lD+DTFBRcjueL9lOUfXsLfwP92h4e+Heb+PjiqS3/OURWPtywfafK0kj++yDFjWUmrA==",
890 | "dev": true,
891 | "license": "MIT",
892 | "dependencies": {
893 | "@vitest/spy": "3.0.9",
894 | "estree-walker": "^3.0.3",
895 | "magic-string": "^0.30.17"
896 | },
897 | "funding": {
898 | "url": "https://opencollective.com/vitest"
899 | },
900 | "peerDependencies": {
901 | "msw": "^2.4.9",
902 | "vite": "^5.0.0 || ^6.0.0"
903 | },
904 | "peerDependenciesMeta": {
905 | "msw": {
906 | "optional": true
907 | },
908 | "vite": {
909 | "optional": true
910 | }
911 | }
912 | },
913 | "node_modules/@vitest/mocker/node_modules/estree-walker": {
914 | "version": "3.0.3",
915 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
916 | "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
917 | "dev": true,
918 | "license": "MIT",
919 | "dependencies": {
920 | "@types/estree": "^1.0.0"
921 | }
922 | },
923 | "node_modules/@vitest/pretty-format": {
924 | "version": "3.0.9",
925 | "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.9.tgz",
926 | "integrity": "sha512-OW9F8t2J3AwFEwENg3yMyKWweF7oRJlMyHOMIhO5F3n0+cgQAJZBjNgrF8dLwFTEXl5jUqBLXd9QyyKv8zEcmA==",
927 | "dev": true,
928 | "license": "MIT",
929 | "dependencies": {
930 | "tinyrainbow": "^2.0.0"
931 | },
932 | "funding": {
933 | "url": "https://opencollective.com/vitest"
934 | }
935 | },
936 | "node_modules/@vitest/runner": {
937 | "version": "3.0.9",
938 | "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.9.tgz",
939 | "integrity": "sha512-NX9oUXgF9HPfJSwl8tUZCMP1oGx2+Sf+ru6d05QjzQz4OwWg0psEzwY6VexP2tTHWdOkhKHUIZH+fS6nA7jfOw==",
940 | "dev": true,
941 | "license": "MIT",
942 | "dependencies": {
943 | "@vitest/utils": "3.0.9",
944 | "pathe": "^2.0.3"
945 | },
946 | "funding": {
947 | "url": "https://opencollective.com/vitest"
948 | }
949 | },
950 | "node_modules/@vitest/snapshot": {
951 | "version": "3.0.9",
952 | "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.9.tgz",
953 | "integrity": "sha512-AiLUiuZ0FuA+/8i19mTYd+re5jqjEc2jZbgJ2up0VY0Ddyyxg/uUtBDpIFAy4uzKaQxOW8gMgBdAJJ2ydhu39A==",
954 | "dev": true,
955 | "license": "MIT",
956 | "dependencies": {
957 | "@vitest/pretty-format": "3.0.9",
958 | "magic-string": "^0.30.17",
959 | "pathe": "^2.0.3"
960 | },
961 | "funding": {
962 | "url": "https://opencollective.com/vitest"
963 | }
964 | },
965 | "node_modules/@vitest/spy": {
966 | "version": "3.0.9",
967 | "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.9.tgz",
968 | "integrity": "sha512-/CcK2UDl0aQ2wtkp3YVWldrpLRNCfVcIOFGlVGKO4R5eajsH393Z1yiXLVQ7vWsj26JOEjeZI0x5sm5P4OGUNQ==",
969 | "dev": true,
970 | "license": "MIT",
971 | "dependencies": {
972 | "tinyspy": "^3.0.2"
973 | },
974 | "funding": {
975 | "url": "https://opencollective.com/vitest"
976 | }
977 | },
978 | "node_modules/@vitest/utils": {
979 | "version": "3.0.9",
980 | "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.9.tgz",
981 | "integrity": "sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng==",
982 | "dev": true,
983 | "license": "MIT",
984 | "dependencies": {
985 | "@vitest/pretty-format": "3.0.9",
986 | "loupe": "^3.1.3",
987 | "tinyrainbow": "^2.0.0"
988 | },
989 | "funding": {
990 | "url": "https://opencollective.com/vitest"
991 | }
992 | },
993 | "node_modules/assertion-error": {
994 | "version": "2.0.1",
995 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
996 | "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
997 | "dev": true,
998 | "license": "MIT",
999 | "engines": {
1000 | "node": ">=12"
1001 | }
1002 | },
1003 | "node_modules/benchmark": {
1004 | "version": "2.1.4",
1005 | "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz",
1006 | "integrity": "sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ==",
1007 | "dev": true,
1008 | "license": "MIT",
1009 | "dependencies": {
1010 | "lodash": "^4.17.4",
1011 | "platform": "^1.3.3"
1012 | }
1013 | },
1014 | "node_modules/cac": {
1015 | "version": "6.7.14",
1016 | "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
1017 | "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
1018 | "dev": true,
1019 | "license": "MIT",
1020 | "engines": {
1021 | "node": ">=8"
1022 | }
1023 | },
1024 | "node_modules/chai": {
1025 | "version": "5.2.0",
1026 | "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz",
1027 | "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==",
1028 | "dev": true,
1029 | "license": "MIT",
1030 | "dependencies": {
1031 | "assertion-error": "^2.0.1",
1032 | "check-error": "^2.1.1",
1033 | "deep-eql": "^5.0.1",
1034 | "loupe": "^3.1.0",
1035 | "pathval": "^2.0.0"
1036 | },
1037 | "engines": {
1038 | "node": ">=12"
1039 | }
1040 | },
1041 | "node_modules/check-error": {
1042 | "version": "2.1.1",
1043 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
1044 | "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
1045 | "dev": true,
1046 | "license": "MIT",
1047 | "engines": {
1048 | "node": ">= 16"
1049 | }
1050 | },
1051 | "node_modules/commondir": {
1052 | "version": "1.0.1",
1053 | "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
1054 | "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
1055 | "dev": true,
1056 | "license": "MIT"
1057 | },
1058 | "node_modules/debug": {
1059 | "version": "4.4.0",
1060 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
1061 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
1062 | "dev": true,
1063 | "license": "MIT",
1064 | "dependencies": {
1065 | "ms": "^2.1.3"
1066 | },
1067 | "engines": {
1068 | "node": ">=6.0"
1069 | },
1070 | "peerDependenciesMeta": {
1071 | "supports-color": {
1072 | "optional": true
1073 | }
1074 | }
1075 | },
1076 | "node_modules/deep-eql": {
1077 | "version": "5.0.2",
1078 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
1079 | "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
1080 | "dev": true,
1081 | "license": "MIT",
1082 | "engines": {
1083 | "node": ">=6"
1084 | }
1085 | },
1086 | "node_modules/deepmerge": {
1087 | "version": "4.3.1",
1088 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
1089 | "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
1090 | "dev": true,
1091 | "license": "MIT",
1092 | "engines": {
1093 | "node": ">=0.10.0"
1094 | }
1095 | },
1096 | "node_modules/es-module-lexer": {
1097 | "version": "1.6.0",
1098 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz",
1099 | "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==",
1100 | "dev": true,
1101 | "license": "MIT"
1102 | },
1103 | "node_modules/esbuild": {
1104 | "version": "0.25.1",
1105 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz",
1106 | "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==",
1107 | "dev": true,
1108 | "hasInstallScript": true,
1109 | "license": "MIT",
1110 | "bin": {
1111 | "esbuild": "bin/esbuild"
1112 | },
1113 | "engines": {
1114 | "node": ">=18"
1115 | },
1116 | "optionalDependencies": {
1117 | "@esbuild/aix-ppc64": "0.25.1",
1118 | "@esbuild/android-arm": "0.25.1",
1119 | "@esbuild/android-arm64": "0.25.1",
1120 | "@esbuild/android-x64": "0.25.1",
1121 | "@esbuild/darwin-arm64": "0.25.1",
1122 | "@esbuild/darwin-x64": "0.25.1",
1123 | "@esbuild/freebsd-arm64": "0.25.1",
1124 | "@esbuild/freebsd-x64": "0.25.1",
1125 | "@esbuild/linux-arm": "0.25.1",
1126 | "@esbuild/linux-arm64": "0.25.1",
1127 | "@esbuild/linux-ia32": "0.25.1",
1128 | "@esbuild/linux-loong64": "0.25.1",
1129 | "@esbuild/linux-mips64el": "0.25.1",
1130 | "@esbuild/linux-ppc64": "0.25.1",
1131 | "@esbuild/linux-riscv64": "0.25.1",
1132 | "@esbuild/linux-s390x": "0.25.1",
1133 | "@esbuild/linux-x64": "0.25.1",
1134 | "@esbuild/netbsd-arm64": "0.25.1",
1135 | "@esbuild/netbsd-x64": "0.25.1",
1136 | "@esbuild/openbsd-arm64": "0.25.1",
1137 | "@esbuild/openbsd-x64": "0.25.1",
1138 | "@esbuild/sunos-x64": "0.25.1",
1139 | "@esbuild/win32-arm64": "0.25.1",
1140 | "@esbuild/win32-ia32": "0.25.1",
1141 | "@esbuild/win32-x64": "0.25.1"
1142 | }
1143 | },
1144 | "node_modules/estree-walker": {
1145 | "version": "2.0.2",
1146 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
1147 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
1148 | "dev": true,
1149 | "license": "MIT"
1150 | },
1151 | "node_modules/expect-type": {
1152 | "version": "1.2.0",
1153 | "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.0.tgz",
1154 | "integrity": "sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA==",
1155 | "dev": true,
1156 | "license": "Apache-2.0",
1157 | "engines": {
1158 | "node": ">=12.0.0"
1159 | }
1160 | },
1161 | "node_modules/fdir": {
1162 | "version": "6.4.3",
1163 | "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz",
1164 | "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==",
1165 | "dev": true,
1166 | "license": "MIT",
1167 | "peerDependencies": {
1168 | "picomatch": "^3 || ^4"
1169 | },
1170 | "peerDependenciesMeta": {
1171 | "picomatch": {
1172 | "optional": true
1173 | }
1174 | }
1175 | },
1176 | "node_modules/fsevents": {
1177 | "version": "2.3.3",
1178 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1179 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1180 | "dev": true,
1181 | "hasInstallScript": true,
1182 | "license": "MIT",
1183 | "optional": true,
1184 | "os": [
1185 | "darwin"
1186 | ],
1187 | "engines": {
1188 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1189 | }
1190 | },
1191 | "node_modules/function-bind": {
1192 | "version": "1.1.2",
1193 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
1194 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
1195 | "dev": true,
1196 | "license": "MIT",
1197 | "funding": {
1198 | "url": "https://github.com/sponsors/ljharb"
1199 | }
1200 | },
1201 | "node_modules/hasown": {
1202 | "version": "2.0.2",
1203 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
1204 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
1205 | "dev": true,
1206 | "license": "MIT",
1207 | "dependencies": {
1208 | "function-bind": "^1.1.2"
1209 | },
1210 | "engines": {
1211 | "node": ">= 0.4"
1212 | }
1213 | },
1214 | "node_modules/is-core-module": {
1215 | "version": "2.16.1",
1216 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
1217 | "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
1218 | "dev": true,
1219 | "license": "MIT",
1220 | "dependencies": {
1221 | "hasown": "^2.0.2"
1222 | },
1223 | "engines": {
1224 | "node": ">= 0.4"
1225 | },
1226 | "funding": {
1227 | "url": "https://github.com/sponsors/ljharb"
1228 | }
1229 | },
1230 | "node_modules/is-module": {
1231 | "version": "1.0.0",
1232 | "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
1233 | "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
1234 | "dev": true,
1235 | "license": "MIT"
1236 | },
1237 | "node_modules/is-reference": {
1238 | "version": "1.2.1",
1239 | "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
1240 | "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
1241 | "dev": true,
1242 | "license": "MIT",
1243 | "dependencies": {
1244 | "@types/estree": "*"
1245 | }
1246 | },
1247 | "node_modules/lodash": {
1248 | "version": "4.17.21",
1249 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
1250 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
1251 | "dev": true,
1252 | "license": "MIT"
1253 | },
1254 | "node_modules/loupe": {
1255 | "version": "3.1.3",
1256 | "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz",
1257 | "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==",
1258 | "dev": true,
1259 | "license": "MIT"
1260 | },
1261 | "node_modules/magic-string": {
1262 | "version": "0.30.17",
1263 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
1264 | "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
1265 | "dev": true,
1266 | "license": "MIT",
1267 | "dependencies": {
1268 | "@jridgewell/sourcemap-codec": "^1.5.0"
1269 | }
1270 | },
1271 | "node_modules/ms": {
1272 | "version": "2.1.3",
1273 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1274 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1275 | "dev": true,
1276 | "license": "MIT"
1277 | },
1278 | "node_modules/nanoid": {
1279 | "version": "3.3.10",
1280 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.10.tgz",
1281 | "integrity": "sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==",
1282 | "dev": true,
1283 | "funding": [
1284 | {
1285 | "type": "github",
1286 | "url": "https://github.com/sponsors/ai"
1287 | }
1288 | ],
1289 | "license": "MIT",
1290 | "bin": {
1291 | "nanoid": "bin/nanoid.cjs"
1292 | },
1293 | "engines": {
1294 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1295 | }
1296 | },
1297 | "node_modules/path-parse": {
1298 | "version": "1.0.7",
1299 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
1300 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
1301 | "dev": true,
1302 | "license": "MIT"
1303 | },
1304 | "node_modules/pathe": {
1305 | "version": "2.0.3",
1306 | "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
1307 | "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
1308 | "dev": true,
1309 | "license": "MIT"
1310 | },
1311 | "node_modules/pathval": {
1312 | "version": "2.0.0",
1313 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz",
1314 | "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==",
1315 | "dev": true,
1316 | "license": "MIT",
1317 | "engines": {
1318 | "node": ">= 14.16"
1319 | }
1320 | },
1321 | "node_modules/picocolors": {
1322 | "version": "1.1.1",
1323 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1324 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1325 | "dev": true,
1326 | "license": "ISC"
1327 | },
1328 | "node_modules/picomatch": {
1329 | "version": "4.0.2",
1330 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
1331 | "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
1332 | "dev": true,
1333 | "license": "MIT",
1334 | "engines": {
1335 | "node": ">=12"
1336 | },
1337 | "funding": {
1338 | "url": "https://github.com/sponsors/jonschlinkert"
1339 | }
1340 | },
1341 | "node_modules/platform": {
1342 | "version": "1.3.6",
1343 | "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",
1344 | "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==",
1345 | "dev": true,
1346 | "license": "MIT"
1347 | },
1348 | "node_modules/postcss": {
1349 | "version": "8.5.3",
1350 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
1351 | "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
1352 | "dev": true,
1353 | "funding": [
1354 | {
1355 | "type": "opencollective",
1356 | "url": "https://opencollective.com/postcss/"
1357 | },
1358 | {
1359 | "type": "tidelift",
1360 | "url": "https://tidelift.com/funding/github/npm/postcss"
1361 | },
1362 | {
1363 | "type": "github",
1364 | "url": "https://github.com/sponsors/ai"
1365 | }
1366 | ],
1367 | "license": "MIT",
1368 | "dependencies": {
1369 | "nanoid": "^3.3.8",
1370 | "picocolors": "^1.1.1",
1371 | "source-map-js": "^1.2.1"
1372 | },
1373 | "engines": {
1374 | "node": "^10 || ^12 || >=14"
1375 | }
1376 | },
1377 | "node_modules/prettier": {
1378 | "version": "3.5.3",
1379 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
1380 | "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
1381 | "dev": true,
1382 | "license": "MIT",
1383 | "bin": {
1384 | "prettier": "bin/prettier.cjs"
1385 | },
1386 | "engines": {
1387 | "node": ">=14"
1388 | },
1389 | "funding": {
1390 | "url": "https://github.com/prettier/prettier?sponsor=1"
1391 | }
1392 | },
1393 | "node_modules/resolve": {
1394 | "version": "1.22.10",
1395 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
1396 | "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
1397 | "dev": true,
1398 | "license": "MIT",
1399 | "dependencies": {
1400 | "is-core-module": "^2.16.0",
1401 | "path-parse": "^1.0.7",
1402 | "supports-preserve-symlinks-flag": "^1.0.0"
1403 | },
1404 | "bin": {
1405 | "resolve": "bin/resolve"
1406 | },
1407 | "engines": {
1408 | "node": ">= 0.4"
1409 | },
1410 | "funding": {
1411 | "url": "https://github.com/sponsors/ljharb"
1412 | }
1413 | },
1414 | "node_modules/rollup": {
1415 | "version": "4.36.0",
1416 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.36.0.tgz",
1417 | "integrity": "sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q==",
1418 | "dev": true,
1419 | "license": "MIT",
1420 | "dependencies": {
1421 | "@types/estree": "1.0.6"
1422 | },
1423 | "bin": {
1424 | "rollup": "dist/bin/rollup"
1425 | },
1426 | "engines": {
1427 | "node": ">=18.0.0",
1428 | "npm": ">=8.0.0"
1429 | },
1430 | "optionalDependencies": {
1431 | "@rollup/rollup-android-arm-eabi": "4.36.0",
1432 | "@rollup/rollup-android-arm64": "4.36.0",
1433 | "@rollup/rollup-darwin-arm64": "4.36.0",
1434 | "@rollup/rollup-darwin-x64": "4.36.0",
1435 | "@rollup/rollup-freebsd-arm64": "4.36.0",
1436 | "@rollup/rollup-freebsd-x64": "4.36.0",
1437 | "@rollup/rollup-linux-arm-gnueabihf": "4.36.0",
1438 | "@rollup/rollup-linux-arm-musleabihf": "4.36.0",
1439 | "@rollup/rollup-linux-arm64-gnu": "4.36.0",
1440 | "@rollup/rollup-linux-arm64-musl": "4.36.0",
1441 | "@rollup/rollup-linux-loongarch64-gnu": "4.36.0",
1442 | "@rollup/rollup-linux-powerpc64le-gnu": "4.36.0",
1443 | "@rollup/rollup-linux-riscv64-gnu": "4.36.0",
1444 | "@rollup/rollup-linux-s390x-gnu": "4.36.0",
1445 | "@rollup/rollup-linux-x64-gnu": "4.36.0",
1446 | "@rollup/rollup-linux-x64-musl": "4.36.0",
1447 | "@rollup/rollup-win32-arm64-msvc": "4.36.0",
1448 | "@rollup/rollup-win32-ia32-msvc": "4.36.0",
1449 | "@rollup/rollup-win32-x64-msvc": "4.36.0",
1450 | "fsevents": "~2.3.2"
1451 | }
1452 | },
1453 | "node_modules/siginfo": {
1454 | "version": "2.0.0",
1455 | "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
1456 | "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
1457 | "dev": true,
1458 | "license": "ISC"
1459 | },
1460 | "node_modules/source-map-js": {
1461 | "version": "1.2.1",
1462 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
1463 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
1464 | "dev": true,
1465 | "license": "BSD-3-Clause",
1466 | "engines": {
1467 | "node": ">=0.10.0"
1468 | }
1469 | },
1470 | "node_modules/stackback": {
1471 | "version": "0.0.2",
1472 | "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
1473 | "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
1474 | "dev": true,
1475 | "license": "MIT"
1476 | },
1477 | "node_modules/std-env": {
1478 | "version": "3.8.1",
1479 | "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz",
1480 | "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==",
1481 | "dev": true,
1482 | "license": "MIT"
1483 | },
1484 | "node_modules/supports-preserve-symlinks-flag": {
1485 | "version": "1.0.0",
1486 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
1487 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
1488 | "dev": true,
1489 | "license": "MIT",
1490 | "engines": {
1491 | "node": ">= 0.4"
1492 | },
1493 | "funding": {
1494 | "url": "https://github.com/sponsors/ljharb"
1495 | }
1496 | },
1497 | "node_modules/tinybench": {
1498 | "version": "2.9.0",
1499 | "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
1500 | "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
1501 | "dev": true,
1502 | "license": "MIT"
1503 | },
1504 | "node_modules/tinyexec": {
1505 | "version": "0.3.2",
1506 | "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
1507 | "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
1508 | "dev": true,
1509 | "license": "MIT"
1510 | },
1511 | "node_modules/tinypool": {
1512 | "version": "1.0.2",
1513 | "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz",
1514 | "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==",
1515 | "dev": true,
1516 | "license": "MIT",
1517 | "engines": {
1518 | "node": "^18.0.0 || >=20.0.0"
1519 | }
1520 | },
1521 | "node_modules/tinyrainbow": {
1522 | "version": "2.0.0",
1523 | "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
1524 | "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
1525 | "dev": true,
1526 | "license": "MIT",
1527 | "engines": {
1528 | "node": ">=14.0.0"
1529 | }
1530 | },
1531 | "node_modules/tinyspy": {
1532 | "version": "3.0.2",
1533 | "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz",
1534 | "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==",
1535 | "dev": true,
1536 | "license": "MIT",
1537 | "engines": {
1538 | "node": ">=14.0.0"
1539 | }
1540 | },
1541 | "node_modules/tslib": {
1542 | "version": "2.8.1",
1543 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
1544 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
1545 | "dev": true,
1546 | "license": "0BSD"
1547 | },
1548 | "node_modules/typescript": {
1549 | "version": "5.8.2",
1550 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
1551 | "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
1552 | "dev": true,
1553 | "license": "Apache-2.0",
1554 | "bin": {
1555 | "tsc": "bin/tsc",
1556 | "tsserver": "bin/tsserver"
1557 | },
1558 | "engines": {
1559 | "node": ">=14.17"
1560 | }
1561 | },
1562 | "node_modules/undici-types": {
1563 | "version": "6.20.0",
1564 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
1565 | "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
1566 | "dev": true,
1567 | "license": "MIT"
1568 | },
1569 | "node_modules/vite": {
1570 | "version": "6.2.2",
1571 | "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.2.tgz",
1572 | "integrity": "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==",
1573 | "dev": true,
1574 | "license": "MIT",
1575 | "dependencies": {
1576 | "esbuild": "^0.25.0",
1577 | "postcss": "^8.5.3",
1578 | "rollup": "^4.30.1"
1579 | },
1580 | "bin": {
1581 | "vite": "bin/vite.js"
1582 | },
1583 | "engines": {
1584 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
1585 | },
1586 | "funding": {
1587 | "url": "https://github.com/vitejs/vite?sponsor=1"
1588 | },
1589 | "optionalDependencies": {
1590 | "fsevents": "~2.3.3"
1591 | },
1592 | "peerDependencies": {
1593 | "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
1594 | "jiti": ">=1.21.0",
1595 | "less": "*",
1596 | "lightningcss": "^1.21.0",
1597 | "sass": "*",
1598 | "sass-embedded": "*",
1599 | "stylus": "*",
1600 | "sugarss": "*",
1601 | "terser": "^5.16.0",
1602 | "tsx": "^4.8.1",
1603 | "yaml": "^2.4.2"
1604 | },
1605 | "peerDependenciesMeta": {
1606 | "@types/node": {
1607 | "optional": true
1608 | },
1609 | "jiti": {
1610 | "optional": true
1611 | },
1612 | "less": {
1613 | "optional": true
1614 | },
1615 | "lightningcss": {
1616 | "optional": true
1617 | },
1618 | "sass": {
1619 | "optional": true
1620 | },
1621 | "sass-embedded": {
1622 | "optional": true
1623 | },
1624 | "stylus": {
1625 | "optional": true
1626 | },
1627 | "sugarss": {
1628 | "optional": true
1629 | },
1630 | "terser": {
1631 | "optional": true
1632 | },
1633 | "tsx": {
1634 | "optional": true
1635 | },
1636 | "yaml": {
1637 | "optional": true
1638 | }
1639 | }
1640 | },
1641 | "node_modules/vite-node": {
1642 | "version": "3.0.9",
1643 | "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.9.tgz",
1644 | "integrity": "sha512-w3Gdx7jDcuT9cNn9jExXgOyKmf5UOTb6WMHz8LGAm54eS1Elf5OuBhCxl6zJxGhEeIkgsE1WbHuoL0mj/UXqXg==",
1645 | "dev": true,
1646 | "license": "MIT",
1647 | "dependencies": {
1648 | "cac": "^6.7.14",
1649 | "debug": "^4.4.0",
1650 | "es-module-lexer": "^1.6.0",
1651 | "pathe": "^2.0.3",
1652 | "vite": "^5.0.0 || ^6.0.0"
1653 | },
1654 | "bin": {
1655 | "vite-node": "vite-node.mjs"
1656 | },
1657 | "engines": {
1658 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
1659 | },
1660 | "funding": {
1661 | "url": "https://opencollective.com/vitest"
1662 | }
1663 | },
1664 | "node_modules/vitest": {
1665 | "version": "3.0.9",
1666 | "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.9.tgz",
1667 | "integrity": "sha512-BbcFDqNyBlfSpATmTtXOAOj71RNKDDvjBM/uPfnxxVGrG+FSH2RQIwgeEngTaTkuU/h0ScFvf+tRcKfYXzBybQ==",
1668 | "dev": true,
1669 | "license": "MIT",
1670 | "dependencies": {
1671 | "@vitest/expect": "3.0.9",
1672 | "@vitest/mocker": "3.0.9",
1673 | "@vitest/pretty-format": "^3.0.9",
1674 | "@vitest/runner": "3.0.9",
1675 | "@vitest/snapshot": "3.0.9",
1676 | "@vitest/spy": "3.0.9",
1677 | "@vitest/utils": "3.0.9",
1678 | "chai": "^5.2.0",
1679 | "debug": "^4.4.0",
1680 | "expect-type": "^1.1.0",
1681 | "magic-string": "^0.30.17",
1682 | "pathe": "^2.0.3",
1683 | "std-env": "^3.8.0",
1684 | "tinybench": "^2.9.0",
1685 | "tinyexec": "^0.3.2",
1686 | "tinypool": "^1.0.2",
1687 | "tinyrainbow": "^2.0.0",
1688 | "vite": "^5.0.0 || ^6.0.0",
1689 | "vite-node": "3.0.9",
1690 | "why-is-node-running": "^2.3.0"
1691 | },
1692 | "bin": {
1693 | "vitest": "vitest.mjs"
1694 | },
1695 | "engines": {
1696 | "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
1697 | },
1698 | "funding": {
1699 | "url": "https://opencollective.com/vitest"
1700 | },
1701 | "peerDependencies": {
1702 | "@edge-runtime/vm": "*",
1703 | "@types/debug": "^4.1.12",
1704 | "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
1705 | "@vitest/browser": "3.0.9",
1706 | "@vitest/ui": "3.0.9",
1707 | "happy-dom": "*",
1708 | "jsdom": "*"
1709 | },
1710 | "peerDependenciesMeta": {
1711 | "@edge-runtime/vm": {
1712 | "optional": true
1713 | },
1714 | "@types/debug": {
1715 | "optional": true
1716 | },
1717 | "@types/node": {
1718 | "optional": true
1719 | },
1720 | "@vitest/browser": {
1721 | "optional": true
1722 | },
1723 | "@vitest/ui": {
1724 | "optional": true
1725 | },
1726 | "happy-dom": {
1727 | "optional": true
1728 | },
1729 | "jsdom": {
1730 | "optional": true
1731 | }
1732 | }
1733 | },
1734 | "node_modules/why-is-node-running": {
1735 | "version": "2.3.0",
1736 | "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
1737 | "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
1738 | "dev": true,
1739 | "license": "MIT",
1740 | "dependencies": {
1741 | "siginfo": "^2.0.0",
1742 | "stackback": "0.0.2"
1743 | },
1744 | "bin": {
1745 | "why-is-node-running": "cli.js"
1746 | },
1747 | "engines": {
1748 | "node": ">=8"
1749 | }
1750 | }
1751 | }
1752 | }
1753 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ulid",
3 | "version": "3.0.0",
4 | "description": "A universally-unique, lexicographically-sortable, identifier generator",
5 | "type": "module",
6 | "exports": {
7 | ".": {
8 | "types": {
9 | "require": "./dist/index.d.cts",
10 | "default": "./dist/index.d.ts"
11 | },
12 | "node": {
13 | "require": "./dist/node/index.cjs",
14 | "default": "./dist/node/index.js"
15 | },
16 | "default": {
17 | "require": "./dist/browser/index.cjs",
18 | "default": "./dist/browser/index.js"
19 | }
20 | },
21 | "./package.json": "./package.json"
22 | },
23 | "main": "dist/node/index.cjs",
24 | "module": "./dist/node/index.js",
25 | "browser": {
26 | "./dist/node/index.cjs": "./dist/browser/index.cjs",
27 | "./dist/node/index.js": "./dist/browser/index.js"
28 | },
29 | "react-native": "./dist/browser/index.cjs",
30 | "types": "dist/index.d.ts",
31 | "sideEffects": false,
32 | "bin": "./dist/cli.js",
33 | "scripts": {
34 | "bench": "npm run build && node test/benchmark.js",
35 | "build": "npm run clean && npm run build:node:cjs && npm run build:node:esm && npm run build:browser:cjs && npm run build:browser:esm && npm run build:cli && npm run build:types",
36 | "build:browser:cjs": "FMT=cjs ENV=browser rollup -c --name ulidx",
37 | "build:browser:esm": "FMT=esm ENV=browser rollup -c --name ulidx",
38 | "build:cli": "FMT=esm ENV=cli rollup -c && chmod +x ./dist/cli.js",
39 | "build:node:cjs": "FMT=cjs ENV=node rollup -c",
40 | "build:node:esm": "FMT=esm ENV=node rollup -c",
41 | "build:types": "tsc -p tsconfig.dec.json --emitDeclarationOnly && find ./dist -name '*.d.ts' -exec sh -c 'cp {} $(dirname {})/$(basename -s .d.ts {}).d.cts' \\;",
42 | "clean": "rm -rf ./dist",
43 | "format": "prettier --write \"{{source,test}/**/*.{js,ts},rollup.config.js,vitest.config.js}\"",
44 | "test": "npm run build && npm run test:specs && npm run test:format && npm run test:types",
45 | "test:format": "prettier --check \"{{source,test}/**/*.{js,ts},rollup.config.js,vitest.config.js}\"",
46 | "test:specs": "vitest",
47 | "test:types": "npx --yes @arethetypeswrong/cli --pack ."
48 | },
49 | "files": [
50 | "dist/**/*"
51 | ],
52 | "repository": {
53 | "type": "git",
54 | "url": "git+https://github.com/ulid/javascript.git"
55 | },
56 | "author": "Alizain Feerasta",
57 | "license": "MIT",
58 | "bugs": {
59 | "url": "https://github.com/ulid/javascript/issues"
60 | },
61 | "homepage": "https://github.com/ulid/javascript#readme",
62 | "devDependencies": {
63 | "@rollup/plugin-alias": "^5.1.1",
64 | "@rollup/plugin-commonjs": "^28.0.3",
65 | "@rollup/plugin-node-resolve": "^16.0.1",
66 | "@rollup/plugin-typescript": "^12.1.2",
67 | "@types/node": "^22.13.10",
68 | "benchmark": "^2.1.4",
69 | "prettier": "^3.5.3",
70 | "rollup": "^4.36.0",
71 | "tslib": "^2.8.1",
72 | "typescript": "^5.8.2",
73 | "vitest": "^3.0.9"
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import { builtinModules } from "node:module";
2 | import typescript from "@rollup/plugin-typescript";
3 | import resolve from "@rollup/plugin-node-resolve";
4 | import alias from "@rollup/plugin-alias";
5 | import pkg from "./package.json" with { type: "json" };
6 |
7 | const EXTENSIONS = [".js", ".ts"];
8 | const ENV = process.env.ENV ? process.env.ENV : "node";
9 | const FMT = process.env.FMT ? process.env.FMT : "esm";
10 |
11 | const entry = ENV === "cli" ? "source/cli.ts" : "source/index.ts";
12 | const output = ENV === "cli" ? "dist" : `dist/${ENV}`;
13 |
14 | const plugins = [
15 | typescript({
16 | tsconfig: "tsconfig.json"
17 | }),
18 | resolve({ extensions: EXTENSIONS })
19 | ];
20 | if (ENV !== "node") {
21 | plugins.unshift(
22 | alias({
23 | entries: [{ find: "node:crypto", replacement: "./stub.js" }]
24 | })
25 | );
26 | }
27 | const extension = FMT === "cjs" ? "cjs" : "js";
28 | const externals =
29 | FMT === "esm"
30 | ? [...builtinModules, ...(pkg.dependencies ? Object.keys(pkg.dependencies) : [])]
31 | : [...builtinModules];
32 |
33 | export default {
34 | external: externals,
35 | input: entry,
36 | output: [
37 | {
38 | dir: output,
39 | format: FMT,
40 | entryFileNames: `[name].${extension}`
41 | }
42 | ],
43 | plugins
44 | };
45 |
--------------------------------------------------------------------------------
/source/cli.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | import { monotonicFactory } from "./ulid.js";
4 |
5 | function parseArgs(args: Array): Record {
6 | const output = {};
7 |
8 | while (args.length > 0) {
9 | const arg = args.shift();
10 |
11 | if (/^\-\-/.test(arg)) {
12 | if (/=/.test(arg)) {
13 | const [key, value] = arg.split("=");
14 | output[key.substring(2)] = value;
15 | } else {
16 | const value = args.shift();
17 |
18 | if (/^-/.test(value)) {
19 | args.unshift(value);
20 | } else if (!value) {
21 | output[arg.substring(2)] = true;
22 | } else {
23 | output[arg.substring(2)] = value;
24 | }
25 | }
26 | }
27 | }
28 |
29 | return output;
30 | }
31 |
32 | const argv = parseArgs(process.argv.slice(2));
33 |
34 | const count = /^\d+/.test(argv["count"] as string) ? parseInt(argv["count"] as string, 10) : 1;
35 |
36 | const factory = monotonicFactory();
37 |
38 | for (let i = 0; i < count; i += 1) {
39 | console.log(factory());
40 | }
41 |
--------------------------------------------------------------------------------
/source/constants.ts:
--------------------------------------------------------------------------------
1 | // These values should NEVER change. The values are precisely for
2 | // generating ULIDs.
3 | export const B32_CHARACTERS = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
4 | export const ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; // Crockford's Base32
5 | export const ENCODING_LEN = 32; // from ENCODING.length;
6 | export const MAX_ULID = "7ZZZZZZZZZZZZZZZZZZZZZZZZZ";
7 | export const MIN_ULID = "00000000000000000000000000";
8 | export const RANDOM_LEN = 16;
9 | export const TIME_LEN = 10;
10 | export const TIME_MAX = 281474976710655; // from Math.pow(2, 48) - 1;
11 | export const ULID_REGEX = /^[0-7][0-9a-hjkmnp-tv-zA-HJKMNP-TV-Z]{25}$/;
12 | export const UUID_REGEX = /^[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$/;
13 |
--------------------------------------------------------------------------------
/source/crockford.ts:
--------------------------------------------------------------------------------
1 | // Code from https://github.com/devbanana/crockford-base32/blob/develop/src/index.ts
2 | import { B32_CHARACTERS, ENCODING, ENCODING_LEN } from "./constants.js";
3 | import { ULIDError, ULIDErrorCode } from "./error.js";
4 | import { replaceCharAt } from "./utils.js";
5 |
6 | export function crockfordEncode(input: Uint8Array): string {
7 | const output: number[] = [];
8 | let bitsRead = 0;
9 | let buffer = 0;
10 | const reversedInput = new Uint8Array(input.slice().reverse());
11 | for (const byte of reversedInput) {
12 | buffer |= byte << bitsRead;
13 | bitsRead += 8;
14 |
15 | while (bitsRead >= 5) {
16 | output.unshift(buffer & 0x1f);
17 | buffer >>>= 5;
18 | bitsRead -= 5;
19 | }
20 | }
21 | if (bitsRead > 0) {
22 | output.unshift(buffer & 0x1f);
23 | }
24 | return output.map(byte => B32_CHARACTERS.charAt(byte)).join("");
25 | }
26 |
27 | export function crockfordDecode(input: string): Uint8Array {
28 | const sanitizedInput = input.toUpperCase().split("").reverse().join("");
29 | const output: number[] = [];
30 | let bitsRead = 0;
31 | let buffer = 0;
32 | for (const character of sanitizedInput) {
33 | const byte = B32_CHARACTERS.indexOf(character);
34 | if (byte === -1) {
35 | throw new Error(`Invalid base 32 character found in string: ${character}`);
36 | }
37 | buffer |= byte << bitsRead;
38 | bitsRead += 5;
39 | while (bitsRead >= 8) {
40 | output.unshift(buffer & 0xff);
41 | buffer >>>= 8;
42 | bitsRead -= 8;
43 | }
44 | }
45 | if (bitsRead >= 5 || buffer > 0) {
46 | output.unshift(buffer & 0xff);
47 | }
48 | return new Uint8Array(output);
49 | }
50 |
51 | /**
52 | * Fix a ULID's Base32 encoding -
53 | * i and l (case-insensitive) will be treated as 1 and o (case-insensitive) will be treated as 0.
54 | * hyphens are ignored during decoding.
55 | * @param id The ULID
56 | * @returns The cleaned up ULID
57 | */
58 | export function fixULIDBase32(id: string): string {
59 | return id.replace(/i/gi, "1").replace(/l/gi, "1").replace(/o/gi, "0").replace(/-/g, "");
60 | }
61 |
62 | export function incrementBase32(str: string): string {
63 | let done: string | undefined = undefined,
64 | index = str.length,
65 | char: string,
66 | charIndex: number,
67 | output = str;
68 | const maxCharIndex = ENCODING_LEN - 1;
69 | while (!done && index-- >= 0) {
70 | char = output[index];
71 | charIndex = ENCODING.indexOf(char);
72 | if (charIndex === -1) {
73 | throw new ULIDError(
74 | ULIDErrorCode.Base32IncorrectEncoding,
75 | "Incorrectly encoded string"
76 | );
77 | }
78 | if (charIndex === maxCharIndex) {
79 | output = replaceCharAt(output, index, ENCODING[0]);
80 | continue;
81 | }
82 | done = replaceCharAt(output, index, ENCODING[charIndex + 1]);
83 | }
84 | if (typeof done === "string") {
85 | return done;
86 | }
87 | throw new ULIDError(ULIDErrorCode.Base32IncorrectEncoding, "Failed incrementing string");
88 | }
89 |
--------------------------------------------------------------------------------
/source/error.ts:
--------------------------------------------------------------------------------
1 | export enum ULIDErrorCode {
2 | Base32IncorrectEncoding = "B32_ENC_INVALID",
3 | DecodeTimeInvalidCharacter = "DEC_TIME_CHAR",
4 | DecodeTimeValueMalformed = "DEC_TIME_MALFORMED",
5 | EncodeTimeNegative = "ENC_TIME_NEG",
6 | EncodeTimeSizeExceeded = "ENC_TIME_SIZE_EXCEED",
7 | EncodeTimeValueMalformed = "ENC_TIME_MALFORMED",
8 | PRNGDetectFailure = "PRNG_DETECT",
9 | ULIDInvalid = "ULID_INVALID",
10 | Unexpected = "UNEXPECTED",
11 | UUIDInvalid = "UUID_INVALID"
12 | }
13 |
14 | export class ULIDError extends Error {
15 | public code: ULIDErrorCode;
16 |
17 | constructor(errorCode: ULIDErrorCode, message: string) {
18 | super(`${message} (${errorCode})`);
19 |
20 | this.name = "ULIDError";
21 |
22 | this.code = errorCode;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/source/index.ts:
--------------------------------------------------------------------------------
1 | export { decodeTime, encodeTime, isValid, monotonicFactory, ulid } from "./ulid.js";
2 | export { ulidToUUID, uuidToULID } from "./uuid.js";
3 | export { fixULIDBase32, incrementBase32 } from "./crockford.js";
4 | export { ULIDError, ULIDErrorCode } from "./error.js";
5 | export { MAX_ULID, MIN_ULID, TIME_LEN, TIME_MAX } from "./constants.js";
6 | export * from "./types.js";
7 |
--------------------------------------------------------------------------------
/source/stub.ts:
--------------------------------------------------------------------------------
1 | export default undefined;
2 |
--------------------------------------------------------------------------------
/source/types.ts:
--------------------------------------------------------------------------------
1 | export type PRNG = () => number;
2 |
3 | export type ULID = string;
4 |
5 | export type ULIDFactory = (seedTime?: number) => ULID;
6 |
7 | export type UUID = string;
8 |
--------------------------------------------------------------------------------
/source/ulid.ts:
--------------------------------------------------------------------------------
1 | import crypto from "node:crypto";
2 | import { incrementBase32 } from "./crockford.js";
3 | import { ENCODING, ENCODING_LEN, RANDOM_LEN, TIME_LEN, TIME_MAX } from "./constants.js";
4 | import { ULIDError, ULIDErrorCode } from "./error.js";
5 | import { PRNG, ULID, ULIDFactory } from "./types.js";
6 | import { randomChar } from "./utils.js";
7 |
8 | /**
9 | * Decode time from a ULID
10 | * @param id The ULID
11 | * @returns The decoded timestamp
12 | */
13 | export function decodeTime(id: ULID): number {
14 | if (id.length !== TIME_LEN + RANDOM_LEN) {
15 | throw new ULIDError(ULIDErrorCode.DecodeTimeValueMalformed, "Malformed ULID");
16 | }
17 | const time = id
18 | .substr(0, TIME_LEN)
19 | .toUpperCase()
20 | .split("")
21 | .reverse()
22 | .reduce((carry, char, index) => {
23 | const encodingIndex = ENCODING.indexOf(char);
24 | if (encodingIndex === -1) {
25 | throw new ULIDError(
26 | ULIDErrorCode.DecodeTimeInvalidCharacter,
27 | `Time decode error: Invalid character: ${char}`
28 | );
29 | }
30 | return (carry += encodingIndex * Math.pow(ENCODING_LEN, index));
31 | }, 0);
32 | if (time > TIME_MAX) {
33 | throw new ULIDError(
34 | ULIDErrorCode.DecodeTimeValueMalformed,
35 | `Malformed ULID: timestamp too large: ${time}`
36 | );
37 | }
38 | return time;
39 | }
40 |
41 | /**
42 | * Detect the best PRNG (pseudo-random number generator)
43 | * @param root The root to check from (global/window)
44 | * @returns The PRNG function
45 | */
46 | export function detectPRNG(root?: any): PRNG {
47 | const rootLookup = root || detectRoot();
48 | const globalCrypto =
49 | (rootLookup && (rootLookup.crypto || rootLookup.msCrypto)) ||
50 | (typeof crypto !== "undefined" ? crypto : null);
51 | if (typeof globalCrypto?.getRandomValues === "function") {
52 | return () => {
53 | const buffer = new Uint8Array(1);
54 | globalCrypto.getRandomValues(buffer);
55 | return buffer[0] / 0xff;
56 | };
57 | } else if (typeof globalCrypto?.randomBytes === "function") {
58 | return () => globalCrypto.randomBytes(1).readUInt8() / 0xff;
59 | } else if (crypto?.randomBytes) {
60 | return () => crypto.randomBytes(1).readUInt8() / 0xff;
61 | }
62 | throw new ULIDError(ULIDErrorCode.PRNGDetectFailure, "Failed to find a reliable PRNG");
63 | }
64 |
65 | function detectRoot(): any {
66 | if (inWebWorker()) return self;
67 | if (typeof window !== "undefined") {
68 | return window;
69 | }
70 | if (typeof global !== "undefined") {
71 | return global;
72 | }
73 | if (typeof globalThis !== "undefined") {
74 | return globalThis;
75 | }
76 | return null;
77 | }
78 |
79 | export function encodeRandom(len: number, prng: PRNG): string {
80 | let str = "";
81 | for (; len > 0; len--) {
82 | str = randomChar(prng) + str;
83 | }
84 | return str;
85 | }
86 |
87 | /**
88 | * Encode the time portion of a ULID
89 | * @param now The current timestamp
90 | * @param len Length to generate
91 | * @returns The encoded time
92 | */
93 | export function encodeTime(now: number, len: number = TIME_LEN): string {
94 | if (isNaN(now)) {
95 | throw new ULIDError(
96 | ULIDErrorCode.EncodeTimeValueMalformed,
97 | `Time must be a number: ${now}`
98 | );
99 | } else if (now > TIME_MAX) {
100 | throw new ULIDError(
101 | ULIDErrorCode.EncodeTimeSizeExceeded,
102 | `Cannot encode a time larger than ${TIME_MAX}: ${now}`
103 | );
104 | } else if (now < 0) {
105 | throw new ULIDError(ULIDErrorCode.EncodeTimeNegative, `Time must be positive: ${now}`);
106 | } else if (Number.isInteger(now) === false) {
107 | throw new ULIDError(
108 | ULIDErrorCode.EncodeTimeValueMalformed,
109 | `Time must be an integer: ${now}`
110 | );
111 | }
112 | let mod: number,
113 | str: string = "";
114 | for (let currentLen = len; currentLen > 0; currentLen--) {
115 | mod = now % ENCODING_LEN;
116 | str = ENCODING.charAt(mod) + str;
117 | now = (now - mod) / ENCODING_LEN;
118 | }
119 | return str;
120 | }
121 |
122 | function inWebWorker(): boolean {
123 | // @ts-ignore
124 | return typeof WorkerGlobalScope !== "undefined" && self instanceof WorkerGlobalScope;
125 | }
126 |
127 | /**
128 | * Check if a ULID is valid
129 | * @param id The ULID to test
130 | * @returns True if valid, false otherwise
131 | * @example
132 | * isValid("01HNZX8JGFACFA36RBXDHEQN6E"); // true
133 | * isValid(""); // false
134 | */
135 | export function isValid(id: string): boolean {
136 | return (
137 | typeof id === "string" &&
138 | id.length === TIME_LEN + RANDOM_LEN &&
139 | id
140 | .toUpperCase()
141 | .split("")
142 | .every(char => ENCODING.indexOf(char) !== -1)
143 | );
144 | }
145 |
146 | /**
147 | * Create a ULID factory to generate monotonically-increasing
148 | * ULIDs
149 | * @param prng The PRNG to use
150 | * @returns A ulid factory
151 | * @example
152 | * const ulid = monotonicFactory();
153 | * ulid(); // "01HNZXD07M5CEN5XA66EMZSRZW"
154 | */
155 | export function monotonicFactory(prng?: PRNG): ULIDFactory {
156 | const currentPRNG = prng || detectPRNG();
157 | let lastTime: number = 0,
158 | lastRandom: string;
159 | return function _ulid(seedTime?: number): ULID {
160 | const seed = !seedTime || isNaN(seedTime) ? Date.now() : seedTime;
161 | if (seed <= lastTime) {
162 | const incrementedRandom = (lastRandom = incrementBase32(lastRandom));
163 | return encodeTime(lastTime, TIME_LEN) + incrementedRandom;
164 | }
165 | lastTime = seed;
166 | const newRandom = (lastRandom = encodeRandom(RANDOM_LEN, currentPRNG));
167 | return encodeTime(seed, TIME_LEN) + newRandom;
168 | };
169 | }
170 |
171 | /**
172 | * Generate a ULID
173 | * @param seedTime Optional time seed
174 | * @param prng Optional PRNG function
175 | * @returns A ULID string
176 | * @example
177 | * ulid(); // "01HNZXD07M5CEN5XA66EMZSRZW"
178 | */
179 | export function ulid(seedTime?: number, prng?: PRNG): ULID {
180 | const currentPRNG = prng || detectPRNG();
181 | const seed = !seedTime || isNaN(seedTime) ? Date.now() : seedTime;
182 | return encodeTime(seed, TIME_LEN) + encodeRandom(RANDOM_LEN, currentPRNG);
183 | }
184 |
--------------------------------------------------------------------------------
/source/utils.ts:
--------------------------------------------------------------------------------
1 | import { ENCODING, ENCODING_LEN } from "./constants.js";
2 | import { PRNG } from "./types.js";
3 |
4 | export function randomChar(prng: PRNG): string {
5 | let rand = Math.floor(prng() * ENCODING_LEN);
6 | if (rand === ENCODING_LEN) {
7 | rand = ENCODING_LEN - 1;
8 | }
9 | return ENCODING.charAt(rand);
10 | }
11 |
12 | export function replaceCharAt(str: string, index: number, char: string): string {
13 | if (index > str.length - 1) {
14 | return str;
15 | }
16 | return str.substr(0, index) + char + str.substr(index + 1);
17 | }
18 |
--------------------------------------------------------------------------------
/source/uuid.ts:
--------------------------------------------------------------------------------
1 | import { UUID } from "crypto";
2 | import { ULID_REGEX, UUID_REGEX } from "./constants.js";
3 | import { crockfordDecode, crockfordEncode } from "./crockford.js";
4 | import { ULIDError, ULIDErrorCode } from "./error.js";
5 | import { ULID } from "./types.js";
6 |
7 | /**
8 | * Convert a ULID to a UUID
9 | * @param ulid The ULID to convert
10 | * @returns A UUID string
11 | */
12 | export function ulidToUUID(ulid: ULID): UUID {
13 | const isValid = ULID_REGEX.test(ulid);
14 | if (!isValid) {
15 | throw new ULIDError(ULIDErrorCode.ULIDInvalid, `Invalid ULID: ${ulid}`);
16 | }
17 | const uint8Array = crockfordDecode(ulid);
18 | let uuid = Array.from(uint8Array)
19 | .map(byte => byte.toString(16).padStart(2, "0"))
20 | .join("");
21 | uuid =
22 | uuid.substring(0, 8) +
23 | "-" +
24 | uuid.substring(8, 12) +
25 | "-" +
26 | uuid.substring(12, 16) +
27 | "-" +
28 | uuid.substring(16, 20) +
29 | "-" +
30 | uuid.substring(20);
31 | return uuid.toUpperCase() as UUID;
32 | }
33 |
34 | /**
35 | * Convert a UUID to a ULID
36 | * @param uuid The UUID to convert
37 | * @returns A ULID string
38 | */
39 | export function uuidToULID(uuid: string): ULID {
40 | const isValid = UUID_REGEX.test(uuid);
41 | if (!isValid) {
42 | throw new ULIDError(ULIDErrorCode.UUIDInvalid, `Invalid UUID: ${uuid}`);
43 | }
44 | const bytes = uuid.replace(/-/g, "").match(/.{1,2}/g);
45 | if (!bytes) {
46 | throw new ULIDError(ULIDErrorCode.Unexpected, `Failed parsing UUID bytes: ${uuid}`);
47 | }
48 | const uint8Array = new Uint8Array(bytes.map(byte => parseInt(byte, 16)));
49 | return crockfordEncode(uint8Array);
50 | }
51 |
--------------------------------------------------------------------------------
/test/benchmark.js:
--------------------------------------------------------------------------------
1 | import Benchmark from "benchmark";
2 | import { ulid } from "../dist/node/index.js";
3 |
4 | const suite = new Benchmark.Suite();
5 |
6 | // add tests
7 | suite.add("Simple ulid", function () {
8 | ulid();
9 | });
10 | suite.add("ulid with timestamp", function () {
11 | ulid(Date.now());
12 | });
13 |
14 | // add listeners
15 | suite.on("cycle", function (event) {
16 | console.log(String(event.target));
17 | });
18 | suite.on("complete", function () {
19 | console.log("Done!");
20 | });
21 |
22 | // run async
23 | suite.run({ async: true });
24 |
--------------------------------------------------------------------------------
/test/node/crockford.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from "vitest";
2 | import { fixULIDBase32, incrementBase32 } from "../../";
3 |
4 | describe("fixULIDBase32", () => {
5 | it("fixes mis-encoded ULIDs", () => {
6 | expect(fixULIDBase32("oLARYZ6-S41TSV4RRF-FQ69G5FAV")).to.equal(
7 | "01ARYZ6S41TSV4RRFFQ69G5FAV"
8 | );
9 | });
10 | });
11 |
12 | describe("incrementBase32", () => {
13 | it("increments correctly", () => {
14 | expect(incrementBase32("A109C")).toEqual("A109D");
15 | });
16 |
17 | it("carries correctly", () => {
18 | expect(incrementBase32("A1YZZ")).toEqual("A1Z00");
19 | });
20 |
21 | it("double increments correctly", () => {
22 | expect(incrementBase32(incrementBase32("A1YZZ"))).toEqual("A1Z01");
23 | });
24 |
25 | it("throws when it cannot increment", () => {
26 | expect(() => {
27 | incrementBase32("ZZZ");
28 | }).toThrow(/B32_ENC_INVALID/);
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/test/node/ulid.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from "vitest";
2 | import { decodeTime, encodeTime, monotonicFactory, ulid, ULIDFactory } from "../../";
3 |
4 | const ULID_REXP = /^[0-7][0-9a-hjkmnp-tv-zA-HJKMNP-TV-Z]{25}$/;
5 |
6 | describe("decodeTime", function () {
7 | it("extracts a timestamp from a ULID", () => {
8 | expect(decodeTime("01ARYZ6S41TSV4RRFFQ69G5FAV")).to.equal(1469918176385);
9 | });
10 | });
11 |
12 | describe("encodeTime", function () {
13 | it("encodes a timestamp", () => {
14 | expect(encodeTime(1469918176385)).to.equal("01ARYZ6S41");
15 | });
16 | });
17 |
18 | describe("monotonicFactory", () => {
19 | function stubbedPrng() {
20 | return 0.96;
21 | }
22 |
23 | it("creates a factory", () => {
24 | const factory = monotonicFactory();
25 | expect(factory).toBeTypeOf("function");
26 | });
27 |
28 | describe("returned factory", () => {
29 | it("generates a ULID", () => {
30 | const factory = monotonicFactory();
31 | const id = factory();
32 | expect(id).toMatch(ULID_REXP);
33 | });
34 |
35 | describe("during single point in time", function () {
36 | const SEED_TIME = 1469918176385;
37 | const stubbedUlid: ULIDFactory = monotonicFactory(stubbedPrng);
38 |
39 | it("first call", function () {
40 | expect(stubbedUlid(SEED_TIME)).to.equal("01ARYZ6S41YYYYYYYYYYYYYYYY");
41 | });
42 |
43 | it("second call", function () {
44 | expect(stubbedUlid(SEED_TIME)).to.equal("01ARYZ6S41YYYYYYYYYYYYYYYZ");
45 | });
46 |
47 | it("third call", function () {
48 | expect(stubbedUlid(SEED_TIME)).to.equal("01ARYZ6S41YYYYYYYYYYYYYYZ0");
49 | });
50 |
51 | it("fourth call", function () {
52 | expect(stubbedUlid(SEED_TIME)).to.equal("01ARYZ6S41YYYYYYYYYYYYYYZ1");
53 | });
54 | });
55 |
56 | describe("with specific seedTime", function () {
57 | const stubbedUlid: ULIDFactory = monotonicFactory(stubbedPrng);
58 |
59 | it("first call", function () {
60 | expect(stubbedUlid(1469918176385)).to.equal("01ARYZ6S41YYYYYYYYYYYYYYYY");
61 | });
62 |
63 | it("second call with the same", function () {
64 | expect(stubbedUlid(1469918176385)).to.equal("01ARYZ6S41YYYYYYYYYYYYYYYZ");
65 | });
66 |
67 | it("third call with less than", function () {
68 | expect(stubbedUlid(100000000)).to.equal("01ARYZ6S41YYYYYYYYYYYYYYZ0");
69 | });
70 |
71 | it("fourth call with even more less than", function () {
72 | expect(stubbedUlid(10000)).to.equal("01ARYZ6S41YYYYYYYYYYYYYYZ1");
73 | });
74 |
75 | it("fifth call with 1 greater than", function () {
76 | expect(stubbedUlid(1469918176386)).to.equal("01ARYZ6S42YYYYYYYYYYYYYYYY");
77 | });
78 | });
79 | });
80 | });
81 |
82 | describe("ulid", () => {
83 | it("generates a ULID", () => {
84 | const id = ulid();
85 | expect(id).toMatch(ULID_REXP);
86 | });
87 | });
88 |
--------------------------------------------------------------------------------
/test/node/uuid.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from "vitest";
2 | import { ulidToUUID, uuidToULID } from "../../";
3 |
4 | describe("ulidToUUID", () => {
5 | it("converts ULIDs to UUIDs", () => {
6 | expect(ulidToUUID("01ARYZ6S41TSV4RRFFQ69G5FAV")).to.equal(
7 | "01563DF3-6481-D676-4C61-EFB99302BD5B"
8 | );
9 | expect(ulidToUUID("01JQ4T23H220KM7X0B3V1109DQ")).to.equal(
10 | "0195C9A1-0E22-1027-43F4-0B1EC21025B7"
11 | );
12 | });
13 | });
14 |
15 | describe("uuidToULID", () => {
16 | it("converts UUIDs to ULIDs", () => {
17 | expect(uuidToULID("0195C9A4-2E32-C014-5F4F-A7CEF5BE83D5")).to.equal(
18 | "01JQ4T8BHJR0A5YKX7SVTVX0YN"
19 | );
20 | expect(uuidToULID("0195C9A4-74CC-5149-BCC4-0A556A0CF19D")).to.equal(
21 | "01JQ4T8X6CA54VSH0AANN0SWCX"
22 | );
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/tsconfig.dec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "./dist",
5 | "declaration": true
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "esModuleInterop": true,
4 | "module": "node16",
5 | "moduleResolution": "node16",
6 | "declaration": false,
7 | "target": "es2020",
8 | "types": ["node"]
9 | },
10 | "include": [
11 | "./source/**/*"
12 | ],
13 | "exclude":[
14 | "node_modules"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/vitest.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vitest/config";
2 |
3 | export default defineConfig({
4 | test: {
5 | exclude: [],
6 | watch: false
7 | }
8 | });
9 |
--------------------------------------------------------------------------------