@boneskull/bargs 1.0.0 → 3.0.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 +305 -299
- package/dist/bargs.cjs +464 -142
- package/dist/bargs.cjs.map +1 -1
- package/dist/bargs.d.cts +35 -17
- package/dist/bargs.d.cts.map +1 -1
- package/dist/bargs.d.ts +35 -17
- package/dist/bargs.d.ts.map +1 -1
- package/dist/bargs.js +462 -142
- package/dist/bargs.js.map +1 -1
- package/dist/help.cjs +1 -2
- package/dist/help.cjs.map +1 -1
- package/dist/help.d.cts +20 -3
- package/dist/help.d.cts.map +1 -1
- package/dist/help.d.ts +20 -3
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +1 -2
- package/dist/help.js.map +1 -1
- package/dist/index.cjs +27 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -78
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +15 -78
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -30
- package/dist/index.js.map +1 -1
- package/dist/opt.cjs +147 -80
- package/dist/opt.cjs.map +1 -1
- package/dist/opt.d.cts +88 -77
- package/dist/opt.d.cts.map +1 -1
- package/dist/opt.d.ts +88 -77
- package/dist/opt.d.ts.map +1 -1
- package/dist/opt.js +146 -79
- package/dist/opt.js.map +1 -1
- package/dist/parser.cjs +3 -230
- package/dist/parser.cjs.map +1 -1
- package/dist/parser.d.cts +3 -51
- package/dist/parser.d.cts.map +1 -1
- package/dist/parser.d.ts +3 -51
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +2 -223
- package/dist/parser.js.map +1 -1
- package/dist/types.cjs +1 -3
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +110 -122
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +110 -122
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -3
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/dist/validate.cjs +0 -463
- package/dist/validate.cjs.map +0 -1
- package/dist/validate.d.cts +0 -28
- package/dist/validate.d.cts.map +0 -1
- package/dist/validate.d.ts +0 -28
- package/dist/validate.d.ts.map +0 -1
- package/dist/validate.js +0 -459
- package/dist/validate.js.map +0 -1
package/dist/bargs.cjs
CHANGED
|
@@ -1,187 +1,509 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Core bargs
|
|
3
|
+
* Core bargs API using parser combinator pattern.
|
|
4
4
|
*
|
|
5
|
-
* Provides `bargs()`
|
|
6
|
-
*
|
|
7
|
-
* `--version` flags, argument parsing, and handler invocation. Supports both
|
|
8
|
-
* simple CLIs with options/positionals and command-based CLIs with
|
|
9
|
-
* subcommands.
|
|
5
|
+
* Provides `bargs.create()` for building CLIs with a fluent API, plus
|
|
6
|
+
* combinator functions like `pipe()`, `map()`, and `handle()`.
|
|
10
7
|
*
|
|
11
8
|
* @packageDocumentation
|
|
12
9
|
*/
|
|
13
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.bargs =
|
|
15
|
-
exports.
|
|
11
|
+
exports.bargs = void 0;
|
|
12
|
+
exports.handle = handle;
|
|
13
|
+
exports.map = map;
|
|
14
|
+
exports.merge = merge;
|
|
16
15
|
const errors_js_1 = require("./errors.cjs");
|
|
17
16
|
const help_js_1 = require("./help.cjs");
|
|
18
17
|
const parser_js_1 = require("./parser.cjs");
|
|
19
18
|
const theme_js_1 = require("./theme.cjs");
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
function handle(parserOrFn, maybeFn) {
|
|
20
|
+
// Direct form: handle(parser, fn) returns Command
|
|
21
|
+
// Check for Parser first since CallableParser is also a function
|
|
22
|
+
if (isParser(parserOrFn)) {
|
|
23
|
+
const parser = parserOrFn;
|
|
24
|
+
const parserWithTransform = parser;
|
|
25
|
+
const fn = maybeFn;
|
|
26
|
+
const cmd = {
|
|
27
|
+
__brand: 'Command',
|
|
28
|
+
__optionsSchema: parser.__optionsSchema,
|
|
29
|
+
__positionalsSchema: parser.__positionalsSchema,
|
|
30
|
+
handler: fn,
|
|
31
|
+
};
|
|
32
|
+
// Preserve transforms from the parser
|
|
33
|
+
if (parserWithTransform.__transform) {
|
|
34
|
+
cmd.__transform = parserWithTransform.__transform;
|
|
35
|
+
}
|
|
36
|
+
return cmd;
|
|
37
|
+
}
|
|
38
|
+
// Curried form: handle(fn) returns (parser) => Command
|
|
39
|
+
const fn = parserOrFn;
|
|
40
|
+
return (parser) => {
|
|
41
|
+
const parserWithTransform = parser;
|
|
42
|
+
const cmd = {
|
|
43
|
+
__brand: 'Command',
|
|
44
|
+
__optionsSchema: parser.__optionsSchema,
|
|
45
|
+
__positionalsSchema: parser.__positionalsSchema,
|
|
46
|
+
handler: fn,
|
|
47
|
+
};
|
|
48
|
+
// Preserve transforms from the parser
|
|
49
|
+
if (parserWithTransform.__transform) {
|
|
50
|
+
cmd.__transform = parserWithTransform.__transform;
|
|
51
|
+
}
|
|
52
|
+
return cmd;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function map(parserOrFn, maybeFn) {
|
|
56
|
+
// Direct form: map(parser, fn) returns Parser
|
|
57
|
+
// Check for Parser first since CallableParser is also a function
|
|
58
|
+
if (isParser(parserOrFn)) {
|
|
59
|
+
const parser = parserOrFn;
|
|
60
|
+
const fn = maybeFn;
|
|
61
|
+
return {
|
|
62
|
+
...parser,
|
|
63
|
+
__brand: 'Parser',
|
|
64
|
+
__positionals: [],
|
|
65
|
+
__transform: fn,
|
|
66
|
+
__values: {},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// Curried form: map(fn) returns (parser) => Parser
|
|
70
|
+
const fn = parserOrFn;
|
|
71
|
+
return (parser) => {
|
|
72
|
+
return {
|
|
73
|
+
...parser,
|
|
74
|
+
__brand: 'Parser',
|
|
75
|
+
__positionals: [],
|
|
76
|
+
__transform: fn,
|
|
77
|
+
__values: {},
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function merge(...parsers) {
|
|
82
|
+
if (parsers.length === 0) {
|
|
83
|
+
throw new errors_js_1.BargsError('merge() requires at least one parser');
|
|
31
84
|
}
|
|
32
|
-
|
|
33
|
-
|
|
85
|
+
// Start with the first parser and fold the rest in
|
|
86
|
+
let result = parsers[0];
|
|
87
|
+
for (let i = 1; i < parsers.length; i++) {
|
|
88
|
+
const next = parsers[i];
|
|
89
|
+
// Merge options schemas
|
|
90
|
+
const mergedOptions = {
|
|
91
|
+
...result.__optionsSchema,
|
|
92
|
+
...next.__optionsSchema,
|
|
93
|
+
};
|
|
94
|
+
// Merge positionals schemas
|
|
95
|
+
const mergedPositionals = [
|
|
96
|
+
...result.__positionalsSchema,
|
|
97
|
+
...next.__positionalsSchema,
|
|
98
|
+
];
|
|
99
|
+
const resultWithTransform = result;
|
|
100
|
+
const nextWithTransform = next;
|
|
101
|
+
let mergedTransform;
|
|
102
|
+
if (resultWithTransform.__transform && nextWithTransform.__transform) {
|
|
103
|
+
// Chain transforms
|
|
104
|
+
const t1 = resultWithTransform.__transform;
|
|
105
|
+
const t2 = nextWithTransform.__transform;
|
|
106
|
+
mergedTransform = (r) => {
|
|
107
|
+
const r1 = t1(r);
|
|
108
|
+
if (r1 instanceof Promise) {
|
|
109
|
+
return r1.then(t2);
|
|
110
|
+
}
|
|
111
|
+
return t2(r1);
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
mergedTransform =
|
|
116
|
+
nextWithTransform.__transform ?? resultWithTransform.__transform;
|
|
117
|
+
}
|
|
118
|
+
result = {
|
|
119
|
+
__brand: 'Parser',
|
|
120
|
+
__optionsSchema: mergedOptions,
|
|
121
|
+
__positionals: [],
|
|
122
|
+
__positionalsSchema: mergedPositionals,
|
|
123
|
+
__values: {},
|
|
124
|
+
};
|
|
125
|
+
if (mergedTransform) {
|
|
126
|
+
result.__transform =
|
|
127
|
+
mergedTransform;
|
|
128
|
+
}
|
|
34
129
|
}
|
|
35
|
-
|
|
36
|
-
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
133
|
+
// CLI BUILDER
|
|
134
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
135
|
+
/**
|
|
136
|
+
* Create a new CLI.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
*
|
|
140
|
+
* ```typescript
|
|
141
|
+
* const cli = await bargs
|
|
142
|
+
* .create('my-app', { version: '1.0.0' })
|
|
143
|
+
* .globals(
|
|
144
|
+
* map(opt.options({ verbose: opt.boolean() }), ({ values }) => ({
|
|
145
|
+
* values: { ...values, ts: Date.now() },
|
|
146
|
+
* positionals: [] as const,
|
|
147
|
+
* })),
|
|
148
|
+
* )
|
|
149
|
+
* .command(
|
|
150
|
+
* 'greet',
|
|
151
|
+
* pos.positionals(pos.string({ name: 'name', required: true })),
|
|
152
|
+
* ({ positionals }) => console.log(`Hello, ${positionals[0]}!`),
|
|
153
|
+
* )
|
|
154
|
+
* .parseAsync();
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
const create = (name, options = {}) => {
|
|
158
|
+
const theme = options.theme ? (0, theme_js_1.getTheme)(options.theme) : theme_js_1.defaultTheme;
|
|
159
|
+
return createCliBuilder({
|
|
160
|
+
commands: new Map(),
|
|
161
|
+
name,
|
|
162
|
+
options,
|
|
163
|
+
theme,
|
|
164
|
+
});
|
|
37
165
|
};
|
|
38
166
|
/**
|
|
39
|
-
* Check if
|
|
167
|
+
* Check if something is a Command (has __brand: 'Command').
|
|
40
168
|
*/
|
|
41
|
-
const
|
|
42
|
-
if (
|
|
169
|
+
const isCommand = (x) => {
|
|
170
|
+
if (x === null || x === undefined) {
|
|
43
171
|
return false;
|
|
44
172
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
// Check if any option has 'V' as an alias
|
|
49
|
-
return Object.values(options).some((opt) => opt.aliases?.includes('V'));
|
|
173
|
+
const obj = x;
|
|
174
|
+
return '__brand' in obj && obj.__brand === 'Command';
|
|
50
175
|
};
|
|
51
176
|
/**
|
|
52
|
-
*
|
|
177
|
+
* Create a CLI builder.
|
|
53
178
|
*/
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
179
|
+
const createCliBuilder = (state) => {
|
|
180
|
+
return {
|
|
181
|
+
// Overloaded command(): accepts either (name, Command, desc?) or (name, Parser, handler, desc?)
|
|
182
|
+
command(name, cmdOrParser, handlerOrDesc, maybeDesc) {
|
|
183
|
+
let cmd;
|
|
184
|
+
let description;
|
|
185
|
+
if (isCommand(cmdOrParser)) {
|
|
186
|
+
// Form 1: command(name, Command, description?)
|
|
187
|
+
cmd = cmdOrParser;
|
|
188
|
+
description = handlerOrDesc;
|
|
189
|
+
}
|
|
190
|
+
else if (isParser(cmdOrParser)) {
|
|
191
|
+
// Form 2: command(name, Parser, handler, description?)
|
|
192
|
+
const parser = cmdOrParser;
|
|
193
|
+
const handler = handlerOrDesc;
|
|
194
|
+
description = maybeDesc;
|
|
195
|
+
// Create Command from Parser + handler
|
|
196
|
+
const parserWithTransform = parser;
|
|
197
|
+
const newCmd = {
|
|
198
|
+
__brand: 'Command',
|
|
199
|
+
__optionsSchema: parser.__optionsSchema,
|
|
200
|
+
__positionalsSchema: parser.__positionalsSchema,
|
|
201
|
+
handler,
|
|
202
|
+
};
|
|
203
|
+
// Preserve transforms from the parser
|
|
204
|
+
if (parserWithTransform.__transform) {
|
|
205
|
+
newCmd.__transform = parserWithTransform.__transform;
|
|
206
|
+
}
|
|
207
|
+
cmd = newCmd;
|
|
65
208
|
}
|
|
66
209
|
else {
|
|
67
|
-
|
|
210
|
+
throw new Error('command() requires a Command or Parser as second argument');
|
|
211
|
+
}
|
|
212
|
+
state.commands.set(name, { cmd, description });
|
|
213
|
+
return this;
|
|
214
|
+
},
|
|
215
|
+
// Overloaded defaultCommand(): accepts name, Command, or (Parser, handler)
|
|
216
|
+
defaultCommand(nameOrCmdOrParser, maybeHandler) {
|
|
217
|
+
// Form 1: defaultCommand(name) - just set the name
|
|
218
|
+
if (typeof nameOrCmdOrParser === 'string') {
|
|
219
|
+
return createCliBuilder({
|
|
220
|
+
...state,
|
|
221
|
+
defaultCommandName: nameOrCmdOrParser,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
// Generate a unique name for the default command
|
|
225
|
+
const defaultName = '__default__';
|
|
226
|
+
if (isCommand(nameOrCmdOrParser)) {
|
|
227
|
+
// Form 2: defaultCommand(Command)
|
|
228
|
+
state.commands.set(defaultName, {
|
|
229
|
+
cmd: nameOrCmdOrParser,
|
|
230
|
+
description: undefined,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
else if (isParser(nameOrCmdOrParser)) {
|
|
234
|
+
// Form 3: defaultCommand(Parser, handler)
|
|
235
|
+
const parser = nameOrCmdOrParser;
|
|
236
|
+
const handler = maybeHandler;
|
|
237
|
+
const parserWithTransform = parser;
|
|
238
|
+
const newCmd = {
|
|
239
|
+
__brand: 'Command',
|
|
240
|
+
__optionsSchema: parser.__optionsSchema,
|
|
241
|
+
__positionalsSchema: parser.__positionalsSchema,
|
|
242
|
+
handler,
|
|
243
|
+
};
|
|
244
|
+
// Preserve transforms from the parser
|
|
245
|
+
if (parserWithTransform.__transform) {
|
|
246
|
+
newCmd.__transform = parserWithTransform.__transform;
|
|
247
|
+
}
|
|
248
|
+
state.commands.set(defaultName, {
|
|
249
|
+
cmd: newCmd,
|
|
250
|
+
description: undefined,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
throw new Error('defaultCommand() requires a name, Command, or Parser');
|
|
255
|
+
}
|
|
256
|
+
return createCliBuilder({
|
|
257
|
+
...state,
|
|
258
|
+
defaultCommandName: defaultName,
|
|
259
|
+
});
|
|
260
|
+
},
|
|
261
|
+
globals(parser) {
|
|
262
|
+
return createCliBuilder({
|
|
263
|
+
...state,
|
|
264
|
+
globalParser: parser,
|
|
265
|
+
});
|
|
266
|
+
},
|
|
267
|
+
parse(args = process.argv.slice(2)) {
|
|
268
|
+
const result = parseCore(state, args, false);
|
|
269
|
+
if (result instanceof Promise) {
|
|
270
|
+
throw new errors_js_1.BargsError('Async transform or handler detected. Use parseAsync() instead of parse().');
|
|
271
|
+
}
|
|
272
|
+
return result;
|
|
273
|
+
},
|
|
274
|
+
async parseAsync(args = process.argv.slice(2)) {
|
|
275
|
+
return parseCore(state, args, true);
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* Core parse logic shared between parse() and parseAsync().
|
|
281
|
+
*/
|
|
282
|
+
const parseCore = (state, args, allowAsync) => {
|
|
283
|
+
const { commands, options, theme } = state;
|
|
284
|
+
// Handle --help
|
|
285
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
286
|
+
// Check for command-specific help
|
|
287
|
+
const helpIndex = args.findIndex((a) => a === '--help' || a === '-h');
|
|
288
|
+
const commandIndex = args.findIndex((a) => !a.startsWith('-'));
|
|
289
|
+
if (commandIndex >= 0 && commandIndex < helpIndex && commands.size > 0) {
|
|
290
|
+
const commandName = args[commandIndex];
|
|
291
|
+
if (commands.has(commandName)) {
|
|
292
|
+
console.log(generateCommandHelpNew(state, commandName, theme));
|
|
293
|
+
process.exit(0);
|
|
68
294
|
}
|
|
69
295
|
}
|
|
70
|
-
|
|
71
|
-
console.log((0, help_js_1.generateHelp)(config, theme));
|
|
72
|
-
}
|
|
296
|
+
console.log(generateHelpNew(state, theme));
|
|
73
297
|
process.exit(0);
|
|
74
298
|
}
|
|
75
|
-
// Handle --version
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
console.log(config.version);
|
|
299
|
+
// Handle --version
|
|
300
|
+
if (args.includes('--version') && options.version) {
|
|
301
|
+
console.log(options.version);
|
|
79
302
|
process.exit(0);
|
|
80
303
|
}
|
|
81
|
-
|
|
304
|
+
// If we have commands, dispatch to the appropriate one
|
|
305
|
+
if (commands.size > 0) {
|
|
306
|
+
return runWithCommands(state, args, allowAsync);
|
|
307
|
+
}
|
|
308
|
+
// Simple CLI (no commands)
|
|
309
|
+
return runSimple(state, args, allowAsync);
|
|
82
310
|
};
|
|
83
311
|
/**
|
|
84
|
-
*
|
|
312
|
+
* Generate command-specific help.
|
|
85
313
|
*/
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
console.log((0, help_js_1.generateHelp)(config, theme));
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
console.log((0, help_js_1.generateHelp)(config, theme));
|
|
94
|
-
}
|
|
95
|
-
process.exit(1);
|
|
314
|
+
const generateCommandHelpNew = (state, commandName, theme) => {
|
|
315
|
+
const commandEntry = state.commands.get(commandName);
|
|
316
|
+
if (!commandEntry) {
|
|
317
|
+
return `Unknown command: ${commandName}`;
|
|
96
318
|
}
|
|
97
|
-
|
|
319
|
+
// TODO: Implement proper command help generation
|
|
320
|
+
const config = {
|
|
321
|
+
commands: {
|
|
322
|
+
[commandName]: {
|
|
323
|
+
description: commandEntry.description ?? '',
|
|
324
|
+
options: commandEntry.cmd.__optionsSchema,
|
|
325
|
+
positionals: commandEntry.cmd.__positionalsSchema,
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
name: state.name,
|
|
329
|
+
};
|
|
330
|
+
return (0, help_js_1.generateCommandHelp)(config, commandName, theme);
|
|
98
331
|
};
|
|
99
332
|
/**
|
|
100
|
-
*
|
|
101
|
-
* handler returns a thenable.
|
|
333
|
+
* Generate help for the new CLI structure.
|
|
102
334
|
*/
|
|
103
|
-
|
|
104
|
-
//
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
335
|
+
const generateHelpNew = (state, theme) => {
|
|
336
|
+
// TODO: Implement proper help generation for new structure
|
|
337
|
+
// For now, delegate to existing help generator with minimal config
|
|
338
|
+
const config = {
|
|
339
|
+
commands: Object.fromEntries(Array.from(state.commands.entries()).map(([name, { description }]) => [
|
|
340
|
+
name,
|
|
341
|
+
{ description: description ?? '' },
|
|
342
|
+
])),
|
|
343
|
+
description: state.options.description,
|
|
344
|
+
name: state.name,
|
|
345
|
+
options: state.globalParser?.__optionsSchema,
|
|
346
|
+
version: state.options.version,
|
|
347
|
+
};
|
|
348
|
+
return (0, help_js_1.generateHelp)(config, theme);
|
|
349
|
+
};
|
|
350
|
+
/**
|
|
351
|
+
* Check if something is a Parser (has __brand: 'Parser'). Parsers can be either
|
|
352
|
+
* objects or functions (CallableParser).
|
|
353
|
+
*/
|
|
354
|
+
const isParser = (x) => {
|
|
355
|
+
if (x === null || x === undefined) {
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
// Handle both plain objects and functions with Parser properties
|
|
359
|
+
const obj = x;
|
|
360
|
+
return '__brand' in obj && obj.__brand === 'Parser';
|
|
361
|
+
};
|
|
362
|
+
/**
|
|
363
|
+
* Run a simple CLI (no commands).
|
|
364
|
+
*/
|
|
365
|
+
const runSimple = (state, args, allowAsync) => {
|
|
366
|
+
const { globalParser } = state;
|
|
367
|
+
const optionsSchema = globalParser?.__optionsSchema ?? {};
|
|
368
|
+
const positionalsSchema = globalParser?.__positionalsSchema ?? [];
|
|
369
|
+
const parsed = (0, parser_js_1.parseSimple)({
|
|
370
|
+
args,
|
|
371
|
+
options: optionsSchema,
|
|
372
|
+
positionals: positionalsSchema,
|
|
373
|
+
});
|
|
374
|
+
let result = {
|
|
375
|
+
positionals: parsed.positionals,
|
|
376
|
+
values: parsed.values,
|
|
377
|
+
};
|
|
378
|
+
// Apply transforms if any
|
|
379
|
+
const transform = globalParser?.__transform;
|
|
380
|
+
if (transform) {
|
|
381
|
+
const transformed = transform(result);
|
|
382
|
+
if (transformed instanceof Promise) {
|
|
383
|
+
if (!allowAsync) {
|
|
384
|
+
throw new errors_js_1.BargsError('Async transform detected. Use parseAsync() instead of parse().');
|
|
135
385
|
}
|
|
136
|
-
return
|
|
386
|
+
return transformed.then((r) => ({
|
|
387
|
+
...r,
|
|
388
|
+
command: undefined,
|
|
389
|
+
}));
|
|
137
390
|
}
|
|
391
|
+
result = transformed;
|
|
138
392
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
393
|
+
return { ...result, command: undefined };
|
|
394
|
+
};
|
|
395
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
396
|
+
// PUBLIC API
|
|
397
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
143
398
|
/**
|
|
144
|
-
*
|
|
145
|
-
* supporting async handlers.
|
|
399
|
+
* Run a CLI with commands.
|
|
146
400
|
*/
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
(
|
|
150
|
-
const
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
//
|
|
157
|
-
|
|
158
|
-
|
|
401
|
+
const runWithCommands = (state, args, allowAsync) => {
|
|
402
|
+
const { commands, defaultCommandName, globalParser } = state;
|
|
403
|
+
// Find command name (first non-flag argument)
|
|
404
|
+
const commandIndex = args.findIndex((arg) => !arg.startsWith('-'));
|
|
405
|
+
const potentialCommandName = commandIndex >= 0 ? args[commandIndex] : undefined;
|
|
406
|
+
// Check if it's a known command
|
|
407
|
+
let commandName;
|
|
408
|
+
let remainingArgs;
|
|
409
|
+
if (potentialCommandName && commands.has(potentialCommandName)) {
|
|
410
|
+
// It's a known command - remove it from args
|
|
411
|
+
commandName = potentialCommandName;
|
|
412
|
+
remainingArgs = [
|
|
413
|
+
...args.slice(0, commandIndex),
|
|
414
|
+
...args.slice(commandIndex + 1),
|
|
415
|
+
];
|
|
416
|
+
}
|
|
417
|
+
else if (defaultCommandName) {
|
|
418
|
+
// Not a known command, but we have a default - use all args as positionals/options
|
|
419
|
+
commandName = defaultCommandName;
|
|
420
|
+
remainingArgs = args;
|
|
421
|
+
}
|
|
422
|
+
else if (potentialCommandName) {
|
|
423
|
+
// Not a known command and no default
|
|
424
|
+
throw new errors_js_1.HelpError(`Unknown command: ${potentialCommandName}`);
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
// No command and no default
|
|
428
|
+
throw new errors_js_1.HelpError('No command specified.');
|
|
429
|
+
}
|
|
430
|
+
const commandEntry = commands.get(commandName);
|
|
431
|
+
if (!commandEntry) {
|
|
432
|
+
throw new errors_js_1.HelpError(`Unknown command: ${commandName}`);
|
|
433
|
+
}
|
|
434
|
+
const { cmd } = commandEntry;
|
|
435
|
+
// Merge global and command options schemas
|
|
436
|
+
const globalOptionsSchema = globalParser?.__optionsSchema ?? {};
|
|
437
|
+
const commandOptionsSchema = cmd.__optionsSchema;
|
|
438
|
+
const mergedOptionsSchema = {
|
|
439
|
+
...globalOptionsSchema,
|
|
440
|
+
...commandOptionsSchema,
|
|
441
|
+
};
|
|
442
|
+
const commandPositionalsSchema = cmd.__positionalsSchema;
|
|
443
|
+
// Parse with merged schema
|
|
444
|
+
const parsed = (0, parser_js_1.parseSimple)({
|
|
445
|
+
args: remainingArgs,
|
|
446
|
+
options: mergedOptionsSchema,
|
|
447
|
+
positionals: commandPositionalsSchema,
|
|
448
|
+
});
|
|
449
|
+
let result = {
|
|
450
|
+
positionals: parsed.positionals,
|
|
451
|
+
values: parsed.values,
|
|
452
|
+
};
|
|
453
|
+
// Helper to check for async and throw if not allowed
|
|
454
|
+
const checkAsync = (value, context) => {
|
|
455
|
+
if (value instanceof Promise && !allowAsync) {
|
|
456
|
+
throw new errors_js_1.BargsError(`Async ${context} detected. Use parseAsync() instead of parse().`);
|
|
159
457
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const transformed =
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
};
|
|
176
|
-
// Call handler if provided (async)
|
|
177
|
-
if (config.handler) {
|
|
178
|
-
await (0, parser_js_1.runHandler)(config.handler, result);
|
|
458
|
+
};
|
|
459
|
+
// Get transforms
|
|
460
|
+
const globalTransform = globalParser?.__transform;
|
|
461
|
+
const commandTransform = cmd?.__transform;
|
|
462
|
+
// Apply transforms and run handler
|
|
463
|
+
const applyTransformsAndHandle = () => {
|
|
464
|
+
// Apply global transforms first
|
|
465
|
+
if (globalTransform) {
|
|
466
|
+
const transformed = globalTransform(result);
|
|
467
|
+
checkAsync(transformed, 'global transform');
|
|
468
|
+
if (transformed instanceof Promise) {
|
|
469
|
+
return transformed.then((r) => {
|
|
470
|
+
result = r;
|
|
471
|
+
return continueWithCommandTransform();
|
|
472
|
+
});
|
|
179
473
|
}
|
|
180
|
-
|
|
474
|
+
result = transformed;
|
|
181
475
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
476
|
+
return continueWithCommandTransform();
|
|
477
|
+
};
|
|
478
|
+
const continueWithCommandTransform = () => {
|
|
479
|
+
// Apply command transforms
|
|
480
|
+
if (commandTransform) {
|
|
481
|
+
const transformed = commandTransform(result);
|
|
482
|
+
checkAsync(transformed, 'command transform');
|
|
483
|
+
if (transformed instanceof Promise) {
|
|
484
|
+
return transformed.then((r) => {
|
|
485
|
+
result = r;
|
|
486
|
+
return runHandler();
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
result = transformed;
|
|
490
|
+
}
|
|
491
|
+
return runHandler();
|
|
492
|
+
};
|
|
493
|
+
const runHandler = () => {
|
|
494
|
+
const handlerResult = cmd.handler(result);
|
|
495
|
+
checkAsync(handlerResult, 'handler');
|
|
496
|
+
if (handlerResult instanceof Promise) {
|
|
497
|
+
return handlerResult.then(() => ({ ...result, command: commandName }));
|
|
498
|
+
}
|
|
499
|
+
return { ...result, command: commandName };
|
|
500
|
+
};
|
|
501
|
+
return applyTransformsAndHandle();
|
|
502
|
+
};
|
|
503
|
+
/**
|
|
504
|
+
* Main bargs namespace.
|
|
505
|
+
*/
|
|
506
|
+
exports.bargs = {
|
|
507
|
+
create,
|
|
508
|
+
};
|
|
187
509
|
//# sourceMappingURL=bargs.js.map
|