args-tokens 0.7.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -20
- package/lib/{esm/parse.d.ts → parse.d.ts} +3 -2
- package/lib/{esm/parse.js → parse.js} +3 -2
- package/lib/{esm/resolver.d.ts → resolver.d.ts} +7 -0
- package/lib/{esm/resolver.js → resolver.js} +42 -9
- package/package.json +28 -31
- package/lib/cjs/index.js +0 -11
- package/lib/cjs/parse.d.ts +0 -40
- package/lib/cjs/parse.js +0 -37
- package/lib/cjs/parser.js +0 -231
- package/lib/cjs/resolver.d.ts +0 -50
- package/lib/cjs/resolver.js +0 -201
- package/lib/esm/index.d.ts +0 -6
- package/lib/esm/parser.d.ts +0 -77
- /package/lib/{cjs/index.d.ts → index.d.ts} +0 -0
- /package/lib/{esm/index.js → index.js} +0 -0
- /package/lib/{cjs/parser.d.ts → parser.d.ts} +0 -0
- /package/lib/{esm/parser.js → parser.js} +0 -0
package/README.md
CHANGED
|
@@ -2,10 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
[![Version][npm-version-src]][npm-version-href]
|
|
4
4
|
[![JSR][jsr-src]][jsr-href]
|
|
5
|
+
[![InstallSize][install-size-src]][install-size-src]
|
|
5
6
|
[![CI][ci-src]][ci-href]
|
|
6
7
|
|
|
7
8
|
> [`parseArgs` tokens](https://nodejs.org/api/util.html#parseargs-tokens) compatibility and more high-performance parser
|
|
8
9
|
|
|
10
|
+
## ✨ Features
|
|
11
|
+
|
|
12
|
+
- ✅ High performance parser and resolver
|
|
13
|
+
- ✅ `util.parseArgs` token compatibility
|
|
14
|
+
- ✅ Type safe argument values
|
|
15
|
+
- ✅ ES Modules distribution library
|
|
16
|
+
- ✅ Support multi runtime: Browser, Node.js, Deno, Bun
|
|
17
|
+
|
|
9
18
|
## 🐱 Motivation
|
|
10
19
|
|
|
11
20
|
- Although Node.js [`parseArgs`](https://nodejs.org/api/util.html#utilparseargsconfig) can return tokens, that the short options are not in the format I expect. Of course, I recoginize the background of [this issue](https://github.com/pkgjs/parseargs/issues/78).
|
|
@@ -19,26 +28,36 @@ With [mitata](https://github.com/evanwashere/mitata):
|
|
|
19
28
|
pnpm bench:mitata
|
|
20
29
|
|
|
21
30
|
> args-tokens@0.0.0 bench:mitata /path/to/projects/args-tokens
|
|
22
|
-
> node --expose-gc bench/
|
|
31
|
+
> node --expose-gc bench/mitata.js
|
|
23
32
|
|
|
24
33
|
clk: ~2.87 GHz
|
|
25
34
|
cpu: Apple M1 Max
|
|
26
35
|
runtime: node 18.19.1 (arm64-darwin)
|
|
27
36
|
|
|
28
|
-
benchmark
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
args-tokens parseArgs
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
benchmark avg (min … max) p75 / p99 (min … top 1%)
|
|
38
|
+
--------------------------------------------------------------- -------------------------------
|
|
39
|
+
util.parseArgs 4.16 µs/iter 4.20 µs █
|
|
40
|
+
(4.09 µs … 4.29 µs) 4.28 µs ██ ▅▅▅ ▅
|
|
41
|
+
( 1.36 kb … 1.52 kb) 1.37 kb ██▁████▅▅█▅▁██▁▁▅▁█▅█
|
|
42
|
+
|
|
43
|
+
args-tokens parse (equivalent to util.parseArgs) 1.65 µs/iter 1.66 µs █
|
|
44
|
+
(1.61 µs … 1.80 µs) 1.79 µs ▅▃ █▂ ▄
|
|
45
|
+
( 1.95 kb … 2.66 kb) 1.97 kb █████▆█▄▃▃▅▃▁▃▃▁▄▁▁▁▂
|
|
46
|
+
|
|
47
|
+
args-tokens parseArgs 729.56 ns/iter 734.11 ns █
|
|
48
|
+
(697.43 ns … 797.08 ns) 774.93 ns ▂█▅▂
|
|
49
|
+
( 2.87 kb … 3.54 kb) 3.11 kb ▂▂▃▇▆▅▆████▃▃▄▂▂▂▂▂▁▂
|
|
50
|
+
|
|
51
|
+
args-tokens resolveArgs 886.78 ns/iter 887.70 ns █
|
|
52
|
+
(853.96 ns … 978.89 ns) 957.24 ns █
|
|
53
|
+
( 2.51 kb … 2.87 kb) 2.79 kb ▂▃█▃▄▅█▄▃▂▂▃▃▂▂▂▂▂▁▁▁
|
|
54
|
+
|
|
55
|
+
┌ ┐
|
|
56
|
+
util.parseArgs ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 4.16 µs
|
|
57
|
+
args-tokens parse (equivalent to util.parseArgs) ┤■■■■■■■■■ 1.65 µs
|
|
58
|
+
args-tokens parseArgs ┤ 729.56 ns
|
|
59
|
+
args-tokens resolveArgs ┤■■ 886.78 ns
|
|
60
|
+
└ ┘
|
|
42
61
|
```
|
|
43
62
|
|
|
44
63
|
With [vitest](https://vitest.dev/guide/features.html#benchmarking):
|
|
@@ -55,15 +74,24 @@ Breaking changes might not follow SemVer, please pin Vitest's version when using
|
|
|
55
74
|
RUN v3.0.5 /path/to/projects/args-tokens
|
|
56
75
|
|
|
57
76
|
|
|
58
|
-
✓ bench/vitest.bench.
|
|
77
|
+
✓ bench/vitest.bench.js > parse and resolve 1350ms
|
|
78
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
79
|
+
· util.parseArgs 221,285.36 0.0041 0.2700 0.0045 0.0044 0.0054 0.0063 0.0629 ±0.38% 110643
|
|
80
|
+
· args-tokens parse 527,127.11 0.0017 0.2153 0.0019 0.0019 0.0023 0.0027 0.0055 ±0.38% 263564 fastest
|
|
81
|
+
|
|
82
|
+
✓ bench/vitest.bench.js > parseArgs 1434ms
|
|
59
83
|
name hz min max mean p75 p99 p995 p999 rme samples
|
|
60
|
-
· node:util
|
|
61
|
-
· args-tokens 1,
|
|
84
|
+
· node:util 235,217.05 0.0039 0.2665 0.0043 0.0042 0.0048 0.0058 0.0139 ±0.43% 117609
|
|
85
|
+
· args-tokens 1,307,135.24 0.0006 0.1737 0.0008 0.0008 0.0009 0.0010 0.0016 ±0.43% 653568 fastest
|
|
62
86
|
|
|
63
87
|
BENCH Summary
|
|
64
88
|
|
|
65
|
-
args-tokens - bench/vitest.bench.
|
|
66
|
-
|
|
89
|
+
args-tokens parse - bench/vitest.bench.js > parse and resolve
|
|
90
|
+
2.38x faster than util.parseArgs
|
|
91
|
+
|
|
92
|
+
args-tokens - bench/vitest.bench.js > parseArgs
|
|
93
|
+
5.56x faster than node:util
|
|
94
|
+
|
|
67
95
|
```
|
|
68
96
|
|
|
69
97
|
## ❓ What's different about parseArgs tokens?
|
|
@@ -273,6 +301,10 @@ const tokens = parseArgs(['-a=1'], { allowCompatible: true }) // add `allowCompa
|
|
|
273
301
|
deepStrictEqual(tokensNode, tokens)
|
|
274
302
|
```
|
|
275
303
|
|
|
304
|
+
## 💁♀️ Showcases
|
|
305
|
+
|
|
306
|
+
- [pnpmc](https://github.com/kazupon/pnpmc): PNPM Catalogs Tooling
|
|
307
|
+
|
|
276
308
|
## 🙌 Contributing guidelines
|
|
277
309
|
|
|
278
310
|
If you are interested in contributing to `args-tokens`, I highly recommend checking out [the contributing guidelines](/CONTRIBUTING.md) here. You'll find all the relevant information such as [how to make a PR](/CONTRIBUTING.md#pull-request-guidelines), [how to setup development](/CONTRIBUTING.md#development-setup)) etc., there.
|
|
@@ -294,5 +326,7 @@ This project is inspired by:
|
|
|
294
326
|
[npm-version-href]: https://npmjs.com/package/args-tokens
|
|
295
327
|
[jsr-src]: https://jsr.io/badges/@kazupon/args-tokens
|
|
296
328
|
[jsr-href]: https://jsr.io/@kazupon/args-tokens
|
|
329
|
+
[install-size-src]: https://pkg-size.dev/badge/install/35082
|
|
330
|
+
[install-size-href]: https://pkg-size.dev/args-tokens
|
|
297
331
|
[ci-src]: https://github.com/kazupon/args-tokens/actions/workflows/ci.yml/badge.svg
|
|
298
332
|
[ci-href]: https://github.com/kazupon/args-tokens/actions/workflows/ci.yml
|
|
@@ -33,8 +33,9 @@ export type ParsedArgs<T extends ArgOptions> = {
|
|
|
33
33
|
* console.log('values', values)
|
|
34
34
|
* console.log('positionals', positionals)
|
|
35
35
|
* ```
|
|
36
|
-
* @param args command line arguments
|
|
37
|
-
* @param options parse options, about details see {@link ParseOptions}
|
|
36
|
+
* @param args - command line arguments
|
|
37
|
+
* @param options - parse options, about details see {@link ParseOptions}
|
|
38
|
+
* @throws if command line arguments are invalid, this function will cause {@link AggregateError | validation errors}.
|
|
38
39
|
* @returns parsed values
|
|
39
40
|
*/
|
|
40
41
|
export declare function parse<O extends ArgOptions>(args: string[], options?: ParseOptions<O>): ParsedArgs<O>;
|
|
@@ -23,8 +23,9 @@ const DEFAULT_OPTIONS = {
|
|
|
23
23
|
* console.log('values', values)
|
|
24
24
|
* console.log('positionals', positionals)
|
|
25
25
|
* ```
|
|
26
|
-
* @param args command line arguments
|
|
27
|
-
* @param options parse options, about details see {@link ParseOptions}
|
|
26
|
+
* @param args - command line arguments
|
|
27
|
+
* @param options - parse options, about details see {@link ParseOptions}
|
|
28
|
+
* @throws if command line arguments are invalid, this function will cause {@link AggregateError | validation errors}.
|
|
28
29
|
* @returns parsed values
|
|
29
30
|
*/
|
|
30
31
|
export function parse(args, options = {}) {
|
|
@@ -43,6 +43,13 @@ type ResolveArgValues<O extends ArgOptions, V extends Record<keyof O, unknown>>
|
|
|
43
43
|
type FilterArgs<O extends ArgOptions, V extends Record<keyof O, unknown>, K extends keyof ArgOptionSchema> = {
|
|
44
44
|
[Option in keyof O as O[Option][K] extends {} ? Option : never]: V[Option];
|
|
45
45
|
};
|
|
46
|
+
/**
|
|
47
|
+
* Resolve command line arguments
|
|
48
|
+
* @param options - An options that contains {@link ArgOptionSchema | options schema}.
|
|
49
|
+
* @param tokens - An array of {@link ArgToken | tokens}.
|
|
50
|
+
* @throws if command line arguments are invalid, this function will cause {@link AggregateError | validation errors}.
|
|
51
|
+
* @returns An object that contains the values of the arguments and positional arguments.
|
|
52
|
+
*/
|
|
46
53
|
export declare function resolveArgs<T extends ArgOptions>(options: T, tokens: ArgToken[]): {
|
|
47
54
|
values: ArgValues<T>;
|
|
48
55
|
positionals: string[];
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
// Modifier: kazuya kawaguchi (a.k.a. kazupon)
|
|
3
3
|
import { hasLongOptionPrefix, isShortOption } from './parser.js';
|
|
4
|
+
/**
|
|
5
|
+
* Resolve command line arguments
|
|
6
|
+
* @param options - An options that contains {@link ArgOptionSchema | options schema}.
|
|
7
|
+
* @param tokens - An array of {@link ArgToken | tokens}.
|
|
8
|
+
* @throws if command line arguments are invalid, this function will cause {@link AggregateError | validation errors}.
|
|
9
|
+
* @returns An object that contains the values of the arguments and positional arguments.
|
|
10
|
+
*/
|
|
4
11
|
export function resolveArgs(options, tokens) {
|
|
5
12
|
const values = {};
|
|
6
13
|
const positionals = [];
|
|
@@ -103,22 +110,36 @@ export function resolveArgs(options, tokens) {
|
|
|
103
110
|
/**
|
|
104
111
|
* resolve values
|
|
105
112
|
*/
|
|
113
|
+
const errors = [];
|
|
106
114
|
for (const [option, schema] of Object.entries(options)) {
|
|
107
|
-
if (
|
|
108
|
-
|
|
115
|
+
if (schema.required) {
|
|
116
|
+
const found = longOptionTokens.find(token => token.name === option) ||
|
|
117
|
+
(schema.short && shortOptionTokens.find(token => token.name === schema.short));
|
|
118
|
+
if (!found) {
|
|
119
|
+
errors.push(createRequireError(option, schema));
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
109
122
|
}
|
|
110
123
|
// eslint-disable-next-line unicorn/no-for-loop
|
|
111
124
|
for (let i = 0; i < longOptionTokens.length; i++) {
|
|
112
125
|
const token = longOptionTokens[i];
|
|
113
126
|
// eslint-disable-next-line unicorn/no-null
|
|
114
127
|
if (option === token.name && token.rawName != null && hasLongOptionPrefix(token.rawName)) {
|
|
115
|
-
validateRequire(token, option, schema);
|
|
128
|
+
const invalid = validateRequire(token, option, schema);
|
|
129
|
+
if (invalid) {
|
|
130
|
+
errors.push(invalid);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
116
133
|
if (schema.type === 'boolean') {
|
|
117
134
|
// NOTE: re-set value to undefined, because long boolean type option is set on analyze phase
|
|
118
135
|
token.value = undefined;
|
|
119
136
|
}
|
|
120
137
|
else {
|
|
121
|
-
validateValue(token, option, schema);
|
|
138
|
+
const invalid = validateValue(token, option, schema);
|
|
139
|
+
if (invalid) {
|
|
140
|
+
errors.push(invalid);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
122
143
|
}
|
|
123
144
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
124
145
|
;
|
|
@@ -131,13 +152,21 @@ export function resolveArgs(options, tokens) {
|
|
|
131
152
|
const token = shortOptionTokens[i];
|
|
132
153
|
// eslint-disable-next-line unicorn/no-null
|
|
133
154
|
if (schema.short === token.name && token.rawName != null && isShortOption(token.rawName)) {
|
|
134
|
-
validateRequire(token, option, schema);
|
|
155
|
+
const invalid = validateRequire(token, option, schema);
|
|
156
|
+
if (invalid) {
|
|
157
|
+
errors.push(invalid);
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
135
160
|
if (schema.type === 'boolean') {
|
|
136
161
|
// NOTE: re-set value to undefined, because short boolean type option is set on analyze phase
|
|
137
162
|
token.value = undefined;
|
|
138
163
|
}
|
|
139
164
|
else {
|
|
140
|
-
validateValue(token, option, schema);
|
|
165
|
+
const invalid = validateValue(token, option, schema);
|
|
166
|
+
if (invalid) {
|
|
167
|
+
errors.push(invalid);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
141
170
|
}
|
|
142
171
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
143
172
|
;
|
|
@@ -153,6 +182,10 @@ export function resolveArgs(options, tokens) {
|
|
|
153
182
|
values[option] = schema.default;
|
|
154
183
|
}
|
|
155
184
|
}
|
|
185
|
+
if (errors.length > 0) {
|
|
186
|
+
// eslint-disable-next-line unicorn/error-message
|
|
187
|
+
throw new AggregateError(errors);
|
|
188
|
+
}
|
|
156
189
|
return { values, positionals };
|
|
157
190
|
}
|
|
158
191
|
function createRequireError(option, schema) {
|
|
@@ -160,20 +193,20 @@ function createRequireError(option, schema) {
|
|
|
160
193
|
}
|
|
161
194
|
function validateRequire(token, option, schema) {
|
|
162
195
|
if (schema.required && schema.type !== 'boolean' && !token.value) {
|
|
163
|
-
|
|
196
|
+
return createRequireError(option, schema);
|
|
164
197
|
}
|
|
165
198
|
}
|
|
166
199
|
function validateValue(token, option, schema) {
|
|
167
200
|
switch (schema.type) {
|
|
168
201
|
case 'number': {
|
|
169
202
|
if (!isNumeric(token.value)) {
|
|
170
|
-
|
|
203
|
+
return createTypeError(option, schema);
|
|
171
204
|
}
|
|
172
205
|
break;
|
|
173
206
|
}
|
|
174
207
|
case 'string': {
|
|
175
208
|
if (typeof token.value !== 'string') {
|
|
176
|
-
|
|
209
|
+
return createTypeError(option, schema);
|
|
177
210
|
}
|
|
178
211
|
break;
|
|
179
212
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "args-tokens",
|
|
3
3
|
"description": "parseArgs tokens compatibility and more high-performance parser",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "kazuya kawaguchi",
|
|
7
7
|
"email": "kawakazu80@gmail.com"
|
|
@@ -26,69 +26,68 @@
|
|
|
26
26
|
"access": "public"
|
|
27
27
|
},
|
|
28
28
|
"engines": {
|
|
29
|
-
"node": ">=
|
|
29
|
+
"node": ">= 20"
|
|
30
30
|
},
|
|
31
|
+
"type": "module",
|
|
31
32
|
"files": [
|
|
32
33
|
"lib"
|
|
33
34
|
],
|
|
34
|
-
"
|
|
35
|
-
"module": "lib/esm/index.js",
|
|
35
|
+
"module": "lib/index.js",
|
|
36
36
|
"exports": {
|
|
37
37
|
".": {
|
|
38
|
-
"types": "./lib/
|
|
39
|
-
"import": "./lib/
|
|
40
|
-
"require": "./lib/
|
|
41
|
-
"default": "./lib/
|
|
38
|
+
"types": "./lib/index.d.ts",
|
|
39
|
+
"import": "./lib/index.js",
|
|
40
|
+
"require": "./lib/index.js",
|
|
41
|
+
"default": "./lib/index.js"
|
|
42
42
|
},
|
|
43
43
|
"./parser": {
|
|
44
|
-
"types": "./lib/
|
|
45
|
-
"import": "./lib/
|
|
46
|
-
"require": "./lib/
|
|
47
|
-
"default": "./lib/
|
|
44
|
+
"types": "./lib/parser.d.ts",
|
|
45
|
+
"import": "./lib/parser.js",
|
|
46
|
+
"require": "./lib/parser.js",
|
|
47
|
+
"default": "./lib/parser.js"
|
|
48
48
|
},
|
|
49
49
|
"./resolver": {
|
|
50
|
-
"types": "./lib/
|
|
51
|
-
"import": "./lib/
|
|
52
|
-
"require": "./lib/
|
|
53
|
-
"default": "./lib/
|
|
50
|
+
"types": "./lib/resolver.d.ts",
|
|
51
|
+
"import": "./lib/resolver.js",
|
|
52
|
+
"require": "./lib/resolver.js",
|
|
53
|
+
"default": "./lib/resolver.js"
|
|
54
54
|
},
|
|
55
55
|
"./package.json": "./package.json",
|
|
56
56
|
"./*": "./*"
|
|
57
57
|
},
|
|
58
|
-
"types": "lib/
|
|
58
|
+
"types": "lib/index.d.ts",
|
|
59
59
|
"typesVersions": {
|
|
60
60
|
"*": {
|
|
61
61
|
"*": [
|
|
62
|
-
"./lib
|
|
63
|
-
"./lib/esm/*",
|
|
62
|
+
"./lib/*",
|
|
64
63
|
"./*"
|
|
65
64
|
]
|
|
66
65
|
}
|
|
67
66
|
},
|
|
68
67
|
"devDependencies": {
|
|
69
68
|
"@eslint/markdown": "^6.2.2",
|
|
70
|
-
"@kazupon/eslint-config": "^0.
|
|
69
|
+
"@kazupon/eslint-config": "^0.22.0",
|
|
71
70
|
"@kazupon/prettier-config": "^0.1.1",
|
|
72
|
-
"@types/node": "^22.13.
|
|
71
|
+
"@types/node": "^22.13.5",
|
|
73
72
|
"@vitest/eslint-plugin": "^1.1.31",
|
|
74
73
|
"bumpp": "^10.0.3",
|
|
75
|
-
"eslint": "^9.
|
|
74
|
+
"eslint": "^9.21.0",
|
|
76
75
|
"eslint-config-prettier": "^10.0.1",
|
|
77
76
|
"eslint-plugin-jsonc": "^2.19.1",
|
|
78
77
|
"eslint-plugin-promise": "^7.2.1",
|
|
79
78
|
"eslint-plugin-regexp": "^2.7.0",
|
|
80
|
-
"eslint-plugin-unicorn": "^
|
|
81
|
-
"eslint-plugin-yml": "^1.
|
|
79
|
+
"eslint-plugin-unicorn": "^57.0.0",
|
|
80
|
+
"eslint-plugin-yml": "^1.17.0",
|
|
82
81
|
"gh-changelogen": "^0.2.8",
|
|
83
82
|
"jsr": "^0.13.3",
|
|
84
|
-
"knip": "^5.44.
|
|
83
|
+
"knip": "^5.44.4",
|
|
85
84
|
"lint-staged": "^15.4.3",
|
|
86
85
|
"mitata": "^1.0.34",
|
|
87
86
|
"pkg-pr-new": "^0.0.39",
|
|
88
|
-
"prettier": "^3.5.
|
|
87
|
+
"prettier": "^3.5.2",
|
|
89
88
|
"typescript": "^5.7.3",
|
|
90
|
-
"typescript-eslint": "^8.24.
|
|
91
|
-
"vitest": "^3.0.
|
|
89
|
+
"typescript-eslint": "^8.24.1",
|
|
90
|
+
"vitest": "^3.0.6"
|
|
92
91
|
},
|
|
93
92
|
"prettier": "@kazupon/prettier-config",
|
|
94
93
|
"lint-staged": {
|
|
@@ -107,9 +106,7 @@
|
|
|
107
106
|
"scripts": {
|
|
108
107
|
"bench:mitata": "node --expose-gc bench/mitata.js",
|
|
109
108
|
"bench:vitest": "vitest bench --run",
|
|
110
|
-
"build": "
|
|
111
|
-
"build:cjs": "tsc -p ./tsconfig.cjs.json",
|
|
112
|
-
"build:esm": "tsc -p ./tsconfig.esm.json",
|
|
109
|
+
"build": "tsc -p ./tsconfig.build.json",
|
|
113
110
|
"changelog": "gh-changelogen --repo=kazupon/eslint-config",
|
|
114
111
|
"dev": "pnpx @eslint/config-inspector --config eslint.config.ts",
|
|
115
112
|
"dev:eslint": "pnpx @eslint/config-inspector --config eslint.config.ts",
|
package/lib/cjs/index.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// SPDX-License-Identifier: MIT
|
|
3
|
-
// Modifier: kazuya kawaguchi (a.k.a. kazupon)
|
|
4
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.resolveArgs = exports.parseArgs = exports.parse = void 0;
|
|
6
|
-
var parse_js_1 = require("./parse.js");
|
|
7
|
-
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parse_js_1.parse; } });
|
|
8
|
-
var parser_js_1 = require("./parser.js");
|
|
9
|
-
Object.defineProperty(exports, "parseArgs", { enumerable: true, get: function () { return parser_js_1.parseArgs; } });
|
|
10
|
-
var resolver_js_1 = require("./resolver.js");
|
|
11
|
-
Object.defineProperty(exports, "resolveArgs", { enumerable: true, get: function () { return resolver_js_1.resolveArgs; } });
|
package/lib/cjs/parse.d.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { ParserOptions } from './parser';
|
|
2
|
-
import type { ArgOptions, ArgValues } from './resolver';
|
|
3
|
-
/**
|
|
4
|
-
* Parse options for {@link parse} function
|
|
5
|
-
*/
|
|
6
|
-
export interface ParseOptions<O extends ArgOptions> extends ParserOptions {
|
|
7
|
-
/**
|
|
8
|
-
* Command line options, about details see {@link ArgOptions}
|
|
9
|
-
*/
|
|
10
|
-
options?: O;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Parsed command line arguments
|
|
14
|
-
*/
|
|
15
|
-
export type ParsedArgs<T extends ArgOptions> = {
|
|
16
|
-
/**
|
|
17
|
-
* Parsed values, same as `values` in {@link resolveArgs}
|
|
18
|
-
*/
|
|
19
|
-
values: ArgValues<T>;
|
|
20
|
-
/**
|
|
21
|
-
* Positional arguments, same as `positionals` in {@link resolveArgs}
|
|
22
|
-
*/
|
|
23
|
-
positionals: string[];
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Parse command line arguments
|
|
27
|
-
* @description This function is a convenient API, that is used {@link parseArgs} and {@link resolveArgs} in internal.
|
|
28
|
-
* @example
|
|
29
|
-
* ```js
|
|
30
|
-
* import { parse } from 'args-tokens'
|
|
31
|
-
*
|
|
32
|
-
* const { values, positionals } = parse(process.argv.slice(2))
|
|
33
|
-
* console.log('values', values)
|
|
34
|
-
* console.log('positionals', positionals)
|
|
35
|
-
* ```
|
|
36
|
-
* @param args command line arguments
|
|
37
|
-
* @param options parse options, about details see {@link ParseOptions}
|
|
38
|
-
* @returns parsed values
|
|
39
|
-
*/
|
|
40
|
-
export declare function parse<O extends ArgOptions>(args: string[], options?: ParseOptions<O>): ParsedArgs<O>;
|
package/lib/cjs/parse.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// SPDX-License-Identifier: MIT
|
|
3
|
-
// Modifier: kazuya kawaguchi (a.k.a. kazupon)
|
|
4
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.parse = parse;
|
|
6
|
-
const parser_js_1 = require("./parser.js");
|
|
7
|
-
const resolver_js_1 = require("./resolver.js");
|
|
8
|
-
const DEFAULT_OPTIONS = {
|
|
9
|
-
help: {
|
|
10
|
-
type: 'boolean',
|
|
11
|
-
short: 'h'
|
|
12
|
-
},
|
|
13
|
-
version: {
|
|
14
|
-
type: 'boolean',
|
|
15
|
-
short: 'v'
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Parse command line arguments
|
|
20
|
-
* @description This function is a convenient API, that is used {@link parseArgs} and {@link resolveArgs} in internal.
|
|
21
|
-
* @example
|
|
22
|
-
* ```js
|
|
23
|
-
* import { parse } from 'args-tokens'
|
|
24
|
-
*
|
|
25
|
-
* const { values, positionals } = parse(process.argv.slice(2))
|
|
26
|
-
* console.log('values', values)
|
|
27
|
-
* console.log('positionals', positionals)
|
|
28
|
-
* ```
|
|
29
|
-
* @param args command line arguments
|
|
30
|
-
* @param options parse options, about details see {@link ParseOptions}
|
|
31
|
-
* @returns parsed values
|
|
32
|
-
*/
|
|
33
|
-
function parse(args, options = {}) {
|
|
34
|
-
const { options: argOptions, allowCompatible = false } = options;
|
|
35
|
-
const tokens = (0, parser_js_1.parseArgs)(args, { allowCompatible });
|
|
36
|
-
return (0, resolver_js_1.resolveArgs)(argOptions || DEFAULT_OPTIONS, tokens);
|
|
37
|
-
}
|
package/lib/cjs/parser.js
DELETED
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// SPDX-License-Identifier: MIT
|
|
3
|
-
// Modifier: kazuya kawaguchi (a.k.a. kazupon)
|
|
4
|
-
// Forked from `nodejs/node` (`pkgjs/parseargs`)
|
|
5
|
-
// Repository url: https://github.com/nodejs/node (https://github.com/pkgjs/parseargs)
|
|
6
|
-
// Author: Node.js contributors
|
|
7
|
-
// Code url: https://github.com/nodejs/node/blob/main/lib/internal/util/parse_args/parse_args.js
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.parseArgs = parseArgs;
|
|
10
|
-
exports.isShortOption = isShortOption;
|
|
11
|
-
exports.hasLongOptionPrefix = hasLongOptionPrefix;
|
|
12
|
-
const HYPHEN_CHAR = '-';
|
|
13
|
-
const HYPHEN_CODE = HYPHEN_CHAR.codePointAt(0);
|
|
14
|
-
const EQUAL_CHAR = '=';
|
|
15
|
-
const EQUAL_CODE = EQUAL_CHAR.codePointAt(0);
|
|
16
|
-
const TERMINATOR = '--';
|
|
17
|
-
const SHORT_OPTION_PREFIX = HYPHEN_CHAR;
|
|
18
|
-
const LONG_OPTION_PREFIX = '--';
|
|
19
|
-
/**
|
|
20
|
-
* Parse command line arguments
|
|
21
|
-
* @example
|
|
22
|
-
* ```js
|
|
23
|
-
* import { parseArgs } from 'args-tokens' // for Node.js and Bun
|
|
24
|
-
* // import { parseArgs } from 'jsr:@kazupon/args-tokens' // for Deno
|
|
25
|
-
*
|
|
26
|
-
* const tokens = parseArgs(['--foo', 'bar', '-x', '--bar=baz'])
|
|
27
|
-
* // do something with using tokens
|
|
28
|
-
* // ...
|
|
29
|
-
* console.log('tokens:', tokens)
|
|
30
|
-
* ```
|
|
31
|
-
* @param args command line arguments
|
|
32
|
-
* @param options parse options
|
|
33
|
-
* @returns argument tokens
|
|
34
|
-
*/
|
|
35
|
-
function parseArgs(args, options = {}) {
|
|
36
|
-
const { allowCompatible = false } = options;
|
|
37
|
-
const tokens = [];
|
|
38
|
-
const remainings = [...args];
|
|
39
|
-
let index = -1;
|
|
40
|
-
let groupCount = 0;
|
|
41
|
-
let hasShortValueSeparator = false;
|
|
42
|
-
while (remainings.length > 0) {
|
|
43
|
-
const arg = remainings.shift();
|
|
44
|
-
if (arg == undefined) {
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
const nextArg = remainings[0];
|
|
48
|
-
if (groupCount > 0) {
|
|
49
|
-
groupCount--;
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
index++;
|
|
53
|
-
}
|
|
54
|
-
// check if `arg` is an options terminator.
|
|
55
|
-
// guideline 10 in https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
|
|
56
|
-
if (arg === TERMINATOR) {
|
|
57
|
-
tokens.push({
|
|
58
|
-
kind: 'option-terminator',
|
|
59
|
-
index
|
|
60
|
-
});
|
|
61
|
-
const mapped = remainings.map(arg => {
|
|
62
|
-
return { kind: 'positional', index: ++index, value: arg };
|
|
63
|
-
});
|
|
64
|
-
tokens.push(...mapped);
|
|
65
|
-
break;
|
|
66
|
-
}
|
|
67
|
-
if (isShortOption(arg)) {
|
|
68
|
-
const shortOption = arg.charAt(1);
|
|
69
|
-
let value;
|
|
70
|
-
let inlineValue;
|
|
71
|
-
if (groupCount) {
|
|
72
|
-
// e.g. `-abc`
|
|
73
|
-
tokens.push({
|
|
74
|
-
kind: 'option',
|
|
75
|
-
name: shortOption,
|
|
76
|
-
rawName: arg,
|
|
77
|
-
index,
|
|
78
|
-
value,
|
|
79
|
-
inlineValue
|
|
80
|
-
});
|
|
81
|
-
if (groupCount === 1 && hasOptionValue(nextArg)) {
|
|
82
|
-
value = remainings.shift();
|
|
83
|
-
if (hasShortValueSeparator) {
|
|
84
|
-
inlineValue = true;
|
|
85
|
-
hasShortValueSeparator = false;
|
|
86
|
-
}
|
|
87
|
-
tokens.push({
|
|
88
|
-
kind: 'option',
|
|
89
|
-
index,
|
|
90
|
-
value,
|
|
91
|
-
inlineValue
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
// e.g. `-a`
|
|
97
|
-
tokens.push({
|
|
98
|
-
kind: 'option',
|
|
99
|
-
name: shortOption,
|
|
100
|
-
rawName: arg,
|
|
101
|
-
index,
|
|
102
|
-
value,
|
|
103
|
-
inlineValue
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
// eslint-disable-next-line unicorn/no-null
|
|
107
|
-
if (value != null) {
|
|
108
|
-
++index;
|
|
109
|
-
}
|
|
110
|
-
continue;
|
|
111
|
-
}
|
|
112
|
-
if (isShortOptionGroup(arg)) {
|
|
113
|
-
// expend short option group (e.g. `-abc` => `-a -b -c`, `-f=bar` => `-f bar`)
|
|
114
|
-
const expanded = [];
|
|
115
|
-
let shortValue = '';
|
|
116
|
-
for (let i = 1; i < arg.length; i++) {
|
|
117
|
-
const shortableOption = arg.charAt(i);
|
|
118
|
-
if (hasShortValueSeparator) {
|
|
119
|
-
shortValue += shortableOption;
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
if (!allowCompatible && shortableOption.codePointAt(0) === EQUAL_CODE) {
|
|
123
|
-
hasShortValueSeparator = true;
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
expanded.push(`${SHORT_OPTION_PREFIX}${shortableOption}`);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
if (shortValue) {
|
|
131
|
-
expanded.push(shortValue);
|
|
132
|
-
}
|
|
133
|
-
remainings.unshift(...expanded);
|
|
134
|
-
groupCount = expanded.length;
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
if (isLongOption(arg)) {
|
|
138
|
-
// e.g. `--foo`
|
|
139
|
-
const longOption = arg.slice(2);
|
|
140
|
-
tokens.push({
|
|
141
|
-
kind: 'option',
|
|
142
|
-
name: longOption,
|
|
143
|
-
rawName: arg,
|
|
144
|
-
index,
|
|
145
|
-
value: undefined,
|
|
146
|
-
inlineValue: undefined
|
|
147
|
-
});
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
if (isLongOptionAndValue(arg)) {
|
|
151
|
-
// e.g. `--foo=bar`
|
|
152
|
-
const equalIndex = arg.indexOf(EQUAL_CHAR);
|
|
153
|
-
const longOption = arg.slice(2, equalIndex);
|
|
154
|
-
const value = arg.slice(equalIndex + 1);
|
|
155
|
-
tokens.push({
|
|
156
|
-
kind: 'option',
|
|
157
|
-
name: longOption,
|
|
158
|
-
rawName: `${LONG_OPTION_PREFIX}${longOption}`,
|
|
159
|
-
index,
|
|
160
|
-
value,
|
|
161
|
-
inlineValue: true
|
|
162
|
-
});
|
|
163
|
-
continue;
|
|
164
|
-
}
|
|
165
|
-
tokens.push({
|
|
166
|
-
kind: 'positional',
|
|
167
|
-
index,
|
|
168
|
-
value: arg
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
return tokens;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Check if `arg` is a short option (e.g. `-f`)
|
|
175
|
-
* @param arg the argument to check
|
|
176
|
-
* @returns whether `arg` is a short option
|
|
177
|
-
*/
|
|
178
|
-
function isShortOption(arg) {
|
|
179
|
-
return (arg.length === 2 && arg.codePointAt(0) === HYPHEN_CODE && arg.codePointAt(1) !== HYPHEN_CODE);
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Check if `arg` is a short option group (e.g. `-abc`)
|
|
183
|
-
* @param arg the argument to check
|
|
184
|
-
* @returns whether `arg` is a short option group
|
|
185
|
-
*/
|
|
186
|
-
function isShortOptionGroup(arg) {
|
|
187
|
-
if (arg.length <= 2) {
|
|
188
|
-
return false;
|
|
189
|
-
}
|
|
190
|
-
if (arg.codePointAt(0) !== HYPHEN_CODE) {
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
if (arg.codePointAt(1) === HYPHEN_CODE) {
|
|
194
|
-
return false;
|
|
195
|
-
}
|
|
196
|
-
return true;
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Check if `arg` is a long option (e.g. `--foo`)
|
|
200
|
-
* @param arg the argument to check
|
|
201
|
-
* @returns whether `arg` is a long option
|
|
202
|
-
*/
|
|
203
|
-
function isLongOption(arg) {
|
|
204
|
-
return hasLongOptionPrefix(arg) && !arg.includes(EQUAL_CHAR, 3);
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Check if `arg` is a long option with value (e.g. `--foo=bar`)
|
|
208
|
-
* @param arg the argument to check
|
|
209
|
-
* @returns whether `arg` is a long option
|
|
210
|
-
*/
|
|
211
|
-
function isLongOptionAndValue(arg) {
|
|
212
|
-
return hasLongOptionPrefix(arg) && arg.includes(EQUAL_CHAR, 3);
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Check if `arg` is a long option prefix (e.g. `--`)
|
|
216
|
-
* @param arg the argument to check
|
|
217
|
-
* @returns whether `arg` is a long option prefix
|
|
218
|
-
*/
|
|
219
|
-
function hasLongOptionPrefix(arg) {
|
|
220
|
-
// @ts-ignore -- NOTE: `~` is a bitwise NOT operator
|
|
221
|
-
return arg.length > 2 && ~arg.indexOf(LONG_OPTION_PREFIX);
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Check if a `value` is an option value
|
|
225
|
-
* @param value a value to check
|
|
226
|
-
* @returns whether a `value` is an option value
|
|
227
|
-
*/
|
|
228
|
-
function hasOptionValue(value) {
|
|
229
|
-
// eslint-disable-next-line unicorn/no-null
|
|
230
|
-
return !(value == null) && value.codePointAt(0) !== HYPHEN_CODE;
|
|
231
|
-
}
|
package/lib/cjs/resolver.d.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { ArgToken } from './parser';
|
|
2
|
-
/**
|
|
3
|
-
* An option schema for an argument.
|
|
4
|
-
*/
|
|
5
|
-
export interface ArgOptionSchema {
|
|
6
|
-
/**
|
|
7
|
-
* Type of argument.
|
|
8
|
-
*/
|
|
9
|
-
type: 'string' | 'boolean' | 'number';
|
|
10
|
-
/**
|
|
11
|
-
* A single character alias for the option.
|
|
12
|
-
*/
|
|
13
|
-
short?: string;
|
|
14
|
-
/**
|
|
15
|
-
* Whether the argument is required or not.
|
|
16
|
-
*/
|
|
17
|
-
required?: true;
|
|
18
|
-
/**
|
|
19
|
-
* The default value of the argument.
|
|
20
|
-
*/
|
|
21
|
-
default?: string | boolean | number;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* An object that contains {@link ArgOptionSchema | options schema}.
|
|
25
|
-
*/
|
|
26
|
-
export interface ArgOptions {
|
|
27
|
-
[option: string]: ArgOptionSchema;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* An object that contains the values of the arguments.
|
|
31
|
-
*/
|
|
32
|
-
export type ArgValues<T> = T extends ArgOptions ? ResolveArgValues<T, {
|
|
33
|
-
[Option in keyof T]: ExtractOptionValue<T[Option]>;
|
|
34
|
-
}> : {
|
|
35
|
-
[option: string]: string | boolean | number | undefined;
|
|
36
|
-
};
|
|
37
|
-
type ExtractOptionValue<O extends ArgOptionSchema> = O['type'] extends 'string' ? string : O['type'] extends 'boolean' ? boolean : O['type'] extends 'number' ? number : string | boolean | number;
|
|
38
|
-
type ResolveArgValues<O extends ArgOptions, V extends Record<keyof O, unknown>> = {
|
|
39
|
-
-readonly [Option in keyof O]?: V[Option];
|
|
40
|
-
} & FilterArgs<O, V, 'default'> & FilterArgs<O, V, 'required'> extends infer P ? {
|
|
41
|
-
[K in keyof P]: P[K];
|
|
42
|
-
} : never;
|
|
43
|
-
type FilterArgs<O extends ArgOptions, V extends Record<keyof O, unknown>, K extends keyof ArgOptionSchema> = {
|
|
44
|
-
[Option in keyof O as O[Option][K] extends {} ? Option : never]: V[Option];
|
|
45
|
-
};
|
|
46
|
-
export declare function resolveArgs<T extends ArgOptions>(options: T, tokens: ArgToken[]): {
|
|
47
|
-
values: ArgValues<T>;
|
|
48
|
-
positionals: string[];
|
|
49
|
-
};
|
|
50
|
-
export {};
|
package/lib/cjs/resolver.js
DELETED
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// SPDX-License-Identifier: MIT
|
|
3
|
-
// Modifier: kazuya kawaguchi (a.k.a. kazupon)
|
|
4
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.resolveArgs = resolveArgs;
|
|
6
|
-
const parser_js_1 = require("./parser.js");
|
|
7
|
-
function resolveArgs(options, tokens) {
|
|
8
|
-
const values = {};
|
|
9
|
-
const positionals = [];
|
|
10
|
-
const longOptionTokens = [];
|
|
11
|
-
const shortOptionTokens = [];
|
|
12
|
-
let currentLongOption;
|
|
13
|
-
let currentShortOption;
|
|
14
|
-
const expandableShortOptions = [];
|
|
15
|
-
function toShortValue() {
|
|
16
|
-
if (expandableShortOptions.length === 0) {
|
|
17
|
-
return undefined;
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
const value = expandableShortOptions.map(token => token.name).join('');
|
|
21
|
-
expandableShortOptions.length = 0;
|
|
22
|
-
return value;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
function applyLongOptionValue(value = undefined) {
|
|
26
|
-
if (currentLongOption) {
|
|
27
|
-
currentLongOption.value = value;
|
|
28
|
-
longOptionTokens.push({ ...currentLongOption });
|
|
29
|
-
currentLongOption = undefined;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function applyShortOptionValue(value = undefined) {
|
|
33
|
-
if (currentShortOption) {
|
|
34
|
-
currentShortOption.value = value || toShortValue();
|
|
35
|
-
shortOptionTokens.push({ ...currentShortOption });
|
|
36
|
-
currentShortOption = undefined;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* analyze phase to resolve value
|
|
41
|
-
* separate tokens into positionals, long and short options, after that resolve values
|
|
42
|
-
*/
|
|
43
|
-
// eslint-disable-next-line unicorn/no-for-loop
|
|
44
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
45
|
-
const token = tokens[i];
|
|
46
|
-
if (token.kind === 'positional') {
|
|
47
|
-
positionals.push(token.value);
|
|
48
|
-
// check if previous option is not resolved
|
|
49
|
-
applyLongOptionValue(token.value);
|
|
50
|
-
applyShortOptionValue(token.value);
|
|
51
|
-
}
|
|
52
|
-
else if (token.kind === 'option') {
|
|
53
|
-
if (token.rawName) {
|
|
54
|
-
if ((0, parser_js_1.hasLongOptionPrefix)(token.rawName)) {
|
|
55
|
-
if (token.inlineValue) {
|
|
56
|
-
longOptionTokens.push({ ...token });
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
currentLongOption = { ...token };
|
|
60
|
-
}
|
|
61
|
-
// check if previous short option is not resolved
|
|
62
|
-
applyShortOptionValue();
|
|
63
|
-
}
|
|
64
|
-
else if ((0, parser_js_1.isShortOption)(token.rawName)) {
|
|
65
|
-
if (currentShortOption) {
|
|
66
|
-
if (currentShortOption.index === token.index) {
|
|
67
|
-
expandableShortOptions.push({ ...token });
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
currentShortOption.value = toShortValue();
|
|
71
|
-
shortOptionTokens.push({ ...currentShortOption });
|
|
72
|
-
currentShortOption = { ...token };
|
|
73
|
-
}
|
|
74
|
-
// check if previous long option is not resolved
|
|
75
|
-
applyLongOptionValue();
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
currentShortOption = { ...token };
|
|
79
|
-
// check if previous long option is not resolved
|
|
80
|
-
applyLongOptionValue();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
// short option value
|
|
86
|
-
if (currentShortOption && currentShortOption.index == token.index && token.inlineValue) {
|
|
87
|
-
currentShortOption.value = token.value;
|
|
88
|
-
shortOptionTokens.push({ ...currentShortOption });
|
|
89
|
-
currentShortOption = undefined;
|
|
90
|
-
}
|
|
91
|
-
// check if previous long option is not resolved
|
|
92
|
-
applyLongOptionValue();
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
// check if previous option is not resolved
|
|
97
|
-
applyLongOptionValue();
|
|
98
|
-
applyShortOptionValue();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* check if the last long or short option is not resolved
|
|
103
|
-
*/
|
|
104
|
-
applyLongOptionValue();
|
|
105
|
-
applyShortOptionValue();
|
|
106
|
-
/**
|
|
107
|
-
* resolve values
|
|
108
|
-
*/
|
|
109
|
-
for (const [option, schema] of Object.entries(options)) {
|
|
110
|
-
if (longOptionTokens.length === 0 && shortOptionTokens.length === 0 && schema.required) {
|
|
111
|
-
throw createRequireError(option, schema);
|
|
112
|
-
}
|
|
113
|
-
// eslint-disable-next-line unicorn/no-for-loop
|
|
114
|
-
for (let i = 0; i < longOptionTokens.length; i++) {
|
|
115
|
-
const token = longOptionTokens[i];
|
|
116
|
-
// eslint-disable-next-line unicorn/no-null
|
|
117
|
-
if (option === token.name && token.rawName != null && (0, parser_js_1.hasLongOptionPrefix)(token.rawName)) {
|
|
118
|
-
validateRequire(token, option, schema);
|
|
119
|
-
if (schema.type === 'boolean') {
|
|
120
|
-
// NOTE: re-set value to undefined, because long boolean type option is set on analyze phase
|
|
121
|
-
token.value = undefined;
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
validateValue(token, option, schema);
|
|
125
|
-
}
|
|
126
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
127
|
-
;
|
|
128
|
-
values[option] = resolveOptionValue(token, schema);
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
// eslint-disable-next-line unicorn/no-for-loop
|
|
133
|
-
for (let i = 0; i < shortOptionTokens.length; i++) {
|
|
134
|
-
const token = shortOptionTokens[i];
|
|
135
|
-
// eslint-disable-next-line unicorn/no-null
|
|
136
|
-
if (schema.short === token.name && token.rawName != null && (0, parser_js_1.isShortOption)(token.rawName)) {
|
|
137
|
-
validateRequire(token, option, schema);
|
|
138
|
-
if (schema.type === 'boolean') {
|
|
139
|
-
// NOTE: re-set value to undefined, because short boolean type option is set on analyze phase
|
|
140
|
-
token.value = undefined;
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
validateValue(token, option, schema);
|
|
144
|
-
}
|
|
145
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
146
|
-
;
|
|
147
|
-
values[option] = resolveOptionValue(token, schema);
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
// eslint-disable-next-line unicorn/no-null
|
|
152
|
-
if (values[option] == null && schema.default != null) {
|
|
153
|
-
// check if the default value is in values
|
|
154
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
155
|
-
;
|
|
156
|
-
values[option] = schema.default;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return { values, positionals };
|
|
160
|
-
}
|
|
161
|
-
function createRequireError(option, schema) {
|
|
162
|
-
return new Error(`Option '--${option}' ${schema.short ? `or '-${schema.short}'` : ''} is required`);
|
|
163
|
-
}
|
|
164
|
-
function validateRequire(token, option, schema) {
|
|
165
|
-
if (schema.required && schema.type !== 'boolean' && !token.value) {
|
|
166
|
-
throw createRequireError(option, schema);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
function validateValue(token, option, schema) {
|
|
170
|
-
switch (schema.type) {
|
|
171
|
-
case 'number': {
|
|
172
|
-
if (!isNumeric(token.value)) {
|
|
173
|
-
throw createTypeError(option, schema);
|
|
174
|
-
}
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
case 'string': {
|
|
178
|
-
if (typeof token.value !== 'string') {
|
|
179
|
-
throw createTypeError(option, schema);
|
|
180
|
-
}
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
function isNumeric(str) {
|
|
186
|
-
// @ts-ignore
|
|
187
|
-
// eslint-disable-next-line unicorn/prefer-number-properties
|
|
188
|
-
return str.trim() !== '' && !isNaN(str);
|
|
189
|
-
}
|
|
190
|
-
function createTypeError(option, schema) {
|
|
191
|
-
return new TypeError(`Option '--${option}' ${schema.short ? `or '-${schema.short}'` : ''} should be '${schema.type}'`);
|
|
192
|
-
}
|
|
193
|
-
function resolveOptionValue(token, schema) {
|
|
194
|
-
if (token.value) {
|
|
195
|
-
return schema.type === 'number' ? +token.value : token.value;
|
|
196
|
-
}
|
|
197
|
-
if (schema.type === 'boolean') {
|
|
198
|
-
return true;
|
|
199
|
-
}
|
|
200
|
-
return schema.type === 'number' ? +(schema.default || '') : schema.default;
|
|
201
|
-
}
|
package/lib/esm/index.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { parse } from './parse.js';
|
|
2
|
-
export { parseArgs } from './parser.js';
|
|
3
|
-
export { resolveArgs } from './resolver.js';
|
|
4
|
-
export type { ParsedArgs, ParseOptions } from './parse';
|
|
5
|
-
export type { ArgToken, ParserOptions } from './parser';
|
|
6
|
-
export type { ArgOptions, ArgOptionSchema, ArgValues } from './resolver';
|
package/lib/esm/parser.d.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Argument token Kind
|
|
3
|
-
* - `option`: option token, support short option (e.g. `-x`) and long option (e.g. `--foo`)
|
|
4
|
-
* - `option-terminator`: option terminator (`--`) token, see guideline 10 in https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
|
|
5
|
-
* - `positional`: positional token
|
|
6
|
-
*/
|
|
7
|
-
type ArgTokenKind = 'option' | 'option-terminator' | 'positional';
|
|
8
|
-
/**
|
|
9
|
-
* Argument token
|
|
10
|
-
*/
|
|
11
|
-
export interface ArgToken {
|
|
12
|
-
/**
|
|
13
|
-
* Argument token kind
|
|
14
|
-
*/
|
|
15
|
-
kind: ArgTokenKind;
|
|
16
|
-
/**
|
|
17
|
-
* Argument token index, e.g `--foo bar` => `--foo` index is 0, `bar` index is 1
|
|
18
|
-
*/
|
|
19
|
-
index: number;
|
|
20
|
-
/**
|
|
21
|
-
* Option name, e.g. `--foo` => `foo`, `-x` => `x`
|
|
22
|
-
*/
|
|
23
|
-
name?: string;
|
|
24
|
-
/**
|
|
25
|
-
* Raw option name, e.g. `--foo` => `--foo`, `-x` => `-x`
|
|
26
|
-
*/
|
|
27
|
-
rawName?: string;
|
|
28
|
-
/**
|
|
29
|
-
* Option value, e.g. `--foo=bar` => `bar`, `-x=bar` => `bar`.
|
|
30
|
-
* If the `allowCompatible` option is `true`, short option value will be same as Node.js `parseArgs` behavior.
|
|
31
|
-
*/
|
|
32
|
-
value?: string;
|
|
33
|
-
/**
|
|
34
|
-
* Inline value, e.g. `--foo=bar` => `true`, `-x=bar` => `true`.
|
|
35
|
-
*/
|
|
36
|
-
inlineValue?: boolean;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Parser Options
|
|
40
|
-
*/
|
|
41
|
-
export interface ParserOptions {
|
|
42
|
-
/**
|
|
43
|
-
* [Node.js parseArgs](https://nodejs.org/api/util.html#parseargs-tokens) tokens compatible mode
|
|
44
|
-
* @default false
|
|
45
|
-
*/
|
|
46
|
-
allowCompatible?: boolean;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Parse command line arguments
|
|
50
|
-
* @example
|
|
51
|
-
* ```js
|
|
52
|
-
* import { parseArgs } from 'args-tokens' // for Node.js and Bun
|
|
53
|
-
* // import { parseArgs } from 'jsr:@kazupon/args-tokens' // for Deno
|
|
54
|
-
*
|
|
55
|
-
* const tokens = parseArgs(['--foo', 'bar', '-x', '--bar=baz'])
|
|
56
|
-
* // do something with using tokens
|
|
57
|
-
* // ...
|
|
58
|
-
* console.log('tokens:', tokens)
|
|
59
|
-
* ```
|
|
60
|
-
* @param args command line arguments
|
|
61
|
-
* @param options parse options
|
|
62
|
-
* @returns argument tokens
|
|
63
|
-
*/
|
|
64
|
-
export declare function parseArgs(args: string[], options?: ParserOptions): ArgToken[];
|
|
65
|
-
/**
|
|
66
|
-
* Check if `arg` is a short option (e.g. `-f`)
|
|
67
|
-
* @param arg the argument to check
|
|
68
|
-
* @returns whether `arg` is a short option
|
|
69
|
-
*/
|
|
70
|
-
export declare function isShortOption(arg: string): boolean;
|
|
71
|
-
/**
|
|
72
|
-
* Check if `arg` is a long option prefix (e.g. `--`)
|
|
73
|
-
* @param arg the argument to check
|
|
74
|
-
* @returns whether `arg` is a long option prefix
|
|
75
|
-
*/
|
|
76
|
-
export declare function hasLongOptionPrefix(arg: string): boolean;
|
|
77
|
-
export {};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|