args-tokens 0.2.3 → 0.2.5
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/lib/cjs/index.d.ts +64 -0
- package/lib/cjs/index.js +228 -0
- package/lib/esm/index.d.ts +64 -0
- package/lib/esm/index.js +225 -0
- package/package.json +1 -1
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
export 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
|
+
* Parse Options
|
|
40
|
+
*/
|
|
41
|
+
export interface ParseOptions {
|
|
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?: ParseOptions): ArgToken[];
|
package/lib/cjs/index.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
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
|
+
const HYPHEN_CHAR = '-';
|
|
11
|
+
const HYPHEN_CODE = HYPHEN_CHAR.codePointAt(0);
|
|
12
|
+
const EQUAL_CHAR = '=';
|
|
13
|
+
const EQUAL_CODE = EQUAL_CHAR.codePointAt(0);
|
|
14
|
+
const TERMINATOR = '--';
|
|
15
|
+
const SHORT_OPTION_PREFIX = HYPHEN_CHAR;
|
|
16
|
+
const LONG_OPTION_PREFIX = '--';
|
|
17
|
+
/**
|
|
18
|
+
* Parse command line arguments
|
|
19
|
+
* @example
|
|
20
|
+
* ```js
|
|
21
|
+
* import { parseArgs } from 'args-tokens' // for Node.js and Bun
|
|
22
|
+
* // import { parseArgs } from 'jsr:@kazupon/args-tokens' // for Deno
|
|
23
|
+
*
|
|
24
|
+
* const tokens = parseArgs(['--foo', 'bar', '-x', '--bar=baz'])
|
|
25
|
+
* // do something with using tokens
|
|
26
|
+
* // ...
|
|
27
|
+
* console.log('tokens:', tokens)
|
|
28
|
+
* ```
|
|
29
|
+
* @param args command line arguments
|
|
30
|
+
* @param options parse options
|
|
31
|
+
* @returns argument tokens
|
|
32
|
+
*/
|
|
33
|
+
function parseArgs(args, options = {}) {
|
|
34
|
+
const { allowCompatible = false } = options;
|
|
35
|
+
const tokens = [];
|
|
36
|
+
const remainings = [...args];
|
|
37
|
+
let index = -1;
|
|
38
|
+
let groupCount = 0;
|
|
39
|
+
let hasShortValueSeparator = false;
|
|
40
|
+
while (remainings.length > 0) {
|
|
41
|
+
const arg = remainings.shift();
|
|
42
|
+
if (arg == undefined) {
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
const nextArg = remainings[0];
|
|
46
|
+
if (groupCount > 0) {
|
|
47
|
+
groupCount--;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
index++;
|
|
51
|
+
}
|
|
52
|
+
// check if `arg` is an options terminator.
|
|
53
|
+
// guideline 10 in https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
|
|
54
|
+
if (arg === TERMINATOR) {
|
|
55
|
+
tokens.push({
|
|
56
|
+
kind: 'option-terminator',
|
|
57
|
+
index
|
|
58
|
+
});
|
|
59
|
+
const mapped = remainings.map(arg => {
|
|
60
|
+
return { kind: 'positional', index: ++index, value: arg };
|
|
61
|
+
});
|
|
62
|
+
tokens.push(...mapped);
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
if (isShortOption(arg)) {
|
|
66
|
+
const shortOption = arg.charAt(1);
|
|
67
|
+
let value;
|
|
68
|
+
let inlineValue;
|
|
69
|
+
if (groupCount) {
|
|
70
|
+
// e.g. `-abc`
|
|
71
|
+
tokens.push({
|
|
72
|
+
kind: 'option',
|
|
73
|
+
name: shortOption,
|
|
74
|
+
rawName: arg,
|
|
75
|
+
index,
|
|
76
|
+
value,
|
|
77
|
+
inlineValue
|
|
78
|
+
});
|
|
79
|
+
if (groupCount === 1 && hasOptionValue(nextArg)) {
|
|
80
|
+
value = remainings.shift();
|
|
81
|
+
if (hasShortValueSeparator) {
|
|
82
|
+
inlineValue = true;
|
|
83
|
+
hasShortValueSeparator = false;
|
|
84
|
+
}
|
|
85
|
+
tokens.push({
|
|
86
|
+
kind: 'option',
|
|
87
|
+
index,
|
|
88
|
+
value,
|
|
89
|
+
inlineValue
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
// e.g. `-a`
|
|
95
|
+
tokens.push({
|
|
96
|
+
kind: 'option',
|
|
97
|
+
name: shortOption,
|
|
98
|
+
rawName: arg,
|
|
99
|
+
index,
|
|
100
|
+
value,
|
|
101
|
+
inlineValue
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
// eslint-disable-next-line unicorn/no-null
|
|
105
|
+
if (value != null) {
|
|
106
|
+
++index;
|
|
107
|
+
}
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (isShortOptionGroup(arg)) {
|
|
111
|
+
// expend short option group (e.g. `-abc` => `-a -b -c`, `-f=bar` => `-f bar`)
|
|
112
|
+
const expanded = [];
|
|
113
|
+
let shortValue = '';
|
|
114
|
+
for (let i = 1; i < arg.length; i++) {
|
|
115
|
+
const shortableOption = arg.charAt(i);
|
|
116
|
+
if (hasShortValueSeparator) {
|
|
117
|
+
shortValue += shortableOption;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
if (!allowCompatible && shortableOption.codePointAt(0) === EQUAL_CODE) {
|
|
121
|
+
hasShortValueSeparator = true;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
expanded.push(`${SHORT_OPTION_PREFIX}${shortableOption}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (shortValue) {
|
|
129
|
+
expanded.push(shortValue);
|
|
130
|
+
}
|
|
131
|
+
remainings.unshift(...expanded);
|
|
132
|
+
groupCount = expanded.length;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (isLongOption(arg)) {
|
|
136
|
+
// e.g. `--foo`
|
|
137
|
+
const longOption = arg.slice(2);
|
|
138
|
+
tokens.push({
|
|
139
|
+
kind: 'option',
|
|
140
|
+
name: longOption,
|
|
141
|
+
rawName: arg,
|
|
142
|
+
index,
|
|
143
|
+
value: undefined,
|
|
144
|
+
inlineValue: undefined
|
|
145
|
+
});
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (isLongOptionAndValue(arg)) {
|
|
149
|
+
// e.g. `--foo=bar`
|
|
150
|
+
const equalIndex = arg.indexOf(EQUAL_CHAR);
|
|
151
|
+
const longOption = arg.slice(2, equalIndex);
|
|
152
|
+
const value = arg.slice(equalIndex + 1);
|
|
153
|
+
tokens.push({
|
|
154
|
+
kind: 'option',
|
|
155
|
+
name: longOption,
|
|
156
|
+
rawName: `${LONG_OPTION_PREFIX}${longOption}`,
|
|
157
|
+
index,
|
|
158
|
+
value,
|
|
159
|
+
inlineValue: true
|
|
160
|
+
});
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
tokens.push({
|
|
164
|
+
kind: 'positional',
|
|
165
|
+
index,
|
|
166
|
+
value: arg
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return tokens;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Check if `arg` is a short option (e.g. `-f`)
|
|
173
|
+
* @param arg the argument to check
|
|
174
|
+
* @returns whether `arg` is a short option
|
|
175
|
+
*/
|
|
176
|
+
function isShortOption(arg) {
|
|
177
|
+
return (arg.length === 2 && arg.codePointAt(0) === HYPHEN_CODE && arg.codePointAt(1) !== HYPHEN_CODE);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Check if `arg` is a short option group (e.g. `-abc`)
|
|
181
|
+
* @param arg the argument to check
|
|
182
|
+
* @returns whether `arg` is a short option group
|
|
183
|
+
*/
|
|
184
|
+
function isShortOptionGroup(arg) {
|
|
185
|
+
if (arg.length <= 2) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
if (arg.codePointAt(0) !== HYPHEN_CODE) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
if (arg.codePointAt(1) === HYPHEN_CODE) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Check if `arg` is a long option (e.g. `--foo`)
|
|
198
|
+
* @param arg the argument to check
|
|
199
|
+
* @returns whether `arg` is a long option
|
|
200
|
+
*/
|
|
201
|
+
function isLongOption(arg) {
|
|
202
|
+
return hasLongOptionPrefix(arg) && !arg.includes(EQUAL_CHAR, 3);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Check if `arg` is a long option with value (e.g. `--foo=bar`)
|
|
206
|
+
* @param arg the argument to check
|
|
207
|
+
* @returns whether `arg` is a long option
|
|
208
|
+
*/
|
|
209
|
+
function isLongOptionAndValue(arg) {
|
|
210
|
+
return hasLongOptionPrefix(arg) && arg.includes(EQUAL_CHAR, 3);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Check if `arg` is a long option prefix (e.g. `--`)
|
|
214
|
+
* @param arg the argument to check
|
|
215
|
+
* @returns whether `arg` is a long option prefix
|
|
216
|
+
*/
|
|
217
|
+
function hasLongOptionPrefix(arg) {
|
|
218
|
+
return arg.length > 2 && ~arg.indexOf(LONG_OPTION_PREFIX);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Check if a `value` is an option value
|
|
222
|
+
* @param value a value to check
|
|
223
|
+
* @returns whether a `value` is an option value
|
|
224
|
+
*/
|
|
225
|
+
function hasOptionValue(value) {
|
|
226
|
+
// eslint-disable-next-line unicorn/no-null
|
|
227
|
+
return !(value == null) && value.codePointAt(0) !== HYPHEN_CODE;
|
|
228
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
export 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
|
+
* Parse Options
|
|
40
|
+
*/
|
|
41
|
+
export interface ParseOptions {
|
|
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?: ParseOptions): ArgToken[];
|
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Modifier: kazuya kawaguchi (a.k.a. kazupon)
|
|
3
|
+
// Forked from `nodejs/node` (`pkgjs/parseargs`)
|
|
4
|
+
// Repository url: https://github.com/nodejs/node (https://github.com/pkgjs/parseargs)
|
|
5
|
+
// Author: Node.js contributors
|
|
6
|
+
// Code url: https://github.com/nodejs/node/blob/main/lib/internal/util/parse_args/parse_args.js
|
|
7
|
+
const HYPHEN_CHAR = '-';
|
|
8
|
+
const HYPHEN_CODE = HYPHEN_CHAR.codePointAt(0);
|
|
9
|
+
const EQUAL_CHAR = '=';
|
|
10
|
+
const EQUAL_CODE = EQUAL_CHAR.codePointAt(0);
|
|
11
|
+
const TERMINATOR = '--';
|
|
12
|
+
const SHORT_OPTION_PREFIX = HYPHEN_CHAR;
|
|
13
|
+
const LONG_OPTION_PREFIX = '--';
|
|
14
|
+
/**
|
|
15
|
+
* Parse command line arguments
|
|
16
|
+
* @example
|
|
17
|
+
* ```js
|
|
18
|
+
* import { parseArgs } from 'args-tokens' // for Node.js and Bun
|
|
19
|
+
* // import { parseArgs } from 'jsr:@kazupon/args-tokens' // for Deno
|
|
20
|
+
*
|
|
21
|
+
* const tokens = parseArgs(['--foo', 'bar', '-x', '--bar=baz'])
|
|
22
|
+
* // do something with using tokens
|
|
23
|
+
* // ...
|
|
24
|
+
* console.log('tokens:', tokens)
|
|
25
|
+
* ```
|
|
26
|
+
* @param args command line arguments
|
|
27
|
+
* @param options parse options
|
|
28
|
+
* @returns argument tokens
|
|
29
|
+
*/
|
|
30
|
+
export function parseArgs(args, options = {}) {
|
|
31
|
+
const { allowCompatible = false } = options;
|
|
32
|
+
const tokens = [];
|
|
33
|
+
const remainings = [...args];
|
|
34
|
+
let index = -1;
|
|
35
|
+
let groupCount = 0;
|
|
36
|
+
let hasShortValueSeparator = false;
|
|
37
|
+
while (remainings.length > 0) {
|
|
38
|
+
const arg = remainings.shift();
|
|
39
|
+
if (arg == undefined) {
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
const nextArg = remainings[0];
|
|
43
|
+
if (groupCount > 0) {
|
|
44
|
+
groupCount--;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
index++;
|
|
48
|
+
}
|
|
49
|
+
// check if `arg` is an options terminator.
|
|
50
|
+
// guideline 10 in https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
|
|
51
|
+
if (arg === TERMINATOR) {
|
|
52
|
+
tokens.push({
|
|
53
|
+
kind: 'option-terminator',
|
|
54
|
+
index
|
|
55
|
+
});
|
|
56
|
+
const mapped = remainings.map(arg => {
|
|
57
|
+
return { kind: 'positional', index: ++index, value: arg };
|
|
58
|
+
});
|
|
59
|
+
tokens.push(...mapped);
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
if (isShortOption(arg)) {
|
|
63
|
+
const shortOption = arg.charAt(1);
|
|
64
|
+
let value;
|
|
65
|
+
let inlineValue;
|
|
66
|
+
if (groupCount) {
|
|
67
|
+
// e.g. `-abc`
|
|
68
|
+
tokens.push({
|
|
69
|
+
kind: 'option',
|
|
70
|
+
name: shortOption,
|
|
71
|
+
rawName: arg,
|
|
72
|
+
index,
|
|
73
|
+
value,
|
|
74
|
+
inlineValue
|
|
75
|
+
});
|
|
76
|
+
if (groupCount === 1 && hasOptionValue(nextArg)) {
|
|
77
|
+
value = remainings.shift();
|
|
78
|
+
if (hasShortValueSeparator) {
|
|
79
|
+
inlineValue = true;
|
|
80
|
+
hasShortValueSeparator = false;
|
|
81
|
+
}
|
|
82
|
+
tokens.push({
|
|
83
|
+
kind: 'option',
|
|
84
|
+
index,
|
|
85
|
+
value,
|
|
86
|
+
inlineValue
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// e.g. `-a`
|
|
92
|
+
tokens.push({
|
|
93
|
+
kind: 'option',
|
|
94
|
+
name: shortOption,
|
|
95
|
+
rawName: arg,
|
|
96
|
+
index,
|
|
97
|
+
value,
|
|
98
|
+
inlineValue
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
// eslint-disable-next-line unicorn/no-null
|
|
102
|
+
if (value != null) {
|
|
103
|
+
++index;
|
|
104
|
+
}
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (isShortOptionGroup(arg)) {
|
|
108
|
+
// expend short option group (e.g. `-abc` => `-a -b -c`, `-f=bar` => `-f bar`)
|
|
109
|
+
const expanded = [];
|
|
110
|
+
let shortValue = '';
|
|
111
|
+
for (let i = 1; i < arg.length; i++) {
|
|
112
|
+
const shortableOption = arg.charAt(i);
|
|
113
|
+
if (hasShortValueSeparator) {
|
|
114
|
+
shortValue += shortableOption;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
if (!allowCompatible && shortableOption.codePointAt(0) === EQUAL_CODE) {
|
|
118
|
+
hasShortValueSeparator = true;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
expanded.push(`${SHORT_OPTION_PREFIX}${shortableOption}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (shortValue) {
|
|
126
|
+
expanded.push(shortValue);
|
|
127
|
+
}
|
|
128
|
+
remainings.unshift(...expanded);
|
|
129
|
+
groupCount = expanded.length;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (isLongOption(arg)) {
|
|
133
|
+
// e.g. `--foo`
|
|
134
|
+
const longOption = arg.slice(2);
|
|
135
|
+
tokens.push({
|
|
136
|
+
kind: 'option',
|
|
137
|
+
name: longOption,
|
|
138
|
+
rawName: arg,
|
|
139
|
+
index,
|
|
140
|
+
value: undefined,
|
|
141
|
+
inlineValue: undefined
|
|
142
|
+
});
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (isLongOptionAndValue(arg)) {
|
|
146
|
+
// e.g. `--foo=bar`
|
|
147
|
+
const equalIndex = arg.indexOf(EQUAL_CHAR);
|
|
148
|
+
const longOption = arg.slice(2, equalIndex);
|
|
149
|
+
const value = arg.slice(equalIndex + 1);
|
|
150
|
+
tokens.push({
|
|
151
|
+
kind: 'option',
|
|
152
|
+
name: longOption,
|
|
153
|
+
rawName: `${LONG_OPTION_PREFIX}${longOption}`,
|
|
154
|
+
index,
|
|
155
|
+
value,
|
|
156
|
+
inlineValue: true
|
|
157
|
+
});
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
tokens.push({
|
|
161
|
+
kind: 'positional',
|
|
162
|
+
index,
|
|
163
|
+
value: arg
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return tokens;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Check if `arg` is a short option (e.g. `-f`)
|
|
170
|
+
* @param arg the argument to check
|
|
171
|
+
* @returns whether `arg` is a short option
|
|
172
|
+
*/
|
|
173
|
+
function isShortOption(arg) {
|
|
174
|
+
return (arg.length === 2 && arg.codePointAt(0) === HYPHEN_CODE && arg.codePointAt(1) !== HYPHEN_CODE);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Check if `arg` is a short option group (e.g. `-abc`)
|
|
178
|
+
* @param arg the argument to check
|
|
179
|
+
* @returns whether `arg` is a short option group
|
|
180
|
+
*/
|
|
181
|
+
function isShortOptionGroup(arg) {
|
|
182
|
+
if (arg.length <= 2) {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
if (arg.codePointAt(0) !== HYPHEN_CODE) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
if (arg.codePointAt(1) === HYPHEN_CODE) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Check if `arg` is a long option (e.g. `--foo`)
|
|
195
|
+
* @param arg the argument to check
|
|
196
|
+
* @returns whether `arg` is a long option
|
|
197
|
+
*/
|
|
198
|
+
function isLongOption(arg) {
|
|
199
|
+
return hasLongOptionPrefix(arg) && !arg.includes(EQUAL_CHAR, 3);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Check if `arg` is a long option with value (e.g. `--foo=bar`)
|
|
203
|
+
* @param arg the argument to check
|
|
204
|
+
* @returns whether `arg` is a long option
|
|
205
|
+
*/
|
|
206
|
+
function isLongOptionAndValue(arg) {
|
|
207
|
+
return hasLongOptionPrefix(arg) && arg.includes(EQUAL_CHAR, 3);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Check if `arg` is a long option prefix (e.g. `--`)
|
|
211
|
+
* @param arg the argument to check
|
|
212
|
+
* @returns whether `arg` is a long option prefix
|
|
213
|
+
*/
|
|
214
|
+
function hasLongOptionPrefix(arg) {
|
|
215
|
+
return arg.length > 2 && ~arg.indexOf(LONG_OPTION_PREFIX);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Check if a `value` is an option value
|
|
219
|
+
* @param value a value to check
|
|
220
|
+
* @returns whether a `value` is an option value
|
|
221
|
+
*/
|
|
222
|
+
function hasOptionValue(value) {
|
|
223
|
+
// eslint-disable-next-line unicorn/no-null
|
|
224
|
+
return !(value == null) && value.codePointAt(0) !== HYPHEN_CODE;
|
|
225
|
+
}
|