cli-kiss 0.2.6 → 0.2.8

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.
Files changed (39) hide show
  1. package/README.md +62 -4
  2. package/dist/index.d.ts +135 -128
  3. package/dist/index.js +2 -2
  4. package/dist/index.js.map +1 -1
  5. package/docs/.vitepress/config.mts +1 -1
  6. package/docs/.vitepress/theme/Layout.vue +16 -0
  7. package/docs/.vitepress/theme/index.ts +5 -1
  8. package/docs/.vitepress/theme/style.css +5 -1
  9. package/docs/guide/02_commands.md +1 -1
  10. package/docs/guide/03_options.md +11 -11
  11. package/docs/guide/05_input_types.md +9 -10
  12. package/docs/guide/06_run_as_cli.md +1 -1
  13. package/docs/index.md +2 -2
  14. package/docs/public/favicon.ico +0 -0
  15. package/docs/public/logo.png +0 -0
  16. package/package.json +1 -1
  17. package/src/index.ts +1 -0
  18. package/src/lib/Command.ts +50 -30
  19. package/src/lib/Operation.ts +29 -21
  20. package/src/lib/Option.ts +198 -133
  21. package/src/lib/Positional.ts +46 -24
  22. package/src/lib/Reader.ts +194 -207
  23. package/src/lib/Run.ts +19 -8
  24. package/src/lib/Suggest.ts +78 -0
  25. package/src/lib/Type.ts +46 -48
  26. package/src/lib/Typo.ts +72 -47
  27. package/src/lib/Usage.ts +13 -13
  28. package/tests/unit.Reader.commons.ts +92 -116
  29. package/tests/unit.Reader.parsings.ts +14 -26
  30. package/tests/unit.Reader.shortBig.ts +81 -96
  31. package/tests/unit.command.aliases.ts +100 -0
  32. package/tests/unit.command.execute.ts +1 -1
  33. package/tests/unit.command.usage.ts +12 -6
  34. package/tests/unit.fuzzed.alternatives.ts +43 -0
  35. package/tests/unit.runner.colors.ts +11 -35
  36. package/tests/unit.runner.cycle.ts +181 -128
  37. package/tests/unit.runner.errors.ts +26 -19
  38. package/docs/public/hero.png +0 -0
  39. package/tests/unit.Reader.aliases.ts +0 -62
@@ -47,7 +47,7 @@ const rootCommand = commandChained(
47
47
  string: optionSingleValue({
48
48
  long: "string-option",
49
49
  type: type(),
50
- defaultWhenNotDefined: () => undefined,
50
+ fallbackValueIfAbsent: () => undefined,
51
51
  }),
52
52
  number: optionRepeatable({
53
53
  long: "number-option",
@@ -1,4 +1,4 @@
1
- import { it } from "@jest/globals";
1
+ import { expect, it } from "@jest/globals";
2
2
  import {
3
3
  command,
4
4
  Command,
@@ -37,10 +37,9 @@ const rootCommand = commandChained<any, any, any>(
37
37
  options: {
38
38
  choiceOption: optionSingleValue({
39
39
  long: "choice-option",
40
- type: typeChoice("choice", ["unset", "empty", "choice1", "choice2"]),
40
+ type: typeChoice("choice", ["unset", "choice1", "choice2"]),
41
41
  description: "choice-option description",
42
- defaultWhenNotInlined: () => "empty",
43
- defaultWhenNotDefined: () => "unset",
42
+ fallbackValueIfAbsent: () => "unset",
44
43
  }),
45
44
  booleanFlag: optionFlag({
46
45
  short: "b",
@@ -81,7 +80,7 @@ const rootCommand = commandChained<any, any, any>(
81
80
  short: "s",
82
81
  long: "string-option",
83
82
  type: type("cool-stuff"),
84
- defaultWhenNotDefined: () => undefined,
83
+ fallbackValueIfAbsent: () => undefined,
85
84
  description: "string-option description",
86
85
  }),
87
86
  complexOption: optionRepeatable({
@@ -174,10 +173,16 @@ const rootCommand = commandChained<any, any, any>(
174
173
  duduValue: optionSingleValue({
175
174
  long: "dudu",
176
175
  type: type("dudu-value"),
177
- defaultWhenNotDefined: () => "duduDefault",
176
+ fallbackValueIfAbsent: () => "duduDefault",
178
177
  hint: "Dudu option hint",
179
178
  description: "Dudu option description",
180
179
  }),
180
+ impliable: optionSingleValue({
181
+ long: "impliable",
182
+ type: type("text"),
183
+ impliedValueIfNotInlined: () => "implied",
184
+ fallbackValueIfAbsent: () => "absent",
185
+ }),
181
186
  },
182
187
  positionals: [
183
188
  positionalRequired({
@@ -308,6 +313,7 @@ it("run", async function () {
308
313
  " {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<cool-stuff>}@darkBlue}+ string-option description",
309
314
  " {{--complex-option}@darkCyan}+ {{<number,string[,string]...>}@darkBlue}+{{ [*]}-}* complex-option description",
310
315
  " {{--dudu}@darkCyan}+ {{<dudu-value>}@darkBlue}+ Dudu option description {{(Dudu option hint)}-}*",
316
+ " {{--impliable}@darkCyan}+{{[=text]}-}*",
311
317
  "",
312
318
  "{{Examples:}@darkGreen}+",
313
319
  " {{# Example usage of subcommand 2}-}*",
@@ -0,0 +1,43 @@
1
+ import { expect, it } from "@jest/globals";
2
+ import { TypoString, TypoText } from "../src";
3
+ import { suggestTextPushMessage } from "../src/lib/Suggest";
4
+
5
+ it("run", async function () {
6
+ expectReasonables(["--flag", "--blah", "--install"], "--inst", ["--install"]);
7
+ expectReasonables(["install", "dudu", "--blah"], "instlal", ["install"]);
8
+ expectReasonables(["hello", "kat", "cats"], "cat", ["cats", "kat"]);
9
+ expectReasonables(["cut", "kat"], "cat", ["cut", "kat"]);
10
+ expectReasonables(["abc", "ac", "ab"], "acb", ["abc", "ac", "ab"]);
11
+
12
+ const library = [
13
+ "install",
14
+ "install-package",
15
+ "install-package-latest",
16
+ "uninstall",
17
+ "update",
18
+ "list",
19
+ ];
20
+ expectReasonables(library, "instal", ["install", "uninstall"]);
21
+ expectReasonables(library, "insta-package", ["install-package"]);
22
+ expectReasonables(library, "insta-package-lates", ["install-package-latest"]);
23
+ expectReasonables(library, "install-package-lat", [
24
+ "install-package-latest",
25
+ "install-package",
26
+ ]);
27
+ });
28
+
29
+ function expectReasonables(
30
+ references: Array<string>,
31
+ query: string,
32
+ reasonables: Array<string>,
33
+ ) {
34
+ const text = new TypoText();
35
+ suggestTextPushMessage(
36
+ text,
37
+ query,
38
+ references.map((key) => ({ reference: key, hint: new TypoString(key) })),
39
+ );
40
+ expect(text.computeRawString()).toStrictEqual(
41
+ " Did you mean: " + reasonables.join(", ") + " ?",
42
+ );
43
+ }
@@ -1,4 +1,4 @@
1
- import { it } from "@jest/globals";
1
+ import { expect, it } from "@jest/globals";
2
2
  import {
3
3
  command,
4
4
  operation,
@@ -32,12 +32,13 @@ const usageTty = usageToStyledLines({
32
32
  typoSupport: TypoSupport.tty(),
33
33
  }).join("\n");
34
34
 
35
- const unexpectedNone = "Error: Unexpected unknown option: --color";
36
- const unexpectedMock =
37
- "{{Error:}@darkRed}+ Unexpected unknown option: {{--color}@darkYellow}+";
35
+ const unknownOptionNone =
36
+ 'Error: Unknown option: "--color". Did you mean: --help, --version ?';
37
+ const unknownOptionMock =
38
+ '{{Error:}@darkRed}+ Unknown option: {{"--color"}@darkYellow}+. Did you mean: {{--help}@darkCyan}+, {{--version}@darkCyan}+ ?';
38
39
 
39
40
  it("run", async function () {
40
- await withEnv("FORCE_COLOR", "false", async () => {
41
+ await withEnv("FORCE_COLOR", "", async () => {
41
42
  if (process.stdout.isTTY) {
42
43
  await testAllHelpsSuccesses(usageTty);
43
44
  } else {
@@ -54,9 +55,6 @@ it("run", async function () {
54
55
  await withEnv("NO_COLOR", "", async () => {
55
56
  await testAllHelpsSuccesses(usageTty);
56
57
  });
57
- await withEnv("MOCK_COLOR", "", async () => {
58
- await testAllHelpsSuccesses(usageTty);
59
- });
60
58
  await withEnv("TERM", "dumb", async () => {
61
59
  await testAllHelpsSuccesses(usageTty);
62
60
  });
@@ -71,32 +69,12 @@ it("run", async function () {
71
69
  await withEnv("FORCE_COLOR", "0", async () => {
72
70
  await testAllHelpsSuccesses(usageNone);
73
71
  });
74
- await withEnv("MOCK_COLOR", "true", async () => {
75
- await testAllHelpsSuccesses(usageMock);
76
- });
77
72
 
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
- });
90
-
91
- await withEnv("MOCK_COLOR", "1", async () => {
92
- await testAllFlagsFailures("env", usageMock, unexpectedMock);
93
- });
73
+ await testAllFlagsFailures("mock", usageMock, unknownOptionMock);
74
+ await testAllFlagsFailures("never", usageNone, unknownOptionNone);
94
75
  await withEnv("FORCE_COLOR", "0", async () => {
95
- await testAllFlagsFailures("env", usageNone, unexpectedNone);
76
+ await testAllFlagsFailures("env", usageNone, unknownOptionNone);
96
77
  });
97
-
98
- await testAllFlagsFailures("mock", usageMock, unexpectedMock);
99
- await testAllFlagsFailures("never", usageNone, unexpectedNone);
100
78
  });
101
79
  });
102
80
 
@@ -105,24 +83,22 @@ async function testAllFlagsFailures(
105
83
  usageErr: string,
106
84
  message: string,
107
85
  ) {
86
+ await testCase(colorSetup, ["--color"], [], [usageErr, message], 1);
108
87
  await testCase(colorSetup, ["--color=auto"], [], [usageErr, message], 1);
109
88
  await testCase(colorSetup, ["--color=always"], [], [usageErr, message], 1);
110
89
  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
90
  }
114
91
 
115
92
  async function testAllHelpsSuccesses(usageFromEnv: string) {
116
93
  await testCase("flag", ["--color=auto", "--help"], [usageFromEnv], [], 0);
117
94
  await testCase("flag", ["--color=always", "--help"], [usageTty], [], 0);
118
95
  await testCase("flag", ["--color=never", "--help"], [usageNone], [], 0);
119
- await testCase("flag", ["--color=mock", "--help"], [usageMock], [], 0);
120
96
  await testCase("flag", ["--color", "--help"], [usageTty], [], 0);
121
97
  await testCase("flag", ["--help"], [usageFromEnv], [], 0);
122
- await testCase("env", ["--help"], [usageFromEnv], [], 0);
123
98
  await testCase("always", ["--help"], [usageTty], [], 0);
124
99
  await testCase("never", ["--help"], [usageNone], [], 0);
125
100
  await testCase("mock", ["--help"], [usageMock], [], 0);
101
+ await testCase("env", ["--help"], [usageFromEnv], [], 0);
126
102
  }
127
103
 
128
104
  async function testCase(