@optique/core 0.3.0-dev.42 → 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/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);
|