@optique/core 0.3.0-dev.41 → 0.3.0-dev.43
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/facade.cjs +224 -21
- package/dist/facade.d.cts +50 -17
- package/dist/facade.d.ts +50 -17
- package/dist/facade.js +224 -21
- package/dist/parser.d.cts +4 -0
- package/dist/parser.d.ts +4 -0
- package/package.json +1 -1
package/dist/facade.cjs
CHANGED
|
@@ -35,56 +35,259 @@ const require_parser = require('./parser.cjs');
|
|
|
35
35
|
* @throws {RunError} When parsing fails and no `onError` callback is provided.
|
|
36
36
|
*/
|
|
37
37
|
function run(parser, programName, args, options = {}) {
|
|
38
|
-
|
|
38
|
+
const helpMode = options.help?.mode ?? "option";
|
|
39
|
+
const onHelp = options.help?.onShow ?? (() => ({}));
|
|
40
|
+
const versionMode = options.version?.mode ?? "option";
|
|
41
|
+
const versionValue = options.version?.value ?? "";
|
|
42
|
+
const onVersion = options.version?.onShow ?? (() => ({}));
|
|
43
|
+
let { colors, maxWidth, aboveError = "usage", onError = () => {
|
|
39
44
|
throw new RunError("Failed to parse command line arguments.");
|
|
40
45
|
}, stderr = console.error, stdout = console.log } = options;
|
|
46
|
+
const help = options.help ? helpMode : "none";
|
|
41
47
|
const contextualHelpParser = require_parser.object({
|
|
42
48
|
help: require_parser.constant(true),
|
|
43
|
-
|
|
49
|
+
version: require_parser.constant(false),
|
|
50
|
+
commands: require_parser.multiple(require_parser.argument(require_valueparser.string({
|
|
51
|
+
metavar: "COMMAND",
|
|
52
|
+
pattern: /^[^-].*$/
|
|
53
|
+
}))),
|
|
44
54
|
__help: require_parser.flag("--help")
|
|
45
55
|
});
|
|
46
56
|
const helpCommand = require_parser.command("help", require_parser.multiple(require_parser.argument(require_valueparser.string({ metavar: "COMMAND" }))), { description: require_message.message`Show help information.` });
|
|
47
57
|
const helpOption = require_parser.option("--help", { description: require_message.message`Show help information.` });
|
|
48
|
-
const
|
|
58
|
+
const version = options.version ? versionMode : "none";
|
|
59
|
+
const versionCommand = require_parser.command("version", require_parser.object({}), { description: require_message.message`Show version information.` });
|
|
60
|
+
const versionOption = require_parser.option("--version", { description: require_message.message`Show version information.` });
|
|
61
|
+
const augmentedParser = help === "none" && version === "none" ? parser : help === "none" && version === "command" ? require_parser.longestMatch(require_parser.object({
|
|
62
|
+
help: require_parser.constant(false),
|
|
63
|
+
version: require_parser.constant(true),
|
|
64
|
+
result: versionCommand
|
|
65
|
+
}), require_parser.object({
|
|
66
|
+
help: require_parser.constant(false),
|
|
67
|
+
version: require_parser.constant(false),
|
|
68
|
+
result: parser
|
|
69
|
+
})) : help === "none" && version === "option" ? require_parser.longestMatch(require_parser.object({
|
|
70
|
+
help: require_parser.constant(false),
|
|
71
|
+
version: require_parser.constant(false),
|
|
72
|
+
result: parser
|
|
73
|
+
}), require_parser.merge(require_parser.object({
|
|
74
|
+
help: require_parser.constant(false),
|
|
75
|
+
version: require_parser.constant(true)
|
|
76
|
+
}), versionOption)) : help === "none" && version === "both" ? require_parser.longestMatch(require_parser.object({
|
|
77
|
+
help: require_parser.constant(false),
|
|
78
|
+
version: require_parser.constant(true),
|
|
79
|
+
result: versionCommand
|
|
80
|
+
}), require_parser.object({
|
|
81
|
+
help: require_parser.constant(false),
|
|
82
|
+
version: require_parser.constant(false),
|
|
83
|
+
result: parser
|
|
84
|
+
}), require_parser.merge(require_parser.object({
|
|
85
|
+
help: require_parser.constant(false),
|
|
86
|
+
version: require_parser.constant(true)
|
|
87
|
+
}), versionOption)) : help === "command" && version === "none" ? require_parser.longestMatch(require_parser.object({
|
|
88
|
+
help: require_parser.constant(true),
|
|
89
|
+
version: require_parser.constant(false),
|
|
90
|
+
commands: helpCommand
|
|
91
|
+
}), require_parser.object({
|
|
92
|
+
help: require_parser.constant(false),
|
|
93
|
+
version: require_parser.constant(false),
|
|
94
|
+
result: parser
|
|
95
|
+
})) : help === "command" && version === "command" ? require_parser.longestMatch(require_parser.object({
|
|
96
|
+
help: require_parser.constant(true),
|
|
97
|
+
version: require_parser.constant(false),
|
|
98
|
+
commands: helpCommand
|
|
99
|
+
}), require_parser.object({
|
|
100
|
+
help: require_parser.constant(false),
|
|
101
|
+
version: require_parser.constant(true),
|
|
102
|
+
result: versionCommand
|
|
103
|
+
}), require_parser.object({
|
|
104
|
+
help: require_parser.constant(false),
|
|
105
|
+
version: require_parser.constant(false),
|
|
106
|
+
result: parser
|
|
107
|
+
})) : help === "command" && version === "option" ? require_parser.longestMatch(require_parser.object({
|
|
49
108
|
help: require_parser.constant(true),
|
|
109
|
+
version: require_parser.constant(false),
|
|
50
110
|
commands: helpCommand
|
|
51
111
|
}), require_parser.object({
|
|
52
112
|
help: require_parser.constant(false),
|
|
113
|
+
version: require_parser.constant(false),
|
|
114
|
+
result: parser
|
|
115
|
+
}), require_parser.merge(require_parser.object({
|
|
116
|
+
help: require_parser.constant(false),
|
|
117
|
+
version: require_parser.constant(true)
|
|
118
|
+
}), versionOption)) : help === "command" && version === "both" ? require_parser.longestMatch(require_parser.object({
|
|
119
|
+
help: require_parser.constant(true),
|
|
120
|
+
version: require_parser.constant(false),
|
|
121
|
+
commands: helpCommand
|
|
122
|
+
}), require_parser.object({
|
|
123
|
+
help: require_parser.constant(false),
|
|
124
|
+
version: require_parser.constant(true),
|
|
125
|
+
result: versionCommand
|
|
126
|
+
}), require_parser.object({
|
|
127
|
+
help: require_parser.constant(false),
|
|
128
|
+
version: require_parser.constant(false),
|
|
129
|
+
result: parser
|
|
130
|
+
}), require_parser.merge(require_parser.object({
|
|
131
|
+
help: require_parser.constant(false),
|
|
132
|
+
version: require_parser.constant(true)
|
|
133
|
+
}), versionOption)) : help === "option" && version === "none" ? require_parser.longestMatch(require_parser.object({
|
|
134
|
+
help: require_parser.constant(false),
|
|
135
|
+
version: require_parser.constant(false),
|
|
53
136
|
result: parser
|
|
54
|
-
})
|
|
137
|
+
}), contextualHelpParser, require_parser.merge(require_parser.object({
|
|
138
|
+
help: require_parser.constant(true),
|
|
139
|
+
version: require_parser.constant(false),
|
|
140
|
+
commands: require_parser.constant([])
|
|
141
|
+
}), helpOption)) : help === "option" && version === "command" ? require_parser.longestMatch(require_parser.object({
|
|
55
142
|
help: require_parser.constant(false),
|
|
143
|
+
version: require_parser.constant(true),
|
|
144
|
+
result: versionCommand
|
|
145
|
+
}), require_parser.object({
|
|
146
|
+
help: require_parser.constant(false),
|
|
147
|
+
version: require_parser.constant(false),
|
|
56
148
|
result: parser
|
|
57
149
|
}), contextualHelpParser, require_parser.merge(require_parser.object({
|
|
58
150
|
help: require_parser.constant(true),
|
|
151
|
+
version: require_parser.constant(false),
|
|
59
152
|
commands: require_parser.constant([])
|
|
60
|
-
}), helpOption)) : require_parser.longestMatch(require_parser.object({
|
|
153
|
+
}), helpOption)) : help === "option" && version === "option" ? require_parser.longestMatch(require_parser.merge(require_parser.object({
|
|
154
|
+
help: require_parser.constant(false),
|
|
155
|
+
version: require_parser.constant(true)
|
|
156
|
+
}), versionOption), require_parser.object({
|
|
61
157
|
help: require_parser.constant(false),
|
|
158
|
+
version: require_parser.constant(false),
|
|
62
159
|
result: parser
|
|
160
|
+
}), contextualHelpParser, require_parser.merge(require_parser.object({
|
|
161
|
+
help: require_parser.constant(true),
|
|
162
|
+
version: require_parser.constant(false),
|
|
163
|
+
commands: require_parser.constant([])
|
|
164
|
+
}), helpOption)) : help === "option" && version === "both" ? require_parser.longestMatch(require_parser.merge(require_parser.object({
|
|
165
|
+
help: require_parser.constant(false),
|
|
166
|
+
version: require_parser.constant(true)
|
|
167
|
+
}), versionOption), require_parser.object({
|
|
168
|
+
help: require_parser.constant(false),
|
|
169
|
+
version: require_parser.constant(true),
|
|
170
|
+
result: versionCommand
|
|
63
171
|
}), require_parser.object({
|
|
172
|
+
help: require_parser.constant(false),
|
|
173
|
+
version: require_parser.constant(false),
|
|
174
|
+
result: parser
|
|
175
|
+
}), contextualHelpParser, require_parser.merge(require_parser.object({
|
|
176
|
+
help: require_parser.constant(true),
|
|
177
|
+
version: require_parser.constant(false),
|
|
178
|
+
commands: require_parser.constant([])
|
|
179
|
+
}), helpOption)) : help === "both" && version === "none" ? require_parser.longestMatch(require_parser.object({
|
|
180
|
+
help: require_parser.constant(false),
|
|
181
|
+
version: require_parser.constant(false),
|
|
182
|
+
result: parser
|
|
183
|
+
}), require_parser.object({
|
|
184
|
+
help: require_parser.constant(true),
|
|
185
|
+
version: require_parser.constant(false),
|
|
186
|
+
commands: helpCommand
|
|
187
|
+
}), contextualHelpParser, require_parser.merge(require_parser.object({
|
|
188
|
+
help: require_parser.constant(true),
|
|
189
|
+
version: require_parser.constant(false),
|
|
190
|
+
commands: require_parser.constant([])
|
|
191
|
+
}), helpOption)) : help === "both" && version === "command" ? require_parser.longestMatch(require_parser.object({
|
|
64
192
|
help: require_parser.constant(true),
|
|
193
|
+
version: require_parser.constant(false),
|
|
65
194
|
commands: helpCommand
|
|
195
|
+
}), require_parser.object({
|
|
196
|
+
help: require_parser.constant(false),
|
|
197
|
+
version: require_parser.constant(true),
|
|
198
|
+
result: versionCommand
|
|
199
|
+
}), require_parser.object({
|
|
200
|
+
help: require_parser.constant(false),
|
|
201
|
+
version: require_parser.constant(false),
|
|
202
|
+
result: parser
|
|
66
203
|
}), contextualHelpParser, require_parser.merge(require_parser.object({
|
|
67
204
|
help: require_parser.constant(true),
|
|
205
|
+
version: require_parser.constant(false),
|
|
68
206
|
commands: require_parser.constant([])
|
|
69
|
-
}), helpOption))
|
|
70
|
-
|
|
207
|
+
}), helpOption)) : help === "both" && version === "option" ? require_parser.longestMatch(require_parser.merge(require_parser.object({
|
|
208
|
+
help: require_parser.constant(false),
|
|
209
|
+
version: require_parser.constant(true)
|
|
210
|
+
}), versionOption), require_parser.object({
|
|
211
|
+
help: require_parser.constant(true),
|
|
212
|
+
version: require_parser.constant(false),
|
|
213
|
+
commands: helpCommand
|
|
214
|
+
}), require_parser.object({
|
|
215
|
+
help: require_parser.constant(false),
|
|
216
|
+
version: require_parser.constant(false),
|
|
217
|
+
result: parser
|
|
218
|
+
}), contextualHelpParser, require_parser.merge(require_parser.object({
|
|
219
|
+
help: require_parser.constant(true),
|
|
220
|
+
version: require_parser.constant(false),
|
|
221
|
+
commands: require_parser.constant([])
|
|
222
|
+
}), helpOption)) : require_parser.longestMatch(require_parser.merge(require_parser.object({
|
|
223
|
+
help: require_parser.constant(false),
|
|
224
|
+
version: require_parser.constant(true)
|
|
225
|
+
}), versionOption), require_parser.object({
|
|
226
|
+
help: require_parser.constant(false),
|
|
227
|
+
version: require_parser.constant(true),
|
|
228
|
+
result: versionCommand
|
|
229
|
+
}), require_parser.object({
|
|
230
|
+
help: require_parser.constant(true),
|
|
231
|
+
version: require_parser.constant(false),
|
|
232
|
+
commands: helpCommand
|
|
233
|
+
}), require_parser.object({
|
|
234
|
+
help: require_parser.constant(false),
|
|
235
|
+
version: require_parser.constant(false),
|
|
236
|
+
result: parser
|
|
237
|
+
}), require_parser.longestMatch(contextualHelpParser, require_parser.merge(require_parser.object({
|
|
238
|
+
help: require_parser.constant(true),
|
|
239
|
+
version: require_parser.constant(false),
|
|
240
|
+
commands: require_parser.constant([])
|
|
241
|
+
}), helpOption)));
|
|
242
|
+
let result = require_parser.parse(augmentedParser, args);
|
|
243
|
+
if (result.success && typeof result.value === "object" && result.value != null && "help" in result.value && "version" in result.value) {
|
|
244
|
+
const parsedValue = result.value;
|
|
245
|
+
const hasVersionInput = args.includes("--version") || args.length > 0 && args[0] === "version";
|
|
246
|
+
const hasHelpInput = args.includes("--help") || args.length > 0 && args[0] === "help";
|
|
247
|
+
if (parsedValue.version && !hasVersionInput || parsedValue.help && !hasHelpInput && !parsedValue.result) result = require_parser.parse(parser, args);
|
|
248
|
+
}
|
|
71
249
|
if (result.success) {
|
|
72
250
|
const value = result.value;
|
|
73
|
-
if (help === "none") return value;
|
|
74
|
-
if (typeof value === "object" && value != null && "help" in value) {
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
251
|
+
if (help === "none" && version === "none") return value;
|
|
252
|
+
if (typeof value === "object" && value != null && "help" in value && "version" in value) {
|
|
253
|
+
const parsedValue = value;
|
|
254
|
+
if (parsedValue.version) {
|
|
255
|
+
const hasVersionOption = args.includes("--version");
|
|
256
|
+
const hasVersionCommand = args.length > 0 && args[0] === "version";
|
|
257
|
+
if (hasVersionOption || hasVersionCommand) {
|
|
258
|
+
stdout(versionValue);
|
|
259
|
+
try {
|
|
260
|
+
return onVersion(0);
|
|
261
|
+
} catch {
|
|
262
|
+
return onVersion();
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (parsedValue.help) {
|
|
267
|
+
if (version !== "none" && args.includes("--version")) {
|
|
268
|
+
stdout(versionValue);
|
|
269
|
+
try {
|
|
270
|
+
return onVersion(0);
|
|
271
|
+
} catch {
|
|
272
|
+
return onVersion();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
let commandContext = [];
|
|
276
|
+
if (Array.isArray(parsedValue.commands)) commandContext = parsedValue.commands;
|
|
277
|
+
else if (typeof parsedValue.commands === "object" && parsedValue.commands != null && "length" in parsedValue.commands) commandContext = parsedValue.commands;
|
|
278
|
+
const doc = require_parser.getDocPage(commandContext.length < 1 ? augmentedParser : parser, commandContext);
|
|
279
|
+
if (doc != null) stdout(require_doc.formatDocPage(programName, doc, {
|
|
280
|
+
colors,
|
|
281
|
+
maxWidth
|
|
282
|
+
}));
|
|
283
|
+
try {
|
|
284
|
+
return onHelp(0);
|
|
285
|
+
} catch {
|
|
286
|
+
return onHelp();
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return parsedValue.result ?? value;
|
|
77
290
|
} else return value;
|
|
78
|
-
let commandContext = [];
|
|
79
|
-
const helpValue = value;
|
|
80
|
-
if (Array.isArray(helpValue.commands)) commandContext = helpValue.commands;
|
|
81
|
-
else if (typeof helpValue.commands === "object" && helpValue.commands != null && "length" in helpValue.commands) commandContext = helpValue.commands;
|
|
82
|
-
const doc = require_parser.getDocPage(commandContext.length < 1 ? augmentedParser : parser, commandContext);
|
|
83
|
-
if (doc != null) stdout(require_doc.formatDocPage(programName, doc, {
|
|
84
|
-
colors,
|
|
85
|
-
maxWidth
|
|
86
|
-
}));
|
|
87
|
-
return onHelp(0);
|
|
88
291
|
}
|
|
89
292
|
if (aboveError === "help") {
|
|
90
293
|
const doc = require_parser.getDocPage(args.length < 1 ? augmentedParser : parser, args);
|
package/dist/facade.d.cts
CHANGED
|
@@ -21,26 +21,59 @@ interface RunOptions<THelp, TError> {
|
|
|
21
21
|
*/
|
|
22
22
|
readonly maxWidth?: number;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* - `"command"`: Only the `help` subcommand is available
|
|
27
|
-
* - `"option"`: Only the `--help` option is available
|
|
28
|
-
* - `"both"`: Both `help` subcommand and `--help` option are available
|
|
29
|
-
* - `"none"`: No help functionality is provided
|
|
30
|
-
*
|
|
31
|
-
* @default `"none"`
|
|
24
|
+
* Help configuration. When provided, enables help functionality.
|
|
32
25
|
*/
|
|
33
|
-
readonly help?:
|
|
26
|
+
readonly help?: {
|
|
27
|
+
/**
|
|
28
|
+
* Determines how help is made available:
|
|
29
|
+
*
|
|
30
|
+
* - `"command"`: Only the `help` subcommand is available
|
|
31
|
+
* - `"option"`: Only the `--help` option is available
|
|
32
|
+
* - `"both"`: Both `help` subcommand and `--help` option are available
|
|
33
|
+
*
|
|
34
|
+
* @default `"option"`
|
|
35
|
+
*/
|
|
36
|
+
readonly mode?: "command" | "option" | "both";
|
|
37
|
+
/**
|
|
38
|
+
* Callback function invoked when help is requested. The function can
|
|
39
|
+
* optionally receive an exit code parameter.
|
|
40
|
+
*
|
|
41
|
+
* You usually want to pass `process.exit` on Node.js or Bun and `Deno.exit`
|
|
42
|
+
* on Deno to this option.
|
|
43
|
+
*
|
|
44
|
+
* @default Returns `void` when help is shown.
|
|
45
|
+
*/
|
|
46
|
+
readonly onShow?: (() => THelp) | ((exitCode: number) => THelp);
|
|
47
|
+
};
|
|
34
48
|
/**
|
|
35
|
-
*
|
|
36
|
-
* optionally receive an exit code parameter.
|
|
37
|
-
*
|
|
38
|
-
* You usually want to pass `process.exit` on Node.js or Bun and `Deno.exit`
|
|
39
|
-
* on Deno to this option.
|
|
40
|
-
*
|
|
41
|
-
* @default Returns `void` when help is shown.
|
|
49
|
+
* Version configuration. When provided, enables version functionality.
|
|
42
50
|
*/
|
|
43
|
-
readonly
|
|
51
|
+
readonly version?: {
|
|
52
|
+
/**
|
|
53
|
+
* Determines how version is made available:
|
|
54
|
+
*
|
|
55
|
+
* - `"command"`: Only the `version` subcommand is available
|
|
56
|
+
* - `"option"`: Only the `--version` option is available
|
|
57
|
+
* - `"both"`: Both `version` subcommand and `--version` option are available
|
|
58
|
+
*
|
|
59
|
+
* @default `"option"`
|
|
60
|
+
*/
|
|
61
|
+
readonly mode?: "command" | "option" | "both";
|
|
62
|
+
/**
|
|
63
|
+
* The version string to display when version is requested.
|
|
64
|
+
*/
|
|
65
|
+
readonly value: string;
|
|
66
|
+
/**
|
|
67
|
+
* Callback function invoked when version is requested. The function can
|
|
68
|
+
* optionally receive an exit code parameter.
|
|
69
|
+
*
|
|
70
|
+
* You usually want to pass `process.exit` on Node.js or Bun and `Deno.exit`
|
|
71
|
+
* on Deno to this option.
|
|
72
|
+
*
|
|
73
|
+
* @default Returns `void` when version is shown.
|
|
74
|
+
*/
|
|
75
|
+
readonly onShow?: (() => THelp) | ((exitCode: number) => THelp);
|
|
76
|
+
};
|
|
44
77
|
/**
|
|
45
78
|
* What to display above error messages:
|
|
46
79
|
* - `"usage"`: Show usage information
|
package/dist/facade.d.ts
CHANGED
|
@@ -21,26 +21,59 @@ interface RunOptions<THelp, TError> {
|
|
|
21
21
|
*/
|
|
22
22
|
readonly maxWidth?: number;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* - `"command"`: Only the `help` subcommand is available
|
|
27
|
-
* - `"option"`: Only the `--help` option is available
|
|
28
|
-
* - `"both"`: Both `help` subcommand and `--help` option are available
|
|
29
|
-
* - `"none"`: No help functionality is provided
|
|
30
|
-
*
|
|
31
|
-
* @default `"none"`
|
|
24
|
+
* Help configuration. When provided, enables help functionality.
|
|
32
25
|
*/
|
|
33
|
-
readonly help?:
|
|
26
|
+
readonly help?: {
|
|
27
|
+
/**
|
|
28
|
+
* Determines how help is made available:
|
|
29
|
+
*
|
|
30
|
+
* - `"command"`: Only the `help` subcommand is available
|
|
31
|
+
* - `"option"`: Only the `--help` option is available
|
|
32
|
+
* - `"both"`: Both `help` subcommand and `--help` option are available
|
|
33
|
+
*
|
|
34
|
+
* @default `"option"`
|
|
35
|
+
*/
|
|
36
|
+
readonly mode?: "command" | "option" | "both";
|
|
37
|
+
/**
|
|
38
|
+
* Callback function invoked when help is requested. The function can
|
|
39
|
+
* optionally receive an exit code parameter.
|
|
40
|
+
*
|
|
41
|
+
* You usually want to pass `process.exit` on Node.js or Bun and `Deno.exit`
|
|
42
|
+
* on Deno to this option.
|
|
43
|
+
*
|
|
44
|
+
* @default Returns `void` when help is shown.
|
|
45
|
+
*/
|
|
46
|
+
readonly onShow?: (() => THelp) | ((exitCode: number) => THelp);
|
|
47
|
+
};
|
|
34
48
|
/**
|
|
35
|
-
*
|
|
36
|
-
* optionally receive an exit code parameter.
|
|
37
|
-
*
|
|
38
|
-
* You usually want to pass `process.exit` on Node.js or Bun and `Deno.exit`
|
|
39
|
-
* on Deno to this option.
|
|
40
|
-
*
|
|
41
|
-
* @default Returns `void` when help is shown.
|
|
49
|
+
* Version configuration. When provided, enables version functionality.
|
|
42
50
|
*/
|
|
43
|
-
readonly
|
|
51
|
+
readonly version?: {
|
|
52
|
+
/**
|
|
53
|
+
* Determines how version is made available:
|
|
54
|
+
*
|
|
55
|
+
* - `"command"`: Only the `version` subcommand is available
|
|
56
|
+
* - `"option"`: Only the `--version` option is available
|
|
57
|
+
* - `"both"`: Both `version` subcommand and `--version` option are available
|
|
58
|
+
*
|
|
59
|
+
* @default `"option"`
|
|
60
|
+
*/
|
|
61
|
+
readonly mode?: "command" | "option" | "both";
|
|
62
|
+
/**
|
|
63
|
+
* The version string to display when version is requested.
|
|
64
|
+
*/
|
|
65
|
+
readonly value: string;
|
|
66
|
+
/**
|
|
67
|
+
* Callback function invoked when version is requested. The function can
|
|
68
|
+
* optionally receive an exit code parameter.
|
|
69
|
+
*
|
|
70
|
+
* You usually want to pass `process.exit` on Node.js or Bun and `Deno.exit`
|
|
71
|
+
* on Deno to this option.
|
|
72
|
+
*
|
|
73
|
+
* @default Returns `void` when version is shown.
|
|
74
|
+
*/
|
|
75
|
+
readonly onShow?: (() => THelp) | ((exitCode: number) => THelp);
|
|
76
|
+
};
|
|
44
77
|
/**
|
|
45
78
|
* What to display above error messages:
|
|
46
79
|
* - `"usage"`: Show usage information
|
package/dist/facade.js
CHANGED
|
@@ -35,56 +35,259 @@ import { argument, command, constant, flag, getDocPage, longestMatch, merge, mul
|
|
|
35
35
|
* @throws {RunError} When parsing fails and no `onError` callback is provided.
|
|
36
36
|
*/
|
|
37
37
|
function run(parser, programName, args, options = {}) {
|
|
38
|
-
|
|
38
|
+
const helpMode = options.help?.mode ?? "option";
|
|
39
|
+
const onHelp = options.help?.onShow ?? (() => ({}));
|
|
40
|
+
const versionMode = options.version?.mode ?? "option";
|
|
41
|
+
const versionValue = options.version?.value ?? "";
|
|
42
|
+
const onVersion = options.version?.onShow ?? (() => ({}));
|
|
43
|
+
let { colors, maxWidth, aboveError = "usage", onError = () => {
|
|
39
44
|
throw new RunError("Failed to parse command line arguments.");
|
|
40
45
|
}, stderr = console.error, stdout = console.log } = options;
|
|
46
|
+
const help = options.help ? helpMode : "none";
|
|
41
47
|
const contextualHelpParser = object({
|
|
42
48
|
help: constant(true),
|
|
43
|
-
|
|
49
|
+
version: constant(false),
|
|
50
|
+
commands: multiple(argument(string({
|
|
51
|
+
metavar: "COMMAND",
|
|
52
|
+
pattern: /^[^-].*$/
|
|
53
|
+
}))),
|
|
44
54
|
__help: flag("--help")
|
|
45
55
|
});
|
|
46
56
|
const helpCommand = command("help", multiple(argument(string({ metavar: "COMMAND" }))), { description: message`Show help information.` });
|
|
47
57
|
const helpOption = option("--help", { description: message`Show help information.` });
|
|
48
|
-
const
|
|
58
|
+
const version = options.version ? versionMode : "none";
|
|
59
|
+
const versionCommand = command("version", object({}), { description: message`Show version information.` });
|
|
60
|
+
const versionOption = option("--version", { description: message`Show version information.` });
|
|
61
|
+
const augmentedParser = help === "none" && version === "none" ? parser : help === "none" && version === "command" ? longestMatch(object({
|
|
62
|
+
help: constant(false),
|
|
63
|
+
version: constant(true),
|
|
64
|
+
result: versionCommand
|
|
65
|
+
}), object({
|
|
66
|
+
help: constant(false),
|
|
67
|
+
version: constant(false),
|
|
68
|
+
result: parser
|
|
69
|
+
})) : help === "none" && version === "option" ? longestMatch(object({
|
|
70
|
+
help: constant(false),
|
|
71
|
+
version: constant(false),
|
|
72
|
+
result: parser
|
|
73
|
+
}), merge(object({
|
|
74
|
+
help: constant(false),
|
|
75
|
+
version: constant(true)
|
|
76
|
+
}), versionOption)) : help === "none" && version === "both" ? longestMatch(object({
|
|
77
|
+
help: constant(false),
|
|
78
|
+
version: constant(true),
|
|
79
|
+
result: versionCommand
|
|
80
|
+
}), object({
|
|
81
|
+
help: constant(false),
|
|
82
|
+
version: constant(false),
|
|
83
|
+
result: parser
|
|
84
|
+
}), merge(object({
|
|
85
|
+
help: constant(false),
|
|
86
|
+
version: constant(true)
|
|
87
|
+
}), versionOption)) : help === "command" && version === "none" ? longestMatch(object({
|
|
88
|
+
help: constant(true),
|
|
89
|
+
version: constant(false),
|
|
90
|
+
commands: helpCommand
|
|
91
|
+
}), object({
|
|
92
|
+
help: constant(false),
|
|
93
|
+
version: constant(false),
|
|
94
|
+
result: parser
|
|
95
|
+
})) : help === "command" && version === "command" ? longestMatch(object({
|
|
96
|
+
help: constant(true),
|
|
97
|
+
version: constant(false),
|
|
98
|
+
commands: helpCommand
|
|
99
|
+
}), object({
|
|
100
|
+
help: constant(false),
|
|
101
|
+
version: constant(true),
|
|
102
|
+
result: versionCommand
|
|
103
|
+
}), object({
|
|
104
|
+
help: constant(false),
|
|
105
|
+
version: constant(false),
|
|
106
|
+
result: parser
|
|
107
|
+
})) : help === "command" && version === "option" ? longestMatch(object({
|
|
49
108
|
help: constant(true),
|
|
109
|
+
version: constant(false),
|
|
50
110
|
commands: helpCommand
|
|
51
111
|
}), object({
|
|
52
112
|
help: constant(false),
|
|
113
|
+
version: constant(false),
|
|
114
|
+
result: parser
|
|
115
|
+
}), merge(object({
|
|
116
|
+
help: constant(false),
|
|
117
|
+
version: constant(true)
|
|
118
|
+
}), versionOption)) : help === "command" && version === "both" ? longestMatch(object({
|
|
119
|
+
help: constant(true),
|
|
120
|
+
version: constant(false),
|
|
121
|
+
commands: helpCommand
|
|
122
|
+
}), object({
|
|
123
|
+
help: constant(false),
|
|
124
|
+
version: constant(true),
|
|
125
|
+
result: versionCommand
|
|
126
|
+
}), object({
|
|
127
|
+
help: constant(false),
|
|
128
|
+
version: constant(false),
|
|
129
|
+
result: parser
|
|
130
|
+
}), merge(object({
|
|
131
|
+
help: constant(false),
|
|
132
|
+
version: constant(true)
|
|
133
|
+
}), versionOption)) : help === "option" && version === "none" ? longestMatch(object({
|
|
134
|
+
help: constant(false),
|
|
135
|
+
version: constant(false),
|
|
53
136
|
result: parser
|
|
54
|
-
})
|
|
137
|
+
}), contextualHelpParser, merge(object({
|
|
138
|
+
help: constant(true),
|
|
139
|
+
version: constant(false),
|
|
140
|
+
commands: constant([])
|
|
141
|
+
}), helpOption)) : help === "option" && version === "command" ? longestMatch(object({
|
|
55
142
|
help: constant(false),
|
|
143
|
+
version: constant(true),
|
|
144
|
+
result: versionCommand
|
|
145
|
+
}), object({
|
|
146
|
+
help: constant(false),
|
|
147
|
+
version: constant(false),
|
|
56
148
|
result: parser
|
|
57
149
|
}), contextualHelpParser, merge(object({
|
|
58
150
|
help: constant(true),
|
|
151
|
+
version: constant(false),
|
|
59
152
|
commands: constant([])
|
|
60
|
-
}), helpOption)) : longestMatch(object({
|
|
153
|
+
}), helpOption)) : help === "option" && version === "option" ? longestMatch(merge(object({
|
|
154
|
+
help: constant(false),
|
|
155
|
+
version: constant(true)
|
|
156
|
+
}), versionOption), object({
|
|
61
157
|
help: constant(false),
|
|
158
|
+
version: constant(false),
|
|
62
159
|
result: parser
|
|
160
|
+
}), contextualHelpParser, merge(object({
|
|
161
|
+
help: constant(true),
|
|
162
|
+
version: constant(false),
|
|
163
|
+
commands: constant([])
|
|
164
|
+
}), helpOption)) : help === "option" && version === "both" ? longestMatch(merge(object({
|
|
165
|
+
help: constant(false),
|
|
166
|
+
version: constant(true)
|
|
167
|
+
}), versionOption), object({
|
|
168
|
+
help: constant(false),
|
|
169
|
+
version: constant(true),
|
|
170
|
+
result: versionCommand
|
|
63
171
|
}), object({
|
|
172
|
+
help: constant(false),
|
|
173
|
+
version: constant(false),
|
|
174
|
+
result: parser
|
|
175
|
+
}), contextualHelpParser, merge(object({
|
|
176
|
+
help: constant(true),
|
|
177
|
+
version: constant(false),
|
|
178
|
+
commands: constant([])
|
|
179
|
+
}), helpOption)) : help === "both" && version === "none" ? longestMatch(object({
|
|
180
|
+
help: constant(false),
|
|
181
|
+
version: constant(false),
|
|
182
|
+
result: parser
|
|
183
|
+
}), object({
|
|
184
|
+
help: constant(true),
|
|
185
|
+
version: constant(false),
|
|
186
|
+
commands: helpCommand
|
|
187
|
+
}), contextualHelpParser, merge(object({
|
|
188
|
+
help: constant(true),
|
|
189
|
+
version: constant(false),
|
|
190
|
+
commands: constant([])
|
|
191
|
+
}), helpOption)) : help === "both" && version === "command" ? longestMatch(object({
|
|
64
192
|
help: constant(true),
|
|
193
|
+
version: constant(false),
|
|
65
194
|
commands: helpCommand
|
|
195
|
+
}), object({
|
|
196
|
+
help: constant(false),
|
|
197
|
+
version: constant(true),
|
|
198
|
+
result: versionCommand
|
|
199
|
+
}), object({
|
|
200
|
+
help: constant(false),
|
|
201
|
+
version: constant(false),
|
|
202
|
+
result: parser
|
|
66
203
|
}), contextualHelpParser, merge(object({
|
|
67
204
|
help: constant(true),
|
|
205
|
+
version: constant(false),
|
|
68
206
|
commands: constant([])
|
|
69
|
-
}), helpOption))
|
|
70
|
-
|
|
207
|
+
}), helpOption)) : help === "both" && version === "option" ? longestMatch(merge(object({
|
|
208
|
+
help: constant(false),
|
|
209
|
+
version: constant(true)
|
|
210
|
+
}), versionOption), object({
|
|
211
|
+
help: constant(true),
|
|
212
|
+
version: constant(false),
|
|
213
|
+
commands: helpCommand
|
|
214
|
+
}), object({
|
|
215
|
+
help: constant(false),
|
|
216
|
+
version: constant(false),
|
|
217
|
+
result: parser
|
|
218
|
+
}), contextualHelpParser, merge(object({
|
|
219
|
+
help: constant(true),
|
|
220
|
+
version: constant(false),
|
|
221
|
+
commands: constant([])
|
|
222
|
+
}), helpOption)) : longestMatch(merge(object({
|
|
223
|
+
help: constant(false),
|
|
224
|
+
version: constant(true)
|
|
225
|
+
}), versionOption), object({
|
|
226
|
+
help: constant(false),
|
|
227
|
+
version: constant(true),
|
|
228
|
+
result: versionCommand
|
|
229
|
+
}), object({
|
|
230
|
+
help: constant(true),
|
|
231
|
+
version: constant(false),
|
|
232
|
+
commands: helpCommand
|
|
233
|
+
}), object({
|
|
234
|
+
help: constant(false),
|
|
235
|
+
version: constant(false),
|
|
236
|
+
result: parser
|
|
237
|
+
}), longestMatch(contextualHelpParser, merge(object({
|
|
238
|
+
help: constant(true),
|
|
239
|
+
version: constant(false),
|
|
240
|
+
commands: constant([])
|
|
241
|
+
}), helpOption)));
|
|
242
|
+
let result = parse(augmentedParser, args);
|
|
243
|
+
if (result.success && typeof result.value === "object" && result.value != null && "help" in result.value && "version" in result.value) {
|
|
244
|
+
const parsedValue = result.value;
|
|
245
|
+
const hasVersionInput = args.includes("--version") || args.length > 0 && args[0] === "version";
|
|
246
|
+
const hasHelpInput = args.includes("--help") || args.length > 0 && args[0] === "help";
|
|
247
|
+
if (parsedValue.version && !hasVersionInput || parsedValue.help && !hasHelpInput && !parsedValue.result) result = parse(parser, args);
|
|
248
|
+
}
|
|
71
249
|
if (result.success) {
|
|
72
250
|
const value = result.value;
|
|
73
|
-
if (help === "none") return value;
|
|
74
|
-
if (typeof value === "object" && value != null && "help" in value) {
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
251
|
+
if (help === "none" && version === "none") return value;
|
|
252
|
+
if (typeof value === "object" && value != null && "help" in value && "version" in value) {
|
|
253
|
+
const parsedValue = value;
|
|
254
|
+
if (parsedValue.version) {
|
|
255
|
+
const hasVersionOption = args.includes("--version");
|
|
256
|
+
const hasVersionCommand = args.length > 0 && args[0] === "version";
|
|
257
|
+
if (hasVersionOption || hasVersionCommand) {
|
|
258
|
+
stdout(versionValue);
|
|
259
|
+
try {
|
|
260
|
+
return onVersion(0);
|
|
261
|
+
} catch {
|
|
262
|
+
return onVersion();
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (parsedValue.help) {
|
|
267
|
+
if (version !== "none" && args.includes("--version")) {
|
|
268
|
+
stdout(versionValue);
|
|
269
|
+
try {
|
|
270
|
+
return onVersion(0);
|
|
271
|
+
} catch {
|
|
272
|
+
return onVersion();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
let commandContext = [];
|
|
276
|
+
if (Array.isArray(parsedValue.commands)) commandContext = parsedValue.commands;
|
|
277
|
+
else if (typeof parsedValue.commands === "object" && parsedValue.commands != null && "length" in parsedValue.commands) commandContext = parsedValue.commands;
|
|
278
|
+
const doc = getDocPage(commandContext.length < 1 ? augmentedParser : parser, commandContext);
|
|
279
|
+
if (doc != null) stdout(formatDocPage(programName, doc, {
|
|
280
|
+
colors,
|
|
281
|
+
maxWidth
|
|
282
|
+
}));
|
|
283
|
+
try {
|
|
284
|
+
return onHelp(0);
|
|
285
|
+
} catch {
|
|
286
|
+
return onHelp();
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return parsedValue.result ?? value;
|
|
77
290
|
} else return value;
|
|
78
|
-
let commandContext = [];
|
|
79
|
-
const helpValue = value;
|
|
80
|
-
if (Array.isArray(helpValue.commands)) commandContext = helpValue.commands;
|
|
81
|
-
else if (typeof helpValue.commands === "object" && helpValue.commands != null && "length" in helpValue.commands) commandContext = helpValue.commands;
|
|
82
|
-
const doc = getDocPage(commandContext.length < 1 ? augmentedParser : parser, commandContext);
|
|
83
|
-
if (doc != null) stdout(formatDocPage(programName, doc, {
|
|
84
|
-
colors,
|
|
85
|
-
maxWidth
|
|
86
|
-
}));
|
|
87
|
-
return onHelp(0);
|
|
88
291
|
}
|
|
89
292
|
if (aboveError === "help") {
|
|
90
293
|
const doc = getDocPage(args.length < 1 ? augmentedParser : parser, args);
|
package/dist/parser.d.cts
CHANGED
|
@@ -661,6 +661,7 @@ declare function or<TA, TB, TC, TD, TE, TF, TG, TH, TI, TJ, TStateA, TStateB, TS
|
|
|
661
661
|
* @param b The second {@link Parser} to try.
|
|
662
662
|
* @returns A {@link Parser} that tries to parse using both parsers
|
|
663
663
|
* and returns the result of the parser that consumed more tokens.
|
|
664
|
+
* @since 0.3.0
|
|
664
665
|
*/
|
|
665
666
|
declare function longestMatch<TA, TB, TStateA, TStateB>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>): Parser<TA | TB, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>]>;
|
|
666
667
|
/**
|
|
@@ -679,6 +680,7 @@ declare function longestMatch<TA, TB, TStateA, TStateB>(a: Parser<TA, TStateA>,
|
|
|
679
680
|
* @param c The third {@link Parser} to try.
|
|
680
681
|
* @returns A {@link Parser} that tries to parse using all parsers
|
|
681
682
|
* and returns the result of the parser that consumed the most tokens.
|
|
683
|
+
* @since 0.3.0
|
|
682
684
|
*/
|
|
683
685
|
declare function longestMatch<TA, TB, TC, TStateA, TStateB, TStateC>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>): Parser<TA | TB | TC, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>]>;
|
|
684
686
|
/**
|
|
@@ -700,6 +702,7 @@ declare function longestMatch<TA, TB, TC, TStateA, TStateB, TStateC>(a: Parser<T
|
|
|
700
702
|
* @param d The fourth {@link Parser} to try.
|
|
701
703
|
* @returns A {@link Parser} that tries to parse using all parsers
|
|
702
704
|
* and returns the result of the parser that consumed the most tokens.
|
|
705
|
+
* @since 0.3.0
|
|
703
706
|
*/
|
|
704
707
|
declare function longestMatch<TA, TB, TC, TD, TStateA, TStateB, TStateC, TStateD>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>): Parser<TA | TB | TC | TD, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>]>;
|
|
705
708
|
/**
|
|
@@ -724,6 +727,7 @@ declare function longestMatch<TA, TB, TC, TD, TStateA, TStateB, TStateC, TStateD
|
|
|
724
727
|
* @param e The fifth {@link Parser} to try.
|
|
725
728
|
* @returns A {@link Parser} that tries to parse using all parsers
|
|
726
729
|
* and returns the result of the parser that consumed the most tokens.
|
|
730
|
+
* @since 0.3.0
|
|
727
731
|
*/
|
|
728
732
|
declare function longestMatch<TA, TB, TC, TD, TE, TStateA, TStateB, TStateC, TStateD, TStateE>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>): Parser<TA | TB | TC | TD | TE, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>]>;
|
|
729
733
|
/**
|
package/dist/parser.d.ts
CHANGED
|
@@ -661,6 +661,7 @@ declare function or<TA, TB, TC, TD, TE, TF, TG, TH, TI, TJ, TStateA, TStateB, TS
|
|
|
661
661
|
* @param b The second {@link Parser} to try.
|
|
662
662
|
* @returns A {@link Parser} that tries to parse using both parsers
|
|
663
663
|
* and returns the result of the parser that consumed more tokens.
|
|
664
|
+
* @since 0.3.0
|
|
664
665
|
*/
|
|
665
666
|
declare function longestMatch<TA, TB, TStateA, TStateB>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>): Parser<TA | TB, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>]>;
|
|
666
667
|
/**
|
|
@@ -679,6 +680,7 @@ declare function longestMatch<TA, TB, TStateA, TStateB>(a: Parser<TA, TStateA>,
|
|
|
679
680
|
* @param c The third {@link Parser} to try.
|
|
680
681
|
* @returns A {@link Parser} that tries to parse using all parsers
|
|
681
682
|
* and returns the result of the parser that consumed the most tokens.
|
|
683
|
+
* @since 0.3.0
|
|
682
684
|
*/
|
|
683
685
|
declare function longestMatch<TA, TB, TC, TStateA, TStateB, TStateC>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>): Parser<TA | TB | TC, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>]>;
|
|
684
686
|
/**
|
|
@@ -700,6 +702,7 @@ declare function longestMatch<TA, TB, TC, TStateA, TStateB, TStateC>(a: Parser<T
|
|
|
700
702
|
* @param d The fourth {@link Parser} to try.
|
|
701
703
|
* @returns A {@link Parser} that tries to parse using all parsers
|
|
702
704
|
* and returns the result of the parser that consumed the most tokens.
|
|
705
|
+
* @since 0.3.0
|
|
703
706
|
*/
|
|
704
707
|
declare function longestMatch<TA, TB, TC, TD, TStateA, TStateB, TStateC, TStateD>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>): Parser<TA | TB | TC | TD, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>]>;
|
|
705
708
|
/**
|
|
@@ -724,6 +727,7 @@ declare function longestMatch<TA, TB, TC, TD, TStateA, TStateB, TStateC, TStateD
|
|
|
724
727
|
* @param e The fifth {@link Parser} to try.
|
|
725
728
|
* @returns A {@link Parser} that tries to parse using all parsers
|
|
726
729
|
* and returns the result of the parser that consumed the most tokens.
|
|
730
|
+
* @since 0.3.0
|
|
727
731
|
*/
|
|
728
732
|
declare function longestMatch<TA, TB, TC, TD, TE, TStateA, TStateB, TStateC, TStateD, TStateE>(a: Parser<TA, TStateA>, b: Parser<TB, TStateB>, c: Parser<TC, TStateC>, d: Parser<TD, TStateD>, e: Parser<TE, TStateE>): Parser<TA | TB | TC | TD | TE, undefined | [0, ParserResult<TStateA>] | [1, ParserResult<TStateB>] | [2, ParserResult<TStateC>] | [3, ParserResult<TStateD>] | [4, ParserResult<TStateE>]>;
|
|
729
733
|
/**
|