cli-kiss 0.2.2 → 0.2.4

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.
@@ -1,7 +1,7 @@
1
1
  import { expect, it } from "@jest/globals";
2
- import { ReaderArgs } from "../src";
2
+ import { ReaderArgs, ReaderOptionParsing } from "../src";
3
3
 
4
- it("run", async () => {
4
+ it("run", async function () {
5
5
  const stream = new ReaderArgs([
6
6
  "positional-0",
7
7
  "-aasof-normal",
@@ -12,47 +12,48 @@ it("run", async () => {
12
12
  "1.1",
13
13
  "-eesov-split",
14
14
  "1.2",
15
- "-ffsov-join=2",
15
+ "-ffsov-join=2.1",
16
+ "-ggsov-join=2.2",
16
17
  "positional-2",
17
18
  ]);
18
19
 
19
20
  expect(stream.consumePositional()).toStrictEqual("positional-0");
20
21
 
22
+ const kSofUnset = stream.registerOption({
23
+ longs: [],
24
+ shorts: ["sof-unset"],
25
+ parsing: optionFlagParsing,
26
+ });
21
27
  const kSofNormal = stream.registerOption({
22
28
  shorts: ["sof-normal"],
23
29
  longs: [],
24
- valued: false,
30
+ parsing: optionFlagParsing,
25
31
  });
26
32
  const kSofPositive = stream.registerOption({
27
33
  longs: [],
28
34
  shorts: ["sof-positive"],
29
- valued: false,
35
+ parsing: optionFlagParsing,
30
36
  });
31
37
  const kSofNegative = stream.registerOption({
32
38
  longs: [],
33
39
  shorts: ["sof-negative"],
34
- valued: false,
35
- });
36
- const kSofUnset = stream.registerOption({
37
- longs: [],
38
- shorts: ["sof-unset"],
39
- valued: false,
40
+ parsing: optionFlagParsing,
40
41
  });
41
42
 
42
43
  const kAa = stream.registerOption({
43
44
  longs: [],
44
45
  shorts: ["aa"],
45
- valued: false,
46
+ parsing: optionFlagParsing,
46
47
  });
47
48
  const kBb = stream.registerOption({
48
49
  longs: [],
49
50
  shorts: ["bb"],
50
- valued: false,
51
+ parsing: optionFlagParsing,
51
52
  });
52
53
  const kCc = stream.registerOption({
53
54
  longs: [],
54
55
  shorts: ["cc"],
55
- valued: false,
56
+ parsing: optionFlagParsing,
56
57
  });
57
58
 
58
59
  expect(stream.consumePositional()).toStrictEqual("positional-1");
@@ -60,51 +61,94 @@ it("run", async () => {
60
61
  const kSovSplit = stream.registerOption({
61
62
  longs: [],
62
63
  shorts: ["sov-split"],
63
- valued: true,
64
+ parsing: optionValueFixedUniqueParsing,
64
65
  });
65
66
  const kSovJoin = stream.registerOption({
66
67
  longs: [],
67
68
  shorts: ["sov-join"],
68
- valued: true,
69
+ parsing: optionValueFixedUniqueParsing,
69
70
  });
70
71
  const kSovUnset = stream.registerOption({
71
72
  longs: [],
72
73
  shorts: ["sov-unset"],
73
- valued: true,
74
+ parsing: optionValueFixedUniqueParsing,
74
75
  });
75
76
 
76
77
  const kDd = stream.registerOption({
77
78
  longs: [],
78
79
  shorts: ["dd"],
79
- valued: false,
80
+ parsing: optionFlagParsing,
80
81
  });
81
82
  const kEe = stream.registerOption({
82
83
  longs: [],
83
84
  shorts: ["ee"],
84
- valued: false,
85
+ parsing: optionFlagParsing,
85
86
  });
86
87
  const kFf = stream.registerOption({
87
88
  longs: [],
88
89
  shorts: ["ff"],
89
- valued: false,
90
+ parsing: optionFlagParsing,
91
+ });
92
+ const kGg = stream.registerOption({
93
+ longs: [],
94
+ shorts: ["gg"],
95
+ parsing: optionFlagParsing,
90
96
  });
91
97
 
92
98
  expect(stream.consumePositional()).toStrictEqual("positional-2");
93
99
 
94
- expect(stream.getOptionValues(kSofNormal)).toStrictEqual(["true"]);
95
- expect(stream.getOptionValues(kSofPositive)).toStrictEqual(["true"]);
96
- expect(stream.getOptionValues(kSofNegative)).toStrictEqual(["false"]);
97
100
  expect(stream.getOptionValues(kSofUnset)).toStrictEqual([]);
101
+ expect(stream.getOptionValues(kSofNormal)).toStrictEqual([
102
+ { inlined: null, separated: [] },
103
+ ]);
104
+ expect(stream.getOptionValues(kSofPositive)).toStrictEqual([
105
+ { inlined: "true", separated: [] },
106
+ ]);
107
+ expect(stream.getOptionValues(kSofNegative)).toStrictEqual([
108
+ { inlined: "false", separated: [] },
109
+ ]);
98
110
 
99
- expect(stream.getOptionValues(kAa)).toStrictEqual(["true"]);
100
- expect(stream.getOptionValues(kBb)).toStrictEqual(["true"]);
101
- expect(stream.getOptionValues(kCc)).toStrictEqual(["true"]);
111
+ expect(stream.getOptionValues(kAa)).toStrictEqual([
112
+ { inlined: null, separated: [] },
113
+ ]);
114
+ expect(stream.getOptionValues(kBb)).toStrictEqual([
115
+ { inlined: null, separated: [] },
116
+ ]);
117
+ expect(stream.getOptionValues(kCc)).toStrictEqual([
118
+ { inlined: null, separated: [] },
119
+ ]);
102
120
 
103
121
  expect(stream.getOptionValues(kSovUnset)).toStrictEqual([]);
104
- expect(stream.getOptionValues(kSovSplit)).toStrictEqual(["1.1", "1.2"]);
105
- expect(stream.getOptionValues(kSovJoin)).toStrictEqual(["2"]);
122
+ expect(stream.getOptionValues(kSovSplit)).toStrictEqual([
123
+ { inlined: null, separated: ["1.1"] },
124
+ { inlined: null, separated: ["1.2"] },
125
+ ]);
126
+ expect(stream.getOptionValues(kSovJoin)).toStrictEqual([
127
+ { inlined: "2.1", separated: [] },
128
+ { inlined: "2.2", separated: [] },
129
+ ]);
106
130
 
107
- expect(stream.getOptionValues(kDd)).toStrictEqual(["true"]);
108
- expect(stream.getOptionValues(kEe)).toStrictEqual(["true"]);
109
- expect(stream.getOptionValues(kFf)).toStrictEqual(["true"]);
131
+ expect(stream.getOptionValues(kDd)).toStrictEqual([
132
+ { inlined: null, separated: [] },
133
+ ]);
134
+ expect(stream.getOptionValues(kEe)).toStrictEqual([
135
+ { inlined: null, separated: [] },
136
+ ]);
137
+ expect(stream.getOptionValues(kFf)).toStrictEqual([
138
+ { inlined: null, separated: [] },
139
+ ]);
140
+ expect(stream.getOptionValues(kGg)).toStrictEqual([
141
+ { inlined: null, separated: [] },
142
+ ]);
110
143
  });
144
+
145
+ const optionFlagParsing: ReaderOptionParsing = {
146
+ consumeShortGroup: false,
147
+ consumeNextArg: () => false,
148
+ };
149
+
150
+ const optionValueFixedUniqueParsing: ReaderOptionParsing = {
151
+ consumeShortGroup: true,
152
+ consumeNextArg: (inlined, separated) =>
153
+ inlined === null && separated.length === 0,
154
+ };
@@ -2,6 +2,7 @@ import { expect, it } from "@jest/globals";
2
2
  import {
3
3
  command,
4
4
  Command,
5
+ commandChained,
5
6
  commandWithSubcommands,
6
7
  operation,
7
8
  optionFlag,
@@ -16,128 +17,182 @@ import {
16
17
  typeString,
17
18
  } from "../src";
18
19
 
19
- const rootCommand = commandWithSubcommands<string, any, any>(
20
- { description: "Root command description" },
20
+ const rootCommand = commandChained(
21
+ { description: "?" },
21
22
  operation(
22
23
  {
23
24
  options: {
24
- booleanFlag: optionFlag({
25
- long: "boolean-flag",
26
- default: () => false,
25
+ flagPositive: optionFlag({
26
+ short: "fp",
27
+ long: "flag-positive",
28
+ default: true,
27
29
  }),
28
- stringOption: optionSingleValue({
29
- long: "string-option",
30
- type: typeString,
31
- default: () => undefined,
32
- }),
33
- numberOption: optionRepeatable({
34
- long: "number-option",
35
- type: typeList(typeNumber),
30
+ flagNegative: optionFlag({
31
+ short: "fn",
32
+ long: "flag-negative",
33
+ default: false,
36
34
  }),
37
35
  },
38
- positionals: [
39
- positionalRequired({ type: typeNumber }),
40
- positionalRequired({ type: typeNumber }),
41
- ],
36
+ positionals: [positionalRequired({ label: "POS-1", type: typeNumber })],
42
37
  },
43
- async (context, inputs) => {
38
+ async function (context, inputs) {
44
39
  return { at: "root", context, inputs };
45
40
  },
46
41
  ),
47
- {
48
- sub1: command(
49
- { description: "Subcommand 1 description" },
50
- operation(
51
- {
52
- options: {},
53
- positionals: [positionalRequired({ type: typeString })],
54
- },
55
- async (context, inputs) => {
56
- return { at: "sub1", context, inputs };
42
+ commandWithSubcommands<any, any, any>(
43
+ { description: "?" },
44
+ operation(
45
+ {
46
+ options: {
47
+ string: optionSingleValue({
48
+ long: "string-option",
49
+ type: typeString,
50
+ default: () => undefined,
51
+ }),
52
+ number: optionRepeatable({
53
+ long: "number-option",
54
+ type: typeList(typeNumber),
55
+ }),
57
56
  },
58
- ),
57
+ positionals: [positionalRequired({ type: typeNumber })],
58
+ },
59
+ async function (context, inputs) {
60
+ return { at: "mid", context, inputs };
61
+ },
59
62
  ),
60
- sub2: command(
61
- { description: "Subcommand 2 description" },
62
- operation(
63
- {
64
- options: {},
65
- positionals: [
66
- positionalRequired({ type: typeNumber }),
67
- positionalOptional({ type: typeString, default: () => "42" }),
68
- positionalVariadics({ type: typeString }),
69
- ],
70
- },
71
- async (context, inputs) => {
72
- return { at: "sub2", context, inputs };
73
- },
63
+ {
64
+ sub1: command(
65
+ { description: "?" },
66
+ operation(
67
+ {
68
+ options: {},
69
+ positionals: [positionalRequired({ type: typeString })],
70
+ },
71
+ async function (context, inputs) {
72
+ return { at: "sub1", context, inputs };
73
+ },
74
+ ),
74
75
  ),
75
- ),
76
- },
76
+ sub2: command(
77
+ { description: "?" },
78
+ operation(
79
+ {
80
+ options: {},
81
+ positionals: [
82
+ positionalRequired({ type: typeNumber }),
83
+ positionalOptional({ type: typeString, default: () => "42" }),
84
+ positionalVariadics({ type: typeString }),
85
+ ],
86
+ },
87
+ async function (context, inputs) {
88
+ return { at: "sub2", context, inputs };
89
+ },
90
+ ),
91
+ ),
92
+ },
93
+ ),
77
94
  );
78
95
 
79
- it("run", async () => {
80
- const res1 = await executeInterpreted(
81
- ["50", "51", "sub1", "final"],
82
- "Run Context Input",
83
- rootCommand,
84
- );
85
- expect(res1).toStrictEqual({
96
+ it("run", async function () {
97
+ expect(
98
+ await executeInterpreted(
99
+ ["-fn=true", "-fp", "50", "51", "sub1", "final"],
100
+ "Run Context Input",
101
+ rootCommand,
102
+ ),
103
+ ).toStrictEqual({
104
+ at: "sub1",
86
105
  context: {
87
- context: "Run Context Input",
88
- inputs: {
89
- options: {
90
- booleanFlag: false,
91
- stringOption: undefined,
92
- numberOption: [],
106
+ at: "mid",
107
+ context: {
108
+ at: "root",
109
+ context: "Run Context Input",
110
+ inputs: {
111
+ options: { flagPositive: true, flagNegative: true },
112
+ positionals: [50],
93
113
  },
94
- positionals: [50, 51],
95
114
  },
96
- at: "root",
115
+ inputs: {
116
+ options: { string: undefined, number: [] },
117
+ positionals: [51],
118
+ },
97
119
  },
98
120
  inputs: {
99
121
  options: {},
100
122
  positionals: ["final"],
101
123
  },
102
- at: "sub1",
103
124
  });
104
125
 
105
- const res2 = await executeInterpreted(
106
- [
107
- "40",
108
- "41",
109
- "sub2",
110
- "--string-option=hello",
111
- "--number-option",
112
- "123.1,123.2",
113
- "--number-option",
114
- "123.3",
115
- "88.88",
116
- "a,b",
117
- "final",
118
- "--boolean-flag",
119
- ],
120
- "Run Context Input",
121
- rootCommand,
122
- );
123
- expect(res2).toStrictEqual({
126
+ expect(
127
+ await executeInterpreted(
128
+ ["50", "51", "sub2", "9999.99"],
129
+ "Run Context Input",
130
+ rootCommand,
131
+ ),
132
+ ).toStrictEqual({
133
+ at: "sub2",
124
134
  context: {
125
- context: "Run Context Input",
135
+ at: "mid",
136
+ context: {
137
+ at: "root",
138
+ context: "Run Context Input",
139
+ inputs: {
140
+ options: { flagPositive: true, flagNegative: false },
141
+ positionals: [50],
142
+ },
143
+ },
126
144
  inputs: {
127
- options: {
128
- booleanFlag: true,
129
- stringOption: "hello",
130
- numberOption: [[123.1, 123.2], [123.3]],
145
+ options: { string: undefined, number: [] },
146
+ positionals: [51],
147
+ },
148
+ },
149
+ inputs: {
150
+ options: {},
151
+ positionals: [9999.99, "42", []],
152
+ },
153
+ });
154
+
155
+ expect(
156
+ await executeInterpreted(
157
+ [
158
+ "40",
159
+ "41",
160
+ "sub2",
161
+ "--string-option=hello",
162
+ "--number-option",
163
+ "123.1,123.2",
164
+ "--number-option",
165
+ "123.3",
166
+ "88.88",
167
+ "a,b",
168
+ "final",
169
+ "--no-flag-positive",
170
+ "--no-flag-negative",
171
+ ],
172
+ "Run Context Input",
173
+ rootCommand,
174
+ ),
175
+ ).toStrictEqual({
176
+ at: "sub2",
177
+ context: {
178
+ at: "mid",
179
+ context: {
180
+ at: "root",
181
+ context: "Run Context Input",
182
+ inputs: {
183
+ options: { flagPositive: false, flagNegative: false },
184
+ positionals: [40],
131
185
  },
132
- positionals: [40, 41],
133
186
  },
134
- at: "root",
187
+ inputs: {
188
+ options: { string: "hello", number: [[123.1, 123.2], [123.3]] },
189
+ positionals: [41],
190
+ },
135
191
  },
136
192
  inputs: {
137
193
  options: {},
138
194
  positionals: [88.88, "a,b", ["final"]],
139
195
  },
140
- at: "sub2",
141
196
  });
142
197
  });
143
198
 
@@ -147,7 +202,7 @@ async function executeInterpreted<Context, Result>(
147
202
  command: Command<Context, Result>,
148
203
  ) {
149
204
  const readerArgs = new ReaderArgs(args);
150
- const commandFactory = command.createFactory(readerArgs);
151
- const commandInstance = commandFactory.createInstance();
152
- return await commandInstance.executeWithContext(context);
205
+ const commandDecoder = command.consumeAndMakeDecoder(readerArgs);
206
+ const commandInterpreter = commandDecoder.decodeAndMakeInterpreter();
207
+ return await commandInterpreter.executeWithContext(context);
153
208
  }