cli-kiss 0.2.4 → 0.2.5
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 +150 -164
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/docs/.vitepress/config.mts +1 -0
- 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_types.md +66 -66
- package/docs/guide/06_run.md +28 -40
- 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 +74 -46
- package/src/lib/Type.ts +227 -141
- package/src/lib/Typo.ts +36 -24
- package/src/lib/Usage.ts +27 -42
- 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 +197 -0
- package/tests/unit.runner.cycle.ts +69 -55
- package/tests/unit.runner.errors.ts +12 -20
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ type ReaderOptionKey = (string | {
|
|
|
11
11
|
*/
|
|
12
12
|
type ReaderOptionParsing = {
|
|
13
13
|
consumeShortGroup: boolean;
|
|
14
|
-
consumeNextArg: (inlined: string | null, separated: Array<string>,
|
|
14
|
+
consumeNextArg: (inlined: string | null, separated: Array<string>, nextArg: string | undefined) => boolean;
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
17
|
* Result of parsing an option, including its inlined value and any following separated values.
|
|
@@ -105,17 +105,17 @@ declare class ReaderArgs {
|
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
107
|
* Decodes a raw CLI string into a typed value.
|
|
108
|
-
* A pair of a human-readable `content` name
|
|
108
|
+
* A pair of a human-readable `content` name and a `decoder` function.
|
|
109
109
|
*
|
|
110
|
-
* Built-in: {@link
|
|
111
|
-
* {@link typeInteger}, {@link
|
|
112
|
-
* Composite: {@link
|
|
110
|
+
* Built-in: {@link type}, {@link typeBoolean}, {@link typeNumber},
|
|
111
|
+
* {@link typeInteger}, {@link typeDatetime}, {@link typeUrl}.
|
|
112
|
+
* Composite: {@link typeChoice}, {@link typeConverted}, {@link typeTuple}, {@link typeList}.
|
|
113
113
|
*
|
|
114
114
|
* @typeParam Value - Type produced by the decoder.
|
|
115
115
|
*/
|
|
116
116
|
type Type<Value> = {
|
|
117
117
|
/**
|
|
118
|
-
* Human-readable name shown in help and errors (e.g. `"
|
|
118
|
+
* Human-readable name shown in help and errors (e.g. `"name"`, `"number"`).
|
|
119
119
|
*/
|
|
120
120
|
content: string;
|
|
121
121
|
/**
|
|
@@ -133,71 +133,71 @@ type Type<Value> = {
|
|
|
133
133
|
*
|
|
134
134
|
* @example
|
|
135
135
|
* ```ts
|
|
136
|
-
* typeBoolean.decoder("true") // → true
|
|
137
|
-
* typeBoolean.decoder("yes") // → true
|
|
138
|
-
* typeBoolean.decoder("y") // → true
|
|
139
|
-
* typeBoolean.decoder("false") // → false
|
|
140
|
-
* typeBoolean.decoder("no") // → false
|
|
141
|
-
* typeBoolean.decoder("n") // → false
|
|
136
|
+
* typeBoolean("flag").decoder("true") // → true
|
|
137
|
+
* typeBoolean("flag").decoder("yes") // → true
|
|
138
|
+
* typeBoolean("flag").decoder("y") // → true
|
|
139
|
+
* typeBoolean("flag").decoder("false") // → false
|
|
140
|
+
* typeBoolean("flag").decoder("no") // → false
|
|
141
|
+
* typeBoolean("flag").decoder("n") // → false
|
|
142
142
|
* ```
|
|
143
143
|
*/
|
|
144
|
-
declare
|
|
144
|
+
declare function typeBoolean(name?: string): Type<boolean>;
|
|
145
145
|
/**
|
|
146
146
|
* Parses a date/time string via `Date.parse`.
|
|
147
147
|
* Accepts any format supported by `Date.parse`, including ISO 8601.
|
|
148
148
|
*
|
|
149
149
|
* @example
|
|
150
150
|
* ```ts
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
151
|
+
* typeDatetime("my-datetime").decoder("2024-01-15") // → Date object for 2024-01-15
|
|
152
|
+
* typeDatetime("my-datetime").decoder("2024-01-15T13:45:30Z") // → Date object for 2024-01-15 13:45:30 UTC
|
|
153
|
+
* typeDatetime("my-datetime").decoder("not a date") // throws TypoError
|
|
154
154
|
* ```
|
|
155
155
|
*/
|
|
156
|
-
declare
|
|
156
|
+
declare function typeDatetime(name?: string): Type<Date>;
|
|
157
157
|
/**
|
|
158
158
|
* Parses a string to `number` via `Number()`; `NaN` throws {@link TypoError}.
|
|
159
159
|
*
|
|
160
160
|
* @example
|
|
161
161
|
* ```ts
|
|
162
|
-
* typeNumber.decoder("3.14") // → 3.14
|
|
163
|
-
* typeNumber.decoder("-1") // → -1
|
|
164
|
-
* typeNumber.decoder("hello") // throws TypoError
|
|
162
|
+
* typeNumber("my-number").decoder("3.14") // → 3.14
|
|
163
|
+
* typeNumber("my-number").decoder("-1") // → -1
|
|
164
|
+
* typeNumber("my-number").decoder("hello") // throws TypoError
|
|
165
165
|
* ```
|
|
166
166
|
*/
|
|
167
|
-
declare
|
|
167
|
+
declare function typeNumber(name?: string): Type<number>;
|
|
168
168
|
/**
|
|
169
169
|
* Parses an integer string to `bigint` via `BigInt()`.
|
|
170
170
|
* Floats and non-numeric strings throw {@link TypoError}.
|
|
171
171
|
*
|
|
172
172
|
* @example
|
|
173
173
|
* ```ts
|
|
174
|
-
* typeInteger.decoder("42") // → 42n
|
|
175
|
-
* typeInteger.decoder("3.14") // throws TypoError
|
|
176
|
-
* typeInteger.decoder("abc") // throws TypoError
|
|
174
|
+
* typeInteger("my-integer").decoder("42") // → 42n
|
|
175
|
+
* typeInteger("my-integer").decoder("3.14") // throws TypoError
|
|
176
|
+
* typeInteger("my-integer").decoder("abc") // throws TypoError
|
|
177
177
|
* ```
|
|
178
178
|
*/
|
|
179
|
-
declare
|
|
179
|
+
declare function typeInteger(name?: string): Type<bigint>;
|
|
180
180
|
/**
|
|
181
181
|
* Parses an absolute URL string to a `URL` object.
|
|
182
182
|
* Relative or malformed URLs throw {@link TypoError}.
|
|
183
183
|
*
|
|
184
184
|
* @example
|
|
185
185
|
* ```ts
|
|
186
|
-
* typeUrl.decoder("https://example.com") // → URL { href: "https://example.com/", ... }
|
|
187
|
-
* typeUrl.decoder("not-a-url") // throws TypoError
|
|
186
|
+
* typeUrl("my-url").decoder("https://example.com") // → URL { href: "https://example.com/", ... }
|
|
187
|
+
* typeUrl("my-url").decoder("not-a-url") // throws TypoError
|
|
188
188
|
* ```
|
|
189
189
|
*/
|
|
190
|
-
declare
|
|
190
|
+
declare function typeUrl(name?: string): Type<URL>;
|
|
191
191
|
/**
|
|
192
|
-
*
|
|
193
|
-
*
|
|
192
|
+
* A named type that accepts any string as input.
|
|
193
|
+
* @param name - Name shown in help and errors (e.g. `"my-value"`).
|
|
194
194
|
* @example
|
|
195
195
|
* ```ts
|
|
196
|
-
*
|
|
197
|
-
*
|
|
196
|
+
* type("greeting").decoder("hello") // → "hello"
|
|
197
|
+
* type("greeting").decoder("") // → ""
|
|
198
198
|
* ```
|
|
199
199
|
*/
|
|
200
|
-
declare
|
|
200
|
+
declare function type(name?: string): Type<string>;
|
|
201
201
|
/**
|
|
202
202
|
* Chains `before`'s decoder with an `after` transformation.
|
|
203
203
|
* `before` errors are prefixed with `"from: <content>"` for traceability.
|
|
@@ -205,45 +205,54 @@ declare const typeString: Type<string>;
|
|
|
205
205
|
* @typeParam Before - Intermediate type from `before.decoder`.
|
|
206
206
|
* @typeParam After - Final type from `after.decoder`.
|
|
207
207
|
*
|
|
208
|
-
* @param
|
|
209
|
-
* @param
|
|
210
|
-
* @param
|
|
211
|
-
* @param after.decoder - Converts a `Before` value to `After`.
|
|
208
|
+
* @param name - Name shown in help and errors (e.g. `"my-value"`).
|
|
209
|
+
* @param before - Base type to decode the raw string.
|
|
210
|
+
* @param mapper - Transforms `before`'s output to the final value; errors are wrapped with context.
|
|
212
211
|
* @returns A {@link Type}`<After>`.
|
|
213
212
|
*
|
|
214
213
|
* @example
|
|
215
214
|
* ```ts
|
|
216
|
-
* const typePort =
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
* if (n < 1 || n > 65535) throw new Error("Out of range");
|
|
220
|
-
* return n;
|
|
221
|
-
* },
|
|
215
|
+
* const typePort = typeConverted("port", typeNumber(), (n) => {
|
|
216
|
+
* if (n < 1 || n > 65535) throw new Error("Out of range");
|
|
217
|
+
* return n;
|
|
222
218
|
* });
|
|
223
219
|
* // "--port 8080" → 8080
|
|
224
220
|
* // "--port 99999" → TypoError: --port: <PORT>: Port: Out of range
|
|
225
221
|
* ```
|
|
226
222
|
*/
|
|
227
|
-
declare function
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
223
|
+
declare function typeConverted<Before, After>(name: string, before: Type<Before>, mapper: (value: Before) => After): Type<After>;
|
|
224
|
+
/**
|
|
225
|
+
* Adds a name to a {@link Type} for clearer error messages and help text.
|
|
226
|
+
*
|
|
227
|
+
* @param name - Name to use for the type.
|
|
228
|
+
* @param type - Base type to name.
|
|
229
|
+
* @returns A {@link Type} with the given name.
|
|
230
|
+
*/
|
|
231
|
+
declare function typeRenamed<Value>(type: Type<Value>, name: string): Type<Value>;
|
|
232
|
+
/**
|
|
233
|
+
* Creates a {@link Type} for filesystem paths with optional existence checks.
|
|
234
|
+
* @param checks - Optional checks for path existence and type (file/directory).
|
|
235
|
+
* @returns A {@link Type}`<string>` representing the path.
|
|
236
|
+
*/
|
|
237
|
+
declare function typePath(name?: string, checks?: {
|
|
238
|
+
checkSyncExistAs?: "file" | "directory" | "anything";
|
|
239
|
+
}): Type<string>;
|
|
231
240
|
/**
|
|
232
241
|
* Creates a {@link Type}`<string>` that only accepts a fixed set of values.
|
|
233
242
|
* Out-of-set inputs throw {@link TypoError} listing up to 5 valid options.
|
|
234
243
|
*
|
|
235
|
-
* @param
|
|
244
|
+
* @param name - Name shown in help and errors.
|
|
236
245
|
* @param values - Ordered list of accepted values.
|
|
237
246
|
* @returns A {@link Type}`<string>`.
|
|
238
247
|
*
|
|
239
248
|
* @example
|
|
240
249
|
* ```ts
|
|
241
|
-
* const typeEnv =
|
|
250
|
+
* const typeEnv = typeChoice("environment", ["dev", "staging", "prod"]);
|
|
242
251
|
* typeEnv.decoder("prod") // → "prod"
|
|
243
252
|
* typeEnv.decoder("unknown") // throws TypoError: Invalid value: "unknown" (expected one of: "dev" | "staging" | "prod")
|
|
244
253
|
* ```
|
|
245
254
|
*/
|
|
246
|
-
declare function
|
|
255
|
+
declare function typeChoice<const Value extends string>(name: string, values: Array<Value>, caseSensitive?: boolean): Type<Value>;
|
|
247
256
|
/**
|
|
248
257
|
* Splits a delimited string into a typed tuple.
|
|
249
258
|
* Each part is decoded by the corresponding element type; wrong count or decode failure throws {@link TypoError}.
|
|
@@ -256,7 +265,7 @@ declare function typeOneOf<const Value extends string>(content: string, values:
|
|
|
256
265
|
*
|
|
257
266
|
* @example
|
|
258
267
|
* ```ts
|
|
259
|
-
* const typePoint = typeTuple([typeNumber, typeNumber]);
|
|
268
|
+
* const typePoint = typeTuple([typeNumber("x"), typeNumber("y")]);
|
|
260
269
|
* typePoint.decoder("3.14,2.71") // → [3.14, 2.71]
|
|
261
270
|
* typePoint.decoder("1,2,3") // → [1, 2]
|
|
262
271
|
* typePoint.decoder("x,2") // throws TypoError: at 0: Number: Unable to parse: "x"
|
|
@@ -282,7 +291,7 @@ declare function typeTuple<const Elements extends Array<any>>(elementTypes: {
|
|
|
282
291
|
* typeNumbers.decoder("1,2,3") // → [1, 2, 3]
|
|
283
292
|
* typeNumbers.decoder("1,x,3") // throws TypoError: at 1: Number: Unable to parse: "x"
|
|
284
293
|
*
|
|
285
|
-
* const typePaths = typeList(
|
|
294
|
+
* const typePaths = typeList(typePath(), ":");
|
|
286
295
|
* typePaths.decoder("/usr/bin:/usr/local/bin") // → ["/usr/bin", "/usr/local/bin"]
|
|
287
296
|
* ```
|
|
288
297
|
*/
|
|
@@ -298,6 +307,10 @@ type TypoColor = "darkBlack" | "darkRed" | "darkGreen" | "darkYellow" | "darkBlu
|
|
|
298
307
|
* All fields are optional; ignored entirely in `"none"` mode.
|
|
299
308
|
*/
|
|
300
309
|
type TypoStyle = {
|
|
310
|
+
/**
|
|
311
|
+
* Letter case.
|
|
312
|
+
*/
|
|
313
|
+
case?: "upper" | "lower";
|
|
301
314
|
/**
|
|
302
315
|
* Foreground (text) color.
|
|
303
316
|
*/
|
|
@@ -428,7 +441,7 @@ declare class TypoGrid {
|
|
|
428
441
|
* Renders as an array of styled, column-padded strings.
|
|
429
442
|
*
|
|
430
443
|
* @param typoSupport - Rendering mode.
|
|
431
|
-
* @returns
|
|
444
|
+
* @returns Array of styled strings.
|
|
432
445
|
*/
|
|
433
446
|
computeStyledLines(typoSupport: TypoSupport): Array<string>;
|
|
434
447
|
}
|
|
@@ -477,16 +490,12 @@ declare class TypoSupport {
|
|
|
477
490
|
static tty(): TypoSupport;
|
|
478
491
|
/**
|
|
479
492
|
* Deterministic textual styling for snapshot tests.
|
|
480
|
-
* Style flags appear as suffixes: `{text}@color`, `{text}+` (bold), `{text}-` (dim),
|
|
481
|
-
* `{text}*` (italic), `{text}_` (underline), `{text}~` (strikethrough).
|
|
482
493
|
*/
|
|
483
494
|
static mock(): TypoSupport;
|
|
484
495
|
/**
|
|
485
|
-
* Auto-detects styling mode from the process environment.
|
|
486
|
-
* `FORCE_COLOR=0` / `NO_COLOR` → none; `FORCE_COLOR` (truthy) / `isTTY` → tty; else → none.
|
|
487
|
-
* Falls back to none if `process` is unavailable.
|
|
496
|
+
* Auto-detects styling mode from the process environment on best-effort basis.
|
|
488
497
|
*/
|
|
489
|
-
static
|
|
498
|
+
static inferFromEnv(): TypoSupport;
|
|
490
499
|
/**
|
|
491
500
|
* Applies `typoStyle` to `value` according to the current mode.
|
|
492
501
|
*
|
|
@@ -510,9 +519,12 @@ declare class TypoSupport {
|
|
|
510
519
|
type UsageCommand = {
|
|
511
520
|
/**
|
|
512
521
|
* Segments of the usage line
|
|
513
|
-
* (e.g. `my-cli <POSITIONAL> subcommand <ANOTHER_POSITIONAL>`).
|
|
514
522
|
*/
|
|
515
|
-
segments: Array<
|
|
523
|
+
segments: Array<{
|
|
524
|
+
positional: string;
|
|
525
|
+
} | {
|
|
526
|
+
subcommand: string;
|
|
527
|
+
}>;
|
|
516
528
|
/**
|
|
517
529
|
* Command metadata.
|
|
518
530
|
*/
|
|
@@ -530,27 +542,6 @@ type UsageCommand = {
|
|
|
530
542
|
*/
|
|
531
543
|
options: Array<UsageOption>;
|
|
532
544
|
};
|
|
533
|
-
/**
|
|
534
|
-
* One segment of the usage line.
|
|
535
|
-
*/
|
|
536
|
-
type UsageSegment = {
|
|
537
|
-
positional: string;
|
|
538
|
-
} | {
|
|
539
|
-
subcommand: string;
|
|
540
|
-
};
|
|
541
|
-
/**
|
|
542
|
-
* Usage metadata. Produced by {@link Operation.generateUsage}, consumed when building {@link UsageCommand}.
|
|
543
|
-
*/
|
|
544
|
-
type UsageOperation = {
|
|
545
|
-
/**
|
|
546
|
-
* Registered options.
|
|
547
|
-
*/
|
|
548
|
-
options: Array<UsageOption>;
|
|
549
|
-
/**
|
|
550
|
-
* Declared positionals, in order.
|
|
551
|
-
*/
|
|
552
|
-
positionals: Array<UsagePositional>;
|
|
553
|
-
};
|
|
554
545
|
/**
|
|
555
546
|
* Positional metadata for the `Positionals:` section of help.
|
|
556
547
|
*/
|
|
@@ -558,16 +549,15 @@ type UsagePositional = {
|
|
|
558
549
|
/**
|
|
559
550
|
* Help text.
|
|
560
551
|
*/
|
|
561
|
-
description
|
|
552
|
+
description?: string | undefined;
|
|
562
553
|
/**
|
|
563
554
|
* Short note shown in parentheses.
|
|
564
555
|
*/
|
|
565
|
-
hint
|
|
556
|
+
hint?: string | undefined;
|
|
566
557
|
/**
|
|
567
558
|
* Placeholder label shown in the usage line and the `Positionals:` section.
|
|
568
|
-
* Required: `<NAME>`, optional: `[NAME]`, variadic: `[NAME]...`.
|
|
569
559
|
*/
|
|
570
|
-
label:
|
|
560
|
+
label: string;
|
|
571
561
|
};
|
|
572
562
|
/**
|
|
573
563
|
* Entry in the `Subcommands:` section.
|
|
@@ -580,11 +570,11 @@ type UsageSubcommand = {
|
|
|
580
570
|
/**
|
|
581
571
|
* From {@link CommandInformation.description}.
|
|
582
572
|
*/
|
|
583
|
-
description
|
|
573
|
+
description?: string | undefined;
|
|
584
574
|
/**
|
|
585
575
|
* From {@link CommandInformation.hint}.
|
|
586
576
|
*/
|
|
587
|
-
hint
|
|
577
|
+
hint?: string | undefined;
|
|
588
578
|
};
|
|
589
579
|
/**
|
|
590
580
|
* Option metadata for the `Options:` section of help.
|
|
@@ -593,27 +583,27 @@ type UsageOption = {
|
|
|
593
583
|
/**
|
|
594
584
|
* Short-form name without `-` (e.g. `"v"`).
|
|
595
585
|
*/
|
|
596
|
-
short
|
|
586
|
+
short?: string | undefined;
|
|
597
587
|
/**
|
|
598
588
|
* Long-form name without `--` (e.g. `"verbose"`).
|
|
599
589
|
*/
|
|
600
|
-
long:
|
|
590
|
+
long: string;
|
|
601
591
|
/**
|
|
602
|
-
*
|
|
592
|
+
* Value placeholder in help (e.g. `"<FILE>"`).
|
|
603
593
|
*/
|
|
604
|
-
|
|
594
|
+
label?: string | undefined;
|
|
605
595
|
/**
|
|
606
|
-
*
|
|
596
|
+
* Extra annotation appended to the option label in help.
|
|
607
597
|
*/
|
|
608
|
-
|
|
598
|
+
annotation?: string | undefined;
|
|
609
599
|
/**
|
|
610
|
-
*
|
|
600
|
+
* Help text.
|
|
611
601
|
*/
|
|
612
|
-
|
|
602
|
+
description?: string | undefined;
|
|
613
603
|
/**
|
|
614
|
-
*
|
|
604
|
+
* Short note shown in parentheses.
|
|
615
605
|
*/
|
|
616
|
-
|
|
606
|
+
hint?: string | undefined;
|
|
617
607
|
};
|
|
618
608
|
/**
|
|
619
609
|
* Converts a {@link UsageCommand} model into an array of styled lines ready to be
|
|
@@ -660,7 +650,7 @@ type UsageOption = {
|
|
|
660
650
|
* ```
|
|
661
651
|
*/
|
|
662
652
|
declare function usageToStyledLines(params: {
|
|
663
|
-
cliName:
|
|
653
|
+
cliName: string;
|
|
664
654
|
usage: UsageCommand;
|
|
665
655
|
typoSupport: TypoSupport;
|
|
666
656
|
}): string[];
|
|
@@ -697,15 +687,15 @@ type OptionDecoder<Value> = {
|
|
|
697
687
|
/**
|
|
698
688
|
* Creates a boolean flag option (`--verbose`, optionally `--flag=no`).
|
|
699
689
|
*
|
|
700
|
-
* Parsing: absent →
|
|
701
|
-
* specified more than once → {@link TypoError}.
|
|
690
|
+
* Parsing: absent → default value; `--flag` / `--flag=yes` → `true`; `--flag=no` → `false`;
|
|
691
|
+
* specified more than once → throws {@link TypoError}.
|
|
702
692
|
*
|
|
703
693
|
* @param definition.long - Long-form name (without `--`).
|
|
704
694
|
* @param definition.short - Short-form name (without `-`).
|
|
705
695
|
* @param definition.description - Help text.
|
|
706
696
|
* @param definition.hint - Short note shown in parentheses.
|
|
707
697
|
* @param definition.aliases - Additional names.
|
|
708
|
-
* @param definition.default - Default when absent.
|
|
698
|
+
* @param definition.default - Default value when absent.
|
|
709
699
|
* @returns An {@link Option}`<boolean>`.
|
|
710
700
|
*
|
|
711
701
|
* @example
|
|
@@ -715,15 +705,20 @@ type OptionDecoder<Value> = {
|
|
|
715
705
|
* short: "v",
|
|
716
706
|
* description: "Enable verbose output",
|
|
717
707
|
* });
|
|
708
|
+
* // Usage:
|
|
709
|
+
* // my-cli → false
|
|
710
|
+
* // my-cli --verbose → true
|
|
711
|
+
* // my-cli --verbose=yes → true
|
|
712
|
+
* // my-cli -v=no → false
|
|
718
713
|
* ```
|
|
719
714
|
*/
|
|
720
715
|
declare function optionFlag(definition: {
|
|
721
|
-
long:
|
|
716
|
+
long: string;
|
|
722
717
|
short?: string;
|
|
723
718
|
description?: string;
|
|
724
719
|
hint?: string;
|
|
725
720
|
aliases?: {
|
|
726
|
-
longs?: Array<
|
|
721
|
+
longs?: Array<string>;
|
|
727
722
|
shorts?: Array<string>;
|
|
728
723
|
};
|
|
729
724
|
default?: boolean;
|
|
@@ -731,7 +726,7 @@ declare function optionFlag(definition: {
|
|
|
731
726
|
/**
|
|
732
727
|
* Creates an option that accepts exactly one value (e.g. `--output dist/`).
|
|
733
728
|
*
|
|
734
|
-
* Parsing: absent → `
|
|
729
|
+
* Parsing: absent → `defaultValue()`; once → decoded with `type`; more than once → {@link TypoError}.
|
|
735
730
|
* Value syntax: `--long value`, `--long=value`, `-s value`, `-s=value`, `-svalue`.
|
|
736
731
|
*
|
|
737
732
|
* @typeParam Value - Type produced by the decoder.
|
|
@@ -741,9 +736,9 @@ declare function optionFlag(definition: {
|
|
|
741
736
|
* @param definition.description - Help text.
|
|
742
737
|
* @param definition.hint - Short note shown in parentheses.
|
|
743
738
|
* @param definition.aliases - Additional names.
|
|
744
|
-
* @param definition.label - Value placeholder in help. Defaults to uppercased `type.content`.
|
|
745
739
|
* @param definition.type - Decoder for the raw string value.
|
|
746
|
-
* @param definition.
|
|
740
|
+
* @param definition.valueWhenNotDefined - Default value when the option is not specified at all.
|
|
741
|
+
* @param definition.valueWhenNotInlined - Default value when the option is specified without an inline value (e.g. `--option` or `-o`).
|
|
747
742
|
* @returns An {@link Option}`<Value>`.
|
|
748
743
|
*
|
|
749
744
|
* @example
|
|
@@ -751,25 +746,28 @@ declare function optionFlag(definition: {
|
|
|
751
746
|
* const outputOption = optionSingleValue({
|
|
752
747
|
* long: "output",
|
|
753
748
|
* short: "o",
|
|
754
|
-
* type:
|
|
755
|
-
* label: "PATH",
|
|
749
|
+
* type: typePath(),
|
|
756
750
|
* description: "Output directory",
|
|
757
|
-
*
|
|
751
|
+
* valueWhenNotDefined: () => "dist",
|
|
758
752
|
* });
|
|
753
|
+
* // Usage:
|
|
754
|
+
* // my-cli → "dist"
|
|
755
|
+
* // my-cli --output folder → "folder"
|
|
756
|
+
* // my-cli -o folder → "folder"
|
|
759
757
|
* ```
|
|
760
758
|
*/
|
|
761
759
|
declare function optionSingleValue<Value>(definition: {
|
|
762
|
-
long:
|
|
760
|
+
long: string;
|
|
763
761
|
short?: string;
|
|
764
762
|
description?: string;
|
|
765
763
|
hint?: string;
|
|
766
764
|
aliases?: {
|
|
767
|
-
longs?: Array<
|
|
765
|
+
longs?: Array<string>;
|
|
768
766
|
shorts?: Array<string>;
|
|
769
767
|
};
|
|
770
|
-
label?: Uppercase<string>;
|
|
771
768
|
type: Type<Value>;
|
|
772
|
-
|
|
769
|
+
defaultWhenNotDefined: () => Value;
|
|
770
|
+
defaultWhenNotInlined?: () => Value;
|
|
773
771
|
}): Option<Value>;
|
|
774
772
|
/**
|
|
775
773
|
* Creates an option that collects every occurrence into an array (e.g. `--file a.ts --file b.ts`).
|
|
@@ -784,7 +782,6 @@ declare function optionSingleValue<Value>(definition: {
|
|
|
784
782
|
* @param definition.description - Help text.
|
|
785
783
|
* @param definition.hint - Short note shown in parentheses.
|
|
786
784
|
* @param definition.aliases - Additional names.
|
|
787
|
-
* @param definition.label - Value placeholder in help. Defaults to uppercased `type.content`.
|
|
788
785
|
* @param definition.type - Decoder applied to each raw string value.
|
|
789
786
|
* @returns An {@link Option}`<Array<Value>>`.
|
|
790
787
|
*
|
|
@@ -801,15 +798,14 @@ declare function optionSingleValue<Value>(definition: {
|
|
|
801
798
|
* ```
|
|
802
799
|
*/
|
|
803
800
|
declare function optionRepeatable<Value>(definition: {
|
|
804
|
-
long:
|
|
801
|
+
long: string;
|
|
805
802
|
short?: string;
|
|
806
803
|
description?: string;
|
|
807
804
|
hint?: string;
|
|
808
805
|
aliases?: {
|
|
809
|
-
longs?: Array<
|
|
806
|
+
longs?: Array<string>;
|
|
810
807
|
shorts?: Array<string>;
|
|
811
808
|
};
|
|
812
|
-
label?: Uppercase<string>;
|
|
813
809
|
type: Type<Value>;
|
|
814
810
|
}): Option<Array<Value>>;
|
|
815
811
|
|
|
@@ -845,41 +841,36 @@ type PositionalDecoder<Value> = {
|
|
|
845
841
|
};
|
|
846
842
|
/**
|
|
847
843
|
* Creates a required positional — missing token throws {@link TypoError}.
|
|
848
|
-
* Label defaults to uppercased `type.content` in angle brackets (e.g. `<STRING>`).
|
|
849
844
|
*
|
|
850
845
|
* @typeParam Value - Type produced by the decoder.
|
|
851
846
|
*
|
|
852
847
|
* @param definition.description - Help text.
|
|
853
848
|
* @param definition.hint - Short note shown in parentheses.
|
|
854
|
-
* @param definition.label - Label without brackets; defaults to uppercased `type.content`.
|
|
855
849
|
* @param definition.type - Decoder for the raw token.
|
|
856
850
|
* @returns A {@link Positional}`<Value>`.
|
|
857
851
|
*
|
|
858
852
|
* @example
|
|
859
853
|
* ```ts
|
|
860
854
|
* const namePositional = positionalRequired({
|
|
861
|
-
* type:
|
|
862
|
-
* label: "NAME",
|
|
855
|
+
* type: type("name"),
|
|
863
856
|
* description: "The name to greet",
|
|
864
857
|
* });
|
|
865
|
-
* //
|
|
858
|
+
* // Usage:
|
|
859
|
+
* // my-cli Alice → "Alice"
|
|
866
860
|
* ```
|
|
867
861
|
*/
|
|
868
862
|
declare function positionalRequired<Value>(definition: {
|
|
869
863
|
description?: string;
|
|
870
864
|
hint?: string;
|
|
871
|
-
label?: Uppercase<string>;
|
|
872
865
|
type: Type<Value>;
|
|
873
866
|
}): Positional<Value>;
|
|
874
867
|
/**
|
|
875
868
|
* Creates an optional positional — absent token falls back to `default()`.
|
|
876
|
-
* Label defaults to uppercased `type.content` in square brackets (e.g. `[STRING]`).
|
|
877
869
|
*
|
|
878
870
|
* @typeParam Value - Type produced by the decoder (or the default).
|
|
879
871
|
*
|
|
880
872
|
* @param definition.description - Help text.
|
|
881
873
|
* @param definition.hint - Short note shown in parentheses.
|
|
882
|
-
* @param definition.label - Label without brackets; defaults to uppercased `type.content`.
|
|
883
874
|
* @param definition.type - Decoder for the raw token.
|
|
884
875
|
* @param definition.default - Value when absent. Throw to make it required.
|
|
885
876
|
* @returns A {@link Positional}`<Value>`.
|
|
@@ -887,51 +878,48 @@ declare function positionalRequired<Value>(definition: {
|
|
|
887
878
|
* @example
|
|
888
879
|
* ```ts
|
|
889
880
|
* const greeteePositional = positionalOptional({
|
|
890
|
-
* type:
|
|
891
|
-
* label: "NAME",
|
|
881
|
+
* type: type("name"),
|
|
892
882
|
* description: "Name to greet (default: world)",
|
|
893
883
|
* default: () => "world",
|
|
894
884
|
* });
|
|
895
|
-
* //
|
|
896
|
-
* //
|
|
885
|
+
* // Usage:
|
|
886
|
+
* // my-cli → "world"
|
|
887
|
+
* // my-cli Alice → "Alice"
|
|
897
888
|
* ```
|
|
898
889
|
*/
|
|
899
890
|
declare function positionalOptional<Value>(definition: {
|
|
900
891
|
description?: string;
|
|
901
892
|
hint?: string;
|
|
902
|
-
label?: Uppercase<string>;
|
|
903
893
|
type: Type<Value>;
|
|
904
894
|
default: () => Value;
|
|
905
895
|
}): Positional<Value>;
|
|
906
896
|
/**
|
|
907
897
|
* Creates a variadic positional that collects zero or more remaining tokens into an array.
|
|
908
|
-
*
|
|
898
|
+
* Optionally stops at `endDelimiter` (consumed, not included).
|
|
909
899
|
*
|
|
910
900
|
* @typeParam Value - Type produced by the decoder for each token.
|
|
911
901
|
*
|
|
912
902
|
* @param definition.endDelimiter - Sentinel token that stops collection (consumed, not included).
|
|
913
903
|
* @param definition.description - Help text.
|
|
914
904
|
* @param definition.hint - Short note shown in parentheses.
|
|
915
|
-
* @param definition.label - Label without brackets; defaults to uppercased `type.content`.
|
|
916
905
|
* @param definition.type - Decoder applied to each token.
|
|
917
906
|
* @returns A {@link Positional}`<Array<Value>>`.
|
|
918
907
|
*
|
|
919
908
|
* @example
|
|
920
909
|
* ```ts
|
|
921
910
|
* const filesPositional = positionalVariadics({
|
|
922
|
-
* type:
|
|
923
|
-
* label: "FILE",
|
|
911
|
+
* type: typePath(),
|
|
924
912
|
* description: "Files to process",
|
|
925
913
|
* });
|
|
926
|
-
* //
|
|
927
|
-
* //
|
|
914
|
+
* // Usage:
|
|
915
|
+
* // my-cli → []
|
|
916
|
+
* // my-cli a.ts b.ts c.ts → ["a.ts", "b.ts", "c.ts"]
|
|
928
917
|
* ```
|
|
929
918
|
*/
|
|
930
919
|
declare function positionalVariadics<Value>(definition: {
|
|
931
920
|
endDelimiter?: string;
|
|
932
921
|
description?: string;
|
|
933
922
|
hint?: string;
|
|
934
|
-
label?: Uppercase<string>;
|
|
935
923
|
type: Type<Value>;
|
|
936
924
|
}): Positional<Array<Value>>;
|
|
937
925
|
|
|
@@ -948,7 +936,16 @@ type Operation<Context, Result> = {
|
|
|
948
936
|
/**
|
|
949
937
|
* Returns usage metadata without consuming any arguments.
|
|
950
938
|
*/
|
|
951
|
-
generateUsage():
|
|
939
|
+
generateUsage(): {
|
|
940
|
+
/**
|
|
941
|
+
* Registered options.
|
|
942
|
+
*/
|
|
943
|
+
options: Array<UsageOption>;
|
|
944
|
+
/**
|
|
945
|
+
* Declared positionals, in order.
|
|
946
|
+
*/
|
|
947
|
+
positionals: Array<UsagePositional>;
|
|
948
|
+
};
|
|
952
949
|
/**
|
|
953
950
|
* Consumes args from `readerArgs` and returns an {@link OperationDecoder}.
|
|
954
951
|
*/
|
|
@@ -1001,10 +998,10 @@ type OperationInterpreter<Context, Result> = {
|
|
|
1001
998
|
* const greetOperation = operation(
|
|
1002
999
|
* {
|
|
1003
1000
|
* options: {
|
|
1004
|
-
* loud: optionFlag({ long: "loud", description: "Print in uppercase" }),
|
|
1001
|
+
* loud: optionFlag({ long: "loud", description: "Print in uppercase", default: false }),
|
|
1005
1002
|
* },
|
|
1006
1003
|
* positionals: [
|
|
1007
|
-
* positionalRequired({ type:
|
|
1004
|
+
* positionalRequired({ type: type("name"), description: "Name to greet" }),
|
|
1008
1005
|
* ],
|
|
1009
1006
|
* },
|
|
1010
1007
|
* async function (_ctx, { options: { loud }, positionals: [name] }) {
|
|
@@ -1108,10 +1105,12 @@ type CommandInformation = {
|
|
|
1108
1105
|
} | {
|
|
1109
1106
|
option: {
|
|
1110
1107
|
long: string;
|
|
1111
|
-
|
|
1108
|
+
inlined?: string;
|
|
1109
|
+
separated?: Array<string>;
|
|
1112
1110
|
} | {
|
|
1113
1111
|
short: string;
|
|
1114
|
-
|
|
1112
|
+
inlined?: string;
|
|
1113
|
+
separated?: Array<string>;
|
|
1115
1114
|
};
|
|
1116
1115
|
}>;
|
|
1117
1116
|
}>;
|
|
@@ -1131,7 +1130,7 @@ type CommandInformation = {
|
|
|
1131
1130
|
* const greet = command(
|
|
1132
1131
|
* { description: "Greet a user" },
|
|
1133
1132
|
* operation(
|
|
1134
|
-
* { options: {}, positionals: [positionalRequired({ type:
|
|
1133
|
+
* { options: {}, positionals: [positionalRequired({ type: type("name") })] },
|
|
1135
1134
|
* async (_ctx, { positionals: [name] }) => console.log(`Hello, ${name}!`),
|
|
1136
1135
|
* ),
|
|
1137
1136
|
* );
|
|
@@ -1163,7 +1162,7 @@ declare function command<Context, Result>(information: CommandInformation, opera
|
|
|
1163
1162
|
* ```
|
|
1164
1163
|
*/
|
|
1165
1164
|
declare function commandWithSubcommands<Context, Payload, Result>(information: CommandInformation, operation: Operation<Context, Payload>, subcommands: {
|
|
1166
|
-
[subcommand:
|
|
1165
|
+
[subcommand: string]: Command<Payload, Result>;
|
|
1167
1166
|
}): Command<Context, Result>;
|
|
1168
1167
|
/**
|
|
1169
1168
|
* Chains an {@link Operation} and a {@link Command}: `operation` runs first, its
|
|
@@ -1177,18 +1176,6 @@ declare function commandWithSubcommands<Context, Payload, Result>(information: C
|
|
|
1177
1176
|
* @param operation - Runs first; output becomes `subcommand`'s context.
|
|
1178
1177
|
* @param subcommand - Runs after `operation`.
|
|
1179
1178
|
* @returns A {@link Command} composing both stages.
|
|
1180
|
-
*
|
|
1181
|
-
* @example
|
|
1182
|
-
* ```ts
|
|
1183
|
-
* const authenticatedDeploy = commandChained(
|
|
1184
|
-
* { description: "Authenticate then deploy" },
|
|
1185
|
-
* operation(
|
|
1186
|
-
* { options: { token: optionSingleValue({ long: "token", type: typeString, default: () => "" }) }, positionals: [] },
|
|
1187
|
-
* async (_ctx, { options: { token } }) => ({ token }),
|
|
1188
|
-
* ),
|
|
1189
|
-
* command({ description: "Deploy" }, deployOperation),
|
|
1190
|
-
* );
|
|
1191
|
-
* ```
|
|
1192
1179
|
*/
|
|
1193
1180
|
declare function commandChained<Context, Payload, Result>(information: CommandInformation, operation: Operation<Context, Payload>, subcommand: Command<Payload, Result>): Command<Context, Result>;
|
|
1194
1181
|
|
|
@@ -1206,8 +1193,7 @@ declare function commandChained<Context, Payload, Result>(information: CommandIn
|
|
|
1206
1193
|
* @param cliArgs - Raw arguments, typically `process.argv.slice(2)`.
|
|
1207
1194
|
* @param context - Forwarded to the handler.
|
|
1208
1195
|
* @param command - Root {@link Command}.
|
|
1209
|
-
* @param options.
|
|
1210
|
-
* `"mock"` (snapshot-friendly), `undefined` (auto-detect from env).
|
|
1196
|
+
* @param options.colorSetup - Configures color support; enables `--color` flag if set to `"flag"`.
|
|
1211
1197
|
* @param options.usageOnHelp - Enables `--help` flag (default `true`).
|
|
1212
1198
|
* @param options.usageOnError - Prints usage to stderr on parse error (default `true`).
|
|
1213
1199
|
* @param options.buildVersion - Enables `--version`; prints `<cliName> <buildVersion>`.
|
|
@@ -1218,12 +1204,12 @@ declare function commandChained<Context, Payload, Result>(information: CommandIn
|
|
|
1218
1204
|
*
|
|
1219
1205
|
* @example
|
|
1220
1206
|
* ```ts
|
|
1221
|
-
* import { runAndExit, command, operation, positionalRequired,
|
|
1207
|
+
* import { runAndExit, command, operation, positionalRequired, type } from "cli-kiss";
|
|
1222
1208
|
*
|
|
1223
1209
|
* const greetCommand = command(
|
|
1224
1210
|
* { description: "Greet someone" },
|
|
1225
1211
|
* operation(
|
|
1226
|
-
* { options: {}, positionals: [positionalRequired({ type:
|
|
1212
|
+
* { options: {}, positionals: [positionalRequired({ type: type("name") })] },
|
|
1227
1213
|
* async function (_ctx, { positionals: [name] }) {
|
|
1228
1214
|
* console.log(`Hello, ${name}!`);
|
|
1229
1215
|
* },
|
|
@@ -1235,8 +1221,8 @@ declare function commandChained<Context, Payload, Result>(information: CommandIn
|
|
|
1235
1221
|
* });
|
|
1236
1222
|
* ```
|
|
1237
1223
|
*/
|
|
1238
|
-
declare function runAndExit<Context>(cliName:
|
|
1239
|
-
|
|
1224
|
+
declare function runAndExit<Context>(cliName: string, cliArgs: ReadonlyArray<string>, context: Context, command: Command<Context, void>, options?: {
|
|
1225
|
+
colorSetup?: "flag" | "env" | "always" | "never" | "mock" | undefined;
|
|
1240
1226
|
usageOnHelp?: boolean | undefined;
|
|
1241
1227
|
usageOnError?: boolean | undefined;
|
|
1242
1228
|
buildVersion?: string | undefined;
|
|
@@ -1244,4 +1230,4 @@ declare function runAndExit<Context>(cliName: Lowercase<string>, cliArgs: Readon
|
|
|
1244
1230
|
onExit?: ((code: number) => never) | undefined;
|
|
1245
1231
|
}): Promise<never>;
|
|
1246
1232
|
|
|
1247
|
-
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 ReaderOptionKey, type ReaderOptionParsing, type ReaderOptionValue, type ReaderOptions, type ReaderPositionals, type Type, type TypoColor, TypoError, TypoGrid, TypoString, type TypoStyle, TypoSupport, TypoText, type UsageCommand, type
|
|
1233
|
+
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 ReaderOptionKey, type ReaderOptionParsing, type ReaderOptionValue, type ReaderOptions, type ReaderPositionals, type Type, type TypoColor, TypoError, TypoGrid, TypoString, type TypoStyle, TypoSupport, TypoText, type UsageCommand, type UsageOption, type UsagePositional, type UsageSubcommand, command, commandChained, commandWithSubcommands, operation, optionFlag, optionRepeatable, optionSingleValue, positionalOptional, positionalRequired, positionalVariadics, runAndExit, type, typeBoolean, typeChoice, typeConverted, typeDatetime, typeInteger, typeList, typeNumber, typePath, typeRenamed, typeTuple, typeUrl, typoStyleConstants, typoStyleFailure, typoStyleLogic, typoStyleQuote, typoStyleRegularStrong, typoStyleRegularWeaker, typoStyleTitle, typoStyleUserInput, usageToStyledLines };
|