termkit 2.1.0 → 2.2.0
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 +113 -38
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +59 -65
- package/dist/index.mjs +58 -60
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# TermKit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
TermKit is a complete terminal toolkit for Node.js. Build CLI programs with a fluent command API — nested subcommands, middleware, typed options — then prompt users interactively, render progress bars, tables, and charts, all from a single package with full TypeScript support.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -10,12 +10,14 @@ npm install termkit
|
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
-
###
|
|
13
|
+
### Program
|
|
14
|
+
|
|
15
|
+
`Program` is the entry point for CLI argument parsing. Define commands with `Program.command`, declare options, attach middleware and actions, then call `Program.parse` to run.
|
|
14
16
|
|
|
15
17
|
```ts
|
|
16
|
-
import {
|
|
18
|
+
import { Program } from 'termkit'
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
Program.command('my-app')
|
|
19
21
|
.version('1.0.0')
|
|
20
22
|
.description('My CLI application')
|
|
21
23
|
.option('v', 'verbose', null, 'Enable verbose output')
|
|
@@ -24,11 +26,7 @@ const program = command('my-app')
|
|
|
24
26
|
console.log(options.output)
|
|
25
27
|
})
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
program.parse(process.argv)
|
|
29
|
-
} catch (err) {
|
|
30
|
-
console.error(err)
|
|
31
|
-
}
|
|
29
|
+
Program.parse(process.argv)
|
|
32
30
|
```
|
|
33
31
|
|
|
34
32
|
### Options
|
|
@@ -36,7 +34,7 @@ try {
|
|
|
36
34
|
Options support four variable shapes:
|
|
37
35
|
|
|
38
36
|
```ts
|
|
39
|
-
command('app')
|
|
37
|
+
Program.command('app')
|
|
40
38
|
.option('b', 'boolean', null, 'Flag with no value')
|
|
41
39
|
.option('o', 'optional', '[val]', 'Optional value')
|
|
42
40
|
.option('r', 'required', '<val>', 'Required value')
|
|
@@ -56,34 +54,40 @@ Accessible in actions and middleware via the long name:
|
|
|
56
54
|
|
|
57
55
|
### Value coercion
|
|
58
56
|
|
|
59
|
-
Append `:number
|
|
57
|
+
Append `:number`, `:integer`, or `:boolean` to a variable to coerce the parsed string. Append `(min,max)` to enforce a numeric or length range. Use `|`-separated values for an enum:
|
|
60
58
|
|
|
61
59
|
```ts
|
|
62
|
-
command('app')
|
|
63
|
-
.option('p', 'port',
|
|
64
|
-
.option('
|
|
65
|
-
.option('n', 'nums',
|
|
60
|
+
Program.command('app')
|
|
61
|
+
.option('p', 'port', '<port:integer(1,65535)>', 'Port number')
|
|
62
|
+
.option('e', 'env', '<env:dev|staging|prod>', 'Environment')
|
|
63
|
+
.option('n', 'nums', '[nums:number...]', 'List of numbers')
|
|
64
|
+
.option('t', 'token', '<token:string(32,64)>', 'API token')
|
|
66
65
|
.action((options) => {
|
|
67
|
-
options.port
|
|
68
|
-
options.
|
|
69
|
-
options.nums
|
|
66
|
+
options.port // number
|
|
67
|
+
options.env // 'dev' | 'staging' | 'prod'
|
|
68
|
+
options.nums // number[]
|
|
69
|
+
options.token // string
|
|
70
70
|
})
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
Append `=default` inside the brackets to set a default value:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
.option('p', 'port', '[port:integer=3000]', 'Port number')
|
|
77
|
+
```
|
|
78
|
+
|
|
73
79
|
### Subcommands
|
|
74
80
|
|
|
75
81
|
Commands nest to any depth. Each level can have its own options and middleware.
|
|
76
82
|
|
|
77
83
|
```ts
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
command('app')
|
|
84
|
+
Program.command('app')
|
|
81
85
|
.commands([
|
|
82
|
-
command('serve')
|
|
86
|
+
Program.command('serve')
|
|
83
87
|
.option('p', 'port', '<port:number>', 'Port to listen on')
|
|
84
88
|
.action((options) => startServer(options.port)),
|
|
85
89
|
|
|
86
|
-
command('build')
|
|
90
|
+
Program.command('build')
|
|
87
91
|
.option('w', 'watch', null, 'Watch for changes')
|
|
88
92
|
.action((options) => runBuild(options)),
|
|
89
93
|
])
|
|
@@ -92,9 +96,9 @@ command('app')
|
|
|
92
96
|
Commands can also carry their own positional variables:
|
|
93
97
|
|
|
94
98
|
```ts
|
|
95
|
-
command('get', '<id>') // required
|
|
96
|
-
command('list', '[filter]') // optional
|
|
97
|
-
command('tag', '[tags...]') // array
|
|
99
|
+
Program.command('get', '<id>') // required
|
|
100
|
+
Program.command('list', '[filter]') // optional
|
|
101
|
+
Program.command('tag', '[tags...]') // array
|
|
98
102
|
```
|
|
99
103
|
|
|
100
104
|
### Middleware
|
|
@@ -102,7 +106,7 @@ command('tag', '[tags...]') // array
|
|
|
102
106
|
Middleware runs before the action. It can mutate the options object and supports async.
|
|
103
107
|
|
|
104
108
|
```ts
|
|
105
|
-
command('app')
|
|
109
|
+
Program.command('app')
|
|
106
110
|
.middleware(async (options) => {
|
|
107
111
|
options.user = await getUser(options.token)
|
|
108
112
|
})
|
|
@@ -118,9 +122,7 @@ Use `.middlewares([...])` to register several at once. When navigating into a su
|
|
|
118
122
|
Apply middleware or options to every command created after the call:
|
|
119
123
|
|
|
120
124
|
```ts
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
setDefaults({
|
|
125
|
+
Program.setDefaults({
|
|
124
126
|
middlewares: [
|
|
125
127
|
async (options) => { options.timestamp = Date.now() }
|
|
126
128
|
]
|
|
@@ -136,6 +138,19 @@ my-app help
|
|
|
136
138
|
my-app serve help
|
|
137
139
|
```
|
|
138
140
|
|
|
141
|
+
### configure
|
|
142
|
+
|
|
143
|
+
Sets global display options for the entire toolkit — accent color used in help output, tables, charts, and prompts; plus Unicode glyph support.
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import { configure } from 'termkit'
|
|
147
|
+
|
|
148
|
+
configure({
|
|
149
|
+
color: '#a855f7', // any named color, hex string, or xterm number
|
|
150
|
+
glyphs: true,
|
|
151
|
+
})
|
|
152
|
+
```
|
|
153
|
+
|
|
139
154
|
### Input
|
|
140
155
|
|
|
141
156
|
Interactive text prompt. Supports string, number, integer, boolean, and enum types with validation.
|
|
@@ -326,7 +341,7 @@ new Table(rows, { columns: ['name', 'role'] }).print()
|
|
|
326
341
|
|
|
327
342
|
### Chart
|
|
328
343
|
|
|
329
|
-
The `Chart` namespace provides horizontal bar, vertical column, heatmap, and
|
|
344
|
+
The `Chart` namespace provides horizontal bar, vertical column, heatmap, scatter, line, and sparkline visualizations. Every chart class has a `.print()` method that writes to stdout and a `.toString()` method that returns the rendered string.
|
|
330
345
|
|
|
331
346
|
All chart constructors accept optional `paddingX` and `paddingY` options to add whitespace around the output.
|
|
332
347
|
|
|
@@ -570,6 +585,60 @@ Each `add()` call accepts the same options as `Bar` and returns a `Bar` instance
|
|
|
570
585
|
|
|
571
586
|
Options: `interval`.
|
|
572
587
|
|
|
588
|
+
### Spinner
|
|
589
|
+
|
|
590
|
+
Animated spinner for indeterminate work. Shares the same completion API as `Bar` — `.succeed()`, `.fail()`, `.warn()`, `.info()`.
|
|
591
|
+
|
|
592
|
+
```ts
|
|
593
|
+
import { Spinner } from 'termkit'
|
|
594
|
+
|
|
595
|
+
const spinner = new Spinner({ text: 'Loading…' })
|
|
596
|
+
spinner.start()
|
|
597
|
+
|
|
598
|
+
await doWork()
|
|
599
|
+
|
|
600
|
+
spinner.succeed('Done')
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
Update the label while running:
|
|
604
|
+
|
|
605
|
+
```ts
|
|
606
|
+
spinner.message('Still working…')
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
Built-in frame sets are available on `Spinner.FRAMES`:
|
|
610
|
+
|
|
611
|
+
```ts
|
|
612
|
+
new Spinner({ frames: Spinner.FRAMES.dots, text: 'Thinking…' }).start()
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
Frame sets: `braille`, `dots`, `line`, `arrow`, `bounce`.
|
|
616
|
+
|
|
617
|
+
Options: `frames`, `text`, `prefix`, `suffix`, `reverse`, `interval`, `colors`, `bgColors`, `colorCycle`, `shimmer`, `successColor`, `failColor`, `warnColor`, `infoColor`, `glyphs`.
|
|
618
|
+
|
|
619
|
+
### Scrollbox
|
|
620
|
+
|
|
621
|
+
Interactive terminal pager. Renders a fixed-height viewport over an array of strings with keyboard navigation. Requires an interactive TTY.
|
|
622
|
+
|
|
623
|
+
```ts
|
|
624
|
+
import { scrollbox } from 'termkit'
|
|
625
|
+
|
|
626
|
+
await scrollbox(lines, { height: 20, title: 'Output', lineNumbers: true })
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
Or use the class directly for more control:
|
|
630
|
+
|
|
631
|
+
```ts
|
|
632
|
+
import { Scrollbox } from 'termkit'
|
|
633
|
+
|
|
634
|
+
const box = new Scrollbox({ height: 15, scrollbar: true, wrapLines: true })
|
|
635
|
+
await box.show(lines)
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
Keyboard controls: ↑↓ / `j` `k` scroll one line · `d` / `u` half-page · `f` / `b` full page · `g` top · `G` bottom · Enter / Escape / `q` close.
|
|
639
|
+
|
|
640
|
+
Options: `height`, `title`, `lineNumbers`, `scrollbar`, `borderColor`, `wrapLines`.
|
|
641
|
+
|
|
573
642
|
### truncate
|
|
574
643
|
|
|
575
644
|
ANSI-aware string truncation. Measures visible length ignoring escape codes, and appends a configurable suffix.
|
|
@@ -595,16 +664,22 @@ console.log(wrap(longParagraph, 60))
|
|
|
595
664
|
|
|
596
665
|
## API
|
|
597
666
|
|
|
667
|
+
### Program
|
|
668
|
+
|
|
669
|
+
| Method | Signature | Description |
|
|
670
|
+
|---|---|---|
|
|
671
|
+
| `Program.command` | `(name, variables?, info?) => Command` | Create a command |
|
|
672
|
+
| `Program.option` | `(short, long, variables, info) => Option` | Create a standalone option |
|
|
673
|
+
| `Program.middleware` | `(fn) => fn` | Identity helper for typing middleware inline |
|
|
674
|
+
| `Program.parse` | `(argv) => Promise<void>` | Parse argv using the root command |
|
|
675
|
+
| `Program.setDefaults` | `(defaults) => void` | Apply middleware/options to all new commands |
|
|
676
|
+
|
|
598
677
|
### Functions
|
|
599
678
|
|
|
600
679
|
| Function | Signature | Description |
|
|
601
680
|
|---|---|---|
|
|
602
|
-
| `
|
|
603
|
-
| `
|
|
604
|
-
| `middleware` | `(fn) => fn` | Identity helper for typing middleware inline |
|
|
605
|
-
| `parse` | `(argv) => Promise<unknown>` | Parse using the root command |
|
|
606
|
-
| `setDefaults` | `(defaults) => void` | Set defaults applied to all new commands |
|
|
607
|
-
| `configure` | `(opts) => void` | Set global display options (color, glyphs) |
|
|
681
|
+
| `configure` | `(opts) => void` | Set global accent color and display options |
|
|
682
|
+
| `scrollbox` | `(lines, options?) => Promise<void>` | Interactive terminal pager |
|
|
608
683
|
| `markup` | `(data, options?) => string` | Pretty-print a value with syntax coloring |
|
|
609
684
|
| `input` | `(prompt, options?) => Promise<string \| number \| boolean \| null>` | Interactive text prompt |
|
|
610
685
|
| `confirm` | `(prompt, options?) => Promise<boolean \| null>` | Boolean yes/no prompt |
|
|
@@ -620,7 +695,7 @@ console.log(wrap(longParagraph, 60))
|
|
|
620
695
|
|
|
621
696
|
### Classes
|
|
622
697
|
|
|
623
|
-
`Command`, `Option`, `Variable`, `TermKit`, `Bar`, `MultiBar`, `Spinner`, `Input`, `Select`, `MultiSelect`, `Log`, `Table`, `Column`, `Chart.Bar`, `Chart.VerticalBar`, `Chart.Heatmap`, `Chart.Scatter`, `Chart.Line`
|
|
698
|
+
`Command`, `Option`, `Variable`, `TermKit`, `Bar`, `MultiBar`, `Spinner`, `Scrollbox`, `Input`, `Select`, `MultiSelect`, `Log`, `Table`, `Column`, `Chart.Bar`, `Chart.VerticalBar`, `Chart.Heatmap`, `Chart.Scatter`, `Chart.Line`
|
|
624
699
|
|
|
625
700
|
### Types
|
|
626
701
|
|
package/dist/index.d.ts
CHANGED
|
@@ -42,9 +42,11 @@ export interface CommandDefaults {
|
|
|
42
42
|
middlewares?: MiddlewareFn[];
|
|
43
43
|
options?: Option[];
|
|
44
44
|
}
|
|
45
|
-
export declare const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
export declare const Program: {
|
|
46
|
+
command: (name: string, variables?: string | null, info?: string) => Command;
|
|
47
|
+
option: (short: string | null, long: string | null, variables: string | null, info: string) => Option;
|
|
48
|
+
middleware: (fn: MiddlewareFn) => MiddlewareFn;
|
|
49
|
+
parse: (arr: string[]) => Promise<void>;
|
|
50
|
+
setDefaults: (data: CommandDefaults) => void;
|
|
51
|
+
};
|
|
50
52
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -40,37 +40,30 @@ __export(index_exports, {
|
|
|
40
40
|
MultiBar: () => MultiBar,
|
|
41
41
|
MultiSelect: () => MultiSelect,
|
|
42
42
|
Option: () => Option,
|
|
43
|
+
Program: () => Program,
|
|
43
44
|
Scrollbox: () => Scrollbox,
|
|
44
45
|
Select: () => Select,
|
|
45
46
|
Spinner: () => Spinner,
|
|
46
47
|
Table: () => Table,
|
|
47
48
|
TermKit: () => TermKit,
|
|
48
49
|
Variable: () => Variable,
|
|
49
|
-
command: () => command,
|
|
50
50
|
configure: () => configure,
|
|
51
51
|
confirm: () => confirm,
|
|
52
52
|
input: () => input,
|
|
53
53
|
log: () => log,
|
|
54
54
|
markup: () => markup,
|
|
55
|
-
middleware: () => middleware,
|
|
56
55
|
multiSelect: () => multiSelect,
|
|
57
|
-
option: () => option,
|
|
58
56
|
padLeft: () => padLeft,
|
|
59
57
|
padRight: () => padRight,
|
|
60
58
|
padSides: () => padSides,
|
|
61
|
-
parse: () => parse,
|
|
62
59
|
scrollbox: () => scrollbox,
|
|
63
60
|
select: () => select,
|
|
64
|
-
setDefaults: () => setDefaults,
|
|
65
61
|
stringLength: () => stringLength,
|
|
66
62
|
truncate: () => truncate,
|
|
67
63
|
wrap: () => wrap
|
|
68
64
|
});
|
|
69
65
|
module.exports = __toCommonJS(index_exports);
|
|
70
66
|
|
|
71
|
-
// src/models/Command.ts
|
|
72
|
-
var import_cosmetic = __toESM(require("cosmetic"));
|
|
73
|
-
|
|
74
67
|
// src/config.ts
|
|
75
68
|
var isLegacyTerminal = process.env.TERM === "dumb" || process.platform === "win32" && !process.env.WT_SESSION && process.env.TERM_PROGRAM !== "vscode" && process.env.TERM_PROGRAM !== "Hyper";
|
|
76
69
|
var config = {
|
|
@@ -86,6 +79,9 @@ function configure(opts) {
|
|
|
86
79
|
if (opts.interactive !== void 0) config.interactive = opts.interactive;
|
|
87
80
|
}
|
|
88
81
|
|
|
82
|
+
// src/models/Command.ts
|
|
83
|
+
var import_cosmetic = __toESM(require("cosmetic"));
|
|
84
|
+
|
|
89
85
|
// src/models/Variable.ts
|
|
90
86
|
var Variable = class {
|
|
91
87
|
constructor(data) {
|
|
@@ -182,10 +178,10 @@ var Option = class {
|
|
|
182
178
|
|
|
183
179
|
// src/utils/findCommand.ts
|
|
184
180
|
function findCommand(array, commands) {
|
|
185
|
-
for (const
|
|
186
|
-
if (array[0] ===
|
|
181
|
+
for (const command of commands) {
|
|
182
|
+
if (array[0] === command.name) {
|
|
187
183
|
array.shift();
|
|
188
|
-
return
|
|
184
|
+
return command;
|
|
189
185
|
}
|
|
190
186
|
}
|
|
191
187
|
return null;
|
|
@@ -780,11 +776,11 @@ async function findVariable(array, variable, commands) {
|
|
|
780
776
|
}
|
|
781
777
|
|
|
782
778
|
// src/utils/findCommandVariables.ts
|
|
783
|
-
async function findCommandVariables(array,
|
|
784
|
-
if (!
|
|
779
|
+
async function findCommandVariables(array, command) {
|
|
780
|
+
if (!command.variables) return null;
|
|
785
781
|
const result = {};
|
|
786
|
-
for (const variable of
|
|
787
|
-
const value = await findVariable(array, variable,
|
|
782
|
+
for (const variable of command.variables) {
|
|
783
|
+
const value = await findVariable(array, variable, command.commandStrings);
|
|
788
784
|
if (value !== true) result[variable.name] = value;
|
|
789
785
|
}
|
|
790
786
|
return Object.keys(result).length > 0 ? result : null;
|
|
@@ -818,40 +814,40 @@ async function findVariables(base2, array, variables, commands) {
|
|
|
818
814
|
}
|
|
819
815
|
|
|
820
816
|
// src/utils/findOptions.ts
|
|
821
|
-
async function findOptions(array,
|
|
817
|
+
async function findOptions(array, command) {
|
|
822
818
|
const result = {};
|
|
823
819
|
while (array.length > 0 && array[0].startsWith("-")) {
|
|
824
820
|
if (array[0].startsWith("--")) {
|
|
825
821
|
const raw = array.shift().slice(2);
|
|
826
822
|
if (raw.startsWith("no-")) {
|
|
827
823
|
const longName = raw.slice(3);
|
|
828
|
-
const negated = findOption(longName,
|
|
824
|
+
const negated = findOption(longName, command.optionsArray);
|
|
829
825
|
if (negated?.long) {
|
|
830
826
|
result[negated.long] = false;
|
|
831
827
|
continue;
|
|
832
828
|
}
|
|
833
829
|
}
|
|
834
|
-
const
|
|
835
|
-
if (!
|
|
830
|
+
const option = findOption(raw, command.optionsArray);
|
|
831
|
+
if (!option) throw new Error(`Unknown Option: --${raw}`);
|
|
836
832
|
try {
|
|
837
|
-
Object.assign(result, await findVariables(
|
|
833
|
+
Object.assign(result, await findVariables(option.long, array, option.variables, command.commandStrings));
|
|
838
834
|
} catch (err) {
|
|
839
835
|
;
|
|
840
|
-
err.message += ` for --${
|
|
836
|
+
err.message += ` for --${option.long}`;
|
|
841
837
|
throw err;
|
|
842
838
|
}
|
|
843
839
|
} else {
|
|
844
840
|
let string = array.shift();
|
|
845
841
|
const short = string.slice(1, 2);
|
|
846
|
-
const
|
|
847
|
-
if (!
|
|
842
|
+
const option = findOption(short, command.optionsArray);
|
|
843
|
+
if (!option) throw new Error(`Unknown Option: -${short}`);
|
|
848
844
|
string = "-" + string.slice(2);
|
|
849
845
|
if (string !== "-") array.unshift(string);
|
|
850
846
|
try {
|
|
851
|
-
Object.assign(result, await findVariables(
|
|
847
|
+
Object.assign(result, await findVariables(option.long, array, option.variables, command.commandStrings));
|
|
852
848
|
} catch (err) {
|
|
853
849
|
;
|
|
854
|
-
err.message += ` for --${
|
|
850
|
+
err.message += ` for --${option.long}`;
|
|
855
851
|
throw err;
|
|
856
852
|
}
|
|
857
853
|
}
|
|
@@ -996,7 +992,7 @@ var Command = class {
|
|
|
996
992
|
async parse(input2) {
|
|
997
993
|
const array = [...input2];
|
|
998
994
|
array.splice(0, 2);
|
|
999
|
-
let
|
|
995
|
+
let command = this;
|
|
1000
996
|
const options = { _source: Array.from(array) };
|
|
1001
997
|
const ddIdx = array.indexOf("--");
|
|
1002
998
|
if (ddIdx !== -1) {
|
|
@@ -1005,19 +1001,19 @@ var Command = class {
|
|
|
1005
1001
|
}
|
|
1006
1002
|
while (array.length) {
|
|
1007
1003
|
if (!array.includes("help")) {
|
|
1008
|
-
Object.assign(options, await findOptions(array,
|
|
1009
|
-
const cmdVars = await findCommandVariables(array,
|
|
1004
|
+
Object.assign(options, await findOptions(array, command));
|
|
1005
|
+
const cmdVars = await findCommandVariables(array, command);
|
|
1010
1006
|
if (cmdVars) Object.assign(options, cmdVars);
|
|
1011
|
-
Object.assign(options, await findOptions(array,
|
|
1007
|
+
Object.assign(options, await findOptions(array, command));
|
|
1012
1008
|
}
|
|
1013
1009
|
if (array.length) {
|
|
1014
1010
|
if (!array.includes("help")) {
|
|
1015
|
-
for (const mw of
|
|
1011
|
+
for (const mw of command.middlewaresArray) await mw(options);
|
|
1016
1012
|
}
|
|
1017
|
-
const next = findCommand(array,
|
|
1018
|
-
if (!next && array[0] === "help") return
|
|
1013
|
+
const next = findCommand(array, command.commandsArray);
|
|
1014
|
+
if (!next && array[0] === "help") return command.help(options._source);
|
|
1019
1015
|
if (!next) throw new SyntaxError(`Unknown command: ${array[0]}`);
|
|
1020
|
-
const name =
|
|
1016
|
+
const name = command.name ?? "_base";
|
|
1021
1017
|
if (!options._parents) options._parents = {};
|
|
1022
1018
|
options._parents[name] = {};
|
|
1023
1019
|
for (const key of Object.keys(options)) {
|
|
@@ -1026,10 +1022,10 @@ var Command = class {
|
|
|
1026
1022
|
delete options[key];
|
|
1027
1023
|
}
|
|
1028
1024
|
}
|
|
1029
|
-
|
|
1025
|
+
command = next;
|
|
1030
1026
|
}
|
|
1031
1027
|
}
|
|
1032
|
-
for (const opt of
|
|
1028
|
+
for (const opt of command.optionsArray) {
|
|
1033
1029
|
if (!opt.long || !opt.variables) continue;
|
|
1034
1030
|
for (const v of opt.variables) {
|
|
1035
1031
|
if (v.default !== null && !(opt.long in options)) {
|
|
@@ -1037,10 +1033,10 @@ var Command = class {
|
|
|
1037
1033
|
}
|
|
1038
1034
|
}
|
|
1039
1035
|
}
|
|
1040
|
-
for (const mw of
|
|
1041
|
-
if (
|
|
1042
|
-
if (options._source.length === 2) return
|
|
1043
|
-
throw new Error(`No action for command: ${
|
|
1036
|
+
for (const mw of command.middlewaresArray) await mw(options);
|
|
1037
|
+
if (command.actionFunction) return command.actionFunction(options);
|
|
1038
|
+
if (options._source.length === 2) return command.help(options._source);
|
|
1039
|
+
throw new Error(`No action for command: ${command.name ?? "_base"}`);
|
|
1044
1040
|
}
|
|
1045
1041
|
};
|
|
1046
1042
|
|
|
@@ -2792,32 +2788,34 @@ var TermKit = _TermKit;
|
|
|
2792
2788
|
var import_cosmetic4 = __toESM(require("cosmetic"));
|
|
2793
2789
|
var base = null;
|
|
2794
2790
|
var commandDefaults = {};
|
|
2795
|
-
var
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
process.stderr.
|
|
2791
|
+
var Program = {
|
|
2792
|
+
command: (name, variables, info) => {
|
|
2793
|
+
const cmd = new Command(Object.assign({ name, variables, info }, commandDefaults));
|
|
2794
|
+
if (!base) base = cmd;
|
|
2795
|
+
return cmd;
|
|
2796
|
+
},
|
|
2797
|
+
option: (short, long, variables, info) => new Option({ short, long, variables, info }),
|
|
2798
|
+
middleware: (fn) => fn,
|
|
2799
|
+
parse: async (arr) => {
|
|
2800
|
+
if (!base) throw new Error("No command defined");
|
|
2801
|
+
try {
|
|
2802
|
+
await base.parse(arr);
|
|
2803
|
+
} catch (err) {
|
|
2804
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2805
|
+
if (process.stderr.isTTY && config.glyphs) {
|
|
2806
|
+
process.stderr.write(`\x1B[31m\u2716\x1B[0m ${msg}
|
|
2810
2807
|
`);
|
|
2811
|
-
|
|
2812
|
-
|
|
2808
|
+
} else {
|
|
2809
|
+
process.stderr.write(`Error: ${msg}
|
|
2813
2810
|
`);
|
|
2811
|
+
}
|
|
2812
|
+
process.exit(1);
|
|
2814
2813
|
}
|
|
2815
|
-
|
|
2814
|
+
},
|
|
2815
|
+
setDefaults: (data) => {
|
|
2816
|
+
commandDefaults = data;
|
|
2816
2817
|
}
|
|
2817
2818
|
};
|
|
2818
|
-
var setDefaults = (data) => {
|
|
2819
|
-
commandDefaults = data;
|
|
2820
|
-
};
|
|
2821
2819
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2822
2820
|
0 && (module.exports = {
|
|
2823
2821
|
Bar,
|
|
@@ -2830,28 +2828,24 @@ var setDefaults = (data) => {
|
|
|
2830
2828
|
MultiBar,
|
|
2831
2829
|
MultiSelect,
|
|
2832
2830
|
Option,
|
|
2831
|
+
Program,
|
|
2833
2832
|
Scrollbox,
|
|
2834
2833
|
Select,
|
|
2835
2834
|
Spinner,
|
|
2836
2835
|
Table,
|
|
2837
2836
|
TermKit,
|
|
2838
2837
|
Variable,
|
|
2839
|
-
command,
|
|
2840
2838
|
configure,
|
|
2841
2839
|
confirm,
|
|
2842
2840
|
input,
|
|
2843
2841
|
log,
|
|
2844
2842
|
markup,
|
|
2845
|
-
middleware,
|
|
2846
2843
|
multiSelect,
|
|
2847
|
-
option,
|
|
2848
2844
|
padLeft,
|
|
2849
2845
|
padRight,
|
|
2850
2846
|
padSides,
|
|
2851
|
-
parse,
|
|
2852
2847
|
scrollbox,
|
|
2853
2848
|
select,
|
|
2854
|
-
setDefaults,
|
|
2855
2849
|
stringLength,
|
|
2856
2850
|
truncate,
|
|
2857
2851
|
wrap
|
package/dist/index.mjs
CHANGED
|
@@ -4,9 +4,6 @@ var __export = (target, all) => {
|
|
|
4
4
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
-
// src/models/Command.ts
|
|
8
|
-
import cosmetic from "cosmetic";
|
|
9
|
-
|
|
10
7
|
// src/config.ts
|
|
11
8
|
var isLegacyTerminal = process.env.TERM === "dumb" || process.platform === "win32" && !process.env.WT_SESSION && process.env.TERM_PROGRAM !== "vscode" && process.env.TERM_PROGRAM !== "Hyper";
|
|
12
9
|
var config = {
|
|
@@ -22,6 +19,9 @@ function configure(opts) {
|
|
|
22
19
|
if (opts.interactive !== void 0) config.interactive = opts.interactive;
|
|
23
20
|
}
|
|
24
21
|
|
|
22
|
+
// src/models/Command.ts
|
|
23
|
+
import cosmetic from "cosmetic";
|
|
24
|
+
|
|
25
25
|
// src/models/Variable.ts
|
|
26
26
|
var Variable = class {
|
|
27
27
|
constructor(data) {
|
|
@@ -118,10 +118,10 @@ var Option = class {
|
|
|
118
118
|
|
|
119
119
|
// src/utils/findCommand.ts
|
|
120
120
|
function findCommand(array, commands) {
|
|
121
|
-
for (const
|
|
122
|
-
if (array[0] ===
|
|
121
|
+
for (const command of commands) {
|
|
122
|
+
if (array[0] === command.name) {
|
|
123
123
|
array.shift();
|
|
124
|
-
return
|
|
124
|
+
return command;
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
return null;
|
|
@@ -716,11 +716,11 @@ async function findVariable(array, variable, commands) {
|
|
|
716
716
|
}
|
|
717
717
|
|
|
718
718
|
// src/utils/findCommandVariables.ts
|
|
719
|
-
async function findCommandVariables(array,
|
|
720
|
-
if (!
|
|
719
|
+
async function findCommandVariables(array, command) {
|
|
720
|
+
if (!command.variables) return null;
|
|
721
721
|
const result = {};
|
|
722
|
-
for (const variable of
|
|
723
|
-
const value = await findVariable(array, variable,
|
|
722
|
+
for (const variable of command.variables) {
|
|
723
|
+
const value = await findVariable(array, variable, command.commandStrings);
|
|
724
724
|
if (value !== true) result[variable.name] = value;
|
|
725
725
|
}
|
|
726
726
|
return Object.keys(result).length > 0 ? result : null;
|
|
@@ -754,40 +754,40 @@ async function findVariables(base2, array, variables, commands) {
|
|
|
754
754
|
}
|
|
755
755
|
|
|
756
756
|
// src/utils/findOptions.ts
|
|
757
|
-
async function findOptions(array,
|
|
757
|
+
async function findOptions(array, command) {
|
|
758
758
|
const result = {};
|
|
759
759
|
while (array.length > 0 && array[0].startsWith("-")) {
|
|
760
760
|
if (array[0].startsWith("--")) {
|
|
761
761
|
const raw = array.shift().slice(2);
|
|
762
762
|
if (raw.startsWith("no-")) {
|
|
763
763
|
const longName = raw.slice(3);
|
|
764
|
-
const negated = findOption(longName,
|
|
764
|
+
const negated = findOption(longName, command.optionsArray);
|
|
765
765
|
if (negated?.long) {
|
|
766
766
|
result[negated.long] = false;
|
|
767
767
|
continue;
|
|
768
768
|
}
|
|
769
769
|
}
|
|
770
|
-
const
|
|
771
|
-
if (!
|
|
770
|
+
const option = findOption(raw, command.optionsArray);
|
|
771
|
+
if (!option) throw new Error(`Unknown Option: --${raw}`);
|
|
772
772
|
try {
|
|
773
|
-
Object.assign(result, await findVariables(
|
|
773
|
+
Object.assign(result, await findVariables(option.long, array, option.variables, command.commandStrings));
|
|
774
774
|
} catch (err) {
|
|
775
775
|
;
|
|
776
|
-
err.message += ` for --${
|
|
776
|
+
err.message += ` for --${option.long}`;
|
|
777
777
|
throw err;
|
|
778
778
|
}
|
|
779
779
|
} else {
|
|
780
780
|
let string = array.shift();
|
|
781
781
|
const short = string.slice(1, 2);
|
|
782
|
-
const
|
|
783
|
-
if (!
|
|
782
|
+
const option = findOption(short, command.optionsArray);
|
|
783
|
+
if (!option) throw new Error(`Unknown Option: -${short}`);
|
|
784
784
|
string = "-" + string.slice(2);
|
|
785
785
|
if (string !== "-") array.unshift(string);
|
|
786
786
|
try {
|
|
787
|
-
Object.assign(result, await findVariables(
|
|
787
|
+
Object.assign(result, await findVariables(option.long, array, option.variables, command.commandStrings));
|
|
788
788
|
} catch (err) {
|
|
789
789
|
;
|
|
790
|
-
err.message += ` for --${
|
|
790
|
+
err.message += ` for --${option.long}`;
|
|
791
791
|
throw err;
|
|
792
792
|
}
|
|
793
793
|
}
|
|
@@ -932,7 +932,7 @@ var Command = class {
|
|
|
932
932
|
async parse(input2) {
|
|
933
933
|
const array = [...input2];
|
|
934
934
|
array.splice(0, 2);
|
|
935
|
-
let
|
|
935
|
+
let command = this;
|
|
936
936
|
const options = { _source: Array.from(array) };
|
|
937
937
|
const ddIdx = array.indexOf("--");
|
|
938
938
|
if (ddIdx !== -1) {
|
|
@@ -941,19 +941,19 @@ var Command = class {
|
|
|
941
941
|
}
|
|
942
942
|
while (array.length) {
|
|
943
943
|
if (!array.includes("help")) {
|
|
944
|
-
Object.assign(options, await findOptions(array,
|
|
945
|
-
const cmdVars = await findCommandVariables(array,
|
|
944
|
+
Object.assign(options, await findOptions(array, command));
|
|
945
|
+
const cmdVars = await findCommandVariables(array, command);
|
|
946
946
|
if (cmdVars) Object.assign(options, cmdVars);
|
|
947
|
-
Object.assign(options, await findOptions(array,
|
|
947
|
+
Object.assign(options, await findOptions(array, command));
|
|
948
948
|
}
|
|
949
949
|
if (array.length) {
|
|
950
950
|
if (!array.includes("help")) {
|
|
951
|
-
for (const mw of
|
|
951
|
+
for (const mw of command.middlewaresArray) await mw(options);
|
|
952
952
|
}
|
|
953
|
-
const next = findCommand(array,
|
|
954
|
-
if (!next && array[0] === "help") return
|
|
953
|
+
const next = findCommand(array, command.commandsArray);
|
|
954
|
+
if (!next && array[0] === "help") return command.help(options._source);
|
|
955
955
|
if (!next) throw new SyntaxError(`Unknown command: ${array[0]}`);
|
|
956
|
-
const name =
|
|
956
|
+
const name = command.name ?? "_base";
|
|
957
957
|
if (!options._parents) options._parents = {};
|
|
958
958
|
options._parents[name] = {};
|
|
959
959
|
for (const key of Object.keys(options)) {
|
|
@@ -962,10 +962,10 @@ var Command = class {
|
|
|
962
962
|
delete options[key];
|
|
963
963
|
}
|
|
964
964
|
}
|
|
965
|
-
|
|
965
|
+
command = next;
|
|
966
966
|
}
|
|
967
967
|
}
|
|
968
|
-
for (const opt of
|
|
968
|
+
for (const opt of command.optionsArray) {
|
|
969
969
|
if (!opt.long || !opt.variables) continue;
|
|
970
970
|
for (const v of opt.variables) {
|
|
971
971
|
if (v.default !== null && !(opt.long in options)) {
|
|
@@ -973,10 +973,10 @@ var Command = class {
|
|
|
973
973
|
}
|
|
974
974
|
}
|
|
975
975
|
}
|
|
976
|
-
for (const mw of
|
|
977
|
-
if (
|
|
978
|
-
if (options._source.length === 2) return
|
|
979
|
-
throw new Error(`No action for command: ${
|
|
976
|
+
for (const mw of command.middlewaresArray) await mw(options);
|
|
977
|
+
if (command.actionFunction) return command.actionFunction(options);
|
|
978
|
+
if (options._source.length === 2) return command.help(options._source);
|
|
979
|
+
throw new Error(`No action for command: ${command.name ?? "_base"}`);
|
|
980
980
|
}
|
|
981
981
|
};
|
|
982
982
|
|
|
@@ -2728,32 +2728,34 @@ var TermKit = _TermKit;
|
|
|
2728
2728
|
import { default as default2 } from "cosmetic";
|
|
2729
2729
|
var base = null;
|
|
2730
2730
|
var commandDefaults = {};
|
|
2731
|
-
var
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
process.stderr.
|
|
2731
|
+
var Program = {
|
|
2732
|
+
command: (name, variables, info) => {
|
|
2733
|
+
const cmd = new Command(Object.assign({ name, variables, info }, commandDefaults));
|
|
2734
|
+
if (!base) base = cmd;
|
|
2735
|
+
return cmd;
|
|
2736
|
+
},
|
|
2737
|
+
option: (short, long, variables, info) => new Option({ short, long, variables, info }),
|
|
2738
|
+
middleware: (fn) => fn,
|
|
2739
|
+
parse: async (arr) => {
|
|
2740
|
+
if (!base) throw new Error("No command defined");
|
|
2741
|
+
try {
|
|
2742
|
+
await base.parse(arr);
|
|
2743
|
+
} catch (err) {
|
|
2744
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2745
|
+
if (process.stderr.isTTY && config.glyphs) {
|
|
2746
|
+
process.stderr.write(`\x1B[31m\u2716\x1B[0m ${msg}
|
|
2746
2747
|
`);
|
|
2747
|
-
|
|
2748
|
-
|
|
2748
|
+
} else {
|
|
2749
|
+
process.stderr.write(`Error: ${msg}
|
|
2749
2750
|
`);
|
|
2751
|
+
}
|
|
2752
|
+
process.exit(1);
|
|
2750
2753
|
}
|
|
2751
|
-
|
|
2754
|
+
},
|
|
2755
|
+
setDefaults: (data) => {
|
|
2756
|
+
commandDefaults = data;
|
|
2752
2757
|
}
|
|
2753
2758
|
};
|
|
2754
|
-
var setDefaults = (data) => {
|
|
2755
|
-
commandDefaults = data;
|
|
2756
|
-
};
|
|
2757
2759
|
export {
|
|
2758
2760
|
Bar,
|
|
2759
2761
|
Chart_exports as Chart,
|
|
@@ -2765,28 +2767,24 @@ export {
|
|
|
2765
2767
|
MultiBar,
|
|
2766
2768
|
MultiSelect,
|
|
2767
2769
|
Option,
|
|
2770
|
+
Program,
|
|
2768
2771
|
Scrollbox,
|
|
2769
2772
|
Select,
|
|
2770
2773
|
Spinner,
|
|
2771
2774
|
Table,
|
|
2772
2775
|
TermKit,
|
|
2773
2776
|
Variable,
|
|
2774
|
-
command,
|
|
2775
2777
|
configure,
|
|
2776
2778
|
confirm,
|
|
2777
2779
|
input,
|
|
2778
2780
|
log,
|
|
2779
2781
|
markup,
|
|
2780
|
-
middleware,
|
|
2781
2782
|
multiSelect,
|
|
2782
|
-
option,
|
|
2783
2783
|
padLeft,
|
|
2784
2784
|
padRight,
|
|
2785
2785
|
padSides,
|
|
2786
|
-
parse,
|
|
2787
2786
|
scrollbox,
|
|
2788
2787
|
select,
|
|
2789
|
-
setDefaults,
|
|
2790
2788
|
stringLength,
|
|
2791
2789
|
truncate,
|
|
2792
2790
|
wrap
|