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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # TermKit
2
2
 
3
- A fluent CLI framework for Node.js with nested subcommands, middleware, and TypeScript support.
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
- ### Basic program
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 { command, option, parse } from 'termkit'
18
+ import { Program } from 'termkit'
17
19
 
18
- const program = command('my-app')
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
- try {
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` or `:boolean` to a variable to coerce the parsed string:
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', '<port:number>', 'Port number')
64
- .option('v', 'verbose', '[verbose:boolean]', 'Verbose mode')
65
- .option('n', 'nums', '[nums:number...]', 'List of numbers')
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 // number
68
- options.verbose // boolean
69
- options.nums // number[]
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
- import { command, option } from 'termkit'
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
- import { setDefaults } from 'termkit'
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 scatter visualizations. Every chart class has a `.print()` method that writes to stdout and a `.toString()` method that returns the rendered string.
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
- | `command` | `(name, variables?, info?) => Command` | Create a command |
603
- | `option` | `(short, long, variables, info) => Option` | Create an option |
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 command: (name: string, variables?: string | null, info?: string) => Command;
46
- export declare const middleware: (fn: MiddlewareFn) => MiddlewareFn;
47
- export declare const option: (short: string | null, long: string | null, variables: string | null, info: string) => Option;
48
- export declare const parse: (arr: string[]) => Promise<void>;
49
- export declare const setDefaults: (data: CommandDefaults) => void;
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
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
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 command2 of commands) {
186
- if (array[0] === command2.name) {
181
+ for (const command of commands) {
182
+ if (array[0] === command.name) {
187
183
  array.shift();
188
- return command2;
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, command2) {
784
- if (!command2.variables) return null;
779
+ async function findCommandVariables(array, command) {
780
+ if (!command.variables) return null;
785
781
  const result = {};
786
- for (const variable of command2.variables) {
787
- const value = await findVariable(array, variable, command2.commandStrings);
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, command2) {
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, command2.optionsArray);
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 option2 = findOption(raw, command2.optionsArray);
835
- if (!option2) throw new Error(`Unknown Option: --${raw}`);
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(option2.long, array, option2.variables, command2.commandStrings));
833
+ Object.assign(result, await findVariables(option.long, array, option.variables, command.commandStrings));
838
834
  } catch (err) {
839
835
  ;
840
- err.message += ` for --${option2.long}`;
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 option2 = findOption(short, command2.optionsArray);
847
- if (!option2) throw new Error(`Unknown Option: -${short}`);
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(option2.long, array, option2.variables, command2.commandStrings));
847
+ Object.assign(result, await findVariables(option.long, array, option.variables, command.commandStrings));
852
848
  } catch (err) {
853
849
  ;
854
- err.message += ` for --${option2.long}`;
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 command2 = this;
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, command2));
1009
- const cmdVars = await findCommandVariables(array, command2);
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, command2));
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 command2.middlewaresArray) await mw(options);
1011
+ for (const mw of command.middlewaresArray) await mw(options);
1016
1012
  }
1017
- const next = findCommand(array, command2.commandsArray);
1018
- if (!next && array[0] === "help") return command2.help(options._source);
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 = command2.name ?? "_base";
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
- command2 = next;
1025
+ command = next;
1030
1026
  }
1031
1027
  }
1032
- for (const opt of command2.optionsArray) {
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 command2.middlewaresArray) await mw(options);
1041
- if (command2.actionFunction) return command2.actionFunction(options);
1042
- if (options._source.length === 2) return command2.help(options._source);
1043
- throw new Error(`No action for command: ${command2.name ?? "_base"}`);
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 command = (name, variables, info) => {
2796
- const cmd = new Command(Object.assign({ name, variables, info }, commandDefaults));
2797
- if (!base) base = cmd;
2798
- return cmd;
2799
- };
2800
- var middleware = (fn) => fn;
2801
- var option = (short, long, variables, info) => new Option({ short, long, variables, info });
2802
- var parse = async (arr) => {
2803
- if (!base) throw new Error("No command defined");
2804
- try {
2805
- await base.parse(arr);
2806
- } catch (err) {
2807
- const msg = err instanceof Error ? err.message : String(err);
2808
- if (process.stderr.isTTY && config.glyphs) {
2809
- process.stderr.write(`\x1B[31m\u2716\x1B[0m ${msg}
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
- } else {
2812
- process.stderr.write(`Error: ${msg}
2808
+ } else {
2809
+ process.stderr.write(`Error: ${msg}
2813
2810
  `);
2811
+ }
2812
+ process.exit(1);
2814
2813
  }
2815
- process.exit(1);
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 command2 of commands) {
122
- if (array[0] === command2.name) {
121
+ for (const command of commands) {
122
+ if (array[0] === command.name) {
123
123
  array.shift();
124
- return command2;
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, command2) {
720
- if (!command2.variables) return null;
719
+ async function findCommandVariables(array, command) {
720
+ if (!command.variables) return null;
721
721
  const result = {};
722
- for (const variable of command2.variables) {
723
- const value = await findVariable(array, variable, command2.commandStrings);
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, command2) {
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, command2.optionsArray);
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 option2 = findOption(raw, command2.optionsArray);
771
- if (!option2) throw new Error(`Unknown Option: --${raw}`);
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(option2.long, array, option2.variables, command2.commandStrings));
773
+ Object.assign(result, await findVariables(option.long, array, option.variables, command.commandStrings));
774
774
  } catch (err) {
775
775
  ;
776
- err.message += ` for --${option2.long}`;
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 option2 = findOption(short, command2.optionsArray);
783
- if (!option2) throw new Error(`Unknown Option: -${short}`);
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(option2.long, array, option2.variables, command2.commandStrings));
787
+ Object.assign(result, await findVariables(option.long, array, option.variables, command.commandStrings));
788
788
  } catch (err) {
789
789
  ;
790
- err.message += ` for --${option2.long}`;
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 command2 = this;
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, command2));
945
- const cmdVars = await findCommandVariables(array, command2);
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, command2));
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 command2.middlewaresArray) await mw(options);
951
+ for (const mw of command.middlewaresArray) await mw(options);
952
952
  }
953
- const next = findCommand(array, command2.commandsArray);
954
- if (!next && array[0] === "help") return command2.help(options._source);
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 = command2.name ?? "_base";
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
- command2 = next;
965
+ command = next;
966
966
  }
967
967
  }
968
- for (const opt of command2.optionsArray) {
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 command2.middlewaresArray) await mw(options);
977
- if (command2.actionFunction) return command2.actionFunction(options);
978
- if (options._source.length === 2) return command2.help(options._source);
979
- throw new Error(`No action for command: ${command2.name ?? "_base"}`);
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 command = (name, variables, info) => {
2732
- const cmd = new Command(Object.assign({ name, variables, info }, commandDefaults));
2733
- if (!base) base = cmd;
2734
- return cmd;
2735
- };
2736
- var middleware = (fn) => fn;
2737
- var option = (short, long, variables, info) => new Option({ short, long, variables, info });
2738
- var parse = async (arr) => {
2739
- if (!base) throw new Error("No command defined");
2740
- try {
2741
- await base.parse(arr);
2742
- } catch (err) {
2743
- const msg = err instanceof Error ? err.message : String(err);
2744
- if (process.stderr.isTTY && config.glyphs) {
2745
- process.stderr.write(`\x1B[31m\u2716\x1B[0m ${msg}
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
- } else {
2748
- process.stderr.write(`Error: ${msg}
2748
+ } else {
2749
+ process.stderr.write(`Error: ${msg}
2749
2750
  `);
2751
+ }
2752
+ process.exit(1);
2750
2753
  }
2751
- process.exit(1);
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "termkit",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "Node.js terminal toolkit with CLI commands, progress bars, charts, tables, styled markup, prompts, and text utilities",
5
5
  "keywords": [
6
6
  "animation",