cli-kiss 0.2.5 → 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 +15 -9
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/docs/.vitepress/config.mts +2 -2
- package/docs/.vitepress/theme/style.css +6 -2
- package/docs/guide/{05_types.md → 05_input_types.md} +19 -17
- package/docs/guide/{06_run.md → 06_run_as_cli.md} +10 -15
- package/docs/index.md +3 -2
- package/package.json +1 -1
- package/src/lib/Run.ts +16 -17
- package/src/lib/Type.ts +39 -41
- package/src/lib/Typo.ts +30 -10
- package/src/lib/Usage.ts +3 -3
- package/tests/unit.runner.colors.ts +123 -121
|
@@ -2,133 +2,131 @@ import { it } from "@jest/globals";
|
|
|
2
2
|
import {
|
|
3
3
|
command,
|
|
4
4
|
operation,
|
|
5
|
-
optionRepeatable,
|
|
6
|
-
positionalVariadics,
|
|
7
5
|
runAndExit,
|
|
8
|
-
|
|
6
|
+
RunColorMode,
|
|
9
7
|
TypoSupport,
|
|
10
8
|
usageToStyledLines,
|
|
11
9
|
} from "../src";
|
|
12
10
|
|
|
13
11
|
const cliName = "my-cli";
|
|
12
|
+
const usageBase = {
|
|
13
|
+
segments: [],
|
|
14
|
+
information: { description: "Description" },
|
|
15
|
+
subcommands: [],
|
|
16
|
+
options: [],
|
|
17
|
+
positionals: [],
|
|
18
|
+
};
|
|
19
|
+
const usageNone = usageToStyledLines({
|
|
20
|
+
cliName,
|
|
21
|
+
usage: usageBase,
|
|
22
|
+
typoSupport: TypoSupport.none(),
|
|
23
|
+
}).join("\n");
|
|
24
|
+
const usageMock = usageToStyledLines({
|
|
25
|
+
cliName,
|
|
26
|
+
usage: usageBase,
|
|
27
|
+
typoSupport: TypoSupport.mock(),
|
|
28
|
+
}).join("\n");
|
|
29
|
+
const usageTty = usageToStyledLines({
|
|
30
|
+
cliName,
|
|
31
|
+
usage: usageBase,
|
|
32
|
+
typoSupport: TypoSupport.tty(),
|
|
33
|
+
}).join("\n");
|
|
34
|
+
|
|
35
|
+
const unexpectedNone = "Error: Unexpected unknown option: --color";
|
|
36
|
+
const unexpectedMock =
|
|
37
|
+
"{{Error:}@darkRed}+ Unexpected unknown option: {{--color}@darkYellow}+";
|
|
14
38
|
|
|
15
39
|
it("run", async function () {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
};
|
|
23
|
-
const usageNone = usageToStyledLines({
|
|
24
|
-
cliName,
|
|
25
|
-
usage,
|
|
26
|
-
typoSupport: TypoSupport.none(),
|
|
27
|
-
}).join("\n");
|
|
28
|
-
const usageMock = usageToStyledLines({
|
|
29
|
-
cliName,
|
|
30
|
-
usage,
|
|
31
|
-
typoSupport: TypoSupport.mock(),
|
|
32
|
-
}).join("\n");
|
|
33
|
-
const usageTty = usageToStyledLines({
|
|
34
|
-
cliName,
|
|
35
|
-
usage,
|
|
36
|
-
typoSupport: TypoSupport.tty(),
|
|
37
|
-
}).join("\n");
|
|
40
|
+
await withEnv("FORCE_COLOR", "false", async () => {
|
|
41
|
+
if (process.stdout.isTTY) {
|
|
42
|
+
await testAllHelpsSuccesses(usageTty);
|
|
43
|
+
} else {
|
|
44
|
+
await testAllHelpsSuccesses(usageNone);
|
|
45
|
+
}
|
|
38
46
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
await withEnv("FORCE_COLOR", "1", async () => {
|
|
48
|
+
await withEnv("NO_COLOR", "1", async () => {
|
|
49
|
+
await testAllHelpsSuccesses(usageNone);
|
|
50
|
+
});
|
|
51
|
+
await withEnv("NO_COLOR", "true", async () => {
|
|
52
|
+
await testAllHelpsSuccesses(usageNone);
|
|
53
|
+
});
|
|
54
|
+
await withEnv("NO_COLOR", "", async () => {
|
|
55
|
+
await testAllHelpsSuccesses(usageTty);
|
|
56
|
+
});
|
|
57
|
+
await withEnv("MOCK_COLOR", "", async () => {
|
|
58
|
+
await testAllHelpsSuccesses(usageTty);
|
|
59
|
+
});
|
|
60
|
+
await withEnv("TERM", "dumb", async () => {
|
|
61
|
+
await testAllHelpsSuccesses(usageTty);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
48
64
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
await withEnv("FORCE_COLOR", "2", async () => {
|
|
66
|
+
await testAllHelpsSuccesses(usageTty);
|
|
67
|
+
});
|
|
68
|
+
await withEnv("FORCE_COLOR", "1", async () => {
|
|
69
|
+
await testAllHelpsSuccesses(usageTty);
|
|
70
|
+
});
|
|
71
|
+
await withEnv("FORCE_COLOR", "0", async () => {
|
|
72
|
+
await testAllHelpsSuccesses(usageNone);
|
|
73
|
+
});
|
|
74
|
+
await withEnv("MOCK_COLOR", "true", async () => {
|
|
75
|
+
await testAllHelpsSuccesses(usageMock);
|
|
76
|
+
});
|
|
60
77
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
78
|
+
await withEnv("MOCK_COLOR", "1", async () => {
|
|
79
|
+
await testCase(
|
|
80
|
+
"flag",
|
|
81
|
+
["--color=42"],
|
|
82
|
+
[],
|
|
83
|
+
[
|
|
84
|
+
usageMock,
|
|
85
|
+
'{{Error:}@darkRed}+ {{--color}@darkCyan}+: {{<color-mode>}@darkBlue}+: Invalid value: {{"42"}@darkYellow}+ (expected one of: {{"auto"}@darkYellow}+ | {{"always"}@darkYellow}+ | {{"never"}@darkYellow}+...)',
|
|
86
|
+
],
|
|
87
|
+
1,
|
|
88
|
+
);
|
|
89
|
+
});
|
|
72
90
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
91
|
+
await withEnv("MOCK_COLOR", "1", async () => {
|
|
92
|
+
await testAllFlagsFailures("env", usageMock, unexpectedMock);
|
|
93
|
+
});
|
|
94
|
+
await withEnv("FORCE_COLOR", "0", async () => {
|
|
95
|
+
await testAllFlagsFailures("env", usageNone, unexpectedNone);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
await testAllFlagsFailures("mock", usageMock, unexpectedMock);
|
|
99
|
+
await testAllFlagsFailures("never", usageNone, unexpectedNone);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
async function testAllFlagsFailures(
|
|
104
|
+
colorSetup: "flag" | RunColorMode,
|
|
105
|
+
usageErr: string,
|
|
106
|
+
message: string,
|
|
107
|
+
) {
|
|
108
|
+
await testCase(colorSetup, ["--color=auto"], [], [usageErr, message], 1);
|
|
109
|
+
await testCase(colorSetup, ["--color=always"], [], [usageErr, message], 1);
|
|
110
|
+
await testCase(colorSetup, ["--color=never"], [], [usageErr, message], 1);
|
|
111
|
+
await testCase(colorSetup, ["--color=mock"], [], [usageErr, message], 1);
|
|
112
|
+
await testCase(colorSetup, ["--color"], [], [usageErr, message], 1);
|
|
113
|
+
}
|
|
84
114
|
|
|
85
|
-
|
|
86
|
-
await testCase("flag", ["--color=auto", "--help"], [
|
|
115
|
+
async function testAllHelpsSuccesses(usageFromEnv: string) {
|
|
116
|
+
await testCase("flag", ["--color=auto", "--help"], [usageFromEnv], [], 0);
|
|
87
117
|
await testCase("flag", ["--color=always", "--help"], [usageTty], [], 0);
|
|
88
118
|
await testCase("flag", ["--color=never", "--help"], [usageNone], [], 0);
|
|
89
119
|
await testCase("flag", ["--color=mock", "--help"], [usageMock], [], 0);
|
|
90
|
-
await testCase("flag", ["--help"], [
|
|
91
|
-
await testCase("
|
|
120
|
+
await testCase("flag", ["--color", "--help"], [usageTty], [], 0);
|
|
121
|
+
await testCase("flag", ["--help"], [usageFromEnv], [], 0);
|
|
122
|
+
await testCase("env", ["--help"], [usageFromEnv], [], 0);
|
|
92
123
|
await testCase("always", ["--help"], [usageTty], [], 0);
|
|
93
124
|
await testCase("never", ["--help"], [usageNone], [], 0);
|
|
94
125
|
await testCase("mock", ["--help"], [usageMock], [], 0);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
process.env["MOCK_COLOR"] = "";
|
|
98
|
-
await testCase(
|
|
99
|
-
"flag",
|
|
100
|
-
["--color=42"],
|
|
101
|
-
[],
|
|
102
|
-
[
|
|
103
|
-
usageMock,
|
|
104
|
-
'{{Error:}@darkRed}+ {{--color}@darkCyan}+: {{<color-mode>}@darkBlue}+: Invalid value: {{"42"}@darkYellow}+ (expected one of: {{"auto"}@darkYellow}+ | {{"always"}@darkYellow}+ | {{"never"}@darkYellow}+...)',
|
|
105
|
-
],
|
|
106
|
-
1,
|
|
107
|
-
);
|
|
108
|
-
delete process.env["MOCK_COLOR"];
|
|
109
|
-
|
|
110
|
-
const unexpected1 = "Error: Unexpected unknown option: --color";
|
|
111
|
-
await testCase("never", ["--color=auto"], [], [usageNone, unexpected1], 1);
|
|
112
|
-
await testCase("never", ["--color=always"], [], [usageNone, unexpected1], 1);
|
|
113
|
-
await testCase("never", ["--color=never"], [], [usageNone, unexpected1], 1);
|
|
114
|
-
await testCase("never", ["--color=mock"], [], [usageNone, unexpected1], 1);
|
|
115
|
-
process.env["FORCE_COLOR"] = "0";
|
|
116
|
-
await testCase("env", ["--color=auto"], [], [usageNone, unexpected1], 1);
|
|
117
|
-
await testCase("env", ["--color=always"], [], [usageNone, unexpected1], 1);
|
|
118
|
-
await testCase("env", ["--color=never"], [], [usageNone, unexpected1], 1);
|
|
119
|
-
await testCase("env", ["--color=mock"], [], [usageNone, unexpected1], 1);
|
|
120
|
-
delete process.env["FORCE_COLOR"];
|
|
121
|
-
|
|
122
|
-
const unexpected2 =
|
|
123
|
-
"{{Error:}@darkRed}+ Unexpected unknown option: {{--color}@darkYellow}+";
|
|
124
|
-
await testCase("mock", ["--color=auto"], [], [usageMock, unexpected2], 1);
|
|
125
|
-
await testCase("mock", ["--color=always"], [], [usageMock, unexpected2], 1);
|
|
126
|
-
await testCase("mock", ["--color=never"], [], [usageMock, unexpected2], 1);
|
|
127
|
-
await testCase("mock", ["--color=mock"], [], [usageMock, unexpected2], 1);
|
|
128
|
-
});
|
|
126
|
+
}
|
|
129
127
|
|
|
130
128
|
async function testCase(
|
|
131
|
-
colorSetup: "flag" |
|
|
129
|
+
colorSetup: "flag" | RunColorMode,
|
|
132
130
|
cliArgs: Array<string>,
|
|
133
131
|
expectStdOut: Array<string>,
|
|
134
132
|
expectStdErr: Array<string>,
|
|
@@ -145,21 +143,7 @@ async function testCase(
|
|
|
145
143
|
const onExit = makeMocked<number, never>([null as never]);
|
|
146
144
|
const cmd = command<null, void>(
|
|
147
145
|
{ description: "Description" },
|
|
148
|
-
operation(
|
|
149
|
-
{
|
|
150
|
-
options: {
|
|
151
|
-
value: optionRepeatable({ long: "option", type: type() }),
|
|
152
|
-
},
|
|
153
|
-
positionals: [
|
|
154
|
-
positionalVariadics({ type: type(), description: "Variadics" }),
|
|
155
|
-
],
|
|
156
|
-
},
|
|
157
|
-
async function (_, { options: { value }, positionals: [rest] }) {
|
|
158
|
-
console.log(
|
|
159
|
-
`Has executed: ${JSON.stringify(value)}, ${JSON.stringify(rest)}`,
|
|
160
|
-
);
|
|
161
|
-
},
|
|
162
|
-
),
|
|
146
|
+
operation({ options: {}, positionals: [] }, async function () {}),
|
|
163
147
|
);
|
|
164
148
|
console.log = onLogStdOut.call;
|
|
165
149
|
console.error = onLogStdErr.call;
|
|
@@ -195,3 +179,21 @@ function makeMocked<P, R>(returns: Array<R>) {
|
|
|
195
179
|
},
|
|
196
180
|
};
|
|
197
181
|
}
|
|
182
|
+
|
|
183
|
+
async function withEnv(
|
|
184
|
+
envName: string,
|
|
185
|
+
envValue: string,
|
|
186
|
+
callback: () => Promise<void>,
|
|
187
|
+
) {
|
|
188
|
+
let beforeEnvValue = undefined;
|
|
189
|
+
if (envName in process.env) {
|
|
190
|
+
beforeEnvValue = process.env[envName];
|
|
191
|
+
}
|
|
192
|
+
process.env[envName] = envValue;
|
|
193
|
+
await callback();
|
|
194
|
+
if (beforeEnvValue === undefined) {
|
|
195
|
+
delete process.env[envName];
|
|
196
|
+
} else {
|
|
197
|
+
process.env[envName] = beforeEnvValue;
|
|
198
|
+
}
|
|
199
|
+
}
|