@uniku/cli 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -199
- package/build/bin.mjs +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -1,230 +1,56 @@
|
|
|
1
1
|
# @uniku/cli
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@uniku/cli)
|
|
4
|
+
[](https://jkomyno.github.io/uniku/docs/cli/)
|
|
4
5
|
[](https://opensource.org/licenses/MIT)
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
Generate, validate, and inspect IDs from a terminal or shell pipeline. The CLI supports every format in `uniku`: UUID v4/v7, ULID, TypeID, CUID v2, Nanoid, KSUID, ObjectID, XID, and TSID.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
[CLI documentation](https://jkomyno.github.io/uniku/docs/cli/) · [GitHub releases](https://github.com/jkomyno/uniku/releases) · [Library documentation](https://jkomyno.github.io/uniku/)
|
|
9
10
|
|
|
10
|
-
##
|
|
11
|
+
## Install
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
Install the current standalone binary on macOS or Linux without requiring Node.js:
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
```bash
|
|
15
|
+
```sh
|
|
17
16
|
curl -fsSL https://raw.githubusercontent.com/jkomyno/uniku/main/install.sh | sh
|
|
18
17
|
```
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
# Custom install directory
|
|
24
|
-
UNIKU_INSTALL_DIR=~/.local/bin curl -fsSL https://raw.githubusercontent.com/jkomyno/uniku/main/install.sh | sh
|
|
25
|
-
|
|
26
|
-
# Specific version
|
|
27
|
-
UNIKU_VERSION=0.2.0 curl -fsSL https://raw.githubusercontent.com/jkomyno/uniku/main/install.sh | sh
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
### mise
|
|
31
|
-
|
|
32
|
-
Install the `uniku-cli-v0.2.0` GitHub release binary with [mise](https://mise.jdx.dev):
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
mise use -g github:jkomyno/uniku@uniku-cli-v0.2.0
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
This uses the exact CLI release tag.
|
|
39
|
-
|
|
40
|
-
### npm
|
|
19
|
+
Or install the npm package:
|
|
41
20
|
|
|
42
|
-
```
|
|
43
|
-
# pnpm (recommended)
|
|
44
|
-
pnpm add -g @uniku/cli
|
|
45
|
-
|
|
46
|
-
# npm
|
|
21
|
+
```sh
|
|
47
22
|
npm install -g @uniku/cli
|
|
48
|
-
|
|
49
|
-
# bun
|
|
50
|
-
bun add -g @uniku/cli
|
|
51
23
|
```
|
|
52
24
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
### Generate IDs
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
# UUID v4 (default)
|
|
59
|
-
uniku uuid
|
|
60
|
-
# => 550e8400-e29b-41d4-a716-446655440000
|
|
61
|
-
|
|
62
|
-
# UUID v7 (time-ordered)
|
|
63
|
-
uniku uuid --uuid-version 7
|
|
64
|
-
# => 018e5e5c-7c8a-7000-8000-000000000000
|
|
65
|
-
|
|
66
|
-
# Generate multiple IDs
|
|
67
|
-
uniku uuid --count 5
|
|
68
|
-
|
|
69
|
-
# ULID
|
|
70
|
-
uniku ulid
|
|
71
|
-
# => 01HW9T2W9W9YJ3JZ1H4P4M2T8Q
|
|
72
|
-
|
|
73
|
-
# TypeID
|
|
74
|
-
uniku typeid --prefix user
|
|
75
|
-
# => user_01h2xcejqtf2nbrexx3vqjhp41
|
|
76
|
-
|
|
77
|
-
# Monotonically increasing ULIDs
|
|
78
|
-
uniku ulid --monotonic --count 3
|
|
25
|
+
The [installation guide](https://jkomyno.github.io/uniku/docs/cli/#install) also covers pnpm, Bun, mise, custom install directories, and version pinning.
|
|
79
26
|
|
|
80
|
-
|
|
81
|
-
uniku nanoid --size 12 --alphabet hex
|
|
27
|
+
## Quick start
|
|
82
28
|
|
|
83
|
-
|
|
84
|
-
|
|
29
|
+
```sh
|
|
30
|
+
# Generate a time-ordered UUID v7
|
|
31
|
+
uniku uuid -v 7
|
|
85
32
|
|
|
86
|
-
#
|
|
87
|
-
uniku
|
|
33
|
+
# Generate five TypeIDs as JSON
|
|
34
|
+
uniku typeid --prefix user --count 5 --json
|
|
88
35
|
|
|
89
|
-
#
|
|
90
|
-
uniku objectid
|
|
91
|
-
# => 66e1a8d3f1c2b3a4d5e6f7a8
|
|
92
|
-
|
|
93
|
-
# ObjectID for a fixed Unix timestamp (s)
|
|
94
|
-
uniku objectid --timestamp 1720000000
|
|
95
|
-
|
|
96
|
-
# TSID (64-bit Snowflake-style, time-sorted)
|
|
97
|
-
uniku tsid
|
|
98
|
-
# => 0QXW2CK4XZM2A
|
|
99
|
-
|
|
100
|
-
# TSID for a fixed Unix timestamp (ms) - note: milliseconds, unlike ObjectID/KSUID's seconds
|
|
101
|
-
uniku tsid --timestamp 1720000000000
|
|
102
|
-
|
|
103
|
-
# TSID for a fixed node ID
|
|
104
|
-
uniku tsid --node 42 --node-bits 10
|
|
105
|
-
|
|
106
|
-
# XID (time-sortable, lowercase base32hex)
|
|
107
|
-
uniku xid
|
|
108
|
-
# => 9m4e2mr0ui3e8a215n4g
|
|
109
|
-
|
|
110
|
-
# XID for a fixed Unix timestamp (s)
|
|
111
|
-
uniku xid --timestamp 1720000000
|
|
112
|
-
|
|
113
|
-
# Output as JSON
|
|
114
|
-
uniku uuid --count 3 --json
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
All generate commands also work under `uniku generate <type>` (e.g., `uniku generate uuid`).
|
|
118
|
-
|
|
119
|
-
### Validate IDs
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
# Validate a single ID (type auto-detected)
|
|
36
|
+
# Validate or inspect an existing ID
|
|
123
37
|
uniku validate 018e5e5c-7c8a-7000-8000-000000000000
|
|
38
|
+
uniku inspect 018e5e5c-7c8a-7000-8000-000000000000
|
|
124
39
|
|
|
125
|
-
#
|
|
126
|
-
uniku
|
|
127
|
-
|
|
128
|
-
# Validate a TypeID
|
|
129
|
-
uniku validate --type typeid user_01h2xcejqtf2nbrexx3vqjhp41
|
|
130
|
-
|
|
131
|
-
# Batch validate from stdin
|
|
132
|
-
echo -e "018e5e5c-7c8a-7000-8000-000000000000\ninvalid-id" | uniku validate --stdin
|
|
133
|
-
|
|
134
|
-
# Quiet mode (exit code only: 0 = valid, 2 = invalid)
|
|
135
|
-
uniku validate --quiet 018e5e5c-7c8a-7000-8000-000000000000
|
|
136
|
-
|
|
137
|
-
# JSON output
|
|
138
|
-
uniku validate --json 018e5e5c-7c8a-7000-8000-000000000000
|
|
40
|
+
# Discover every command and option
|
|
41
|
+
uniku --help
|
|
139
42
|
```
|
|
140
43
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
```bash
|
|
144
|
-
# Decode metadata from an ID (type auto-detected)
|
|
145
|
-
uniku inspect 018e5e5c-7c8a-7000-8000-000000000000
|
|
44
|
+
Top-level generator commands also work under `uniku generate <type>`. Use `--json` when output feeds another program.
|
|
146
45
|
|
|
147
|
-
|
|
148
|
-
uniku inspect --type ulid 01HW9T2W9W9YJ3JZ1H4P4M2T8Q
|
|
46
|
+
See the [complete command reference](https://jkomyno.github.io/uniku/docs/cli/) for generator-specific flags, stdin validation, exit codes, timestamp units, and structured output.
|
|
149
47
|
|
|
150
|
-
|
|
151
|
-
uniku inspect user_01h2xcejqtf2nbrexx3vqjhp41
|
|
48
|
+
## Platform support
|
|
152
49
|
|
|
153
|
-
|
|
154
|
-
uniku inspect --json 018e5e5c-7c8a-7000-8000-000000000000
|
|
155
|
-
```
|
|
50
|
+
The standalone binary supports macOS x64/arm64 and Linux x64/arm64. The npm package requires Node.js `>=20.19.0`.
|
|
156
51
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
## Commands Reference
|
|
160
|
-
|
|
161
|
-
| Command | Description |
|
|
162
|
-
|---------|-------------|
|
|
163
|
-
| `uniku uuid` | Generate UUIDs (v4 or v7) |
|
|
164
|
-
| `uniku ulid` | Generate ULIDs |
|
|
165
|
-
| `uniku typeid` | Generate TypeIDs |
|
|
166
|
-
| `uniku nanoid` | Generate Nanoids |
|
|
167
|
-
| `uniku cuid` | Generate CUIDs (v2) |
|
|
168
|
-
| `uniku ksuid` | Generate KSUIDs |
|
|
169
|
-
| `uniku objectid` | Generate MongoDB ObjectIDs |
|
|
170
|
-
| `uniku tsid` | Generate TSIDs (64-bit Snowflake-style, time-sorted) |
|
|
171
|
-
| `uniku xid` | Generate XIDs |
|
|
172
|
-
| `uniku validate <id>` | Check if an ID is valid |
|
|
173
|
-
| `uniku inspect <id>` | Decode and inspect an ID |
|
|
174
|
-
|
|
175
|
-
### Common Options
|
|
176
|
-
|
|
177
|
-
| Option | Alias | Description |
|
|
178
|
-
|--------|-------|-------------|
|
|
179
|
-
| `--count` | `-n` | Number of IDs to generate (default: 1) |
|
|
180
|
-
| `--json` | | Output as JSON |
|
|
181
|
-
| `--help` | | Show help |
|
|
182
|
-
| `--version` | `-V` | Show version |
|
|
183
|
-
|
|
184
|
-
### Generator-Specific Options
|
|
185
|
-
|
|
186
|
-
| Command | Option | Alias | Description |
|
|
187
|
-
|---------|--------|-------|-------------|
|
|
188
|
-
| `uuid` | `--uuid-version` | `-v` | UUID version: 4 or 7 (default: 4) |
|
|
189
|
-
| `uuid` | `--lowercase` | | Output in lowercase |
|
|
190
|
-
| `ulid` | `--monotonic` | | Generate monotonically increasing ULIDs |
|
|
191
|
-
| `ulid` | `--timestamp` | | Unix timestamp in ms or "now" |
|
|
192
|
-
| `ulid` | `--lowercase` | | Output in lowercase |
|
|
193
|
-
| `typeid` | `--prefix` | `-p` | Type prefix, e.g. `user` for `user_...` |
|
|
194
|
-
| `nanoid` | `--size` | `-s` | Length of ID, 1-256 (default: 21) |
|
|
195
|
-
| `nanoid` | `--alphabet` | `-a` | Custom alphabet or preset: hex, numeric, alpha |
|
|
196
|
-
| `cuid` | `--length` | `-l` | Length of ID, 2-32 (default: 24) |
|
|
197
|
-
| `ksuid` | `--timestamp` | | Unix timestamp in seconds or "now" |
|
|
198
|
-
| `objectid` | `--timestamp` | | Unix timestamp in seconds or "now" |
|
|
199
|
-
| `tsid` | `--timestamp` | | Unix timestamp in milliseconds or "now" |
|
|
200
|
-
| `tsid` | `--node` | | Node ID (0 to 2^node-bits - 1) |
|
|
201
|
-
| `tsid` | `--node-bits` | | Number of bits allocated to the node ID, 0-20 (default: 10) |
|
|
202
|
-
| `xid` | `--timestamp` | | Unix timestamp in seconds or "now" |
|
|
203
|
-
|
|
204
|
-
### Validate Options
|
|
205
|
-
|
|
206
|
-
| Option | Description |
|
|
207
|
-
|--------|-------------|
|
|
208
|
-
| `--type` | Expected ID type: uuid, ulid, typeid, nanoid, cuid, ksuid, objectid, tsid, xid (auto-detected if omitted) |
|
|
209
|
-
| `--stdin` | Read IDs from stdin (one per line) |
|
|
210
|
-
| `--quiet` | No output, exit code only (0 = valid, 2 = invalid) |
|
|
211
|
-
| `--json` | Output as JSON |
|
|
212
|
-
|
|
213
|
-
### Inspect Options
|
|
214
|
-
|
|
215
|
-
| Option | Description |
|
|
216
|
-
|--------|-------------|
|
|
217
|
-
| `--type` | ID type: uuid, ulid, typeid, nanoid, cuid, ksuid, objectid, tsid, xid (auto-detected if omitted) |
|
|
218
|
-
| `--json` | Output as JSON |
|
|
219
|
-
|
|
220
|
-
## Tech Stack
|
|
221
|
-
|
|
222
|
-
- [Effect](https://effect.website/) — functional effect system for TypeScript
|
|
223
|
-
- [@effect/cli](https://github.com/Effect-TS/effect/tree/main/packages/cli) — CLI framework built on Effect
|
|
224
|
-
- [@effect/platform](https://github.com/Effect-TS/effect/tree/main/packages/platform) — platform abstraction layer
|
|
225
|
-
- [Bun](https://bun.sh/) — JavaScript runtime
|
|
226
|
-
- [uniku](https://github.com/jkomyno/uniku) — core ID generation library
|
|
52
|
+
The library and CLI publish independently and may have different version numbers.
|
|
227
53
|
|
|
228
54
|
## License
|
|
229
55
|
|
|
230
|
-
MIT
|
|
56
|
+
MIT © [Alberto Schiabel](https://github.com/jkomyno)
|
package/build/bin.mjs
CHANGED
|
@@ -3,5 +3,5 @@ import*as e from"@effect/platform-bun/BunRuntime";import*as t from"@effect/platf
|
|
|
3
3
|
`)}function De(e){return e.hint?`Error: ${e.message}\n ${e.hint}`:`Error: ${e.message}`}const N=l.integer(`count`).pipe(l.withAlias(`n`),l.withDescription(`Number of IDs to generate`),l.withDefault(1)),P=l.boolean(`json`).pipe(l.withDescription(`Output as JSON`),l.withDefault(!1)),Oe=l.choiceWithValue(`uuid-version`,[[`4`,4],[`7`,7]]).pipe(l.withAlias(`v`),l.withDescription(`UUID version: 4, 7`),l.withDefault(4)),F=l.boolean(`lowercase`).pipe(l.withDescription(`Output in lowercase`),l.withDefault(!1)),I=c.make(`uuid`,{count:N,json:P,version:Oe,lowercase:F},r.fn(`cli.generate.uuid`)(function*({count:e,json:t,version:n,lowercase:r}){let i=yield*A,a=yield*be({count:e,version:n,lowercase:r});yield*i.write(M(a),{json:t})})).pipe(c.withDescription(`Generate UUIDs (v4 or v7)`),c.withExamples([{command:`uniku uuid -n 5 --json`,description:`Generate 5 UUIDs as a JSON array (machine-readable)`},{command:`uniku uuid -v 7`,description:`Generate a time-sortable UUID v7`},{command:`uniku uuid`,description:`Generate one random UUID v4`}])),ke=l.string(`prefix`).pipe(l.withAlias(`p`),l.withDescription(`Type prefix, e.g. "user" for user_... (empty by default)`),l.withDefault(``)),L=c.make(`typeid`,{count:N,json:P,prefix:ke},r.fn(`cli.generate.typeid`)(function*({count:e,json:t,prefix:n}){let r=yield*A,i=yield*ve({count:e,prefix:n});yield*r.write(M(i),{json:t})})).pipe(c.withDescription(`Generate TypeIDs`),c.withExamples([{command:`uniku typeid --prefix user`,description:`Generate a TypeID such as user_...`},{command:`uniku typeid -p api_key -n 5 --json`,description:`Generate 5 api_key TypeIDs as JSON`},{command:`uniku typeid`,description:`Generate a canonical prefixless TypeID`}])),Ae=l.boolean(`monotonic`).pipe(l.withDescription(`Generate monotonically increasing ULIDs`),l.withDefault(!1)),je=l.string(`timestamp`).pipe(l.withDescription(`Unix timestamp in milliseconds (or "now")`),l.optional),R=c.make(`ulid`,{count:N,json:P,monotonic:Ae,timestamp:je,lowercase:F},r.fn(`cli.generate.ulid`)(function*({count:e,json:t,monotonic:n,timestamp:r,lowercase:i}){let a=yield*A,s=o.getOrUndefined(r),c=yield*ye({count:e,monotonic:n,timestamp:s===void 0?void 0:yield*K(s),lowercase:i});yield*a.write(M(c),{json:t})})).pipe(c.withDescription(`Generate ULIDs`),c.withExamples([{command:`uniku ulid -n 10 --monotonic --json`,description:`Generate 10 strictly ordered ULIDs as a JSON array`},{command:`uniku ulid --timestamp 1720000000000`,description:`Generate a ULID for a fixed Unix timestamp (ms)`}])),Me=l.integer(`size`).pipe(l.withAlias(`s`),l.withDescription(`Length of ID (1-256)`),l.withDefault(21)),Ne=l.string(`alphabet`).pipe(l.withAlias(`a`),l.withDescription(`Custom alphabet or preset: hex, numeric, alpha`),l.optional),z=c.make(`nanoid`,{count:N,json:P,size:Me,alphabet:Ne},r.fn(`cli.generate.nanoid`)(function*({count:e,json:t,size:n,alphabet:r}){let i=yield*A,a=yield*he({count:e,size:n,alphabet:o.getOrUndefined(r)});yield*i.write(M(a),{json:t})})).pipe(c.withDescription(`Generate Nanoids`),c.withExamples([{command:`uniku nanoid -n 5 --json`,description:`Generate 5 Nanoids as a JSON array`},{command:`uniku nanoid --size 10 --alphabet hex`,description:`Generate a 10-char ID from the hex preset`}])),Pe=l.integer(`length`).pipe(l.withAlias(`l`),l.withDescription(`Length of ID (2-32)`),l.withDefault(24)),B=c.make(`cuid`,{count:N,json:P,length:Pe},r.fn(`cli.generate.cuid`)(function*({count:e,json:t,length:n}){let r=yield*A,i=yield*fe({count:e,length:n});yield*r.write(M(i),{json:t})})).pipe(c.withDescription(`Generate CUIDs (v2)`),c.withExamples([{command:`uniku cuid -n 5 --json`,description:`Generate 5 CUIDs as a JSON array`},{command:`uniku cuid --length 10`,description:`Generate a 10-char CUID`}])),Fe=l.string(`timestamp`).pipe(l.withDescription(`Unix timestamp in seconds (or "now")`),l.optional),V=c.make(`ksuid`,{count:N,json:P,timestamp:Fe},r.fn(`cli.generate.ksuid`)(function*({count:e,json:t,timestamp:n}){let r=yield*A,i=o.getOrUndefined(n),a=yield*pe({count:e,timestamp:i===void 0?void 0:yield*q(i)});yield*r.write(M(a),{json:t})})).pipe(c.withDescription(`Generate KSUIDs`),c.withExamples([{command:`uniku ksuid -n 5 --json`,description:`Generate 5 KSUIDs as a JSON array`},{command:`uniku ksuid --timestamp 1720000000`,description:`Generate a KSUID for a fixed Unix timestamp (s)`}])),Ie=l.string(`timestamp`).pipe(l.withDescription(`Unix timestamp in seconds (or "now")`),l.optional),H=c.make(`objectid`,{count:N,json:P,timestamp:Ie},r.fn(`cli.generate.objectid`)(function*({count:e,json:t,timestamp:n}){let r=yield*A,i=o.getOrUndefined(n),a=yield*ge({count:e,timestamp:i===void 0?void 0:yield*q(i)});yield*r.write(M(a),{json:t})})).pipe(c.withDescription(`Generate MongoDB ObjectIDs`),c.withExamples([{command:`uniku objectid -n 5 --json`,description:`Generate 5 ObjectIDs as a JSON array`},{command:`uniku objectid --timestamp 1720000000`,description:`Generate an ObjectID for a fixed Unix timestamp (s)`}])),Le=l.string(`timestamp`).pipe(l.withDescription(`Unix timestamp in seconds (or "now")`),l.optional),U=c.make(`xid`,{count:N,json:P,timestamp:Le},r.fn(`cli.generate.xid`)(function*({count:e,json:t,timestamp:n}){let r=yield*A,i=o.getOrUndefined(n),a=yield*xe({count:e,timestamp:i===void 0?void 0:yield*q(i)});yield*r.write(M(a),{json:t})})).pipe(c.withDescription(`Generate XIDs`),c.withExamples([{command:`uniku xid -n 5 --json`,description:`Generate 5 XIDs as a JSON array`},{command:`uniku xid --timestamp 1720000000`,description:`Generate an XID for a fixed Unix timestamp (s)`}])),Re=l.string(`timestamp`).pipe(l.withDescription(`Unix timestamp in milliseconds (or "now")`),l.optional),ze=l.string(`node`).pipe(l.withDescription(`Node ID (0 to 2^node-bits - 1)`),l.optional),Be=l.string(`node-bits`).pipe(l.withDescription(`Number of bits allocated to the node ID (0-20, default 10)`),l.optional),W=c.make(`tsid`,{count:N,json:P,timestamp:Re,node:ze,nodeBits:Be},r.fn(`cli.generate.tsid`)(function*({count:e,json:t,timestamp:n,node:r,nodeBits:i}){let a=yield*A,s=o.getOrUndefined(n),c=s===void 0?void 0:yield*K(s),l=o.getOrUndefined(r),u=l===void 0?void 0:yield*Ze(l),d=o.getOrUndefined(i),f=yield*_e({count:e,timestamp:c,node:u,nodeBits:d===void 0?void 0:yield*Qe(d)});yield*a.write(M(f),{json:t})})).pipe(c.withDescription(`Generate TSIDs (64-bit Snowflake-style, time-sorted)`),c.withExamples([{command:`uniku tsid -n 5 --json`,description:`Generate 5 TSIDs as a JSON array`},{command:`uniku tsid --timestamp 1720000000000`,description:`Generate a TSID for a fixed Unix timestamp (ms)`},{command:`uniku tsid --node 42 --node-bits 10`,description:`Generate a TSID for a fixed node ID`}])),Ve=c.make(`generate`).pipe(c.withDescription(`Generate new IDs`),c.withSubcommands([I,R,L,z,B,V,H,U,W]),c.withExamples([{command:`uniku generate uuid -n 5 --json`,description:`Generate 5 UUIDs as a JSON array`},{command:`uniku generate typeid --prefix user`,description:`Generate one user TypeID`},{command:`uniku generate ulid`,description:"Generate one ULID (subcommands also work top-level: `uniku ulid`)"}])),He=I,Ue=R,We=L,Ge=z,Ke=B,qe=V,Je=H,Ye=U,Xe=W,G=r.fn(`cli.generate.parseTimestamp`)(function*(e,t,n){if(e===`now`)return t(yield*u.currentTimeMillis);let r=Number(e);return!Number.isFinite(r)||r<0?yield*new D({code:`INVALID_TIMESTAMP`,message:`Invalid timestamp: "${e}"`,hint:n}):r}),K=e=>G(e,e=>e,`Provide a Unix timestamp in milliseconds or "now"`),q=e=>G(e,e=>Math.floor(e/1e3),`Provide a Unix timestamp in seconds or "now"`),J=r.fn(`cli.generate.parseNonNegativeInt`)(function*(e,t,n,r){let i=Number(e);return!Number.isInteger(i)||i<0?yield*new D({code:t,message:`Invalid ${n}: "${e}"`,hint:r}):i}),Ze=e=>J(e,`INVALID_NODE`,`node`,`Provide a non-negative integer for --node`),Qe=e=>J(e,`INVALID_NODE_BITS`,`node-bits`,`Provide a non-negative integer (0-20) for --node-bits`);function $e(e,t){switch(t){case`uuid`:return tt(e);case`ulid`:return nt(e);case`typeid`:return rt(e);case`ksuid`:return it(e);case`objectid`:return at(e);case`cuid`:return st(e);case`nanoid`:return ct(e);case`tsid`:return lt(e);case`xid`:return ot(e)}}function et(e){return x.isValid(e)?{id:e,valid:!0,type:`uuid`,version:7}:b.isValid(e)?{id:e,valid:!0,type:`uuid`,version:4}:v.isValid(e)?{id:e,valid:!0,type:`typeid`,version:7}:y.isValid(e)?{id:e,valid:!0,type:`ulid`}:m.isValid(e)?{id:e,valid:!0,type:`ksuid`}:g.isValid(e)?{id:e,valid:!0,type:`objectid`}:lt(e).valid?{id:e,valid:!0,type:`tsid`}:S.isValid(e)?{id:e,valid:!0,type:`xid`}:f.isValid(e)?{id:e,valid:!0,type:`cuid`}:h.isValid(e)?{id:e,valid:!0,type:`nanoid`}:{id:e,valid:!1,error:`malformed identifier`}}function tt(e){return x.isValid(e)?{id:e,valid:!0,type:`uuid`,version:7}:b.isValid(e)?{id:e,valid:!0,type:`uuid`,version:4}:{id:e,valid:!1,type:`uuid`,error:`invalid UUID format`}}function nt(e){return y.isValid(e)?{id:e,valid:!0,type:`ulid`}:{id:e,valid:!1,type:`ulid`,error:`invalid ULID format`}}function rt(e){return v.isValid(e)?{id:e,valid:!0,type:`typeid`,version:7}:{id:e,valid:!1,type:`typeid`,error:`invalid TypeID format`}}function it(e){return m.isValid(e)?{id:e,valid:!0,type:`ksuid`}:{id:e,valid:!1,type:`ksuid`,error:`invalid KSUID format`}}function at(e){return g.isValid(e)?{id:e,valid:!0,type:`objectid`}:{id:e,valid:!1,type:`objectid`,error:`invalid ObjectID format`}}function ot(e){return S.isValid(e)?{id:e,valid:!0,type:`xid`}:{id:e,valid:!1,type:`xid`,error:`invalid XID format`}}function st(e){return f.isValid(e)?{id:e,valid:!0,type:`cuid`}:{id:e,valid:!1,type:`cuid`,error:`invalid CUID format`}}function ct(e){return h.isValid(e)?{id:e,valid:!0,type:`nanoid`}:{id:e,valid:!1,type:`nanoid`,error:`invalid Nanoid format`}}function lt(e){try{return _.fromString(e),{id:e,valid:!0,type:`tsid`}}catch{return{id:e,valid:!1,type:`tsid`,error:`invalid TSID format`}}}function ut(e,t){let n=t??dt(e);if(!n)return null;switch(n){case`uuid`:return ft(e);case`ulid`:return pt(e);case`typeid`:return mt(e);case`ksuid`:return ht(e);case`objectid`:return gt(e);case`cuid`:return vt(e);case`nanoid`:return yt(e);case`tsid`:return bt(e);case`xid`:return _t(e)}}function dt(e){let t=et(e);return t.valid?t.type??null:null}function ft(e){if(x.isValid(e)){let t=x.timestamp(e),n=x.toBytes(e),r=Buffer.from(n.slice(10)).toString(`hex`);return{id:e,type:`uuid`,version:7,timestamp:new Date(t).toISOString(),timestamp_ms:t,random:r}}return b.isValid(e)?{id:e,type:`uuid`,version:4,note:`This ID type contains no decodable metadata.`}:{id:e,type:`uuid`,note:`Unrecognized UUID version.`}}function pt(e){let t=y.timestamp(e),n=e.slice(10);return{id:e,type:`ulid`,timestamp:new Date(t).toISOString(),timestamp_ms:t,random:n}}function mt(e){if(!v.isValid(e))return{id:e,type:`typeid`,note:`Unrecognized TypeID format.`};let t=v.timestamp(e),n=v.toBytes(e),r=Buffer.from(n.slice(10)).toString(`hex`);return{id:e,type:`typeid`,version:7,prefix:v.prefix(e),suffix:v.suffix(e),timestamp:new Date(t).toISOString(),timestamp_ms:t,random:r}}function ht(e){let t=m.timestamp(e),n=m.toBytes(e),r=Buffer.from(n.slice(4)).toString(`hex`);return{id:e,type:`ksuid`,timestamp:new Date(t).toISOString(),timestamp_ms:t,random:r}}function gt(e){let t=g.timestamp(e),n=g.toBytes(e),r=Buffer.from(n.slice(4)).toString(`hex`);return{id:e,type:`objectid`,timestamp:new Date(t).toISOString(),timestamp_ms:t,random:r}}function _t(e){let t=S.timestamp(e),n=S.toBytes(e);return{id:e,type:`xid`,timestamp:new Date(t).toISOString(),timestamp_ms:t,random:Buffer.from(n.slice(4)).toString(`hex`)}}function vt(e){return{id:e,type:`cuid`,note:`This ID type contains no decodable metadata.`}}function yt(e){return{id:e,type:`nanoid`,note:`This ID type contains no decodable metadata.`}}function bt(e){let t;try{t=_.fromString(e)}catch{return{id:e,type:`tsid`,note:`Unrecognized TSID format.`}}let n=_.timestamp(t),r=(t&4194303n).toString(16);return{id:e,type:`tsid`,timestamp:new Date(n).toISOString(),timestamp_ms:n,random:r}}function xt(e){let t=e.indexOf(`--`),n=(t===-1?e:e.slice(0,t)).map(e=>e===`-V`?`--version`:e);if(t===-1)return n;let r=e.slice(t+1);return Dt(n)?[...n,...r.map(Et)]:[...n,`--`,...r]}const St=`\0uniku-literal:`,Ct=new Set([`inspect`,`validate`]),wt=new Set([`--completions`,`--log-level`]);function Tt(e){return e.startsWith(St)?e.slice(15):e}function Et(e){return`${St}${e}`}function Dt(e){for(let t=0;t<e.length;t+=1){let n=e[t];if(n.startsWith(`-`)){wt.has(n)&&(t+=1);continue}return Ct.has(n)}return!1}const Ot=s.string(`id`).pipe(s.withDescription(`The ID to inspect`)),kt=l.choice(`type`,w).pipe(l.withDescription(`ID type (auto-detected if omitted)`),l.optional),At=l.boolean(`json`).pipe(l.withDescription(`Output as JSON`),l.withDefault(!1)),jt=c.make(`inspect`,{id:Ot,type:kt,json:At},r.fn(`cli.inspect`)(function*({id:e,type:t,json:n}){let r=yield*A,i=o.getOrUndefined(t),a=Tt(e),s=ut(a,i);if(!s)return yield*new D({code:`UNKNOWN_ID_TYPE`,message:`Could not identify ID type for: "${a}"`,hint:`Use --type to specify the ID type`});yield*r.write(Ce(s),{json:n})})).pipe(c.withDescription(`Decode and inspect an ID`),c.withExamples([{command:`uniku inspect 01J9YR2V5TZB8Q4W6X0E1N7M3S --json`,description:`Decode an ID to structured JSON (type, version, timestamp)`},{command:`uniku inspect --type uuid 3F2504E0-4F89-41D3-9A0C-0305E82C3301`,description:`Skip auto-detection`},{command:`uniku inspect -- --tricky-id`,description:`Inspect an ID that starts with a dash`}]));var Mt=class e extends C.Service()(`uniku/cli/StdinService`){static layer=a.succeed(e,e.of({readLines:r.fn(`StdinService.readLines`)(()=>r.callback(e=>{let t=[];process.stdin.on(`data`,e=>{t.push(e)}),process.stdin.on(`end`,()=>{let n=Buffer.concat(t).toString(`utf-8`).split(`
|
|
4
4
|
`).map(e=>e.trim()).filter(e=>e.length>0);e(r.succeed(n))}),process.stdin.on(`error`,t=>{e(r.fail(new D({code:`STDIN_ERROR`,message:t.message})))}),process.stdin.resume()}))}))};const Nt=s.string(`id`).pipe(s.withDescription(`The ID to validate`),s.optional),Pt=l.choice(`type`,w).pipe(l.withDescription(`Expected ID type (auto-detected if omitted)`),l.optional),Ft=l.boolean(`stdin`).pipe(l.withDescription(`Read IDs from stdin (one per line)`),l.withDefault(!1)),It=l.boolean(`json`).pipe(l.withDescription(`Output validation results as JSON`),l.withDefault(!1)),Lt=l.boolean(`quiet`).pipe(l.withDescription(`No output, exit code only`),l.withDefault(!1)),Rt=c.make(`validate`,{id:Nt,type:Pt,stdin:Ft,json:It,quiet:Lt},r.fn(`cli.validate`)(function*({id:e,type:t,stdin:n,json:r,quiet:i}){let a=yield*A,s=yield*Mt,c=o.getOrUndefined(t),l;if(n){if(l=yield*s.readLines(),l.length===0)return yield*new D({code:`NO_INPUT`,message:`No IDs provided on stdin`})}else if(o.isSome(e))l=[Tt(e.value)];else return yield*new D({code:`NO_INPUT`,message:`No ID provided`,hint:`Pass an ID as argument or use --stdin`});let u=l.map(e=>c?$e(e,c):et(e));if(i||(yield*a.write(Se(u),{json:r})),u.some(e=>!e.valid))return yield*new ue({message:`One or more IDs are invalid`})})).pipe(c.withDescription(`Check if an ID is valid`),c.withExamples([{command:`uniku validate 3F2504E0-4F89-41D3-9A0C-0305E82C3301 --json`,description:`Validate one ID, result as JSON`},{command:`cat ids.txt | uniku validate --stdin --json`,description:`Validate many IDs (one per line), results as a JSON array`},{command:`uniku validate --quiet 01J9YR2V5TZB8Q4W6X0E1N7M3S`,description:`Exit code only: 0 valid, 2 invalid`}])),zt=c.make(`uniku`).pipe(c.withDescription(`Generate and validate unique identifiers`),c.withExamples([{command:`uniku uuid -n 5 --json`,description:`Generate 5 UUIDs as a JSON array (machine-readable)`},{command:`uniku typeid --prefix user`,description:`Generate one user TypeID`},{command:`uniku ulid`,description:`Generate one ULID`},{command:`uniku inspect <id> --json`,description:`Decode an ID (type, version, timestamp) as JSON`},{command:`cat ids.txt | uniku validate --stdin --json`,description:`Validate IDs from stdin, one per line`}]),c.withSubcommands([Ve,Rt,jt,He,Ue,We,Ge,Ke,qe,Je,Ye,Xe])),Bt=e=>c.runWith(zt,{version:e});function Vt(e){return e.includes(`--json`)}const Ht=T.type().pipe(T.tag(`CliError`,e=>e.exitCode),T.tag(`ValidationFailedError`,e=>e.exitCode),T.tag(`ShowHelp`,e=>+(e.errors.length>0)),T.tag(`UnrecognizedOption`,`DuplicateOption`,`MissingOption`,`MissingArgument`,`InvalidValue`,`UnknownSubcommand`,`UserError`,()=>1),T.exhaustive),Ut=r.fn(`cli.handleCliFailure`)(function*(e,t){yield*T.value(e).pipe(T.tag(`CliError`,`ValidationFailedError`,e=>A.use(n=>n.writeError(we(e),{json:Vt(t)}))),T.tag(`ShowHelp`,()=>r.void),T.tag(`UnrecognizedOption`,`DuplicateOption`,`MissingOption`,`MissingArgument`,`InvalidValue`,`UnknownSubcommand`,`UserError`,e=>ee.error(`Error: ${e.message}`)),T.exhaustive),process.exitCode=Ht(e)});var Y=class e extends C.Service()(`uniku/cli/UpdateCheckService`){static layer=a.sync(e,()=>an())};const X=`@uniku/cli`;function Wt(){let e=process.getuid;if(typeof e==`function`)return`uid-${e()}`;try{let e=oe().username.replace(/[^0-9A-Za-z._-]/g,`_`);return e?`user-${e}`:null}catch{return null}}function Gt(){let e=Wt(),t=e?`uniku-update-check-${e}.json`:`uniku-update-check.json`;return ce(ae(),t)}const Kt=Gt();function qt(e){let t=e.match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/);return t?{major:Number(t[1]),minor:Number(t[2]),patch:Number(t[3]),prerelease:t[4]??null}:null}function Jt(e,t){let n=qt(e),r=qt(t);return!n||!r?!1:n.major===r.major?n.minor===r.minor?n.patch===r.patch?n.prerelease===null&&r.prerelease!==null?!0:(n.prerelease!==null&&r.prerelease,!1):n.patch>r.patch:n.minor>r.minor:n.major>r.major}function Z(e){return E.option(E.string(e)).pipe(r.catch(()=>r.succeed(o.none())))}function Q(e){return o.isSome(e)&&e.value.length>0}const Yt=r.all({noUpdateNotifier:Z(`NO_UPDATE_NOTIFIER`),ci:Z(`CI`),continuousIntegration:Z(`CONTINUOUS_INTEGRATION`),nodeEnv:Z(`NODE_ENV`)});function Xt(e=process.stderr.isTTY){return Yt.pipe(r.map(t=>Q(t.noUpdateNotifier)||Q(t.ci)||Q(t.continuousIntegration)||o.isSome(t.nodeEnv)&&t.nodeEnv.value===`test`||!e))}function Zt(e,t){if(t){let t=e.isStandaloneBinary?`Download at https://github.com/jkomyno/uniku/releases`:`Run \`npm install -g ${X}\` to update`;return[``,` Update available: ${e.currentVersion} → ${e.latestVersion}`,` ${t}`,` Set NO_UPDATE_NOTIFIER=1 to disable`,``].join(`
|
|
5
5
|
`)}let n=`\x1B[2m`,r=`\x1B[36m`,i=`\x1B[0m`,a=e.isStandaloneBinary?`Download at ${r}https://github.com/jkomyno/uniku/releases${i}`:`Run ${r}\`npm install -g ${X}\`${i} to update`;return[``,` ${n}Update available:${i} ${n}${e.currentVersion}${i} ${n}→${i} [1;36m${e.latestVersion}${i}`,` ${a}`,` ${n}Set NO_UPDATE_NOTIFIER=1 to disable${i}`,``].join(`
|
|
6
|
-
`)}function Qt(e){return Z(`NO_COLOR`).pipe(r.map(t=>Zt(e,Q(t))))}function $t(e,t){return o.isSome(t)&&!e.includes(`--json`)}function en(e){try{let t=ne(e,`utf-8`),n=JSON.parse(t);if(typeof n!=`object`||!n)return null;let r=n;return typeof r.checkedAt!=`number`||!Number.isFinite(r.checkedAt)||r.latestVersion!==void 0&&typeof r.latestVersion!=`string`?null:r.latestVersion===void 0?{checkedAt:r.checkedAt}:{latestVersion:r.latestVersion,checkedAt:r.checkedAt}}catch{return null}}function tn(e,t){try{te(se(t),{recursive:!0});let n=`${t}.tmp`;ie(n,JSON.stringify(e)),re(n,t)}catch{}}function nn(e){return r.tryPromise({try:t=>fetch(`https://registry.npmjs.org/%40uniku%2Fcli/latest`,{headers:{Accept:`application/json`,"User-Agent":`${X}/${e}`},signal:AbortSignal.any([t,AbortSignal.timeout(5e3)])}).then(async e=>{if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await e.json();if(!t.version)throw Error(`Missing version field`);return t.version}),catch:()=>Error(`fetch failed`)}).pipe(r.catch(()=>r.succeed(null)))}function rn(){try{return typeof __STANDALONE_BINARY__<`u`&&__STANDALONE_BINARY__===!0}catch{return!1}}function an(e={}){let t=e.cacheFile??Kt,n=e.fetchLatestVersion??nn,i=e.now??Date.now,a=e.isStandaloneBinary??rn,s=e.isStderrTTY??(()=>process.stderr.isTTY),c=e.writeStderr??(e=>process.stderr.write(e));return Y.of({check:r.fn(`UpdateCheckService.check`)(function*(e){if(yield*Xt(s()))return o.none();let r=en(t),c=i();if(r&&c-r.checkedAt<864e5)return r.latestVersion&&Jt(r.latestVersion,e)?o.some({currentVersion:e,latestVersion:r.latestVersion,isStandaloneBinary:a()}):o.none();let l=yield*n(e);return l===null?(tn({checkedAt:c},t),o.none()):(tn({latestVersion:l,checkedAt:c},t),Jt(l,e)?o.some({currentVersion:e,latestVersion:l,isStandaloneBinary:a()}):o.none())},r.catch(()=>r.succeed(o.none()))),notify:r.fn(`UpdateCheckService.notify`)(function*(e){let t=yield*Qt(e);yield*r.sync(()=>{c(t)})})})}var $=`0.6.
|
|
6
|
+
`)}function Qt(e){return Z(`NO_COLOR`).pipe(r.map(t=>Zt(e,Q(t))))}function $t(e,t){return o.isSome(t)&&!e.includes(`--json`)}function en(e){try{let t=ne(e,`utf-8`),n=JSON.parse(t);if(typeof n!=`object`||!n)return null;let r=n;return typeof r.checkedAt!=`number`||!Number.isFinite(r.checkedAt)||r.latestVersion!==void 0&&typeof r.latestVersion!=`string`?null:r.latestVersion===void 0?{checkedAt:r.checkedAt}:{latestVersion:r.latestVersion,checkedAt:r.checkedAt}}catch{return null}}function tn(e,t){try{te(se(t),{recursive:!0});let n=`${t}.tmp`;ie(n,JSON.stringify(e)),re(n,t)}catch{}}function nn(e){return r.tryPromise({try:t=>fetch(`https://registry.npmjs.org/%40uniku%2Fcli/latest`,{headers:{Accept:`application/json`,"User-Agent":`${X}/${e}`},signal:AbortSignal.any([t,AbortSignal.timeout(5e3)])}).then(async e=>{if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await e.json();if(!t.version)throw Error(`Missing version field`);return t.version}),catch:()=>Error(`fetch failed`)}).pipe(r.catch(()=>r.succeed(null)))}function rn(){try{return typeof __STANDALONE_BINARY__<`u`&&__STANDALONE_BINARY__===!0}catch{return!1}}function an(e={}){let t=e.cacheFile??Kt,n=e.fetchLatestVersion??nn,i=e.now??Date.now,a=e.isStandaloneBinary??rn,s=e.isStderrTTY??(()=>process.stderr.isTTY),c=e.writeStderr??(e=>process.stderr.write(e));return Y.of({check:r.fn(`UpdateCheckService.check`)(function*(e){if(yield*Xt(s()))return o.none();let r=en(t),c=i();if(r&&c-r.checkedAt<864e5)return r.latestVersion&&Jt(r.latestVersion,e)?o.some({currentVersion:e,latestVersion:r.latestVersion,isStandaloneBinary:a()}):o.none();let l=yield*n(e);return l===null?(tn({checkedAt:c},t),o.none()):(tn({latestVersion:l,checkedAt:c},t),Jt(l,e)?o.some({currentVersion:e,latestVersion:l,isStandaloneBinary:a()}):o.none())},r.catch(()=>r.succeed(o.none()))),notify:r.fn(`UpdateCheckService.notify`)(function*(e){let t=yield*Qt(e);yield*r.sync(()=>{c(t)})})})}var $=`0.6.2`;const on=Bt($),sn=a.mergeAll(A.layer,Mt.layer,Y.layer,t.layer);r.gen(function*(){let e=yield*Y,t=xt(process.argv.slice(2)),a=yield*r.forkChild(e.check($),{startImmediately:!0});yield*on(t).pipe(r.catch(e=>Ut(e,t)));let s=yield*i.join(a).pipe(r.timeoutOption(n.millis(250)));yield*i.interrupt(a);let c=o.flatten(s);$t(t,c)&&(yield*e.notify(c.value))}).pipe(r.provide(sn),e.runMain);export{};
|
|
7
7
|
//# sourceMappingURL=bin.mjs.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"private": false,
|
|
3
3
|
"name": "@uniku/cli",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.2",
|
|
5
5
|
"description": "CLI tool for generating and validating unique identifiers",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Alberto Schiabel",
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
"url": "git+https://github.com/jkomyno/uniku.git",
|
|
15
15
|
"directory": "packages/cli"
|
|
16
16
|
},
|
|
17
|
+
"homepage": "https://jkomyno.github.io/uniku/docs/cli/",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/jkomyno/uniku/issues"
|
|
20
|
+
},
|
|
17
21
|
"type": "module",
|
|
18
22
|
"bin": {
|
|
19
23
|
"uniku": "./build/bin.mjs"
|
|
@@ -32,7 +36,7 @@
|
|
|
32
36
|
"dependencies": {
|
|
33
37
|
"@effect/platform-bun": "4.0.0-beta.93",
|
|
34
38
|
"effect": "4.0.0-beta.93",
|
|
35
|
-
"uniku": "0.4.
|
|
39
|
+
"uniku": "0.4.2"
|
|
36
40
|
},
|
|
37
41
|
"devDependencies": {
|
|
38
42
|
"@effect/vitest": "4.0.0-beta.93",
|