cli-kiss 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.ts +696 -734
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/docs/.vitepress/config.mts +2 -3
- package/docs/.vitepress/theme/index.ts +4 -0
- package/docs/.vitepress/theme/style.css +4 -0
- package/docs/guide/01_getting_started.md +12 -13
- package/docs/guide/02_commands.md +71 -52
- package/docs/guide/03_options.md +25 -33
- package/docs/guide/04_positionals.md +45 -55
- package/docs/guide/05_types.md +66 -66
- package/docs/guide/06_run.md +28 -40
- package/docs/index.md +8 -3
- package/docs/public/favicon.ico +0 -0
- package/docs/public/hero.png +0 -0
- package/package.json +1 -1
- package/src/index.ts +0 -2
- package/src/lib/Command.ts +45 -123
- package/src/lib/Operation.ts +23 -32
- package/src/lib/Option.ts +150 -170
- package/src/lib/Positional.ts +44 -94
- package/src/lib/Reader.ts +123 -99
- package/src/lib/Run.ts +86 -45
- package/src/lib/Type.ts +246 -156
- package/src/lib/Typo.ts +98 -107
- package/src/lib/Usage.ts +163 -82
- package/tests/unit.Reader.aliases.ts +31 -15
- package/tests/unit.Reader.commons.ts +99 -43
- package/tests/unit.Reader.parsings.ts +50 -0
- package/tests/unit.Reader.shortBig.ts +75 -31
- package/tests/unit.command.execute.ts +86 -43
- package/tests/unit.command.usage.ts +88 -82
- package/tests/unit.runner.colors.ts +197 -0
- package/tests/unit.runner.cycle.ts +77 -63
- package/tests/unit.runner.errors.ts +23 -15
package/src/lib/Command.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { Operation } from "./Operation";
|
|
2
|
-
import { OptionUsage } from "./Option";
|
|
3
|
-
import { PositionalUsage } from "./Positional";
|
|
4
2
|
import { ReaderArgs } from "./Reader";
|
|
5
3
|
import {
|
|
6
4
|
TypoError,
|
|
@@ -9,22 +7,21 @@ import {
|
|
|
9
7
|
typoStyleUserInput,
|
|
10
8
|
TypoText,
|
|
11
9
|
} from "./Typo";
|
|
10
|
+
import { UsageCommand } from "./Usage";
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
|
-
* A CLI command
|
|
15
|
-
* Created with {@link command}, {@link commandWithSubcommands}, or {@link commandChained}.
|
|
16
|
-
* Usually passed through {@link runAndExit} to run.
|
|
13
|
+
* A CLI command. Created with {@link command}, {@link commandWithSubcommands}, or {@link commandChained}.
|
|
17
14
|
*
|
|
18
|
-
* @typeParam Context - Injected at execution
|
|
19
|
-
* @typeParam Result -
|
|
15
|
+
* @typeParam Context - Injected at execution; forwarded to handlers.
|
|
16
|
+
* @typeParam Result - Produced on execution; typically `void`.
|
|
20
17
|
*/
|
|
21
18
|
export type Command<Context, Result> = {
|
|
22
19
|
/**
|
|
23
|
-
* Returns
|
|
20
|
+
* Returns static metadata.
|
|
24
21
|
*/
|
|
25
22
|
getInformation(): CommandInformation;
|
|
26
23
|
/**
|
|
27
|
-
*
|
|
24
|
+
* Registers options/positionals on `readerArgs`; returns a {@link CommandDecoder}.
|
|
28
25
|
*/
|
|
29
26
|
consumeAndMakeDecoder(
|
|
30
27
|
readerArgs: ReaderArgs,
|
|
@@ -39,10 +36,9 @@ export type Command<Context, Result> = {
|
|
|
39
36
|
*/
|
|
40
37
|
export type CommandDecoder<Context, Result> = {
|
|
41
38
|
/**
|
|
42
|
-
*
|
|
43
|
-
* Used for `--help` and `usageOnError`.
|
|
39
|
+
* Returns {@link UsageCommand} for the current command path.
|
|
44
40
|
*/
|
|
45
|
-
generateUsage():
|
|
41
|
+
generateUsage(): UsageCommand;
|
|
46
42
|
/**
|
|
47
43
|
* Creates a ready-to-execute {@link CommandInterpreter}.
|
|
48
44
|
*
|
|
@@ -54,7 +50,7 @@ export type CommandDecoder<Context, Result> = {
|
|
|
54
50
|
/**
|
|
55
51
|
* A fully parsed, decoded and ready-to-execute command.
|
|
56
52
|
*
|
|
57
|
-
* @typeParam Context -
|
|
53
|
+
* @typeParam Context - Context passed to the handler.
|
|
58
54
|
* @typeParam Result - Value produced on success.
|
|
59
55
|
*/
|
|
60
56
|
export type CommandInterpreter<Context, Result> = {
|
|
@@ -65,15 +61,15 @@ export type CommandInterpreter<Context, Result> = {
|
|
|
65
61
|
};
|
|
66
62
|
|
|
67
63
|
/**
|
|
68
|
-
*
|
|
64
|
+
* Command metadata shown in `--help` output.
|
|
69
65
|
*/
|
|
70
66
|
export type CommandInformation = {
|
|
71
67
|
/**
|
|
72
|
-
*
|
|
68
|
+
* Shown in the usage header.
|
|
73
69
|
*/
|
|
74
70
|
description: string;
|
|
75
71
|
/**
|
|
76
|
-
*
|
|
72
|
+
* Shown in parentheses, e.g. `"deprecated"`, `"experimental"`.
|
|
77
73
|
*/
|
|
78
74
|
hint?: string;
|
|
79
75
|
/**
|
|
@@ -81,7 +77,7 @@ export type CommandInformation = {
|
|
|
81
77
|
*/
|
|
82
78
|
details?: Array<string>;
|
|
83
79
|
/**
|
|
84
|
-
*
|
|
80
|
+
* Shown in the `Examples:` section.
|
|
85
81
|
*/
|
|
86
82
|
examples?: Array<{
|
|
87
83
|
/**
|
|
@@ -89,7 +85,7 @@ export type CommandInformation = {
|
|
|
89
85
|
*/
|
|
90
86
|
explanation: string;
|
|
91
87
|
/**
|
|
92
|
-
*
|
|
88
|
+
* Example command args.
|
|
93
89
|
*/
|
|
94
90
|
commandArgs: Array<
|
|
95
91
|
| string
|
|
@@ -97,73 +93,21 @@ export type CommandInformation = {
|
|
|
97
93
|
| { subcommand: string }
|
|
98
94
|
| {
|
|
99
95
|
option:
|
|
100
|
-
| { long: string;
|
|
101
|
-
| { short: string;
|
|
96
|
+
| { long: string; inlined?: string; separated?: Array<string> }
|
|
97
|
+
| { short: string; inlined?: string; separated?: Array<string> };
|
|
102
98
|
}
|
|
103
99
|
>;
|
|
104
100
|
}>;
|
|
105
101
|
};
|
|
106
102
|
|
|
107
|
-
/**
|
|
108
|
-
* Full usage/help model.
|
|
109
|
-
* Produced by {@link CommandDecoder.generateUsage},
|
|
110
|
-
* Consumed by {@link usageToStyledLines}.
|
|
111
|
-
*/
|
|
112
|
-
export type CommandUsage = {
|
|
113
|
-
/**
|
|
114
|
-
* Segments forming the usage line
|
|
115
|
-
* (e.g. `my-cli <POSITIONAL> subcommand <ANOTHER_POSITIONAL>`).
|
|
116
|
-
*/
|
|
117
|
-
segments: Array<CommandUsageSegment>;
|
|
118
|
-
/**
|
|
119
|
-
* Command's static metadata.
|
|
120
|
-
*/
|
|
121
|
-
information: CommandInformation;
|
|
122
|
-
/**
|
|
123
|
-
* Positionals in declaration order.
|
|
124
|
-
*/
|
|
125
|
-
positionals: Array<PositionalUsage>;
|
|
126
|
-
/**
|
|
127
|
-
* Available subcommands. Non-empty when subcommand was not specified.
|
|
128
|
-
*/
|
|
129
|
-
subcommands: Array<CommandUsageSubcommand>;
|
|
130
|
-
/**
|
|
131
|
-
* Options in registration order.
|
|
132
|
-
*/
|
|
133
|
-
options: Array<OptionUsage>;
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* One element in the usage segment trail.
|
|
138
|
-
*/
|
|
139
|
-
export type CommandUsageSegment = { positional: string } | { command: string };
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Subcommand entry shown in the `Subcommands:` section of the usage output.
|
|
143
|
-
*/
|
|
144
|
-
export type CommandUsageSubcommand = {
|
|
145
|
-
/**
|
|
146
|
-
* Literal token the user types (e.g. `"deploy"`).
|
|
147
|
-
*/
|
|
148
|
-
name: string;
|
|
149
|
-
/**
|
|
150
|
-
* Short description from the subcommand's {@link CommandInformation}.
|
|
151
|
-
*/
|
|
152
|
-
description: string | undefined;
|
|
153
|
-
/**
|
|
154
|
-
* Hint from the subcommand's {@link CommandInformation}.
|
|
155
|
-
*/
|
|
156
|
-
hint: string | undefined;
|
|
157
|
-
};
|
|
158
|
-
|
|
159
103
|
/**
|
|
160
104
|
* Creates a leaf command that directly executes an {@link Operation}.
|
|
161
105
|
*
|
|
162
106
|
* @typeParam Context - Context forwarded to the handler.
|
|
163
107
|
* @typeParam Result - Value returned by the handler.
|
|
164
108
|
*
|
|
165
|
-
* @param information - Command metadata
|
|
166
|
-
* @param operation -
|
|
109
|
+
* @param information - Command metadata.
|
|
110
|
+
* @param operation - Options, positionals, and handler.
|
|
167
111
|
* @returns A {@link Command}.
|
|
168
112
|
*
|
|
169
113
|
* @example
|
|
@@ -171,7 +115,7 @@ export type CommandUsageSubcommand = {
|
|
|
171
115
|
* const greet = command(
|
|
172
116
|
* { description: "Greet a user" },
|
|
173
117
|
* operation(
|
|
174
|
-
* { options: {}, positionals: [positionalRequired({ type:
|
|
118
|
+
* { options: {}, positionals: [positionalRequired({ type: type("name") })] },
|
|
175
119
|
* async (_ctx, { positionals: [name] }) => console.log(`Hello, ${name}!`),
|
|
176
120
|
* ),
|
|
177
121
|
* );
|
|
@@ -198,7 +142,7 @@ export function command<Context, Result>(
|
|
|
198
142
|
);
|
|
199
143
|
}
|
|
200
144
|
return {
|
|
201
|
-
generateUsage: () =>
|
|
145
|
+
generateUsage: () => generateUsageLeaf(information, operation),
|
|
202
146
|
decodeAndMakeInterpreter() {
|
|
203
147
|
const operationInterpreter =
|
|
204
148
|
operationDecoder.decodeAndMakeInterpreter();
|
|
@@ -211,7 +155,7 @@ export function command<Context, Result>(
|
|
|
211
155
|
};
|
|
212
156
|
} catch (error) {
|
|
213
157
|
return {
|
|
214
|
-
generateUsage: () =>
|
|
158
|
+
generateUsage: () => generateUsageLeaf(information, operation),
|
|
215
159
|
decodeAndMakeInterpreter() {
|
|
216
160
|
throw error;
|
|
217
161
|
},
|
|
@@ -222,17 +166,16 @@ export function command<Context, Result>(
|
|
|
222
166
|
}
|
|
223
167
|
|
|
224
168
|
/**
|
|
225
|
-
* Creates a command that runs
|
|
226
|
-
* then dispatches to a named subcommand based on the next positional token.
|
|
169
|
+
* Creates a command that runs `operation` first, then dispatches to a named subcommand.
|
|
227
170
|
*
|
|
228
171
|
* @typeParam Context - Context accepted by `operation`.
|
|
229
172
|
* @typeParam Payload - Output of `operation`; becomes the subcommand's context.
|
|
230
173
|
* @typeParam Result - Value produced by the selected subcommand.
|
|
231
174
|
*
|
|
232
|
-
* @param information - Command metadata
|
|
233
|
-
* @param operation -
|
|
175
|
+
* @param information - Command metadata.
|
|
176
|
+
* @param operation - Runs first; output becomes the subcommand's context.
|
|
234
177
|
* @param subcommands - Map of subcommand names to their {@link Command}s.
|
|
235
|
-
* @returns A {@link Command}
|
|
178
|
+
* @returns A dispatching {@link Command}.
|
|
236
179
|
*
|
|
237
180
|
* @example
|
|
238
181
|
* ```ts
|
|
@@ -249,7 +192,7 @@ export function command<Context, Result>(
|
|
|
249
192
|
export function commandWithSubcommands<Context, Payload, Result>(
|
|
250
193
|
information: CommandInformation,
|
|
251
194
|
operation: Operation<Context, Payload>,
|
|
252
|
-
subcommands: { [subcommand:
|
|
195
|
+
subcommands: { [subcommand: string]: Command<Payload, Result> },
|
|
253
196
|
): Command<Context, Result> {
|
|
254
197
|
return {
|
|
255
198
|
getInformation() {
|
|
@@ -262,17 +205,16 @@ export function commandWithSubcommands<Context, Payload, Result>(
|
|
|
262
205
|
if (subcommandName === undefined) {
|
|
263
206
|
throw new TypoError(
|
|
264
207
|
new TypoText(
|
|
265
|
-
new TypoString(`<
|
|
208
|
+
new TypoString(`<subcommand>`, typoStyleUserInput),
|
|
266
209
|
new TypoString(`: Is required, but was not provided`),
|
|
267
210
|
),
|
|
268
211
|
);
|
|
269
212
|
}
|
|
270
|
-
const subcommandInput =
|
|
271
|
-
subcommands[subcommandName as Lowercase<string>];
|
|
213
|
+
const subcommandInput = subcommands[subcommandName];
|
|
272
214
|
if (subcommandInput === undefined) {
|
|
273
215
|
throw new TypoError(
|
|
274
216
|
new TypoText(
|
|
275
|
-
new TypoString(`<
|
|
217
|
+
new TypoString(`<subcommand>`, typoStyleUserInput),
|
|
276
218
|
new TypoString(`: Invalid value: `),
|
|
277
219
|
new TypoString(`"${subcommandName}"`, typoStyleQuote),
|
|
278
220
|
),
|
|
@@ -283,8 +225,8 @@ export function commandWithSubcommands<Context, Payload, Result>(
|
|
|
283
225
|
return {
|
|
284
226
|
generateUsage() {
|
|
285
227
|
const subcommandUsage = subcommandDecoder.generateUsage();
|
|
286
|
-
const currentUsage =
|
|
287
|
-
currentUsage.segments.push(
|
|
228
|
+
const currentUsage = generateUsageLeaf(information, operation);
|
|
229
|
+
currentUsage.segments.push({ subcommand: subcommandName });
|
|
288
230
|
currentUsage.segments.push(...subcommandUsage.segments);
|
|
289
231
|
currentUsage.information = subcommandUsage.information;
|
|
290
232
|
currentUsage.positionals.push(...subcommandUsage.positionals);
|
|
@@ -309,8 +251,8 @@ export function commandWithSubcommands<Context, Payload, Result>(
|
|
|
309
251
|
} catch (error) {
|
|
310
252
|
return {
|
|
311
253
|
generateUsage() {
|
|
312
|
-
const currentUsage =
|
|
313
|
-
currentUsage.segments.push(
|
|
254
|
+
const currentUsage = generateUsageLeaf(information, operation);
|
|
255
|
+
currentUsage.segments.push({ positional: "<subcommand>" });
|
|
314
256
|
for (const [name, subcommand] of Object.entries(subcommands)) {
|
|
315
257
|
const { description, hint } = subcommand.getInformation();
|
|
316
258
|
currentUsage.subcommands.push({ name, description, hint });
|
|
@@ -334,22 +276,10 @@ export function commandWithSubcommands<Context, Payload, Result>(
|
|
|
334
276
|
* @typeParam Payload - Output of `operation`; becomes `subcommand`'s context.
|
|
335
277
|
* @typeParam Result - Value produced by `subcommand`.
|
|
336
278
|
*
|
|
337
|
-
* @param information - Command metadata
|
|
338
|
-
* @param operation -
|
|
339
|
-
* @param subcommand -
|
|
340
|
-
* @returns A {@link Command}
|
|
341
|
-
*
|
|
342
|
-
* @example
|
|
343
|
-
* ```ts
|
|
344
|
-
* const authenticatedDeploy = commandChained(
|
|
345
|
-
* { description: "Authenticate then deploy" },
|
|
346
|
-
* operation(
|
|
347
|
-
* { options: { token: optionSingleValue({ long: "token", type: typeString, default: () => "" }) }, positionals: [] },
|
|
348
|
-
* async (_ctx, { options: { token } }) => ({ token }),
|
|
349
|
-
* ),
|
|
350
|
-
* command({ description: "Deploy" }, deployOperation),
|
|
351
|
-
* );
|
|
352
|
-
* ```
|
|
279
|
+
* @param information - Command metadata.
|
|
280
|
+
* @param operation - Runs first; output becomes `subcommand`'s context.
|
|
281
|
+
* @param subcommand - Runs after `operation`.
|
|
282
|
+
* @returns A {@link Command} composing both stages.
|
|
353
283
|
*/
|
|
354
284
|
export function commandChained<Context, Payload, Result>(
|
|
355
285
|
information: CommandInformation,
|
|
@@ -367,7 +297,7 @@ export function commandChained<Context, Payload, Result>(
|
|
|
367
297
|
return {
|
|
368
298
|
generateUsage() {
|
|
369
299
|
const subcommandUsage = subcommandDecoder.generateUsage();
|
|
370
|
-
const currentUsage =
|
|
300
|
+
const currentUsage = generateUsageLeaf(information, operation);
|
|
371
301
|
currentUsage.segments.push(...subcommandUsage.segments);
|
|
372
302
|
currentUsage.information = subcommandUsage.information;
|
|
373
303
|
currentUsage.positionals.push(...subcommandUsage.positionals);
|
|
@@ -392,8 +322,8 @@ export function commandChained<Context, Payload, Result>(
|
|
|
392
322
|
} catch (error) {
|
|
393
323
|
return {
|
|
394
324
|
generateUsage() {
|
|
395
|
-
const currentUsage =
|
|
396
|
-
currentUsage.segments.push(
|
|
325
|
+
const currentUsage = generateUsageLeaf(information, operation);
|
|
326
|
+
currentUsage.segments.push({ positional: "[REST]..." });
|
|
397
327
|
return currentUsage;
|
|
398
328
|
},
|
|
399
329
|
decodeAndMakeInterpreter() {
|
|
@@ -405,23 +335,15 @@ export function commandChained<Context, Payload, Result>(
|
|
|
405
335
|
};
|
|
406
336
|
}
|
|
407
337
|
|
|
408
|
-
function
|
|
409
|
-
return { positional: value };
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
function segmentCommand(value: string): CommandUsageSegment {
|
|
413
|
-
return { command: value };
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
function generateUsageShallow(
|
|
338
|
+
function generateUsageLeaf(
|
|
417
339
|
information: CommandInformation,
|
|
418
340
|
operation: Operation<any, any>,
|
|
419
|
-
):
|
|
341
|
+
): UsageCommand {
|
|
420
342
|
const { positionals, options } = operation.generateUsage();
|
|
421
343
|
return {
|
|
422
|
-
segments: positionals.map((positional) =>
|
|
423
|
-
|
|
424
|
-
),
|
|
344
|
+
segments: positionals.map((positional) => ({
|
|
345
|
+
positional: positional.label,
|
|
346
|
+
})),
|
|
425
347
|
information,
|
|
426
348
|
positionals,
|
|
427
349
|
subcommands: [],
|
package/src/lib/Operation.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Option, OptionDecoder
|
|
2
|
-
import { Positional, PositionalDecoder
|
|
1
|
+
import { Option, OptionDecoder } from "./Option";
|
|
2
|
+
import { Positional, PositionalDecoder } from "./Positional";
|
|
3
3
|
import { ReaderArgs } from "./Reader";
|
|
4
|
+
import { UsageOption, UsagePositional } from "./Usage";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Options, positionals, and an async handler that together form the logic of a CLI command.
|
|
@@ -8,14 +9,23 @@ import { ReaderArgs } from "./Reader";
|
|
|
8
9
|
* Created with {@link operation} and passed to {@link command},
|
|
9
10
|
* {@link commandWithSubcommands}, or {@link commandChained}.
|
|
10
11
|
*
|
|
11
|
-
* @typeParam Context - Injected at execution
|
|
12
|
-
* @typeParam Result - Value produced on execution; typically `void
|
|
12
|
+
* @typeParam Context - Injected at execution; forwarded to handlers.
|
|
13
|
+
* @typeParam Result - Value produced on execution; typically `void`.
|
|
13
14
|
*/
|
|
14
15
|
export type Operation<Context, Result> = {
|
|
15
16
|
/**
|
|
16
17
|
* Returns usage metadata without consuming any arguments.
|
|
17
18
|
*/
|
|
18
|
-
generateUsage():
|
|
19
|
+
generateUsage(): {
|
|
20
|
+
/**
|
|
21
|
+
* Registered options.
|
|
22
|
+
*/
|
|
23
|
+
options: Array<UsageOption>;
|
|
24
|
+
/**
|
|
25
|
+
* Declared positionals, in order.
|
|
26
|
+
*/
|
|
27
|
+
positionals: Array<UsagePositional>;
|
|
28
|
+
};
|
|
19
29
|
/**
|
|
20
30
|
* Consumes args from `readerArgs` and returns an {@link OperationDecoder}.
|
|
21
31
|
*/
|
|
@@ -52,27 +62,10 @@ export type OperationInterpreter<Context, Result> = {
|
|
|
52
62
|
executeWithContext(context: Context): Promise<Result>;
|
|
53
63
|
};
|
|
54
64
|
|
|
55
|
-
/**
|
|
56
|
-
* Usage metadata produced by {@link Operation.generateUsage}.
|
|
57
|
-
* Consumed when building {@link CommandUsage}.
|
|
58
|
-
*/
|
|
59
|
-
export type OperationUsage = {
|
|
60
|
-
/**
|
|
61
|
-
* Usage descriptors for all registered options.
|
|
62
|
-
*/
|
|
63
|
-
options: Array<OptionUsage>;
|
|
64
|
-
/**
|
|
65
|
-
* Usage descriptors for all declared positionals, in order.
|
|
66
|
-
*/
|
|
67
|
-
positionals: Array<PositionalUsage>;
|
|
68
|
-
};
|
|
69
|
-
|
|
70
65
|
/**
|
|
71
66
|
* Creates an {@link Operation} from options, positionals, and an async handler.
|
|
72
67
|
*
|
|
73
|
-
* The `handler` receives
|
|
74
|
-
* `options` (keyed by the same names declared in `inputs.options`) and
|
|
75
|
-
* `positionals` (a tuple in declaration order).
|
|
68
|
+
* The `handler` receives `context` and `inputs` with decoded `options` and `positionals`.
|
|
76
69
|
*
|
|
77
70
|
* @typeParam Context - Context type accepted by the handler.
|
|
78
71
|
* @typeParam Result - Return type of the handler.
|
|
@@ -83,20 +76,20 @@ export type OperationUsage = {
|
|
|
83
76
|
* @param inputs.options - Map of keys to {@link Option} descriptors.
|
|
84
77
|
* @param inputs.positionals - Ordered array of {@link Positional} descriptors.
|
|
85
78
|
* @param handler - Async function implementing the command logic.
|
|
86
|
-
* @returns An {@link Operation}
|
|
79
|
+
* @returns An {@link Operation}.
|
|
87
80
|
*
|
|
88
81
|
* @example
|
|
89
82
|
* ```ts
|
|
90
83
|
* const greetOperation = operation(
|
|
91
84
|
* {
|
|
92
85
|
* options: {
|
|
93
|
-
* loud: optionFlag({ long: "loud", description: "Print in uppercase" }),
|
|
86
|
+
* loud: optionFlag({ long: "loud", description: "Print in uppercase", default: false }),
|
|
94
87
|
* },
|
|
95
88
|
* positionals: [
|
|
96
|
-
* positionalRequired({ type:
|
|
89
|
+
* positionalRequired({ type: type("name"), description: "Name to greet" }),
|
|
97
90
|
* ],
|
|
98
91
|
* },
|
|
99
|
-
* async (_ctx, { options: { loud }, positionals: [name] })
|
|
92
|
+
* async function (_ctx, { options: { loud }, positionals: [name] }) {
|
|
100
93
|
* const message = `Hello, ${name}!`;
|
|
101
94
|
* console.log(loud ? message.toUpperCase() : message);
|
|
102
95
|
* },
|
|
@@ -123,14 +116,12 @@ export function operation<
|
|
|
123
116
|
): Operation<Context, Result> {
|
|
124
117
|
return {
|
|
125
118
|
generateUsage() {
|
|
126
|
-
const optionsUsage = new Array<
|
|
119
|
+
const optionsUsage = new Array<UsageOption>();
|
|
127
120
|
for (const optionKey in inputs.options) {
|
|
128
121
|
const optionInput = inputs.options[optionKey]!;
|
|
129
|
-
|
|
130
|
-
optionsUsage.push(optionInput.generateUsage());
|
|
131
|
-
}
|
|
122
|
+
optionsUsage.push(optionInput.generateUsage());
|
|
132
123
|
}
|
|
133
|
-
const positionalsUsage = new Array<
|
|
124
|
+
const positionalsUsage = new Array<UsagePositional>();
|
|
134
125
|
for (const positionalInput of inputs.positionals) {
|
|
135
126
|
positionalsUsage.push(positionalInput.generateUsage());
|
|
136
127
|
}
|