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.
- package/README.md +62 -4
- package/dist/index.d.ts +135 -128
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/docs/.vitepress/config.mts +1 -1
- package/docs/.vitepress/theme/Layout.vue +16 -0
- package/docs/.vitepress/theme/index.ts +5 -1
- package/docs/.vitepress/theme/style.css +5 -1
- package/docs/guide/02_commands.md +1 -1
- package/docs/guide/03_options.md +11 -11
- package/docs/guide/05_input_types.md +9 -10
- package/docs/guide/06_run_as_cli.md +1 -1
- package/docs/index.md +2 -2
- package/docs/public/favicon.ico +0 -0
- package/docs/public/logo.png +0 -0
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/lib/Command.ts +50 -30
- package/src/lib/Operation.ts +29 -21
- package/src/lib/Option.ts +198 -133
- package/src/lib/Positional.ts +46 -24
- package/src/lib/Reader.ts +194 -207
- package/src/lib/Run.ts +19 -8
- package/src/lib/Suggest.ts +78 -0
- package/src/lib/Type.ts +46 -48
- package/src/lib/Typo.ts +72 -47
- package/src/lib/Usage.ts +13 -13
- package/tests/unit.Reader.commons.ts +92 -116
- package/tests/unit.Reader.parsings.ts +14 -26
- package/tests/unit.Reader.shortBig.ts +81 -96
- package/tests/unit.command.aliases.ts +100 -0
- package/tests/unit.command.execute.ts +1 -1
- package/tests/unit.command.usage.ts +12 -6
- package/tests/unit.fuzzed.alternatives.ts +43 -0
- package/tests/unit.runner.colors.ts +11 -35
- package/tests/unit.runner.cycle.ts +181 -128
- package/tests/unit.runner.errors.ts +26 -19
- package/docs/public/hero.png +0 -0
- package/tests/unit.Reader.aliases.ts +0 -62
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
#
|
|
1
|
+
# cli-kiss
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Type-safe CLI builder for TypeScript. No dependencies, no supply-chain attacks.
|
|
4
|
+
|
|
5
|
+
Small API, standard compliance, polished help output, zero runtime dependencies.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
- Compose commands, subcommands, options, and positionals with strong types
|
|
10
|
+
- Get built-in `--help`, `--version`, and color-aware error messages
|
|
11
|
+
- Ship a real CLI parser without pulling in a dependency tree
|
|
4
12
|
|
|
5
13
|
## Install
|
|
6
14
|
|
|
@@ -8,6 +16,56 @@ Full-featured CLI builder for TypeScript. No bloat, no dependency.
|
|
|
8
16
|
npm install cli-kiss
|
|
9
17
|
```
|
|
10
18
|
|
|
11
|
-
##
|
|
19
|
+
## Example
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import {
|
|
23
|
+
command,
|
|
24
|
+
operation,
|
|
25
|
+
optionFlag,
|
|
26
|
+
positionalRequired,
|
|
27
|
+
runAndExit,
|
|
28
|
+
type,
|
|
29
|
+
} from "cli-kiss";
|
|
30
|
+
|
|
31
|
+
const greet = command(
|
|
32
|
+
{ description: "Greet someone" },
|
|
33
|
+
operation(
|
|
34
|
+
{
|
|
35
|
+
options: {
|
|
36
|
+
loud: optionFlag({ long: "loud", description: "Print in uppercase" }),
|
|
37
|
+
},
|
|
38
|
+
positionals: [positionalRequired({ type: type("name") })],
|
|
39
|
+
},
|
|
40
|
+
async (_ctx, { options: { loud }, positionals: [name] }) => {
|
|
41
|
+
const text = `Hello, ${name}!`;
|
|
42
|
+
console.log(loud ? text.toUpperCase() : text);
|
|
43
|
+
},
|
|
44
|
+
),
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
await runAndExit("greet", process.argv.slice(2), {}, greet, {
|
|
48
|
+
buildVersion: "1.0.0",
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
greet --help
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
Usage: greet <name>
|
|
58
|
+
|
|
59
|
+
Greet someone
|
|
60
|
+
|
|
61
|
+
Positionals:
|
|
62
|
+
<name>
|
|
63
|
+
|
|
64
|
+
Options:
|
|
65
|
+
--loud[=no] Print in uppercase
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Docs
|
|
12
69
|
|
|
13
|
-
|
|
70
|
+
Guides, examples, and API usage:
|
|
71
|
+
[crypto-vincent.github.io/cli-kiss](https://crypto-vincent.github.io/cli-kiss/)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,47 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Opaque key returned by {@link ReaderArgs.registerOption}.
|
|
3
2
|
*/
|
|
4
|
-
type
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
__brand: "ReaderOptionKey";
|
|
3
|
+
type ReaderOptionLongSpec = {
|
|
4
|
+
key: string;
|
|
5
|
+
nextGuard: ReaderOptionNextGuard;
|
|
8
6
|
};
|
|
9
7
|
/**
|
|
10
|
-
* Parsing behaviour for a registered option, passed to {@link ReaderArgs.registerOption}.
|
|
11
8
|
*/
|
|
12
|
-
type
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
type ReaderOptionShortSpec = {
|
|
10
|
+
key: string;
|
|
11
|
+
restGuard: ReaderOptionRestGuard;
|
|
12
|
+
nextGuard: ReaderOptionNextGuard;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
*/
|
|
16
|
+
type ReaderOptionRestGuard = (rest: string) => boolean;
|
|
17
|
+
/**
|
|
18
|
+
*/
|
|
19
|
+
type ReaderOptionNextGuard = (value: ReaderOptionValue, next: string | undefined) => boolean;
|
|
20
|
+
/**
|
|
21
|
+
*/
|
|
22
|
+
type ReaderOptionResult = {
|
|
23
|
+
identifier: string;
|
|
24
|
+
values: ReadonlyArray<ReaderOptionValue>;
|
|
15
25
|
};
|
|
16
26
|
/**
|
|
17
|
-
* Result of parsing an option, including its inlined value and any following separated values.
|
|
18
27
|
*/
|
|
19
28
|
type ReaderOptionValue = {
|
|
20
29
|
inlined: string | null;
|
|
21
|
-
separated:
|
|
30
|
+
separated: ReadonlyArray<string>;
|
|
22
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
*/
|
|
34
|
+
type ReaderOptionGetter = () => ReaderOptionResult;
|
|
23
35
|
/**
|
|
24
36
|
* Option registration/query interface. Subset of {@link ReaderArgs}.
|
|
25
37
|
*/
|
|
26
38
|
type ReaderOptions = {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
*
|
|
30
|
-
* @param definition.longs - Long-form names (without `--`).
|
|
31
|
-
* @param definition.shorts - Short-form names (without `-`).
|
|
32
|
-
* @param definition.parsing - Parsing behaviour.
|
|
33
|
-
* @returns A {@link ReaderOptionKey} for later retrieval.
|
|
34
|
-
* @throws `Error` if a name is already registered or short names overlap.
|
|
35
|
-
*/
|
|
36
|
-
registerOption(definition: {
|
|
37
|
-
longs: Array<string>;
|
|
38
|
-
shorts: Array<string>;
|
|
39
|
-
parsing: ReaderOptionParsing;
|
|
40
|
-
}): ReaderOptionKey;
|
|
41
|
-
/**
|
|
42
|
-
* Returns all values collected for `key`.
|
|
43
|
-
*/
|
|
44
|
-
getOptionValues(key: ReaderOptionKey): Array<ReaderOptionValue>;
|
|
39
|
+
registerOptionLong(longSpec: ReaderOptionLongSpec): ReaderOptionGetter;
|
|
40
|
+
registerOptionShort(shortSpec: ReaderOptionShortSpec): ReaderOptionGetter;
|
|
45
41
|
};
|
|
46
42
|
/**
|
|
47
43
|
* Positional consumption interface. Subset of {@link ReaderArgs}.
|
|
@@ -51,7 +47,7 @@ type ReaderPositionals = {
|
|
|
51
47
|
* Returns the next positional token, parsing intervening options as side-effects.
|
|
52
48
|
*
|
|
53
49
|
* @returns The next positional, or `undefined` when exhausted.
|
|
54
|
-
* @throws
|
|
50
|
+
* @throws on an unrecognised option.
|
|
55
51
|
*/
|
|
56
52
|
consumePositional(): string | undefined;
|
|
57
53
|
};
|
|
@@ -67,38 +63,21 @@ type ReaderPositionals = {
|
|
|
67
63
|
declare class ReaderArgs {
|
|
68
64
|
#private;
|
|
69
65
|
/**
|
|
70
|
-
* @param
|
|
66
|
+
* @param tokens - Raw CLI tokens (e.g. `process.argv.slice(2)`).
|
|
71
67
|
*/
|
|
72
|
-
constructor(
|
|
68
|
+
constructor(tokens: ReadonlyArray<string>);
|
|
69
|
+
/**
|
|
70
|
+
*/
|
|
71
|
+
registerOptionLong(longSpec: ReaderOptionLongSpec): ReaderOptionGetter;
|
|
73
72
|
/**
|
|
74
|
-
* Registers an option; all `longs` and `shorts` share the same key.
|
|
75
|
-
* Short names must not be prefixes of one another.
|
|
76
|
-
*
|
|
77
|
-
* @param definition.longs - Long-form names (without `--`).
|
|
78
|
-
* @param definition.shorts - Short-form names (without `-`).
|
|
79
|
-
* @param definition.parsing - Parsing behaviour.
|
|
80
|
-
* @returns A {@link ReaderOptionKey} for {@link ReaderArgs.getOptionValues}.
|
|
81
|
-
* @throws `Error` if any name is already registered or short names overlap.
|
|
82
|
-
*/
|
|
83
|
-
registerOption(definition: {
|
|
84
|
-
longs: Array<string>;
|
|
85
|
-
shorts: Array<string>;
|
|
86
|
-
parsing: ReaderOptionParsing;
|
|
87
|
-
}): ReaderOptionKey;
|
|
88
|
-
/**
|
|
89
|
-
* Returns all values collected for `key`.
|
|
90
|
-
*
|
|
91
|
-
* @param key - Key from {@link ReaderArgs.registerOption}.
|
|
92
|
-
* @returns One entry per occurrence.
|
|
93
|
-
* @throws `Error` if `key` was not registered.
|
|
94
73
|
*/
|
|
95
|
-
|
|
74
|
+
registerOptionShort(shortSpec: ReaderOptionShortSpec): ReaderOptionGetter;
|
|
96
75
|
/**
|
|
97
76
|
* Returns the next positional token; parses intervening options as a side-effect.
|
|
98
77
|
* All tokens after `--` are treated as positionals.
|
|
99
78
|
*
|
|
100
79
|
* @returns The next positional, or `undefined` when exhausted.
|
|
101
|
-
* @throws
|
|
80
|
+
* @throws on an unrecognised option.
|
|
102
81
|
*/
|
|
103
82
|
consumePositional(): string | undefined;
|
|
104
83
|
}
|
|
@@ -115,7 +94,7 @@ declare class ReaderArgs {
|
|
|
115
94
|
*/
|
|
116
95
|
type Type<Value> = {
|
|
117
96
|
/**
|
|
118
|
-
* Human-readable name shown in help and errors (e.g. `"name"`, `"
|
|
97
|
+
* Human-readable name shown in help and errors (e.g. `"name"`, `"context"`).
|
|
119
98
|
*/
|
|
120
99
|
content: string;
|
|
121
100
|
/**
|
|
@@ -123,7 +102,7 @@ type Type<Value> = {
|
|
|
123
102
|
*
|
|
124
103
|
* @param input - Raw string from the command line.
|
|
125
104
|
* @returns The decoded value.
|
|
126
|
-
* @throws
|
|
105
|
+
* @throws on invalid input.
|
|
127
106
|
*/
|
|
128
107
|
decoder(input: string): Value;
|
|
129
108
|
};
|
|
@@ -142,8 +121,6 @@ type Type<Value> = {
|
|
|
142
121
|
* ```
|
|
143
122
|
*/
|
|
144
123
|
declare function typeBoolean(name?: string): Type<boolean>;
|
|
145
|
-
declare const typeBooleanValuesTrue: Set<string>;
|
|
146
|
-
declare const typeBooleanValuesFalse: Set<string>;
|
|
147
124
|
/**
|
|
148
125
|
* Parses a date/time string via `Date.parse`.
|
|
149
126
|
* Accepts any format supported by `Date.parse`, including ISO 8601.
|
|
@@ -157,7 +134,7 @@ declare const typeBooleanValuesFalse: Set<string>;
|
|
|
157
134
|
*/
|
|
158
135
|
declare function typeDatetime(name?: string): Type<Date>;
|
|
159
136
|
/**
|
|
160
|
-
* Parses a string to `number` via `Number()`; `NaN` throws
|
|
137
|
+
* Parses a string to `number` via `Number()`; `NaN` throws.
|
|
161
138
|
*
|
|
162
139
|
* @example
|
|
163
140
|
* ```ts
|
|
@@ -169,7 +146,7 @@ declare function typeDatetime(name?: string): Type<Date>;
|
|
|
169
146
|
declare function typeNumber(name?: string): Type<number>;
|
|
170
147
|
/**
|
|
171
148
|
* Parses an integer string to `bigint` via `BigInt()`.
|
|
172
|
-
* Floats and non-numeric strings
|
|
149
|
+
* Floats and non-numeric strings throws.
|
|
173
150
|
*
|
|
174
151
|
* @example
|
|
175
152
|
* ```ts
|
|
@@ -181,7 +158,7 @@ declare function typeNumber(name?: string): Type<number>;
|
|
|
181
158
|
declare function typeInteger(name?: string): Type<bigint>;
|
|
182
159
|
/**
|
|
183
160
|
* Parses an absolute URL string to a `URL` object.
|
|
184
|
-
* Relative or malformed URLs
|
|
161
|
+
* Relative or malformed URLs throws.
|
|
185
162
|
*
|
|
186
163
|
* @example
|
|
187
164
|
* ```ts
|
|
@@ -241,7 +218,6 @@ declare function typePath(name?: string, checks?: {
|
|
|
241
218
|
}): Type<string>;
|
|
242
219
|
/**
|
|
243
220
|
* Creates a {@link Type}`<string>` that only accepts a fixed set of values.
|
|
244
|
-
* Out-of-set inputs throw {@link TypoError} listing up to 5 valid options.
|
|
245
221
|
*
|
|
246
222
|
* @param name - Name shown in help and errors.
|
|
247
223
|
* @param values - Ordered list of accepted values.
|
|
@@ -251,13 +227,13 @@ declare function typePath(name?: string, checks?: {
|
|
|
251
227
|
* ```ts
|
|
252
228
|
* const typeEnv = typeChoice("environment", ["dev", "staging", "prod"]);
|
|
253
229
|
* typeEnv.decoder("prod") // → "prod"
|
|
254
|
-
* typeEnv.decoder("unknown") // throws
|
|
230
|
+
* typeEnv.decoder("unknown") // throws
|
|
255
231
|
* ```
|
|
256
232
|
*/
|
|
257
233
|
declare function typeChoice<const Value extends string>(name: string, values: Array<Value>, caseSensitive?: boolean): Type<Value>;
|
|
258
234
|
/**
|
|
259
235
|
* Splits a delimited string into a typed tuple.
|
|
260
|
-
* Each part is decoded by the corresponding element type; wrong count or decode failure throws
|
|
236
|
+
* Each part is decoded by the corresponding element type; wrong count or decode failure throws.
|
|
261
237
|
*
|
|
262
238
|
* @typeParam Elements - Tuple of decoded value types (inferred from `elementTypes`).
|
|
263
239
|
*
|
|
@@ -269,8 +245,9 @@ declare function typeChoice<const Value extends string>(name: string, values: Ar
|
|
|
269
245
|
* ```ts
|
|
270
246
|
* const typePoint = typeTuple([typeNumber("x"), typeNumber("y")]);
|
|
271
247
|
* typePoint.decoder("3.14,2.71") // → [3.14, 2.71]
|
|
272
|
-
* typePoint.decoder("1
|
|
273
|
-
* typePoint.decoder("
|
|
248
|
+
* typePoint.decoder("1") // throws
|
|
249
|
+
* typePoint.decoder("1,2,3") // throws
|
|
250
|
+
* typePoint.decoder("x,2") // throws
|
|
274
251
|
* ```
|
|
275
252
|
*/
|
|
276
253
|
declare function typeTuple<const Elements extends Array<any>>(elementTypes: {
|
|
@@ -278,7 +255,7 @@ declare function typeTuple<const Elements extends Array<any>>(elementTypes: {
|
|
|
278
255
|
}, separator?: string): Type<Elements>;
|
|
279
256
|
/**
|
|
280
257
|
* Splits a delimited string into a typed array.
|
|
281
|
-
* Each part is decoded by `elementType`; failed decodes
|
|
258
|
+
* Each part is decoded by `elementType`; failed decodes throws.
|
|
282
259
|
* Note: splitting an empty string yields one empty element — prefer {@link optionRepeatable} for a zero-default.
|
|
283
260
|
*
|
|
284
261
|
* @typeParam Value - Element type produced by `elementType.decoder`.
|
|
@@ -289,10 +266,9 @@ declare function typeTuple<const Elements extends Array<any>>(elementTypes: {
|
|
|
289
266
|
*
|
|
290
267
|
* @example
|
|
291
268
|
* ```ts
|
|
292
|
-
* const typeNumbers = typeList(typeNumber);
|
|
269
|
+
* const typeNumbers = typeList(typeNumber("v"));
|
|
293
270
|
* typeNumbers.decoder("1,2,3") // → [1, 2, 3]
|
|
294
|
-
* typeNumbers.decoder("1,x,3") // throws
|
|
295
|
-
*
|
|
271
|
+
* typeNumbers.decoder("1,x,3") // throws
|
|
296
272
|
* const typePaths = typeList(typePath(), ":");
|
|
297
273
|
* typePaths.decoder("/usr/bin:/usr/local/bin") // → ["/usr/bin", "/usr/local/bin"]
|
|
298
274
|
* ```
|
|
@@ -381,9 +357,9 @@ declare class TypoString {
|
|
|
381
357
|
#private;
|
|
382
358
|
/**
|
|
383
359
|
* @param value - Raw text content.
|
|
384
|
-
* @param
|
|
360
|
+
* @param style - Style to apply when rendering.
|
|
385
361
|
*/
|
|
386
|
-
constructor(value: string,
|
|
362
|
+
constructor(value: string, style?: TypoStyle);
|
|
387
363
|
/**
|
|
388
364
|
* Returns the text styled by `typoSupport`.
|
|
389
365
|
*
|
|
@@ -394,7 +370,15 @@ declare class TypoString {
|
|
|
394
370
|
* Returns the raw text.
|
|
395
371
|
*/
|
|
396
372
|
getRawString(): string;
|
|
373
|
+
/**
|
|
374
|
+
* Predefined ellipsis segment with subtle styling.
|
|
375
|
+
*/
|
|
376
|
+
static elipsis: TypoString;
|
|
397
377
|
}
|
|
378
|
+
/**
|
|
379
|
+
* A segment of styled text, a string, or an array of segments.
|
|
380
|
+
*/
|
|
381
|
+
type TypoSegment = TypoText | TypoString | Array<TypoSegment>;
|
|
398
382
|
/**
|
|
399
383
|
* Mutable sequence of {@link TypoString} segments.
|
|
400
384
|
*/
|
|
@@ -403,13 +387,15 @@ declare class TypoText {
|
|
|
403
387
|
/**
|
|
404
388
|
* @param segments - Initial text segments
|
|
405
389
|
*/
|
|
406
|
-
constructor(...segments: Array<
|
|
390
|
+
constructor(...segments: Array<TypoSegment>);
|
|
407
391
|
/**
|
|
408
392
|
* Appends new text segment(s).
|
|
409
|
-
*
|
|
410
|
-
* @param segment - Text segment(s) to append.
|
|
411
393
|
*/
|
|
412
|
-
push(
|
|
394
|
+
push(...segments: Array<TypoSegment>): void;
|
|
395
|
+
/**
|
|
396
|
+
* Appends separated segments, optionally truncating with an ellipsis.
|
|
397
|
+
*/
|
|
398
|
+
pushJoined(segments: Array<TypoSegment>, separator: TypoSegment, ellipsisLimit: number): void;
|
|
413
399
|
/**
|
|
414
400
|
* Renders all segments into a single styled string.
|
|
415
401
|
*
|
|
@@ -505,7 +491,7 @@ declare class TypoSupport {
|
|
|
505
491
|
* @param typoStyle - Style to apply.
|
|
506
492
|
* @returns Styled string.
|
|
507
493
|
*/
|
|
508
|
-
computeStyledString(value: string, typoStyle: TypoStyle): string;
|
|
494
|
+
computeStyledString(value: string, typoStyle: TypoStyle | undefined): string;
|
|
509
495
|
/**
|
|
510
496
|
* Formats any thrown value as `"Error: <message>"` with {@link typoStyleFailure} on the prefix.
|
|
511
497
|
*
|
|
@@ -671,7 +657,7 @@ type Option<Value> = {
|
|
|
671
657
|
/**
|
|
672
658
|
* Registers the option on `readerOptions` and returns an {@link OptionDecoder}.
|
|
673
659
|
*/
|
|
674
|
-
registerAndMakeDecoder(readerOptions:
|
|
660
|
+
registerAndMakeDecoder(readerOptions: ReaderOptions): OptionDecoder<Value>;
|
|
675
661
|
};
|
|
676
662
|
/**
|
|
677
663
|
* Produced by {@link Option.registerAndMakeDecoder}.
|
|
@@ -682,15 +668,19 @@ type OptionDecoder<Value> = {
|
|
|
682
668
|
/**
|
|
683
669
|
* Returns the decoded option value.
|
|
684
670
|
*
|
|
685
|
-
* @throws
|
|
671
|
+
* @throws if decoding failed.
|
|
686
672
|
*/
|
|
687
673
|
getAndDecodeValue(): Value;
|
|
688
674
|
};
|
|
689
675
|
/**
|
|
690
676
|
* Creates a boolean flag option (`--verbose`, optionally `--flag=no`).
|
|
691
677
|
*
|
|
692
|
-
*
|
|
693
|
-
*
|
|
678
|
+
* Syntax: `--long`, `--long=no`, `-s`, `-s=no`.
|
|
679
|
+
* Parsing logic:
|
|
680
|
+
* - absent → default value
|
|
681
|
+
* - `--flag` / `--flag=yes` → `true`
|
|
682
|
+
* - `--flag=no` → `false`
|
|
683
|
+
* - specified more than once → throws.
|
|
694
684
|
*
|
|
695
685
|
* @param definition.long - Long-form name (without `--`).
|
|
696
686
|
* @param definition.short - Short-form name (without `-`).
|
|
@@ -707,11 +697,6 @@ type OptionDecoder<Value> = {
|
|
|
707
697
|
* short: "v",
|
|
708
698
|
* description: "Enable verbose output",
|
|
709
699
|
* });
|
|
710
|
-
* // Usage:
|
|
711
|
-
* // my-cli → false
|
|
712
|
-
* // my-cli --verbose → true
|
|
713
|
-
* // my-cli --verbose=yes → true
|
|
714
|
-
* // my-cli -v=no → false
|
|
715
700
|
* ```
|
|
716
701
|
*/
|
|
717
702
|
declare function optionFlag(definition: {
|
|
@@ -728,8 +713,13 @@ declare function optionFlag(definition: {
|
|
|
728
713
|
/**
|
|
729
714
|
* Creates an option that accepts exactly one value (e.g. `--output dist/`).
|
|
730
715
|
*
|
|
731
|
-
*
|
|
732
|
-
*
|
|
716
|
+
* Syntax: `--long value`, `--long=value`, `-s value`, `-s=value`, `-svalue`.
|
|
717
|
+
* Parsing logic:
|
|
718
|
+
* - absent → `fallbackValueIfAbsent()`
|
|
719
|
+
* - `--long value` → decoded with `type.decoder("value")`
|
|
720
|
+
* - more than once → throws
|
|
721
|
+
* - if `impliedValueIfNotInlined` is not provided, then: `--long` / `-s` without a value → throws
|
|
722
|
+
* - if `impliedValueIfNotInlined` is provided, then: `--long` / `-s` without an inline value → `impliedValueIfNotInlined()`
|
|
733
723
|
*
|
|
734
724
|
* @typeParam Value - Type produced by the decoder.
|
|
735
725
|
*
|
|
@@ -739,8 +729,8 @@ declare function optionFlag(definition: {
|
|
|
739
729
|
* @param definition.hint - Short note shown in parentheses.
|
|
740
730
|
* @param definition.aliases - Additional names.
|
|
741
731
|
* @param definition.type - Decoder for the raw string value.
|
|
742
|
-
* @param definition.
|
|
743
|
-
* @param definition.
|
|
732
|
+
* @param definition.fallbackValueIfAbsent - Default value when the option is not specified at all.
|
|
733
|
+
* @param definition.impliedValueIfNotInlined - Default value when the option is specified without an inline value (e.g. `--option` or `-o`).
|
|
744
734
|
* @returns An {@link Option}`<Value>`.
|
|
745
735
|
*
|
|
746
736
|
* @example
|
|
@@ -750,12 +740,8 @@ declare function optionFlag(definition: {
|
|
|
750
740
|
* short: "o",
|
|
751
741
|
* type: typePath(),
|
|
752
742
|
* description: "Output directory",
|
|
753
|
-
*
|
|
743
|
+
* fallbackValueIfAbsent: () => "dist",
|
|
754
744
|
* });
|
|
755
|
-
* // Usage:
|
|
756
|
-
* // my-cli → "dist"
|
|
757
|
-
* // my-cli --output folder → "folder"
|
|
758
|
-
* // my-cli -o folder → "folder"
|
|
759
745
|
* ```
|
|
760
746
|
*/
|
|
761
747
|
declare function optionSingleValue<Value>(definition: {
|
|
@@ -768,14 +754,16 @@ declare function optionSingleValue<Value>(definition: {
|
|
|
768
754
|
shorts?: Array<string>;
|
|
769
755
|
};
|
|
770
756
|
type: Type<Value>;
|
|
771
|
-
|
|
772
|
-
|
|
757
|
+
fallbackValueIfAbsent?: () => Value;
|
|
758
|
+
impliedValueIfNotInlined?: () => Value;
|
|
773
759
|
}): Option<Value>;
|
|
774
760
|
/**
|
|
775
761
|
* Creates an option that collects every occurrence into an array (e.g. `--file a.ts --file b.ts`).
|
|
776
762
|
*
|
|
777
|
-
*
|
|
778
|
-
*
|
|
763
|
+
* Syntax: `--long value`, `--long=value`, `-s value`, `-s=value`, `-svalue`.
|
|
764
|
+
* Parsing logic:
|
|
765
|
+
* - absent → `[]`
|
|
766
|
+
* - N occurrences → array of N decoded values in order.
|
|
779
767
|
*
|
|
780
768
|
* @typeParam Value - Type produced by the decoder for each occurrence.
|
|
781
769
|
*
|
|
@@ -796,7 +784,6 @@ declare function optionSingleValue<Value>(definition: {
|
|
|
796
784
|
* label: "PATH",
|
|
797
785
|
* description: "Input file (may be repeated)",
|
|
798
786
|
* });
|
|
799
|
-
* // Usage: my-cli --file a.ts --file b.ts → ["a.ts", "b.ts"]
|
|
800
787
|
* ```
|
|
801
788
|
*/
|
|
802
789
|
declare function optionRepeatable<Value>(definition: {
|
|
@@ -837,18 +824,24 @@ type PositionalDecoder<Value> = {
|
|
|
837
824
|
/**
|
|
838
825
|
* Returns the decoded positional value.
|
|
839
826
|
*
|
|
840
|
-
* @throws
|
|
827
|
+
* @throws if decoding failed.
|
|
841
828
|
*/
|
|
842
829
|
decodeValue(): Value;
|
|
843
830
|
};
|
|
844
831
|
/**
|
|
845
|
-
* Creates a required positional — missing token throws
|
|
832
|
+
* Creates a required positional — missing token throws.
|
|
833
|
+
*
|
|
834
|
+
* Syntax: `<type>`, e.g. `<NAME>`.
|
|
835
|
+
* Parsing logic:
|
|
836
|
+
* - "token" → decoded with `type.decoder("token")`
|
|
837
|
+
* - token missing → throws
|
|
846
838
|
*
|
|
847
839
|
* @typeParam Value - Type produced by the decoder.
|
|
848
840
|
*
|
|
849
841
|
* @param definition.description - Help text.
|
|
850
842
|
* @param definition.hint - Short note shown in parentheses.
|
|
851
843
|
* @param definition.type - Decoder for the raw token.
|
|
844
|
+
* @param definition.missing - Message shown when the token is missing.
|
|
852
845
|
* @returns A {@link Positional}`<Value>`.
|
|
853
846
|
*
|
|
854
847
|
* @example
|
|
@@ -857,8 +850,6 @@ type PositionalDecoder<Value> = {
|
|
|
857
850
|
* type: type("name"),
|
|
858
851
|
* description: "The name to greet",
|
|
859
852
|
* });
|
|
860
|
-
* // Usage:
|
|
861
|
-
* // my-cli Alice → "Alice"
|
|
862
853
|
* ```
|
|
863
854
|
*/
|
|
864
855
|
declare function positionalRequired<Value>(definition: {
|
|
@@ -869,6 +860,11 @@ declare function positionalRequired<Value>(definition: {
|
|
|
869
860
|
/**
|
|
870
861
|
* Creates an optional positional — absent token falls back to `default()`.
|
|
871
862
|
*
|
|
863
|
+
* Syntax: `[type]`, e.g. `[NAME]`.
|
|
864
|
+
* Parsing logic:
|
|
865
|
+
* - "token" → decoded with `type.decoder("token")`
|
|
866
|
+
* - token missing → `default()`
|
|
867
|
+
*
|
|
872
868
|
* @typeParam Value - Type produced by the decoder (or the default).
|
|
873
869
|
*
|
|
874
870
|
* @param definition.description - Help text.
|
|
@@ -881,12 +877,10 @@ declare function positionalRequired<Value>(definition: {
|
|
|
881
877
|
* ```ts
|
|
882
878
|
* const greeteePositional = positionalOptional({
|
|
883
879
|
* type: type("name"),
|
|
884
|
-
* description: "Name to greet
|
|
880
|
+
* description: "Name to greet",
|
|
881
|
+
* hint: "Defaults to \"world\"",
|
|
885
882
|
* default: () => "world",
|
|
886
883
|
* });
|
|
887
|
-
* // Usage:
|
|
888
|
-
* // my-cli → "world"
|
|
889
|
-
* // my-cli Alice → "Alice"
|
|
890
884
|
* ```
|
|
891
885
|
*/
|
|
892
886
|
declare function positionalOptional<Value>(definition: {
|
|
@@ -899,6 +893,12 @@ declare function positionalOptional<Value>(definition: {
|
|
|
899
893
|
* Creates a variadic positional that collects zero or more remaining tokens into an array.
|
|
900
894
|
* Optionally stops at `endDelimiter` (consumed, not included).
|
|
901
895
|
*
|
|
896
|
+
* Syntax: `[type]...`, e.g. `[NAME]...`.
|
|
897
|
+
* Parsing logic:
|
|
898
|
+
* - "a b ..." → decoded with `[type.decoder("a")`, `type.decoder("b"), ...]``
|
|
899
|
+
* - token missing → stops collection
|
|
900
|
+
* - endDelimiter encountered → stops collection
|
|
901
|
+
*
|
|
902
902
|
* @typeParam Value - Type produced by the decoder for each token.
|
|
903
903
|
*
|
|
904
904
|
* @param definition.endDelimiter - Sentinel token that stops collection (consumed, not included).
|
|
@@ -913,9 +913,6 @@ declare function positionalOptional<Value>(definition: {
|
|
|
913
913
|
* type: typePath(),
|
|
914
914
|
* description: "Files to process",
|
|
915
915
|
* });
|
|
916
|
-
* // Usage:
|
|
917
|
-
* // my-cli → []
|
|
918
|
-
* // my-cli a.ts b.ts c.ts → ["a.ts", "b.ts", "c.ts"]
|
|
919
916
|
* ```
|
|
920
917
|
*/
|
|
921
918
|
declare function positionalVariadics<Value>(definition: {
|
|
@@ -963,7 +960,7 @@ type OperationDecoder<Context, Result> = {
|
|
|
963
960
|
/**
|
|
964
961
|
* Creates a ready-to-execute {@link OperationInterpreter}.
|
|
965
962
|
*
|
|
966
|
-
* @throws
|
|
963
|
+
* @throws if parsing or decoding failed.
|
|
967
964
|
*/
|
|
968
965
|
decodeAndMakeInterpreter(): OperationInterpreter<Context, Result>;
|
|
969
966
|
};
|
|
@@ -1000,7 +997,7 @@ type OperationInterpreter<Context, Result> = {
|
|
|
1000
997
|
* const greetOperation = operation(
|
|
1001
998
|
* {
|
|
1002
999
|
* options: {
|
|
1003
|
-
* loud: optionFlag({ long: "loud", description: "Print in uppercase"
|
|
1000
|
+
* loud: optionFlag({ long: "loud", description: "Print in uppercase" }),
|
|
1004
1001
|
* },
|
|
1005
1002
|
* positionals: [
|
|
1006
1003
|
* positionalRequired({ type: type("name"), description: "Name to greet" }),
|
|
@@ -1013,18 +1010,22 @@ type OperationInterpreter<Context, Result> = {
|
|
|
1013
1010
|
* );
|
|
1014
1011
|
* ```
|
|
1015
1012
|
*/
|
|
1016
|
-
declare function operation<Context, Result, Options extends {
|
|
1013
|
+
declare function operation<Context, Result, const Options extends {
|
|
1017
1014
|
[option: string]: any;
|
|
1018
|
-
}, const Positionals extends Array<any
|
|
1019
|
-
options
|
|
1015
|
+
} = {}, const Positionals extends Array<any> = []>(inputs: {
|
|
1016
|
+
options?: {
|
|
1020
1017
|
[K in keyof Options]: Option<Options[K]>;
|
|
1021
1018
|
};
|
|
1022
|
-
positionals
|
|
1019
|
+
positionals?: {
|
|
1023
1020
|
[K in keyof Positionals]: Positional<Positionals[K]>;
|
|
1024
1021
|
};
|
|
1025
1022
|
}, handler: (context: Context, inputs: {
|
|
1026
|
-
options:
|
|
1027
|
-
|
|
1023
|
+
options: {
|
|
1024
|
+
[K in keyof Options]: Options[K];
|
|
1025
|
+
};
|
|
1026
|
+
positionals: {
|
|
1027
|
+
[K in keyof Positionals]: Positionals[K];
|
|
1028
|
+
};
|
|
1028
1029
|
}) => Promise<Result>): Operation<Context, Result>;
|
|
1029
1030
|
|
|
1030
1031
|
/**
|
|
@@ -1057,7 +1058,7 @@ type CommandDecoder<Context, Result> = {
|
|
|
1057
1058
|
/**
|
|
1058
1059
|
* Creates a ready-to-execute {@link CommandInterpreter}.
|
|
1059
1060
|
*
|
|
1060
|
-
* @throws
|
|
1061
|
+
* @throws if parsing or decoding failed.
|
|
1061
1062
|
*/
|
|
1062
1063
|
decodeAndMakeInterpreter(): CommandInterpreter<Context, Result>;
|
|
1063
1064
|
};
|
|
@@ -1132,15 +1133,16 @@ type CommandInformation = {
|
|
|
1132
1133
|
* const greet = command(
|
|
1133
1134
|
* { description: "Greet a user" },
|
|
1134
1135
|
* operation(
|
|
1135
|
-
* {
|
|
1136
|
+
* { positionals: [positionalRequired({ type: type("name") })] },
|
|
1136
1137
|
* async (_ctx, { positionals: [name] }) => console.log(`Hello, ${name}!`),
|
|
1137
1138
|
* ),
|
|
1138
1139
|
* );
|
|
1139
1140
|
* ```
|
|
1140
1141
|
*/
|
|
1141
|
-
declare function command<Context, Result>(information: CommandInformation, operation: Operation<Context, Result>): Command<Context, Result>;
|
|
1142
|
+
declare function command<Context, Result = void>(information: CommandInformation, operation: Operation<Context, Result>): Command<Context, Result>;
|
|
1142
1143
|
/**
|
|
1143
|
-
* Creates a command that runs `operation` first,
|
|
1144
|
+
* Creates a command that runs `operation` first,
|
|
1145
|
+
* then dispatches result to a named subcommand.
|
|
1144
1146
|
*
|
|
1145
1147
|
* @typeParam Context - Context accepted by `operation`.
|
|
1146
1148
|
* @typeParam Payload - Output of `operation`; becomes the subcommand's context.
|
|
@@ -1163,12 +1165,12 @@ declare function command<Context, Result>(information: CommandInformation, opera
|
|
|
1163
1165
|
* );
|
|
1164
1166
|
* ```
|
|
1165
1167
|
*/
|
|
1166
|
-
declare function commandWithSubcommands<Context, Payload, Result>(information: CommandInformation, operation: Operation<Context, Payload>, subcommands: {
|
|
1168
|
+
declare function commandWithSubcommands<Context, Payload, Result = void>(information: CommandInformation, operation: Operation<Context, Payload>, subcommands: {
|
|
1167
1169
|
[subcommand: string]: Command<Payload, Result>;
|
|
1168
1170
|
}): Command<Context, Result>;
|
|
1169
1171
|
/**
|
|
1170
|
-
* Chains an {@link Operation} and a {@link Command}: `operation` runs first,
|
|
1171
|
-
* output becomes `subcommand`'s context. No token is consumed for routing.
|
|
1172
|
+
* Chains an {@link Operation} and a {@link Command}: `operation` runs first,
|
|
1173
|
+
* its output becomes `subcommand`'s context. No token is consumed for routing.
|
|
1172
1174
|
*
|
|
1173
1175
|
* @typeParam Context - Context accepted by `operation`.
|
|
1174
1176
|
* @typeParam Payload - Output of `operation`; becomes `subcommand`'s context.
|
|
@@ -1179,7 +1181,7 @@ declare function commandWithSubcommands<Context, Payload, Result>(information: C
|
|
|
1179
1181
|
* @param subcommand - Runs after `operation`.
|
|
1180
1182
|
* @returns A {@link Command} composing both stages.
|
|
1181
1183
|
*/
|
|
1182
|
-
declare function commandChained<Context, Payload, Result>(information: CommandInformation, operation: Operation<Context, Payload>, subcommand: Command<Payload, Result>): Command<Context, Result>;
|
|
1184
|
+
declare function commandChained<Context, Payload, Result = void>(information: CommandInformation, operation: Operation<Context, Payload>, subcommand: Command<Payload, Result>): Command<Context, Result>;
|
|
1183
1185
|
|
|
1184
1186
|
/**
|
|
1185
1187
|
* Color selection modes availables
|
|
@@ -1236,4 +1238,9 @@ declare function runAndExit<Context>(cliName: string, cliArgs: ReadonlyArray<str
|
|
|
1236
1238
|
onExit?: ((code: number) => never) | undefined;
|
|
1237
1239
|
}): Promise<never>;
|
|
1238
1240
|
|
|
1239
|
-
|
|
1241
|
+
declare function suggestTextPushMessage(text: TypoText, query: string, candidates: Array<{
|
|
1242
|
+
reference: string;
|
|
1243
|
+
hint: TypoSegment;
|
|
1244
|
+
}>): void;
|
|
1245
|
+
|
|
1246
|
+
export { type Command, type CommandDecoder, type CommandInformation, type CommandInterpreter, type Operation, type OperationDecoder, type OperationInterpreter, type Option, type OptionDecoder, type Positional, type PositionalDecoder, ReaderArgs, type ReaderOptionGetter, type ReaderOptionLongSpec, type ReaderOptionNextGuard, type ReaderOptionRestGuard, type ReaderOptionResult, type ReaderOptionShortSpec, type ReaderOptionValue, type ReaderOptions, type ReaderPositionals, type RunColorMode, type Type, type TypoColor, TypoError, TypoGrid, type TypoSegment, TypoString, type TypoStyle, TypoSupport, TypoText, type UsageCommand, type UsageOption, type UsagePositional, type UsageSubcommand, command, commandChained, commandWithSubcommands, operation, optionFlag, optionRepeatable, optionSingleValue, positionalOptional, positionalRequired, positionalVariadics, runAndExit, suggestTextPushMessage, type, typeBoolean, typeChoice, typeConverted, typeDatetime, typeInteger, typeList, typeNumber, typePath, typeRenamed, typeTuple, typeUrl, typoStyleConstants, typoStyleFailure, typoStyleLogic, typoStyleQuote, typoStyleRegularStrong, typoStyleRegularWeaker, typoStyleTitle, typoStyleUserInput, usageToStyledLines };
|