@trenskow/arguments-parser 0.3.121 → 0.3.122
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.
|
@@ -17,23 +17,73 @@ import {
|
|
|
17
17
|
|
|
18
18
|
import caseit from '@trenskow/caseit';
|
|
19
19
|
|
|
20
|
-
import buildIns from './build-ins/index.js';
|
|
21
|
-
|
|
22
20
|
import zsh from './zsh.js';
|
|
23
21
|
|
|
24
22
|
const supported = {
|
|
25
23
|
zsh
|
|
26
24
|
};
|
|
27
25
|
|
|
28
|
-
const argumentsParser = (
|
|
26
|
+
const argumentsParser = (shell) => {
|
|
27
|
+
|
|
28
|
+
if (!shell) return;
|
|
29
|
+
|
|
30
|
+
shell = supported[shell];
|
|
31
|
+
|
|
32
|
+
if (!shell) {
|
|
33
|
+
process.stderr.write(`Unsupported shell: ${shell}\n`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const normalize = (items) => items
|
|
38
|
+
.map((item) => {
|
|
39
|
+
|
|
40
|
+
if (typeof item === 'string') {
|
|
41
|
+
return {
|
|
42
|
+
type: 'option',
|
|
43
|
+
argument: item
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return item;
|
|
48
|
+
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const filter = (items, current) => {
|
|
52
|
+
return normalize(items)
|
|
53
|
+
.filter((item) => {
|
|
54
|
+
switch (item.type) {
|
|
55
|
+
case 'option':
|
|
56
|
+
// fall through
|
|
57
|
+
case 'command':
|
|
58
|
+
return item.argument !== current && item.argument.startsWith(current);
|
|
59
|
+
default:
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const output = (items) => shell(
|
|
66
|
+
normalize(items)
|
|
67
|
+
.reduce((grouped, item) => {
|
|
68
|
+
|
|
69
|
+
grouped[item.type] = grouped[item.type] || [];
|
|
70
|
+
|
|
71
|
+
switch (item.type) {
|
|
72
|
+
case 'option':
|
|
73
|
+
// fall through
|
|
74
|
+
case 'command':
|
|
75
|
+
grouped[item.type].push(item);
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
}
|
|
29
79
|
|
|
30
|
-
|
|
80
|
+
return grouped;
|
|
31
81
|
|
|
32
|
-
|
|
82
|
+
}, {}));
|
|
33
83
|
|
|
34
84
|
const argumentsParser = (
|
|
35
85
|
{
|
|
36
|
-
args = process.argv.slice(
|
|
86
|
+
args = process.argv.slice(shell.argsOffset || 2),
|
|
37
87
|
argvLevel = 0,
|
|
38
88
|
placeholder = '<>',
|
|
39
89
|
command,
|
|
@@ -90,7 +140,8 @@ const argumentsParser = (output) => {
|
|
|
90
140
|
return output(Object.keys(commands)
|
|
91
141
|
.filter((command) => command.startsWith(tool))
|
|
92
142
|
.map((command) => ({
|
|
93
|
-
|
|
143
|
+
type: 'command',
|
|
144
|
+
argument: caseit(command, 'kebab'),
|
|
94
145
|
description: commands[command].description
|
|
95
146
|
})));
|
|
96
147
|
|
|
@@ -100,8 +151,7 @@ const argumentsParser = (output) => {
|
|
|
100
151
|
autocomplete
|
|
101
152
|
}, command) => {
|
|
102
153
|
|
|
103
|
-
const available = (await autocomplete?.(args[0] || '') || [])
|
|
104
|
-
.filter((item) => item !== args[0] && item.startsWith(args[0] || ''));
|
|
154
|
+
const available = filter(await autocomplete?.(args[0] || '') || []);
|
|
105
155
|
|
|
106
156
|
if (available.length) {
|
|
107
157
|
return output(available);
|
|
@@ -146,7 +196,9 @@ const argumentsParser = (output) => {
|
|
|
146
196
|
|
|
147
197
|
const {
|
|
148
198
|
variadic,
|
|
149
|
-
autocomplete =
|
|
199
|
+
autocomplete = () => [{
|
|
200
|
+
type: 'files'
|
|
201
|
+
}]
|
|
150
202
|
} = options.validationOptions;
|
|
151
203
|
|
|
152
204
|
const allKeyPaths = keyPaths(options.schema)
|
|
@@ -172,17 +224,19 @@ const argumentsParser = (output) => {
|
|
|
172
224
|
if (schemas[idx].enum) {
|
|
173
225
|
return Object.keys(schemas[idx].enum)
|
|
174
226
|
.filter((item) => caseit(key, 'kebab') !== item && item.startsWith(current))
|
|
175
|
-
.map((item) =>
|
|
227
|
+
.map((item) => ({
|
|
228
|
+
type: 'option',
|
|
229
|
+
argument: caseit(item, 'kebab')
|
|
230
|
+
}));
|
|
176
231
|
}
|
|
177
232
|
|
|
178
233
|
if (schemas[idx].type === String && !schemas[idx].autocomplete) {
|
|
179
|
-
return
|
|
180
|
-
|
|
181
|
-
|
|
234
|
+
return [{
|
|
235
|
+
type: 'files'
|
|
236
|
+
}];
|
|
182
237
|
}
|
|
183
238
|
|
|
184
|
-
return (await schemas[idx].autocomplete?.(current) || [])
|
|
185
|
-
.filter((item) => key !== item && item.startsWith(current));
|
|
239
|
+
return filter(await schemas[idx].autocomplete?.(current) || []);
|
|
186
240
|
|
|
187
241
|
} else {
|
|
188
242
|
|
|
@@ -193,8 +247,7 @@ const argumentsParser = (output) => {
|
|
|
193
247
|
if (!current.startsWith('-')) {
|
|
194
248
|
if (variadic === 'allow') {
|
|
195
249
|
items = items.concat(
|
|
196
|
-
(await autocomplete?.(current) || [])
|
|
197
|
-
.filter((item) => current !== item && item.startsWith(current)));
|
|
250
|
+
filter(await autocomplete?.(current) || []));
|
|
198
251
|
}
|
|
199
252
|
}
|
|
200
253
|
|
|
@@ -203,9 +256,9 @@ const argumentsParser = (output) => {
|
|
|
203
256
|
.filter((keyPath) => !spent.includes(keyPath))
|
|
204
257
|
.filter((keyPath) => key !== keyPath && keyPath.startsWith(key) && keyPaths(options.schema).get(keyPath).short)
|
|
205
258
|
.map((keyPath) => ({
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
259
|
+
type: 'option',
|
|
260
|
+
argument: `-${caseit(keyPaths(options.schema).get(keyPath).short, 'kebab')}`,
|
|
261
|
+
description: keyPaths(options.schema).get(keyPath).description
|
|
209
262
|
})));
|
|
210
263
|
|
|
211
264
|
}
|
|
@@ -215,9 +268,9 @@ const argumentsParser = (output) => {
|
|
|
215
268
|
.filter((keyPath) => !spent.includes(keyPath))
|
|
216
269
|
.filter((keyPath) => key !== keyPath && keyPath.startsWith(key))
|
|
217
270
|
.map((keyPath) => ({
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
271
|
+
type: 'option',
|
|
272
|
+
argument: `--${caseit(keyPath, 'kebab')}`,
|
|
273
|
+
description: keyPaths(options.schema).get(keyPath).description
|
|
221
274
|
})));
|
|
222
275
|
|
|
223
276
|
return items;
|
|
@@ -278,4 +331,3 @@ const argumentsParser = (output) => {
|
|
|
278
331
|
};
|
|
279
332
|
|
|
280
333
|
export default argumentsParser;
|
|
281
|
-
export * as buildIns from './build-ins/index.js';
|
package/lib/autocomplete/zsh.js
CHANGED
|
@@ -6,29 +6,45 @@
|
|
|
6
6
|
// See license in LICENSE.
|
|
7
7
|
//
|
|
8
8
|
|
|
9
|
-
import caseit from '@trenskow/caseit';
|
|
10
|
-
|
|
11
9
|
const zsh = (items) => {
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
const keys = Object.keys(items);
|
|
12
|
+
|
|
13
|
+
if (keys.length === 0) {
|
|
14
14
|
process.exit(0);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
keys
|
|
18
|
+
.forEach((key) => {
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
switch (key) {
|
|
21
|
+
case 'command':
|
|
22
|
+
// fall through
|
|
23
|
+
case 'option':
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
process.stdout.write(` "${command}"\n`);
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
25
|
+
process.stdout.write(`_describe '${key}s' '(\n`);
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
items[key]
|
|
28
|
+
.forEach((item) => {
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
const parts = [item.argument, item.description]
|
|
31
|
+
.filter((part) => part)
|
|
32
|
+
.map((part) => ['"', '\\', '$', '`']
|
|
33
|
+
.reduce((part, char) => part.replaceAll(char, `\\${char}`), part));
|
|
34
|
+
|
|
35
|
+
process.stdout.write(` "${parts.join(':')}"\n`);
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
process.stdout.write(')\'\n');
|
|
40
|
+
|
|
41
|
+
break;
|
|
42
|
+
case 'files':
|
|
43
|
+
process.stdout.write('_files\n');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
});
|
|
32
48
|
|
|
33
49
|
process.exit(0);
|
|
34
50
|
|
package/lib/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// files.js
|
|
3
|
-
// @trenskow/arguments-parser
|
|
4
|
-
//
|
|
5
|
-
// Created by Kristian Trenskow on 2026/08/02
|
|
6
|
-
// See license in LICENSE.
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
join,
|
|
11
|
-
resolve
|
|
12
|
-
} from 'path';
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
stat,
|
|
16
|
-
readdir
|
|
17
|
-
} from 'fs/promises';
|
|
18
|
-
|
|
19
|
-
import parallel from '@trenskow/parallel';
|
|
20
|
-
|
|
21
|
-
const safeStat = async (path) => {
|
|
22
|
-
try {
|
|
23
|
-
return await stat(path);
|
|
24
|
-
} catch (_) {
|
|
25
|
-
return undefined;
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export default async (current = '') => {
|
|
30
|
-
|
|
31
|
-
if (current === '') {
|
|
32
|
-
return await parallel(((await readdir(process.cwd()))
|
|
33
|
-
.filter((file) => !file.startsWith('.')))
|
|
34
|
-
.map(async (file) => `${file}${(await safeStat(resolve(process.cwd(), file)))?.isDirectory() ? '/' : ''}`));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const stat = await safeStat(
|
|
38
|
-
resolve(
|
|
39
|
-
process.cwd(),
|
|
40
|
-
current));
|
|
41
|
-
|
|
42
|
-
if (stat?.isDirectory()) {
|
|
43
|
-
|
|
44
|
-
current = current.endsWith('/') ? current : `${current}/`;
|
|
45
|
-
|
|
46
|
-
return (await parallel((await readdir(
|
|
47
|
-
resolve(
|
|
48
|
-
process.cwd(),
|
|
49
|
-
current)))
|
|
50
|
-
.map(async (file) => {
|
|
51
|
-
|
|
52
|
-
if ((await safeStat(resolve(process.cwd(), current, file)))?.isDirectory()) {
|
|
53
|
-
return `${file}/`;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return file;
|
|
57
|
-
|
|
58
|
-
})))
|
|
59
|
-
.filter((file) => !file.startsWith('.'))
|
|
60
|
-
.map((file) => `${current}${file}`);
|
|
61
|
-
|
|
62
|
-
} else if (stat) {
|
|
63
|
-
return [];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return await parallel(((await readdir(join(current, '../')))
|
|
67
|
-
.filter((file) => !file.startsWith('.'))
|
|
68
|
-
.map((file) => join(current, '../', file)))
|
|
69
|
-
.map(async (file) => (await safeStat(file))?.isDirectory() ? `${file}/` : file));
|
|
70
|
-
|
|
71
|
-
};
|