cli-kiss 0.2.4 → 0.2.6
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/index.d.ts +159 -167
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/docs/.vitepress/config.mts +3 -2
- package/docs/.vitepress/theme/style.css +6 -2
- package/docs/guide/01_getting_started.md +12 -13
- package/docs/guide/02_commands.md +12 -29
- package/docs/guide/03_options.md +16 -25
- package/docs/guide/04_positionals.md +45 -55
- package/docs/guide/05_input_types.md +134 -0
- package/docs/guide/06_run_as_cli.md +143 -0
- package/docs/index.md +3 -2
- 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 +14 -35
- package/src/lib/Operation.ts +13 -4
- package/src/lib/Option.ts +118 -162
- package/src/lib/Positional.ts +37 -62
- package/src/lib/Reader.ts +3 -3
- package/src/lib/Run.ts +76 -49
- package/src/lib/Type.ts +227 -143
- package/src/lib/Typo.ts +55 -23
- package/src/lib/Usage.ts +30 -45
- package/tests/unit.Reader.parsings.ts +50 -0
- package/tests/unit.command.execute.ts +13 -13
- package/tests/unit.command.usage.ts +60 -54
- package/tests/unit.runner.colors.ts +199 -0
- package/tests/unit.runner.cycle.ts +69 -55
- package/tests/unit.runner.errors.ts +12 -20
- package/docs/guide/05_types.md +0 -132
- package/docs/guide/06_run.md +0 -160
package/src/lib/Run.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { Command, CommandDecoder } from "./Command";
|
|
2
|
+
import { optionFlag, optionSingleValue } from "./Option";
|
|
2
3
|
import { ReaderArgs } from "./Reader";
|
|
4
|
+
import { typeChoice } from "./Type";
|
|
3
5
|
import { TypoSupport } from "./Typo";
|
|
4
6
|
import { usageToStyledLines } from "./Usage";
|
|
5
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Color selection modes availables
|
|
10
|
+
*/
|
|
11
|
+
export type RunColorMode = "env" | "always" | "never" | "mock";
|
|
12
|
+
|
|
6
13
|
/**
|
|
7
14
|
* Main entry point: parses CLI arguments, executes the matched command, and exits.
|
|
8
15
|
* Handles `--help`, `--version`, usage-on-error, and exit codes.
|
|
@@ -17,8 +24,7 @@ import { usageToStyledLines } from "./Usage";
|
|
|
17
24
|
* @param cliArgs - Raw arguments, typically `process.argv.slice(2)`.
|
|
18
25
|
* @param context - Forwarded to the handler.
|
|
19
26
|
* @param command - Root {@link Command}.
|
|
20
|
-
* @param options.
|
|
21
|
-
* `"mock"` (snapshot-friendly), `undefined` (auto-detect from env).
|
|
27
|
+
* @param options.colorSetup - Configures color support; enables `--color` flag if set to `"flag"`.
|
|
22
28
|
* @param options.usageOnHelp - Enables `--help` flag (default `true`).
|
|
23
29
|
* @param options.usageOnError - Prints usage to stderr on parse error (default `true`).
|
|
24
30
|
* @param options.buildVersion - Enables `--version`; prints `<cliName> <buildVersion>`.
|
|
@@ -29,12 +35,12 @@ import { usageToStyledLines } from "./Usage";
|
|
|
29
35
|
*
|
|
30
36
|
* @example
|
|
31
37
|
* ```ts
|
|
32
|
-
* import { runAndExit, command, operation, positionalRequired,
|
|
38
|
+
* import { runAndExit, command, operation, positionalRequired, type } from "cli-kiss";
|
|
33
39
|
*
|
|
34
40
|
* const greetCommand = command(
|
|
35
41
|
* { description: "Greet someone" },
|
|
36
42
|
* operation(
|
|
37
|
-
* { options: {}, positionals: [positionalRequired({ type:
|
|
43
|
+
* { options: {}, positionals: [positionalRequired({ type: type("name") })] },
|
|
38
44
|
* async function (_ctx, { positionals: [name] }) {
|
|
39
45
|
* console.log(`Hello, ${name}!`);
|
|
40
46
|
* },
|
|
@@ -47,12 +53,12 @@ import { usageToStyledLines } from "./Usage";
|
|
|
47
53
|
* ```
|
|
48
54
|
*/
|
|
49
55
|
export async function runAndExit<Context>(
|
|
50
|
-
cliName:
|
|
56
|
+
cliName: string,
|
|
51
57
|
cliArgs: ReadonlyArray<string>,
|
|
52
58
|
context: Context,
|
|
53
59
|
command: Command<Context, void>,
|
|
54
60
|
options?: {
|
|
55
|
-
|
|
61
|
+
colorSetup?: "flag" | RunColorMode | undefined;
|
|
56
62
|
usageOnHelp?: boolean | undefined;
|
|
57
63
|
usageOnError?: boolean | undefined;
|
|
58
64
|
buildVersion?: string | undefined;
|
|
@@ -61,26 +67,52 @@ export async function runAndExit<Context>(
|
|
|
61
67
|
},
|
|
62
68
|
): Promise<never> {
|
|
63
69
|
const readerArgs = new ReaderArgs(cliArgs);
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
const preprocessors = new Array<
|
|
71
|
+
(commandDecoder: CommandDecoder<Context, void>) => undefined | number
|
|
72
|
+
>();
|
|
73
|
+
let typoSupport = TypoSupport.none();
|
|
74
|
+
const colorSetup = options?.colorSetup ?? "flag";
|
|
75
|
+
if (colorSetup === "flag") {
|
|
76
|
+
const colorOption = optionSingleValue<"auto" | RunColorMode>({
|
|
77
|
+
long: "color",
|
|
78
|
+
type: typeChoice("color-mode", ["auto", "always", "never", "mock"]),
|
|
79
|
+
defaultWhenNotDefined: () => "auto",
|
|
80
|
+
defaultWhenNotInlined: () => "always",
|
|
81
|
+
}).registerAndMakeDecoder(readerArgs);
|
|
82
|
+
preprocessors.push(() => {
|
|
83
|
+
try {
|
|
84
|
+
typoSupport = computeTypoSupport(colorOption.getAndDecodeValue());
|
|
85
|
+
} catch (error) {
|
|
86
|
+
typoSupport = TypoSupport.inferFromEnv();
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
return undefined;
|
|
90
|
+
});
|
|
91
|
+
} else {
|
|
92
|
+
typoSupport = computeTypoSupport(colorSetup);
|
|
93
|
+
}
|
|
94
|
+
if (options?.usageOnHelp ?? true) {
|
|
95
|
+
const helpOption = optionFlag({ long: "help" }).registerAndMakeDecoder(
|
|
96
|
+
readerArgs,
|
|
97
|
+
);
|
|
98
|
+
preprocessors.push((commandDecoder) => {
|
|
99
|
+
if (!helpOption.getAndDecodeValue()) {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
console.log(computeUsageString(cliName, commandDecoder, typoSupport));
|
|
103
|
+
return 0;
|
|
73
104
|
});
|
|
74
105
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
106
|
+
if (options?.buildVersion) {
|
|
107
|
+
const versionOption = optionFlag({
|
|
108
|
+
long: "version",
|
|
109
|
+
}).registerAndMakeDecoder(readerArgs);
|
|
110
|
+
preprocessors.push(() => {
|
|
111
|
+
if (!versionOption.getAndDecodeValue()) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
console.log([cliName, options.buildVersion].join(" "));
|
|
115
|
+
return 0;
|
|
84
116
|
});
|
|
85
117
|
}
|
|
86
118
|
/*
|
|
@@ -91,7 +123,6 @@ export async function runAndExit<Context>(
|
|
|
91
123
|
longs: ["completion"],
|
|
92
124
|
});
|
|
93
125
|
*/
|
|
94
|
-
// TODO - handle color flag ?
|
|
95
126
|
const commandDecoder = command.consumeAndMakeDecoder(readerArgs);
|
|
96
127
|
while (true) {
|
|
97
128
|
try {
|
|
@@ -101,21 +132,14 @@ export async function runAndExit<Context>(
|
|
|
101
132
|
}
|
|
102
133
|
} catch (_) {}
|
|
103
134
|
}
|
|
104
|
-
const typoSupport = computeTypoSupport(options?.useTtyColors);
|
|
105
135
|
const onExit = options?.onExit ?? process.exit;
|
|
106
|
-
if (usageOnHelp) {
|
|
107
|
-
if (readerArgs.getOptionValues("--help" as any).length > 0) {
|
|
108
|
-
console.log(computeUsageString(cliName, commandDecoder, typoSupport));
|
|
109
|
-
return onExit(0);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
if (buildVersion) {
|
|
113
|
-
if (readerArgs.getOptionValues("--version" as any).length > 0) {
|
|
114
|
-
console.log([cliName, buildVersion].join(" "));
|
|
115
|
-
return onExit(0);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
136
|
try {
|
|
137
|
+
for (const preprocessor of preprocessors) {
|
|
138
|
+
const preprocessorResult = preprocessor(commandDecoder);
|
|
139
|
+
if (preprocessorResult !== undefined) {
|
|
140
|
+
return onExit(preprocessorResult);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
119
143
|
const commandInterpreter = commandDecoder.decodeAndMakeInterpreter();
|
|
120
144
|
try {
|
|
121
145
|
await commandInterpreter.executeWithContext(context);
|
|
@@ -146,7 +170,7 @@ function handleError(
|
|
|
146
170
|
}
|
|
147
171
|
|
|
148
172
|
function computeUsageString<Context, Result>(
|
|
149
|
-
cliName:
|
|
173
|
+
cliName: string,
|
|
150
174
|
commandDecoder: CommandDecoder<Context, Result>,
|
|
151
175
|
typoSupport: TypoSupport,
|
|
152
176
|
) {
|
|
@@ -157,14 +181,17 @@ function computeUsageString<Context, Result>(
|
|
|
157
181
|
}).join("\n");
|
|
158
182
|
}
|
|
159
183
|
|
|
160
|
-
function computeTypoSupport(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
184
|
+
function computeTypoSupport(colorMode: "auto" | RunColorMode): TypoSupport {
|
|
185
|
+
switch (colorMode) {
|
|
186
|
+
case "auto":
|
|
187
|
+
return TypoSupport.inferFromEnv();
|
|
188
|
+
case "env":
|
|
189
|
+
return TypoSupport.inferFromEnv();
|
|
190
|
+
case "always":
|
|
191
|
+
return TypoSupport.tty();
|
|
192
|
+
case "never":
|
|
193
|
+
return TypoSupport.none();
|
|
194
|
+
case "mock":
|
|
195
|
+
return TypoSupport.mock();
|
|
196
|
+
}
|
|
170
197
|
}
|