@trenskow/arguments-parser 0.3.130 → 0.3.132
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 +8 -28
- package/index.js +22 -1
- package/lib/autocomplete/bash.js +13 -3
- package/lib/autocomplete/index.js +83 -48
- package/lib/autocomplete/zsh.js +18 -1
- package/lib/index.js +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -80,40 +80,20 @@ Options:
|
|
|
80
80
|
|
|
81
81
|
> The validation schema is described in package [isvalid](https://github.com/trenskow/isvalid).
|
|
82
82
|
|
|
83
|
-
##
|
|
83
|
+
## Autocompletion
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
The library supports Bash and ZSH autocompletion out of the box.
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
To generate the completion scripts to install for the current shell - use the command below...
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
The completion script for Bash should be installed as below.
|
|
92
|
-
|
|
93
|
-
````bash
|
|
94
|
-
_my_script() {
|
|
95
|
-
eval "$(AUTOCOMPLETE=bash my_script "${COMP_WORDS[@]}")"
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
complete -F _my_script my_script
|
|
89
|
+
````
|
|
90
|
+
./my_script _completion
|
|
99
91
|
````
|
|
100
92
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
The completion script for ZSH should be installed as below.
|
|
104
|
-
|
|
105
|
-
````zsh
|
|
106
|
-
#compdef my_script
|
|
107
|
-
|
|
108
|
-
_my_script() {
|
|
109
|
-
|
|
110
|
-
local -a completions
|
|
111
|
-
|
|
112
|
-
eval "$(AUTOCOMPLETE=zsh my_script ${words[@]})"
|
|
113
|
-
|
|
114
|
-
}
|
|
93
|
+
...or if you need to generate for another shell than the current one.
|
|
115
94
|
|
|
116
|
-
|
|
95
|
+
````
|
|
96
|
+
./my_script _completion [bash|zsh]
|
|
117
97
|
````
|
|
118
98
|
|
|
119
99
|
# License
|
package/index.js
CHANGED
|
@@ -6,7 +6,14 @@
|
|
|
6
6
|
// See license in LICENSE.
|
|
7
7
|
//
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
basename,
|
|
11
|
+
extname
|
|
12
|
+
} from 'path';
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
plugins
|
|
16
|
+
} from 'isvalid';
|
|
10
17
|
|
|
11
18
|
import argumentsParser from './lib/index.js';
|
|
12
19
|
import autocomplete from './lib/autocomplete/index.js';
|
|
@@ -65,4 +72,18 @@ plugins.use('argumentsParser.autocomplete', () => ({
|
|
|
65
72
|
}
|
|
66
73
|
}));
|
|
67
74
|
|
|
75
|
+
if (process.argv[2] === '_completion') {
|
|
76
|
+
|
|
77
|
+
const path = process.env.COMPLETION_PATH || process.argv[1];
|
|
78
|
+
|
|
79
|
+
autocomplete.script({
|
|
80
|
+
shell: process.argv[3],
|
|
81
|
+
command: basename(path)
|
|
82
|
+
.slice(0, -extname(path).length)
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
process.exit(0);
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
68
89
|
export default autocomplete(process.env.AUTOCOMPLETE) || argumentsParser;
|
package/lib/autocomplete/bash.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// See license in LICENSE.
|
|
7
7
|
//
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
const bash = (items) => {
|
|
10
10
|
|
|
11
11
|
const keys = Object.keys(items);
|
|
12
12
|
|
|
@@ -52,13 +52,23 @@ export default (items) => {
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
process.stdout.write(')\n');
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
if (files) {
|
|
59
|
-
process.stdout.write('COMPREPLY+=($(compgen -f -- "${COMP_WORDS[COMP_CWORD]}"))\n');
|
|
59
|
+
process.stdout.write('COMPREPLY+=($(compgen -f -- "${COMP_WORDS[COMP_CWORD]}"))\n');
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
process.exit(0);
|
|
63
63
|
|
|
64
64
|
};
|
|
65
|
+
|
|
66
|
+
bash.script = ({
|
|
67
|
+
command
|
|
68
|
+
}) => `_${command}() {
|
|
69
|
+
eval "$(AUTOCOMPLETE=bash AUTOCOMPLETE_CURRENT=$COMP_CWORD ${command} "\${COMP_WORDS[@]}")"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
complete -F _${command} ${command}`;
|
|
73
|
+
|
|
74
|
+
export default bash;
|
|
@@ -25,13 +25,15 @@ const supported = {
|
|
|
25
25
|
zsh
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
+
const currentShell = basename(process.env.SHELL || '');
|
|
29
|
+
|
|
28
30
|
const argumentsParser = (shell) => {
|
|
29
31
|
|
|
30
|
-
if (
|
|
32
|
+
if (typeof shell === 'undefined') return;
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
const writer = supported[shell || currentShell];
|
|
33
35
|
|
|
34
|
-
if (!
|
|
36
|
+
if (!writer) {
|
|
35
37
|
process.stderr.write(`Unsupported shell: ${shell}\n`);
|
|
36
38
|
process.exit(1);
|
|
37
39
|
}
|
|
@@ -64,7 +66,7 @@ const argumentsParser = (shell) => {
|
|
|
64
66
|
});
|
|
65
67
|
};
|
|
66
68
|
|
|
67
|
-
const output = (items) =>
|
|
69
|
+
const output = (items) => writer(
|
|
68
70
|
normalize(items)
|
|
69
71
|
.reduce((grouped, item) => {
|
|
70
72
|
|
|
@@ -85,7 +87,7 @@ const argumentsParser = (shell) => {
|
|
|
85
87
|
|
|
86
88
|
const argumentsParser = (
|
|
87
89
|
{
|
|
88
|
-
args = process.argv.slice(
|
|
90
|
+
args = process.argv.slice(3),
|
|
89
91
|
argvLevel = 0,
|
|
90
92
|
placeholder = '<>',
|
|
91
93
|
command,
|
|
@@ -96,7 +98,8 @@ const argumentsParser = (shell) => {
|
|
|
96
98
|
data: {},
|
|
97
99
|
validationOptions: {}
|
|
98
100
|
},
|
|
99
|
-
parameters = {}
|
|
101
|
+
parameters = {},
|
|
102
|
+
autocompleteIndex = (process.env.AUTOCOMPLETE_INDEX || 2) - 2
|
|
100
103
|
} = {}
|
|
101
104
|
) => {
|
|
102
105
|
|
|
@@ -114,7 +117,8 @@ const argumentsParser = (shell) => {
|
|
|
114
117
|
placeholder,
|
|
115
118
|
command: command,
|
|
116
119
|
options,
|
|
117
|
-
parameters
|
|
120
|
+
parameters,
|
|
121
|
+
autocompleteIndex: autocompleteIndex - 1
|
|
118
122
|
}),
|
|
119
123
|
parameters
|
|
120
124
|
});
|
|
@@ -129,6 +133,18 @@ const argumentsParser = (shell) => {
|
|
|
129
133
|
|
|
130
134
|
const tool = caseit(args[0] || '');
|
|
131
135
|
|
|
136
|
+
if (autocompleteIndex === 0) {
|
|
137
|
+
|
|
138
|
+
return output(Object.keys(commands)
|
|
139
|
+
.filter((command) => command.startsWith(tool))
|
|
140
|
+
.map((command) => ({
|
|
141
|
+
type: 'command',
|
|
142
|
+
argument: caseit(command, 'kebab'),
|
|
143
|
+
description: commands[command].description
|
|
144
|
+
})));
|
|
145
|
+
|
|
146
|
+
}
|
|
147
|
+
|
|
132
148
|
if (commands[tool]) {
|
|
133
149
|
|
|
134
150
|
onCommand?.(tool, args.slice(1));
|
|
@@ -139,13 +155,7 @@ const argumentsParser = (shell) => {
|
|
|
139
155
|
|
|
140
156
|
}
|
|
141
157
|
|
|
142
|
-
|
|
143
|
-
.filter((command) => command.startsWith(tool))
|
|
144
|
-
.map((command) => ({
|
|
145
|
-
type: 'command',
|
|
146
|
-
argument: caseit(command, 'kebab'),
|
|
147
|
-
description: commands[command].description
|
|
148
|
-
})));
|
|
158
|
+
process.exit(0);
|
|
149
159
|
|
|
150
160
|
},
|
|
151
161
|
parameter: async ({
|
|
@@ -153,10 +163,10 @@ const argumentsParser = (shell) => {
|
|
|
153
163
|
autocomplete
|
|
154
164
|
}, command) => {
|
|
155
165
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
166
|
+
if (autocompleteIndex === 0) {
|
|
167
|
+
return output(
|
|
168
|
+
filter(
|
|
169
|
+
await autocomplete?.(args[0] || '') || [], args[0]));
|
|
160
170
|
}
|
|
161
171
|
|
|
162
172
|
parameters[identifier] = args[0];
|
|
@@ -203,6 +213,10 @@ const argumentsParser = (shell) => {
|
|
|
203
213
|
}]
|
|
204
214
|
} = options.validationOptions;
|
|
205
215
|
|
|
216
|
+
const variadicOnly = args
|
|
217
|
+
.slice(0, autocompleteIndex)
|
|
218
|
+
.some((arg) => arg === '--');
|
|
219
|
+
|
|
206
220
|
const allKeyPaths = keyPaths(options.schema)
|
|
207
221
|
.all()
|
|
208
222
|
.filter((keyPath) => keyPath);
|
|
@@ -221,7 +235,7 @@ const argumentsParser = (shell) => {
|
|
|
221
235
|
|
|
222
236
|
key = caseit(key);
|
|
223
237
|
|
|
224
|
-
if (schemas[idx]) {
|
|
238
|
+
if (!variadicOnly && schemas[idx]) {
|
|
225
239
|
|
|
226
240
|
if (schemas[idx].enum) {
|
|
227
241
|
return Object.keys(schemas[idx].enum)
|
|
@@ -244,36 +258,46 @@ const argumentsParser = (shell) => {
|
|
|
244
258
|
|
|
245
259
|
let items = [];
|
|
246
260
|
|
|
247
|
-
if (
|
|
261
|
+
if (variadic === 'allow') {
|
|
262
|
+
items = items.concat(
|
|
263
|
+
filter(await autocomplete?.(current) || [], current));
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (!variadicOnly) {
|
|
267
|
+
|
|
268
|
+
if (!current.startsWith('--')) {
|
|
269
|
+
|
|
270
|
+
items = items.concat(
|
|
271
|
+
allKeyPaths
|
|
272
|
+
.filter((keyPath) => !spent.includes(keyPath))
|
|
273
|
+
.filter((keyPath) => key !== keyPath && keyPath.startsWith(key) && keyPaths(options.schema).get(keyPath).short)
|
|
274
|
+
.map((keyPath) => ({
|
|
275
|
+
type: 'option',
|
|
276
|
+
argument: `-${caseit(keyPaths(options.schema).get(keyPath).short, 'kebab')}`,
|
|
277
|
+
description: keyPaths(options.schema).get(keyPath).description
|
|
278
|
+
})));
|
|
248
279
|
|
|
249
|
-
if (!current.startsWith('-')) {
|
|
250
|
-
if (variadic === 'allow') {
|
|
251
|
-
items = items.concat(
|
|
252
|
-
filter(await autocomplete?.(current) || [], current));
|
|
253
|
-
}
|
|
254
280
|
}
|
|
255
281
|
|
|
282
|
+
|
|
256
283
|
items = items.concat(
|
|
257
284
|
allKeyPaths
|
|
258
285
|
.filter((keyPath) => !spent.includes(keyPath))
|
|
259
|
-
.filter((keyPath) => key !== keyPath && keyPath.startsWith(key)
|
|
286
|
+
.filter((keyPath) => key !== keyPath && keyPath.startsWith(key))
|
|
260
287
|
.map((keyPath) => ({
|
|
261
288
|
type: 'option',
|
|
262
|
-
argument:
|
|
289
|
+
argument: `--${caseit(keyPath, 'kebab')}`,
|
|
263
290
|
description: keyPaths(options.schema).get(keyPath).description
|
|
264
291
|
})));
|
|
265
292
|
|
|
266
293
|
}
|
|
267
294
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
.
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
argument: `--${caseit(keyPath, 'kebab')}`,
|
|
275
|
-
description: keyPaths(options.schema).get(keyPath).description
|
|
276
|
-
})));
|
|
295
|
+
if (variadic === 'allow' && !variadicOnly && current === Array(current.length).fill('-').join('')) {
|
|
296
|
+
items = items.concat([{
|
|
297
|
+
type: 'option',
|
|
298
|
+
argument: '--'.slice(0, -current.length)
|
|
299
|
+
}]);
|
|
300
|
+
}
|
|
277
301
|
|
|
278
302
|
return items;
|
|
279
303
|
|
|
@@ -286,13 +310,12 @@ const argumentsParser = (shell) => {
|
|
|
286
310
|
await complete(-1));
|
|
287
311
|
}
|
|
288
312
|
|
|
289
|
-
for (idx = 0; idx < args.length; idx++) {
|
|
313
|
+
for (idx = 0; idx < autocompleteIndex || idx < args.length; idx++) {
|
|
290
314
|
|
|
291
315
|
if (!schemas[idx]) {
|
|
292
316
|
|
|
293
|
-
if (!args[idx].startsWith('-')) {
|
|
294
|
-
|
|
295
|
-
await complete(idx, args[idx]));
|
|
317
|
+
if (variadicOnly || !args[idx].startsWith('-')) {
|
|
318
|
+
continue;
|
|
296
319
|
}
|
|
297
320
|
|
|
298
321
|
const [keyPath, schema] = allKeyPaths
|
|
@@ -312,15 +335,8 @@ const argumentsParser = (shell) => {
|
|
|
312
335
|
|
|
313
336
|
}
|
|
314
337
|
|
|
315
|
-
const current = await complete(idx - 1, args[idx - 1]);
|
|
316
|
-
|
|
317
|
-
if (current.length) {
|
|
318
|
-
return output(current);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
338
|
return output(
|
|
322
|
-
await complete(
|
|
323
|
-
|
|
339
|
+
await complete(autocompleteIndex));
|
|
324
340
|
|
|
325
341
|
})().then(...resultArguments);
|
|
326
342
|
}
|
|
@@ -334,4 +350,23 @@ const argumentsParser = (shell) => {
|
|
|
334
350
|
|
|
335
351
|
};
|
|
336
352
|
|
|
353
|
+
argumentsParser.script = ({
|
|
354
|
+
shell = currentShell,
|
|
355
|
+
command
|
|
356
|
+
}) => {
|
|
357
|
+
|
|
358
|
+
const writer = supported[shell || currentShell];
|
|
359
|
+
|
|
360
|
+
if (!writer) {
|
|
361
|
+
process.stderr.write(`Unsupported shell: ${shell}\n`);
|
|
362
|
+
process.exit(1);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
process.stdout.write(
|
|
366
|
+
writer.script({
|
|
367
|
+
command
|
|
368
|
+
}));
|
|
369
|
+
|
|
370
|
+
};
|
|
371
|
+
|
|
337
372
|
export default argumentsParser;
|
package/lib/autocomplete/zsh.js
CHANGED
|
@@ -6,7 +6,12 @@
|
|
|
6
6
|
// See license in LICENSE.
|
|
7
7
|
//
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
import {
|
|
10
|
+
basename,
|
|
11
|
+
extname
|
|
12
|
+
} from 'path';
|
|
13
|
+
|
|
14
|
+
const zsh = (items) => {
|
|
10
15
|
|
|
11
16
|
const keys = Object.keys(items);
|
|
12
17
|
|
|
@@ -49,3 +54,15 @@ export default (items) => {
|
|
|
49
54
|
process.exit(0);
|
|
50
55
|
|
|
51
56
|
};
|
|
57
|
+
|
|
58
|
+
zsh.script = ({
|
|
59
|
+
command
|
|
60
|
+
}) => `#compdef ${command}
|
|
61
|
+
|
|
62
|
+
_${command}() {
|
|
63
|
+
eval "$(AUTOCOMPLETE=zsh AUTOCOMPLETE_CURRENT=$CURRENT ${command} "\${words[@]}")"
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
_${command}`;
|
|
67
|
+
|
|
68
|
+
export default zsh;
|
package/lib/index.js
CHANGED