@optique/core 1.0.0-dev.429 → 1.0.0-dev.432
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/dist/context.d.cts +20 -2
- package/dist/context.d.ts +20 -2
- package/dist/facade.cjs +284 -231
- package/dist/facade.d.cts +76 -184
- package/dist/facade.d.ts +76 -184
- package/dist/facade.js +284 -231
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/package.json +1 -1
package/dist/facade.cjs
CHANGED
|
@@ -11,51 +11,67 @@ const require_parser = require('./parser.cjs');
|
|
|
11
11
|
|
|
12
12
|
//#region src/facade.ts
|
|
13
13
|
/**
|
|
14
|
-
* Creates help parsers based on the
|
|
14
|
+
* Creates help parsers based on the sub-config.
|
|
15
15
|
*/
|
|
16
|
-
function createHelpParser(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
case "both": return {
|
|
29
|
-
helpCommand,
|
|
30
|
-
helpOption
|
|
31
|
-
};
|
|
16
|
+
function createHelpParser(commandConfig, optionConfig) {
|
|
17
|
+
let helpCommand = null;
|
|
18
|
+
let helpOption = null;
|
|
19
|
+
if (commandConfig) {
|
|
20
|
+
const names = commandConfig.names ?? ["help"];
|
|
21
|
+
const innerParser = require_modifiers.multiple(require_primitives.argument(require_valueparser.string({ metavar: "COMMAND" }), { description: require_message.message`Command name to show help for.` }));
|
|
22
|
+
const commandParsers = [];
|
|
23
|
+
for (let i = 0; i < names.length; i++) commandParsers.push(require_primitives.command(names[i], innerParser, {
|
|
24
|
+
description: require_message.message`Show help information.`,
|
|
25
|
+
hidden: i === 0 ? commandConfig.hidden : commandConfig.hidden === true ? true : true
|
|
26
|
+
}));
|
|
27
|
+
helpCommand = commandParsers.length === 1 ? commandParsers[0] : require_constructs.longestMatch(...commandParsers);
|
|
32
28
|
}
|
|
29
|
+
if (optionConfig) {
|
|
30
|
+
const names = optionConfig.names ?? ["--help"];
|
|
31
|
+
helpOption = require_primitives.flag(...names, {
|
|
32
|
+
description: require_message.message`Show help information.`,
|
|
33
|
+
hidden: optionConfig.hidden
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
helpCommand,
|
|
38
|
+
helpOption
|
|
39
|
+
};
|
|
33
40
|
}
|
|
34
41
|
/**
|
|
35
|
-
* Creates version parsers based on the
|
|
42
|
+
* Creates version parsers based on the sub-config.
|
|
36
43
|
*/
|
|
37
|
-
function createVersionParser(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
case "both": return {
|
|
50
|
-
versionCommand,
|
|
51
|
-
versionOption
|
|
52
|
-
};
|
|
44
|
+
function createVersionParser(commandConfig, optionConfig) {
|
|
45
|
+
let versionCommand = null;
|
|
46
|
+
let versionOption = null;
|
|
47
|
+
if (commandConfig) {
|
|
48
|
+
const names = commandConfig.names ?? ["version"];
|
|
49
|
+
const innerParser = require_constructs.object({});
|
|
50
|
+
const commandParsers = [];
|
|
51
|
+
for (let i = 0; i < names.length; i++) commandParsers.push(require_primitives.command(names[i], innerParser, {
|
|
52
|
+
description: require_message.message`Show version information.`,
|
|
53
|
+
hidden: i === 0 ? commandConfig.hidden : commandConfig.hidden === true ? true : true
|
|
54
|
+
}));
|
|
55
|
+
versionCommand = commandParsers.length === 1 ? commandParsers[0] : require_constructs.longestMatch(...commandParsers);
|
|
53
56
|
}
|
|
57
|
+
if (optionConfig) {
|
|
58
|
+
const names = optionConfig.names ?? ["--version"];
|
|
59
|
+
versionOption = require_primitives.flag(...names, {
|
|
60
|
+
description: require_message.message`Show version information.`,
|
|
61
|
+
hidden: optionConfig.hidden
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
versionCommand,
|
|
66
|
+
versionOption
|
|
67
|
+
};
|
|
54
68
|
}
|
|
55
69
|
/**
|
|
56
|
-
* Creates completion parsers based on the
|
|
70
|
+
* Creates completion parsers based on the sub-config.
|
|
57
71
|
*/
|
|
58
|
-
function createCompletionParser(
|
|
72
|
+
function createCompletionParser(programName, availableShells, commandConfig, optionConfig) {
|
|
73
|
+
let completionCommand = null;
|
|
74
|
+
let completionOption = null;
|
|
59
75
|
const shellList = [];
|
|
60
76
|
for (const shell in availableShells) {
|
|
61
77
|
if (shellList.length > 0) shellList.push(require_message.text(", "));
|
|
@@ -65,56 +81,44 @@ function createCompletionParser(mode, programName, availableShells, name = "both
|
|
|
65
81
|
shell: require_modifiers.optional(require_primitives.argument(require_valueparser.string({ metavar: "SHELL" }), { description: require_message.message`Shell type (${shellList}). Generate completion script when used alone, or provide completions when followed by arguments.` })),
|
|
66
82
|
args: require_modifiers.multiple(require_primitives.argument(require_valueparser.string({ metavar: "ARG" }), { description: require_message.message`Command line arguments for completion suggestions (used by shell integration; you usually don't need to provide this).` }))
|
|
67
83
|
});
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const showSingular = helpVisibility === "singular" || helpVisibility === "both";
|
|
76
|
-
const showPlural = helpVisibility === "plural" || helpVisibility === "both";
|
|
77
|
-
if (name === "singular" || name === "both") completionCommands.push(require_primitives.command("completion", completionInner, {
|
|
78
|
-
...completionCommandConfig,
|
|
79
|
-
hidden: !showSingular
|
|
80
|
-
}));
|
|
81
|
-
if (name === "plural" || name === "both") completionCommands.push(require_primitives.command("completions", completionInner, {
|
|
82
|
-
...completionCommandConfig,
|
|
83
|
-
hidden: !showPlural
|
|
84
|
-
}));
|
|
85
|
-
const completionCommand = require_constructs.longestMatch(...completionCommands);
|
|
86
|
-
const completionOptions = [];
|
|
87
|
-
if (name === "singular" || name === "both") completionOptions.push(require_primitives.option("--completion", require_valueparser.string({ metavar: "SHELL" }), {
|
|
88
|
-
description: require_message.message`Generate shell completion script.`,
|
|
89
|
-
hidden: !showSingular
|
|
90
|
-
}));
|
|
91
|
-
if (name === "plural" || name === "both") completionOptions.push(require_primitives.option("--completions", require_valueparser.string({ metavar: "SHELL" }), {
|
|
92
|
-
description: require_message.message`Generate shell completion script.`,
|
|
93
|
-
hidden: !showPlural
|
|
94
|
-
}));
|
|
95
|
-
const completionOption = completionOptions.length === 1 ? completionOptions[0] : require_constructs.longestMatch(completionOptions[0], completionOptions[1]);
|
|
96
|
-
const argsParser = require_modifiers.withDefault(require_modifiers.multiple(require_primitives.argument(require_valueparser.string({ metavar: "ARG" }), { description: require_message.message`Command line arguments for completion suggestions (used by shell integration; you usually don't need to provide this).` })), []);
|
|
97
|
-
const optionParser = require_constructs.object({
|
|
98
|
-
shell: completionOption,
|
|
99
|
-
args: argsParser
|
|
100
|
-
});
|
|
101
|
-
switch (mode) {
|
|
102
|
-
case "command": return {
|
|
103
|
-
completionCommand,
|
|
104
|
-
completionOption: null
|
|
105
|
-
};
|
|
106
|
-
case "option": return {
|
|
107
|
-
completionCommand: null,
|
|
108
|
-
completionOption: optionParser
|
|
109
|
-
};
|
|
110
|
-
case "both": return {
|
|
111
|
-
completionCommand,
|
|
112
|
-
completionOption: optionParser
|
|
84
|
+
if (commandConfig) {
|
|
85
|
+
const names = commandConfig.names ?? ["completion"];
|
|
86
|
+
const displayName = names[0];
|
|
87
|
+
const completionCommandConfig = {
|
|
88
|
+
brief: require_message.message`Generate shell completion script or provide completions.`,
|
|
89
|
+
description: require_message.message`Generate shell completion script or provide completions.`,
|
|
90
|
+
footer: require_message.message`Examples:${require_message.lineBreak()} Bash: ${require_message.commandLine(`eval "$(${programName} ${displayName} bash)"`)}${require_message.lineBreak()} zsh: ${require_message.commandLine(`eval "$(${programName} ${displayName} zsh)"`)}${require_message.lineBreak()} fish: ${require_message.commandLine(`eval "$(${programName} ${displayName} fish)"`)}${require_message.lineBreak()} PowerShell: ${require_message.commandLine(`${programName} ${displayName} pwsh > ${programName}-completion.ps1; . ./${programName}-completion.ps1`)}${require_message.lineBreak()} Nushell: ${require_message.commandLine(`${programName} ${displayName} nu | save ${programName}-completion.nu; source ./${programName}-completion.nu`)}`
|
|
113
91
|
};
|
|
92
|
+
const commandParsers = [];
|
|
93
|
+
for (let i = 0; i < names.length; i++) commandParsers.push(require_primitives.command(names[i], completionInner, {
|
|
94
|
+
...completionCommandConfig,
|
|
95
|
+
hidden: i === 0 ? commandConfig.hidden : commandConfig.hidden === true ? true : true
|
|
96
|
+
}));
|
|
97
|
+
completionCommand = commandParsers.length === 1 ? commandParsers[0] : require_constructs.longestMatch(...commandParsers);
|
|
114
98
|
}
|
|
99
|
+
if (optionConfig) {
|
|
100
|
+
const names = optionConfig.names ?? ["--completion"];
|
|
101
|
+
const completionOptions = [];
|
|
102
|
+
for (const name of names) completionOptions.push(require_primitives.option(name, require_valueparser.string({ metavar: "SHELL" }), {
|
|
103
|
+
description: require_message.message`Generate shell completion script.`,
|
|
104
|
+
hidden: optionConfig.hidden
|
|
105
|
+
}));
|
|
106
|
+
const completionOptionParser = completionOptions.length === 1 ? completionOptions[0] : require_constructs.longestMatch(...completionOptions);
|
|
107
|
+
const argsParser = require_modifiers.withDefault(require_modifiers.multiple(require_primitives.argument(require_valueparser.string({ metavar: "ARG" }), { description: require_message.message`Command line arguments for completion suggestions (used by shell integration; you usually don't need to provide this).` })), []);
|
|
108
|
+
completionOption = require_constructs.object({
|
|
109
|
+
shell: completionOptionParser,
|
|
110
|
+
args: argsParser
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
completionCommand,
|
|
115
|
+
completionOption
|
|
116
|
+
};
|
|
115
117
|
}
|
|
116
|
-
function combineWithHelpVersion(originalParser, helpParsers, versionParsers, completionParsers, groups) {
|
|
118
|
+
function combineWithHelpVersion(originalParser, helpParsers, versionParsers, completionParsers, groups, helpOptionNames, versionOptionNames) {
|
|
117
119
|
const parsers = [];
|
|
120
|
+
const effectiveHelpOptionNames = helpOptionNames ?? ["--help"];
|
|
121
|
+
const effectiveVersionOptionNames = versionOptionNames ?? ["--version"];
|
|
118
122
|
if (helpParsers.helpOption) {
|
|
119
123
|
const lenientHelpParser = {
|
|
120
124
|
$mode: "sync",
|
|
@@ -135,11 +139,11 @@ function combineWithHelpVersion(originalParser, helpParsers, versionParsers, com
|
|
|
135
139
|
let versionIndex = -1;
|
|
136
140
|
for (let i = 0; i < buffer.length; i++) {
|
|
137
141
|
if (buffer[i] === "--") break;
|
|
138
|
-
if (buffer[i]
|
|
142
|
+
if (effectiveHelpOptionNames.includes(buffer[i])) {
|
|
139
143
|
helpFound = true;
|
|
140
144
|
helpIndex = i;
|
|
141
145
|
}
|
|
142
|
-
if (buffer[i]
|
|
146
|
+
if (effectiveVersionOptionNames.includes(buffer[i])) versionIndex = i;
|
|
143
147
|
}
|
|
144
148
|
if (helpFound && versionIndex > helpIndex) return {
|
|
145
149
|
success: false,
|
|
@@ -169,7 +173,7 @@ function combineWithHelpVersion(originalParser, helpParsers, versionParsers, com
|
|
|
169
173
|
}
|
|
170
174
|
return {
|
|
171
175
|
success: false,
|
|
172
|
-
error: require_message.message`Flag ${require_message.optionName(
|
|
176
|
+
error: require_message.message`Flag ${require_message.optionName(effectiveHelpOptionNames[0])} not found.`,
|
|
173
177
|
consumed: 0
|
|
174
178
|
};
|
|
175
179
|
},
|
|
@@ -180,16 +184,17 @@ function combineWithHelpVersion(originalParser, helpParsers, versionParsers, com
|
|
|
180
184
|
};
|
|
181
185
|
},
|
|
182
186
|
*suggest(_context, prefix) {
|
|
183
|
-
if (
|
|
187
|
+
for (const name of effectiveHelpOptionNames) if (name.startsWith(prefix)) yield {
|
|
184
188
|
kind: "literal",
|
|
185
|
-
text:
|
|
189
|
+
text: name
|
|
186
190
|
};
|
|
187
191
|
},
|
|
188
192
|
getDocFragments(state) {
|
|
189
193
|
return helpParsers.helpOption?.getDocFragments(state) ?? { fragments: [] };
|
|
190
194
|
}
|
|
191
195
|
};
|
|
192
|
-
|
|
196
|
+
const wrappedHelp = groups?.helpOptionGroup ? require_constructs.group(groups.helpOptionGroup, lenientHelpParser) : lenientHelpParser;
|
|
197
|
+
parsers.push(wrappedHelp);
|
|
193
198
|
}
|
|
194
199
|
if (versionParsers.versionOption) {
|
|
195
200
|
const lenientVersionParser = {
|
|
@@ -211,11 +216,11 @@ function combineWithHelpVersion(originalParser, helpParsers, versionParsers, com
|
|
|
211
216
|
let helpIndex = -1;
|
|
212
217
|
for (let i = 0; i < buffer.length; i++) {
|
|
213
218
|
if (buffer[i] === "--") break;
|
|
214
|
-
if (buffer[i]
|
|
219
|
+
if (effectiveVersionOptionNames.includes(buffer[i])) {
|
|
215
220
|
versionFound = true;
|
|
216
221
|
versionIndex = i;
|
|
217
222
|
}
|
|
218
|
-
if (buffer[i]
|
|
223
|
+
if (effectiveHelpOptionNames.includes(buffer[i])) helpIndex = i;
|
|
219
224
|
}
|
|
220
225
|
if (versionFound && helpIndex > versionIndex) return {
|
|
221
226
|
success: false,
|
|
@@ -237,7 +242,7 @@ function combineWithHelpVersion(originalParser, helpParsers, versionParsers, com
|
|
|
237
242
|
};
|
|
238
243
|
return {
|
|
239
244
|
success: false,
|
|
240
|
-
error: require_message.message`Flag ${require_message.optionName(
|
|
245
|
+
error: require_message.message`Flag ${require_message.optionName(effectiveVersionOptionNames[0])} not found.`,
|
|
241
246
|
consumed: 0
|
|
242
247
|
};
|
|
243
248
|
},
|
|
@@ -248,16 +253,17 @@ function combineWithHelpVersion(originalParser, helpParsers, versionParsers, com
|
|
|
248
253
|
};
|
|
249
254
|
},
|
|
250
255
|
*suggest(_context, prefix) {
|
|
251
|
-
if (
|
|
256
|
+
for (const name of effectiveVersionOptionNames) if (name.startsWith(prefix)) yield {
|
|
252
257
|
kind: "literal",
|
|
253
|
-
text:
|
|
258
|
+
text: name
|
|
254
259
|
};
|
|
255
260
|
},
|
|
256
261
|
getDocFragments(state) {
|
|
257
262
|
return versionParsers.versionOption?.getDocFragments(state) ?? { fragments: [] };
|
|
258
263
|
}
|
|
259
264
|
};
|
|
260
|
-
|
|
265
|
+
const wrappedVersion = groups?.versionOptionGroup ? require_constructs.group(groups.versionOptionGroup, lenientVersionParser) : lenientVersionParser;
|
|
266
|
+
parsers.push(wrappedVersion);
|
|
261
267
|
}
|
|
262
268
|
if (versionParsers.versionCommand) {
|
|
263
269
|
const versionParser = require_constructs.object({
|
|
@@ -267,7 +273,7 @@ function combineWithHelpVersion(originalParser, helpParsers, versionParsers, com
|
|
|
267
273
|
result: versionParsers.versionCommand,
|
|
268
274
|
helpFlag: helpParsers.helpOption ? require_modifiers.optional(helpParsers.helpOption) : require_primitives.constant(false)
|
|
269
275
|
});
|
|
270
|
-
parsers.push(groups?.
|
|
276
|
+
parsers.push(groups?.versionCommandGroup ? require_constructs.group(groups.versionCommandGroup, versionParser) : versionParser);
|
|
271
277
|
}
|
|
272
278
|
if (completionParsers.completionCommand) {
|
|
273
279
|
const completionParser = require_constructs.object({
|
|
@@ -277,7 +283,7 @@ function combineWithHelpVersion(originalParser, helpParsers, versionParsers, com
|
|
|
277
283
|
completionData: completionParsers.completionCommand,
|
|
278
284
|
helpFlag: helpParsers.helpOption ? require_modifiers.optional(helpParsers.helpOption) : require_primitives.constant(false)
|
|
279
285
|
});
|
|
280
|
-
parsers.push(groups?.
|
|
286
|
+
parsers.push(groups?.completionCommandGroup ? require_constructs.group(groups.completionCommandGroup, completionParser) : completionParser);
|
|
281
287
|
}
|
|
282
288
|
if (helpParsers.helpCommand) {
|
|
283
289
|
const helpParser = require_constructs.object({
|
|
@@ -286,7 +292,7 @@ function combineWithHelpVersion(originalParser, helpParsers, versionParsers, com
|
|
|
286
292
|
completion: require_primitives.constant(false),
|
|
287
293
|
commands: helpParsers.helpCommand
|
|
288
294
|
});
|
|
289
|
-
parsers.push(groups?.
|
|
295
|
+
parsers.push(groups?.helpCommandGroup ? require_constructs.group(groups.helpCommandGroup, helpParser) : helpParser);
|
|
290
296
|
}
|
|
291
297
|
parsers.push(require_constructs.object({
|
|
292
298
|
help: require_primitives.constant(false),
|
|
@@ -316,9 +322,10 @@ function combineWithHelpVersion(originalParser, helpParsers, versionParsers, com
|
|
|
316
322
|
return combined;
|
|
317
323
|
}
|
|
318
324
|
/**
|
|
319
|
-
* Classifies the parsing result into a discriminated union for cleaner
|
|
325
|
+
* Classifies the parsing result into a discriminated union for cleaner
|
|
326
|
+
* handling.
|
|
320
327
|
*/
|
|
321
|
-
function classifyResult(result, args) {
|
|
328
|
+
function classifyResult(result, args, helpOptionNames, helpCommandNames, versionOptionNames, versionCommandNames, completionCommandNames) {
|
|
322
329
|
if (!result.success) return {
|
|
323
330
|
type: "error",
|
|
324
331
|
error: result.error
|
|
@@ -326,19 +333,19 @@ function classifyResult(result, args) {
|
|
|
326
333
|
const value$1 = result.value;
|
|
327
334
|
if (typeof value$1 === "object" && value$1 != null && "help" in value$1 && "version" in value$1) {
|
|
328
335
|
const parsedValue = value$1;
|
|
329
|
-
const hasVersionOption = args.includes(
|
|
330
|
-
const hasVersionCommand = args.length > 0 && args[0]
|
|
331
|
-
const hasHelpOption = args.includes(
|
|
332
|
-
const hasHelpCommand = args.length > 0 && args[0]
|
|
333
|
-
const hasCompletionCommand = args.length > 0 && args[0]
|
|
336
|
+
const hasVersionOption = versionOptionNames.some((n) => args.includes(n));
|
|
337
|
+
const hasVersionCommand = args.length > 0 && versionCommandNames.includes(args[0]);
|
|
338
|
+
const hasHelpOption = helpOptionNames.some((n) => args.includes(n));
|
|
339
|
+
const hasHelpCommand = args.length > 0 && helpCommandNames.includes(args[0]);
|
|
340
|
+
const hasCompletionCommand = args.length > 0 && completionCommandNames.includes(args[0]);
|
|
334
341
|
if (hasVersionOption && hasHelpOption && !hasVersionCommand && !hasHelpCommand) {}
|
|
335
342
|
if (hasVersionCommand && hasHelpOption && parsedValue.helpFlag) return {
|
|
336
343
|
type: "help",
|
|
337
|
-
commands: [
|
|
344
|
+
commands: [args[0]]
|
|
338
345
|
};
|
|
339
346
|
if (hasCompletionCommand && hasHelpOption && parsedValue.helpFlag) return {
|
|
340
347
|
type: "help",
|
|
341
|
-
commands: [
|
|
348
|
+
commands: [args[0]]
|
|
342
349
|
};
|
|
343
350
|
if (parsedValue.help && (hasHelpOption || hasHelpCommand)) {
|
|
344
351
|
let commandContext = [];
|
|
@@ -369,7 +376,7 @@ function classifyResult(result, args) {
|
|
|
369
376
|
* Handles shell completion requests.
|
|
370
377
|
* @since 0.6.0
|
|
371
378
|
*/
|
|
372
|
-
function handleCompletion(completionArgs, programName, parser, completionParser, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth,
|
|
379
|
+
function handleCompletion(completionArgs, programName, parser, completionParser, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth, completionCommandDisplayName, completionOptionDisplayName, isOptionMode, sectionOrder) {
|
|
373
380
|
const shellName = completionArgs[0] || "";
|
|
374
381
|
const args = completionArgs.slice(1);
|
|
375
382
|
const callOnError = (code) => {
|
|
@@ -389,7 +396,8 @@ function handleCompletion(completionArgs, programName, parser, completionParser,
|
|
|
389
396
|
if (!shellName) {
|
|
390
397
|
stderr("Error: Missing shell name for completion.\n");
|
|
391
398
|
if (completionParser) {
|
|
392
|
-
const
|
|
399
|
+
const displayName = completionCommandDisplayName ?? "completion";
|
|
400
|
+
const doc = require_parser.getDocPage(completionParser, [displayName]);
|
|
393
401
|
if (doc) stderr(require_doc.formatDocPage(programName, doc, {
|
|
394
402
|
colors,
|
|
395
403
|
maxWidth,
|
|
@@ -414,8 +422,7 @@ function handleCompletion(completionArgs, programName, parser, completionParser,
|
|
|
414
422
|
return callOnError(1);
|
|
415
423
|
}
|
|
416
424
|
if (args.length === 0) {
|
|
417
|
-
const
|
|
418
|
-
const completionArg = completionMode === "option" ? usePlural ? "--completions" : "--completion" : usePlural ? "completions" : "completion";
|
|
425
|
+
const completionArg = isOptionMode ? completionOptionDisplayName ?? "--completion" : completionCommandDisplayName ?? "completion";
|
|
419
426
|
const script = shell.generateScript(programName, [completionArg, shellName]);
|
|
420
427
|
stdout(script);
|
|
421
428
|
if (parser.$mode === "async") return Promise.resolve(callOnCompletion(0));
|
|
@@ -461,18 +468,23 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
461
468
|
const { colors, maxWidth, showDefault, showChoices, sectionOrder, aboveError = "usage", onError = () => {
|
|
462
469
|
throw new RunParserError("Failed to parse command line arguments.");
|
|
463
470
|
}, stderr = console.error, stdout = console.log, brief, description, examples, author, bugs, footer } = options;
|
|
464
|
-
const
|
|
471
|
+
const norm = (c) => c === true ? {} : c;
|
|
472
|
+
const helpCommandConfig = norm(options.help?.command);
|
|
473
|
+
const helpOptionConfig = norm(options.help?.option);
|
|
465
474
|
const onHelp = options.help?.onShow ?? (() => ({}));
|
|
466
|
-
const
|
|
467
|
-
const
|
|
475
|
+
const versionCommandConfig = norm(options.version?.command);
|
|
476
|
+
const versionOptionConfig = norm(options.version?.option);
|
|
468
477
|
const versionValue = options.version?.value ?? "";
|
|
469
478
|
const onVersion = options.version?.onShow ?? (() => ({}));
|
|
470
|
-
const
|
|
471
|
-
const
|
|
472
|
-
const completionName = options.completion?.name ?? "both";
|
|
473
|
-
const completionHelpVisibility = options.completion?.helpVisibility ?? completionName;
|
|
479
|
+
const completionCommandConfig = norm(options.completion?.command);
|
|
480
|
+
const completionOptionConfig = norm(options.completion?.option);
|
|
474
481
|
const onCompletion = options.completion?.onShow ?? (() => ({}));
|
|
475
|
-
const
|
|
482
|
+
const helpOptionNames = helpOptionConfig?.names ?? ["--help"];
|
|
483
|
+
const helpCommandNames = helpCommandConfig?.names ?? ["help"];
|
|
484
|
+
const versionOptionNames = versionOptionConfig?.names ?? ["--version"];
|
|
485
|
+
const versionCommandNames = versionCommandConfig?.names ?? ["version"];
|
|
486
|
+
const completionCommandNames = completionCommandConfig?.names ?? ["completion"];
|
|
487
|
+
const completionOptionNames = completionOptionConfig?.names ?? ["--completion"];
|
|
476
488
|
const defaultShells = {
|
|
477
489
|
bash: require_completion.bash,
|
|
478
490
|
fish: require_completion.fish,
|
|
@@ -484,50 +496,47 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
484
496
|
...defaultShells,
|
|
485
497
|
...options.completion.shells
|
|
486
498
|
} : defaultShells;
|
|
487
|
-
const
|
|
488
|
-
const version = options.version ? versionMode : "none";
|
|
489
|
-
const completion = options.completion ? completionMode : "none";
|
|
490
|
-
const helpParsers = help === "none" ? {
|
|
499
|
+
const helpParsers = options.help ? createHelpParser(helpCommandConfig, helpOptionConfig) : {
|
|
491
500
|
helpCommand: null,
|
|
492
501
|
helpOption: null
|
|
493
|
-
}
|
|
494
|
-
const versionParsers = version
|
|
502
|
+
};
|
|
503
|
+
const versionParsers = options.version ? createVersionParser(versionCommandConfig, versionOptionConfig) : {
|
|
495
504
|
versionCommand: null,
|
|
496
505
|
versionOption: null
|
|
497
|
-
}
|
|
498
|
-
const completionParsers = completion
|
|
506
|
+
};
|
|
507
|
+
const completionParsers = options.completion ? createCompletionParser(programName, availableShells, completionCommandConfig, completionOptionConfig) : {
|
|
499
508
|
completionCommand: null,
|
|
500
509
|
completionOption: null
|
|
501
|
-
}
|
|
510
|
+
};
|
|
502
511
|
if (options.completion) {
|
|
503
|
-
const hasHelpOption = args.includes(
|
|
504
|
-
if (
|
|
505
|
-
if (
|
|
512
|
+
const hasHelpOption = helpOptionConfig ? helpOptionNames.some((n) => args.includes(n)) : false;
|
|
513
|
+
if (completionCommandConfig && args.length >= 1 && completionCommandNames.includes(args[0]) && !hasHelpOption) return handleCompletion(args.slice(1), programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth, completionCommandNames[0], completionOptionNames[0], false, sectionOrder);
|
|
514
|
+
if (completionOptionConfig) for (let i = 0; i < args.length; i++) {
|
|
506
515
|
const arg = args[i];
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
const shell = arg.slice(arg.indexOf("=") + 1);
|
|
516
|
+
const equalsMatch = completionOptionNames.find((n) => arg.startsWith(n + "="));
|
|
517
|
+
if (equalsMatch) {
|
|
518
|
+
const shell = arg.slice(equalsMatch.length + 1);
|
|
511
519
|
const completionArgs = args.slice(i + 1);
|
|
512
|
-
return handleCompletion([shell, ...completionArgs], programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth,
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
return handleCompletion([shell, ...completionArgs], programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth, completionMode, completionName, sectionOrder);
|
|
520
|
-
}
|
|
520
|
+
return handleCompletion([shell, ...completionArgs], programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth, completionCommandNames[0], completionOptionNames[0], true, sectionOrder);
|
|
521
|
+
}
|
|
522
|
+
const exactMatch = completionOptionNames.includes(arg);
|
|
523
|
+
if (exactMatch) {
|
|
524
|
+
const shell = i + 1 < args.length ? args[i + 1] : "";
|
|
525
|
+
const completionArgs = i + 1 < args.length ? args.slice(i + 2) : [];
|
|
526
|
+
return handleCompletion([shell, ...completionArgs], programName, parser, completionParsers.completionCommand, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth, completionCommandNames[0], completionOptionNames[0], true, sectionOrder);
|
|
521
527
|
}
|
|
522
528
|
}
|
|
523
529
|
}
|
|
524
|
-
const augmentedParser = help
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
530
|
+
const augmentedParser = !options.help && !options.version && !options.completion ? parser : combineWithHelpVersion(parser, helpParsers, versionParsers, completionParsers, {
|
|
531
|
+
helpCommandGroup: helpCommandConfig?.group,
|
|
532
|
+
helpOptionGroup: helpOptionConfig?.group,
|
|
533
|
+
versionCommandGroup: versionCommandConfig?.group,
|
|
534
|
+
versionOptionGroup: versionOptionConfig?.group,
|
|
535
|
+
completionCommandGroup: completionCommandConfig?.group,
|
|
536
|
+
completionOptionGroup: completionOptionConfig?.group
|
|
537
|
+
}, helpOptionConfig ? [...helpOptionNames] : void 0, versionOptionConfig ? [...versionOptionNames] : void 0);
|
|
529
538
|
const handleResult = (result) => {
|
|
530
|
-
const classified = classifyResult(result, args);
|
|
539
|
+
const classified = classifyResult(result, args, helpOptionConfig ? [...helpOptionNames] : [], helpCommandConfig ? [...helpCommandNames] : [], versionOptionConfig ? [...versionOptionNames] : [], versionCommandConfig ? [...versionCommandNames] : [], completionCommandConfig ? [...completionCommandNames] : []);
|
|
531
540
|
switch (classified.type) {
|
|
532
541
|
case "success": return classified.value;
|
|
533
542
|
case "version":
|
|
@@ -540,16 +549,16 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
540
549
|
case "completion": throw new RunParserError("Completion should be handled by early return");
|
|
541
550
|
case "help": {
|
|
542
551
|
let helpGeneratorParser;
|
|
543
|
-
const helpAsCommand =
|
|
544
|
-
const versionAsCommand =
|
|
545
|
-
const completionAsCommand =
|
|
546
|
-
const helpAsOption =
|
|
547
|
-
const versionAsOption =
|
|
548
|
-
const completionAsOption =
|
|
552
|
+
const helpAsCommand = helpCommandConfig != null;
|
|
553
|
+
const versionAsCommand = versionCommandConfig != null;
|
|
554
|
+
const completionAsCommand = completionCommandConfig != null;
|
|
555
|
+
const helpAsOption = helpOptionConfig != null;
|
|
556
|
+
const versionAsOption = versionOptionConfig != null;
|
|
557
|
+
const completionAsOption = completionOptionConfig != null;
|
|
549
558
|
const requestedCommand = classified.commands[0];
|
|
550
|
-
if (
|
|
551
|
-
else if (requestedCommand
|
|
552
|
-
else if (requestedCommand
|
|
559
|
+
if (requestedCommand != null && completionCommandNames.includes(requestedCommand) && completionAsCommand && completionParsers.completionCommand) helpGeneratorParser = completionParsers.completionCommand;
|
|
560
|
+
else if (requestedCommand != null && helpCommandNames.includes(requestedCommand) && helpAsCommand && helpParsers.helpCommand) helpGeneratorParser = helpParsers.helpCommand;
|
|
561
|
+
else if (requestedCommand != null && versionCommandNames.includes(requestedCommand) && versionAsCommand && versionParsers.versionCommand) helpGeneratorParser = versionParsers.versionCommand;
|
|
553
562
|
else {
|
|
554
563
|
const commandParsers = [parser];
|
|
555
564
|
const groupedMeta = {};
|
|
@@ -558,15 +567,24 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
558
567
|
if (groupLabel) (groupedMeta[groupLabel] ??= []).push(p);
|
|
559
568
|
else ungroupedMeta.push(p);
|
|
560
569
|
};
|
|
561
|
-
if (helpAsCommand && helpParsers.helpCommand) addMeta(helpParsers.helpCommand,
|
|
562
|
-
if (versionAsCommand && versionParsers.versionCommand) addMeta(versionParsers.versionCommand,
|
|
563
|
-
if (completionAsCommand && completionParsers.completionCommand) addMeta(completionParsers.completionCommand,
|
|
570
|
+
if (helpAsCommand && helpParsers.helpCommand) addMeta(helpParsers.helpCommand, helpCommandConfig?.group);
|
|
571
|
+
if (versionAsCommand && versionParsers.versionCommand) addMeta(versionParsers.versionCommand, versionCommandConfig?.group);
|
|
572
|
+
if (completionAsCommand && completionParsers.completionCommand) addMeta(completionParsers.completionCommand, completionCommandConfig?.group);
|
|
564
573
|
commandParsers.push(...ungroupedMeta);
|
|
565
574
|
for (const [label, parsers] of Object.entries(groupedMeta)) if (parsers.length === 1) commandParsers.push(require_constructs.group(label, parsers[0]));
|
|
566
575
|
else commandParsers.push(require_constructs.group(label, require_constructs.longestMatch(...parsers)));
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
576
|
+
const groupedMetaOptions = {};
|
|
577
|
+
const ungroupedMetaOptions = [];
|
|
578
|
+
const addMetaOption = (p, groupLabel) => {
|
|
579
|
+
if (groupLabel) (groupedMetaOptions[groupLabel] ??= []).push(p);
|
|
580
|
+
else ungroupedMetaOptions.push(p);
|
|
581
|
+
};
|
|
582
|
+
if (helpAsOption && helpParsers.helpOption) addMetaOption(helpParsers.helpOption, helpOptionConfig?.group);
|
|
583
|
+
if (versionAsOption && versionParsers.versionOption) addMetaOption(versionParsers.versionOption, versionOptionConfig?.group);
|
|
584
|
+
if (completionAsOption && completionParsers.completionOption) addMetaOption(completionParsers.completionOption, completionOptionConfig?.group);
|
|
585
|
+
commandParsers.push(...ungroupedMetaOptions);
|
|
586
|
+
for (const [label, optParsers] of Object.entries(groupedMetaOptions)) if (optParsers.length === 1) commandParsers.push(require_constructs.group(label, optParsers[0]));
|
|
587
|
+
else commandParsers.push(require_constructs.group(label, require_constructs.longestMatch(...optParsers)));
|
|
570
588
|
if (commandParsers.length === 1) helpGeneratorParser = commandParsers[0];
|
|
571
589
|
else if (commandParsers.length === 2) helpGeneratorParser = require_constructs.longestMatch(commandParsers[0], commandParsers[1]);
|
|
572
590
|
else helpGeneratorParser = require_constructs.longestMatch(...commandParsers);
|
|
@@ -626,7 +644,7 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
626
644
|
}
|
|
627
645
|
const displayHelp = (doc) => {
|
|
628
646
|
if (doc != null) {
|
|
629
|
-
const isMetaCommandHelp =
|
|
647
|
+
const isMetaCommandHelp = requestedCommand != null && completionCommandNames.includes(requestedCommand) || requestedCommand != null && helpCommandNames.includes(requestedCommand) || requestedCommand != null && versionCommandNames.includes(requestedCommand);
|
|
630
648
|
const isSubcommandHelp = classified.commands.length > 0;
|
|
631
649
|
const isTopLevel = !isSubcommandHelp;
|
|
632
650
|
const shouldOverride = !isMetaCommandHelp && !isSubcommandHelp;
|
|
@@ -774,26 +792,31 @@ function indentLines(text$1, indent) {
|
|
|
774
792
|
* @returns `true` if early exit should be performed, `false` otherwise.
|
|
775
793
|
*/
|
|
776
794
|
function needsEarlyExit(args, options) {
|
|
795
|
+
const norm = (c) => c === true ? {} : c;
|
|
777
796
|
if (options.help) {
|
|
778
|
-
const
|
|
779
|
-
|
|
780
|
-
|
|
797
|
+
const helpOptionConfig = norm(options.help.option);
|
|
798
|
+
const helpCommandConfig = norm(options.help.command);
|
|
799
|
+
const helpOptionNames = helpOptionConfig?.names ?? ["--help"];
|
|
800
|
+
const helpCommandNames = helpCommandConfig?.names ?? ["help"];
|
|
801
|
+
if (helpOptionConfig && helpOptionNames.some((n) => args.includes(n))) return true;
|
|
802
|
+
if (helpCommandConfig && helpCommandNames.includes(args[0])) return true;
|
|
781
803
|
}
|
|
782
804
|
if (options.version) {
|
|
783
|
-
const
|
|
784
|
-
|
|
785
|
-
|
|
805
|
+
const versionOptionConfig = norm(options.version.option);
|
|
806
|
+
const versionCommandConfig = norm(options.version.command);
|
|
807
|
+
const versionOptionNames = versionOptionConfig?.names ?? ["--version"];
|
|
808
|
+
const versionCommandNames = versionCommandConfig?.names ?? ["version"];
|
|
809
|
+
if (versionOptionConfig && versionOptionNames.some((n) => args.includes(n))) return true;
|
|
810
|
+
if (versionCommandConfig && versionCommandNames.includes(args[0])) return true;
|
|
786
811
|
}
|
|
787
812
|
if (options.completion) {
|
|
788
|
-
const
|
|
789
|
-
const
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
if ((completionName === "singular" || completionName === "both") && (arg === "--completion" || arg.startsWith("--completion="))) return true;
|
|
796
|
-
if ((completionName === "plural" || completionName === "both") && (arg === "--completions" || arg.startsWith("--completions="))) return true;
|
|
813
|
+
const completionCommandConfig = norm(options.completion.command);
|
|
814
|
+
const completionOptionConfig = norm(options.completion.option);
|
|
815
|
+
const completionCommandNames = completionCommandConfig?.names ?? ["completion"];
|
|
816
|
+
const completionOptionNames = completionOptionConfig?.names ?? ["--completion"];
|
|
817
|
+
if (completionCommandConfig && completionCommandNames.includes(args[0])) return true;
|
|
818
|
+
if (completionOptionConfig) {
|
|
819
|
+
for (const arg of args) for (const name of completionOptionNames) if (arg === name || arg.startsWith(name + "=")) return true;
|
|
797
820
|
}
|
|
798
821
|
}
|
|
799
822
|
return false;
|
|
@@ -820,13 +843,14 @@ function mergeAnnotations(annotationsList) {
|
|
|
820
843
|
* two-phase parsing is needed.
|
|
821
844
|
*
|
|
822
845
|
* @param contexts Source contexts to collect annotations from.
|
|
846
|
+
* @param options Optional context-required options to pass to each context.
|
|
823
847
|
* @returns Promise with merged annotations and dynamic-context hint.
|
|
824
848
|
*/
|
|
825
|
-
async function collectPhase1Annotations(contexts) {
|
|
849
|
+
async function collectPhase1Annotations(contexts, options) {
|
|
826
850
|
const annotationsList = [];
|
|
827
851
|
let hasDynamic = false;
|
|
828
852
|
for (const context of contexts) {
|
|
829
|
-
const result = context.getAnnotations();
|
|
853
|
+
const result = context.getAnnotations(void 0, options);
|
|
830
854
|
if (result instanceof Promise) {
|
|
831
855
|
hasDynamic = true;
|
|
832
856
|
annotationsList.push(await result);
|
|
@@ -845,12 +869,13 @@ async function collectPhase1Annotations(contexts) {
|
|
|
845
869
|
*
|
|
846
870
|
* @param contexts Source contexts to collect annotations from.
|
|
847
871
|
* @param parsed Optional parsed result from a previous parse pass.
|
|
872
|
+
* @param options Optional context-required options to pass to each context.
|
|
848
873
|
* @returns Promise that resolves to merged annotations.
|
|
849
874
|
*/
|
|
850
|
-
async function collectAnnotations(contexts, parsed) {
|
|
875
|
+
async function collectAnnotations(contexts, parsed, options) {
|
|
851
876
|
const annotationsList = [];
|
|
852
877
|
for (const context of contexts) {
|
|
853
|
-
const result = context.getAnnotations(parsed);
|
|
878
|
+
const result = context.getAnnotations(parsed, options);
|
|
854
879
|
annotationsList.push(result instanceof Promise ? await result : result);
|
|
855
880
|
}
|
|
856
881
|
return mergeAnnotations(annotationsList);
|
|
@@ -860,14 +885,15 @@ async function collectAnnotations(contexts, parsed) {
|
|
|
860
885
|
* whether two-phase parsing is needed.
|
|
861
886
|
*
|
|
862
887
|
* @param contexts Source contexts to collect annotations from.
|
|
888
|
+
* @param options Optional context-required options to pass to each context.
|
|
863
889
|
* @returns Merged annotations with dynamic-context hint.
|
|
864
890
|
* @throws Error if any context returns a Promise.
|
|
865
891
|
*/
|
|
866
|
-
function collectPhase1AnnotationsSync(contexts) {
|
|
892
|
+
function collectPhase1AnnotationsSync(contexts, options) {
|
|
867
893
|
const annotationsList = [];
|
|
868
894
|
let hasDynamic = false;
|
|
869
895
|
for (const context of contexts) {
|
|
870
|
-
const result = context.getAnnotations();
|
|
896
|
+
const result = context.getAnnotations(void 0, options);
|
|
871
897
|
if (result instanceof Promise) throw new Error(`Context ${String(context.id)} returned a Promise in sync mode. Use runWith() or runWithAsync() for async contexts.`);
|
|
872
898
|
if (Object.getOwnPropertySymbols(result).length === 0) hasDynamic = true;
|
|
873
899
|
annotationsList.push(result);
|
|
@@ -882,19 +908,38 @@ function collectPhase1AnnotationsSync(contexts) {
|
|
|
882
908
|
*
|
|
883
909
|
* @param contexts Source contexts to collect annotations from.
|
|
884
910
|
* @param parsed Optional parsed result from a previous parse pass.
|
|
911
|
+
* @param options Optional context-required options to pass to each context.
|
|
885
912
|
* @returns Merged annotations.
|
|
886
913
|
* @throws Error if any context returns a Promise.
|
|
887
914
|
*/
|
|
888
|
-
function collectAnnotationsSync(contexts, parsed) {
|
|
915
|
+
function collectAnnotationsSync(contexts, parsed, options) {
|
|
889
916
|
const annotationsList = [];
|
|
890
917
|
for (const context of contexts) {
|
|
891
|
-
const result = context.getAnnotations(parsed);
|
|
918
|
+
const result = context.getAnnotations(parsed, options);
|
|
892
919
|
if (result instanceof Promise) throw new Error(`Context ${String(context.id)} returned a Promise in sync mode. Use runWith() or runWithAsync() for async contexts.`);
|
|
893
920
|
annotationsList.push(result);
|
|
894
921
|
}
|
|
895
922
|
return mergeAnnotations(annotationsList);
|
|
896
923
|
}
|
|
897
924
|
/**
|
|
925
|
+
* Disposes all contexts that implement `AsyncDisposable` or `Disposable`.
|
|
926
|
+
* Prefers `[Symbol.asyncDispose]` over `[Symbol.dispose]`.
|
|
927
|
+
*
|
|
928
|
+
* @param contexts Source contexts to dispose.
|
|
929
|
+
*/
|
|
930
|
+
async function disposeContexts(contexts) {
|
|
931
|
+
for (const context of contexts) if (Symbol.asyncDispose in context && typeof context[Symbol.asyncDispose] === "function") await context[Symbol.asyncDispose]();
|
|
932
|
+
else if (Symbol.dispose in context && typeof context[Symbol.dispose] === "function") context[Symbol.dispose]();
|
|
933
|
+
}
|
|
934
|
+
/**
|
|
935
|
+
* Disposes all contexts that implement `Disposable` synchronously.
|
|
936
|
+
*
|
|
937
|
+
* @param contexts Source contexts to dispose.
|
|
938
|
+
*/
|
|
939
|
+
function disposeContextsSync(contexts) {
|
|
940
|
+
for (const context of contexts) if (Symbol.dispose in context && typeof context[Symbol.dispose] === "function") context[Symbol.dispose]();
|
|
941
|
+
}
|
|
942
|
+
/**
|
|
898
943
|
* Runs a parser with multiple source contexts.
|
|
899
944
|
*
|
|
900
945
|
* This function automatically handles static and dynamic contexts with proper
|
|
@@ -952,36 +997,40 @@ async function runWith(parser, programName, contexts, options) {
|
|
|
952
997
|
if (parser.$mode === "async") return runParser(parser, programName, args, options);
|
|
953
998
|
return Promise.resolve(runParser(parser, programName, args, options));
|
|
954
999
|
}
|
|
955
|
-
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts);
|
|
956
|
-
if (!needsTwoPhase) {
|
|
957
|
-
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
958
|
-
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
959
|
-
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
960
|
-
}
|
|
961
|
-
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
962
|
-
let firstPassResult;
|
|
963
|
-
let firstPassFailed = false;
|
|
964
1000
|
try {
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
else firstPassFailed = true;
|
|
1001
|
+
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = await collectPhase1Annotations(contexts, options);
|
|
1002
|
+
if (!needsTwoPhase) {
|
|
1003
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1004
|
+
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1005
|
+
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
971
1006
|
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1007
|
+
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1008
|
+
let firstPassResult;
|
|
1009
|
+
let firstPassFailed = false;
|
|
1010
|
+
try {
|
|
1011
|
+
if (parser.$mode === "async") firstPassResult = await require_parser.parseAsync(augmentedParser1, args);
|
|
1012
|
+
else firstPassResult = require_parser.parseSync(augmentedParser1, args);
|
|
1013
|
+
if (typeof firstPassResult === "object" && firstPassResult !== null && "success" in firstPassResult) {
|
|
1014
|
+
const result = firstPassResult;
|
|
1015
|
+
if (result.success) firstPassResult = result.value;
|
|
1016
|
+
else firstPassFailed = true;
|
|
1017
|
+
}
|
|
1018
|
+
} catch {
|
|
1019
|
+
firstPassFailed = true;
|
|
1020
|
+
}
|
|
1021
|
+
if (firstPassFailed) {
|
|
1022
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1023
|
+
if (parser.$mode === "async") return runParser(augmentedParser, programName, args, options);
|
|
1024
|
+
return Promise.resolve(runParser(augmentedParser, programName, args, options));
|
|
1025
|
+
}
|
|
1026
|
+
const phase2Annotations = await collectAnnotations(contexts, firstPassResult, options);
|
|
1027
|
+
const finalAnnotations = mergeAnnotations([phase1Annotations, phase2Annotations]);
|
|
1028
|
+
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1029
|
+
if (parser.$mode === "async") return runParser(augmentedParser2, programName, args, options);
|
|
1030
|
+
return Promise.resolve(runParser(augmentedParser2, programName, args, options));
|
|
1031
|
+
} finally {
|
|
1032
|
+
await disposeContexts(contexts);
|
|
979
1033
|
}
|
|
980
|
-
const phase2Annotations = await collectAnnotations(contexts, firstPassResult);
|
|
981
|
-
const finalAnnotations = mergeAnnotations([phase1Annotations, phase2Annotations]);
|
|
982
|
-
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
983
|
-
if (parser.$mode === "async") return runParser(augmentedParser2, programName, args, options);
|
|
984
|
-
return Promise.resolve(runParser(augmentedParser2, programName, args, options));
|
|
985
1034
|
}
|
|
986
1035
|
/**
|
|
987
1036
|
* Runs a synchronous parser with multiple source contexts.
|
|
@@ -1004,24 +1053,28 @@ function runWithSync(parser, programName, contexts, options) {
|
|
|
1004
1053
|
const args = options?.args ?? [];
|
|
1005
1054
|
if (needsEarlyExit(args, options)) return runParser(parser, programName, args, options);
|
|
1006
1055
|
if (contexts.length === 0) return runParser(parser, programName, args, options);
|
|
1007
|
-
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts);
|
|
1008
|
-
if (!needsTwoPhase) {
|
|
1009
|
-
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1010
|
-
return runParser(augmentedParser, programName, args, options);
|
|
1011
|
-
}
|
|
1012
|
-
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1013
|
-
let firstPassResult;
|
|
1014
1056
|
try {
|
|
1015
|
-
const
|
|
1016
|
-
if (
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1057
|
+
const { annotations: phase1Annotations, hasDynamic: needsTwoPhase } = collectPhase1AnnotationsSync(contexts, options);
|
|
1058
|
+
if (!needsTwoPhase) {
|
|
1059
|
+
const augmentedParser = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1060
|
+
return runParser(augmentedParser, programName, args, options);
|
|
1061
|
+
}
|
|
1062
|
+
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1063
|
+
let firstPassResult;
|
|
1064
|
+
try {
|
|
1065
|
+
const result = require_parser.parseSync(augmentedParser1, args);
|
|
1066
|
+
if (result.success) firstPassResult = result.value;
|
|
1067
|
+
else return runParser(augmentedParser1, programName, args, options);
|
|
1068
|
+
} catch {
|
|
1069
|
+
return runParser(augmentedParser1, programName, args, options);
|
|
1070
|
+
}
|
|
1071
|
+
const phase2Annotations = collectAnnotationsSync(contexts, firstPassResult, options);
|
|
1072
|
+
const finalAnnotations = mergeAnnotations([phase1Annotations, phase2Annotations]);
|
|
1073
|
+
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1074
|
+
return runParser(augmentedParser2, programName, args, options);
|
|
1075
|
+
} finally {
|
|
1076
|
+
disposeContextsSync(contexts);
|
|
1020
1077
|
}
|
|
1021
|
-
const phase2Annotations = collectAnnotationsSync(contexts, firstPassResult);
|
|
1022
|
-
const finalAnnotations = mergeAnnotations([phase1Annotations, phase2Annotations]);
|
|
1023
|
-
const augmentedParser2 = injectAnnotationsIntoParser(parser, finalAnnotations);
|
|
1024
|
-
return runParser(augmentedParser2, programName, args, options);
|
|
1025
1078
|
}
|
|
1026
1079
|
/**
|
|
1027
1080
|
* Runs any parser asynchronously with multiple source contexts.
|