@thi.ng/args 2.2.46 → 2.3.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/CHANGELOG.md +19 -1
- package/README.md +3 -1
- package/api.d.ts +99 -2
- package/cli.d.ts +3 -0
- package/cli.js +78 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +13 -7
- package/usage.js +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2023-12-
|
|
3
|
+
- **Last updated**: 2023-12-18T13:41:19Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -9,6 +9,24 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
9
9
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
10
10
|
and/or version bumps of transitive dependencies.
|
|
11
11
|
|
|
12
|
+
## [2.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/args@2.3.0) (2023-12-18)
|
|
13
|
+
|
|
14
|
+
#### 🚀 Features
|
|
15
|
+
|
|
16
|
+
- add cliApp() runner ([b2248fa](https://github.com/thi-ng/umbrella/commit/b2248fa))
|
|
17
|
+
- update lifecycle hooks, add NO_COLOR support, add docs ([4a0ebda](https://github.com/thi-ng/umbrella/commit/4a0ebda))
|
|
18
|
+
- add CLIAppConfig pre/post lifecycle hooks
|
|
19
|
+
- update UsageOpts.color handling
|
|
20
|
+
- add `NO_COLOR` env var support in cliApp()
|
|
21
|
+
- add doc strings
|
|
22
|
+
- update deps
|
|
23
|
+
- update cliApp() to support command context extensions ([61d9fb8](https://github.com/thi-ng/umbrella/commit/61d9fb8))
|
|
24
|
+
- update cliApp() error handling ([019e5a1](https://github.com/thi-ng/umbrella/commit/019e5a1))
|
|
25
|
+
- update argv handling in cliApp() ([b1ed768](https://github.com/thi-ng/umbrella/commit/b1ed768))
|
|
26
|
+
- add NO_COLOR aware formatters to CommandCtx ([0e7ddda](https://github.com/thi-ng/umbrella/commit/0e7ddda))
|
|
27
|
+
- update deps
|
|
28
|
+
- update cliApp() to use StreamLogger (target: process.stderr) ([b249295](https://github.com/thi-ng/umbrella/commit/b249295))
|
|
29
|
+
|
|
12
30
|
### [2.2.28](https://github.com/thi-ng/umbrella/tree/@thi.ng/args@2.2.28) (2023-08-04)
|
|
13
31
|
|
|
14
32
|
#### ♻️ Refactoring
|
package/README.md
CHANGED
|
@@ -69,14 +69,16 @@ For Node.js REPL:
|
|
|
69
69
|
const args = await import("@thi.ng/args");
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
Package sizes (brotli'd, pre-treeshake): ESM: 2.
|
|
72
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 2.75 KB
|
|
73
73
|
|
|
74
74
|
## Dependencies
|
|
75
75
|
|
|
76
76
|
- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/develop/packages/api)
|
|
77
77
|
- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/develop/packages/checks)
|
|
78
78
|
- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/develop/packages/errors)
|
|
79
|
+
- [@thi.ng/logger](https://github.com/thi-ng/umbrella/tree/develop/packages/logger)
|
|
79
80
|
- [@thi.ng/strings](https://github.com/thi-ng/umbrella/tree/develop/packages/strings)
|
|
81
|
+
- [@thi.ng/text-format](https://github.com/thi-ng/umbrella/tree/develop/packages/text-format)
|
|
80
82
|
|
|
81
83
|
## API
|
|
82
84
|
|
package/api.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type { Fn, IDeref, IObjectOf } from "@thi.ng/api";
|
|
1
|
+
import type { Fn, Fn2, IDeref, IObjectOf } from "@thi.ng/api";
|
|
2
|
+
import type { ILogger } from "@thi.ng/logger";
|
|
3
|
+
import type { FormatPresets } from "@thi.ng/text-format";
|
|
2
4
|
export interface ArgSpecBase {
|
|
3
5
|
/**
|
|
4
6
|
* Shorthand for given arg/option
|
|
@@ -112,9 +114,13 @@ export interface UsageOpts {
|
|
|
112
114
|
/**
|
|
113
115
|
* If false, ANSI colors will be stripped from output.
|
|
114
116
|
*
|
|
117
|
+
* @remarks
|
|
118
|
+
* When using {@link cliApp}, the default for this value will depend on the
|
|
119
|
+
* `NO_COLOR` env var being set. See https://no-color.org/ for details.
|
|
120
|
+
*
|
|
115
121
|
* @defaultValue true
|
|
116
122
|
*/
|
|
117
|
-
color: Partial<ColorTheme> |
|
|
123
|
+
color: Partial<ColorTheme> | boolean;
|
|
118
124
|
/**
|
|
119
125
|
* If true (default), display argument default values. Nullish or false
|
|
120
126
|
* default values will never be shown.
|
|
@@ -172,4 +178,95 @@ export declare class Tuple<T> implements IDeref<T[]> {
|
|
|
172
178
|
constructor(value: T[]);
|
|
173
179
|
deref(): T[];
|
|
174
180
|
}
|
|
181
|
+
export interface CLIAppConfig<OPTS extends object, CTX extends CommandCtx<OPTS, OPTS> = CommandCtx<OPTS, OPTS>> {
|
|
182
|
+
/**
|
|
183
|
+
* App (CLI command) short name.
|
|
184
|
+
*/
|
|
185
|
+
name: string;
|
|
186
|
+
/**
|
|
187
|
+
* Shared args for all commands
|
|
188
|
+
*/
|
|
189
|
+
opts: Args<OPTS>;
|
|
190
|
+
/**
|
|
191
|
+
* Command spec registry
|
|
192
|
+
*/
|
|
193
|
+
commands: IObjectOf<Command<any, OPTS, CTX>>;
|
|
194
|
+
/**
|
|
195
|
+
* If true, the app will only use the single command entry in
|
|
196
|
+
* {@link CLIAppConfig.commands} and not expect the first CLI args to be a
|
|
197
|
+
* command name.
|
|
198
|
+
*/
|
|
199
|
+
single?: boolean;
|
|
200
|
+
/**
|
|
201
|
+
* Usage options, same as {@link UsageOpts}. Usage will be shown
|
|
202
|
+
* automatically in case of arg parse errors.
|
|
203
|
+
*/
|
|
204
|
+
usage: Partial<UsageOpts>;
|
|
205
|
+
/**
|
|
206
|
+
* Arguments vector to use for arg parsing. If omitted, uses `process.argv`
|
|
207
|
+
*/
|
|
208
|
+
argv?: string[];
|
|
209
|
+
/**
|
|
210
|
+
* {@link CLIAppConfig.argv} index to start parsing from.
|
|
211
|
+
*
|
|
212
|
+
* @defaultValue 2
|
|
213
|
+
*/
|
|
214
|
+
start?: number;
|
|
215
|
+
/**
|
|
216
|
+
* {@link CommandCtx} augmentation handler, i.e. an async function which
|
|
217
|
+
* will be called just before the actual command for additional setup/config
|
|
218
|
+
* purposes. The context object returned will be the one passed to the
|
|
219
|
+
* command.
|
|
220
|
+
*/
|
|
221
|
+
ctx: Fn2<CommandCtx<OPTS, OPTS>, Command<any, OPTS, CTX>, Promise<CTX>>;
|
|
222
|
+
/**
|
|
223
|
+
* Lifecycle hook. Function which will be called just after the actual
|
|
224
|
+
* command handler, e.g. for teardown purposes.
|
|
225
|
+
*/
|
|
226
|
+
post?: Fn2<CTX, Command<any, OPTS, CTX>, Promise<void>>;
|
|
227
|
+
}
|
|
228
|
+
export interface Command<OPTS extends BASE, BASE extends object, CTX extends CommandCtx<OPTS, BASE> = CommandCtx<OPTS, BASE>> {
|
|
229
|
+
/**
|
|
230
|
+
* Command description (short, single line)
|
|
231
|
+
*/
|
|
232
|
+
desc: string;
|
|
233
|
+
/**
|
|
234
|
+
* Command specific CLI arg specs
|
|
235
|
+
*/
|
|
236
|
+
opts: Args<Omit<OPTS, keyof BASE>>;
|
|
237
|
+
/**
|
|
238
|
+
* Number of required rest input value (after all parsed options). Leave
|
|
239
|
+
* unset to allow any number.
|
|
240
|
+
*/
|
|
241
|
+
inputs?: number;
|
|
242
|
+
/**
|
|
243
|
+
* Actual command function/implementation.
|
|
244
|
+
*/
|
|
245
|
+
fn: Fn<CTX, Promise<void>>;
|
|
246
|
+
}
|
|
247
|
+
export interface CommandCtx<OPTS extends BASE, BASE extends object> {
|
|
248
|
+
/**
|
|
249
|
+
* Logger to be used by all commands. By default uses a console logger with
|
|
250
|
+
* log level INFO. Can be customized via {@link CLIAppConfig.pre}.
|
|
251
|
+
*/
|
|
252
|
+
logger: ILogger;
|
|
253
|
+
/**
|
|
254
|
+
* `NO_COLOR`-aware text formatting presets. If color output is NOT disabled
|
|
255
|
+
* via the `NO_COLOR` env var, this defaults to
|
|
256
|
+
* [`PRESET_ANSI16`](https://github.com/thi-ng/umbrella/blob/develop/packages/text-format/README.md),
|
|
257
|
+
* otherwise `PRESET_NONE` (i.e. same API, but ignoring any color requests).
|
|
258
|
+
*
|
|
259
|
+
* See https://no-color.org for context.
|
|
260
|
+
*/
|
|
261
|
+
format: FormatPresets;
|
|
262
|
+
/**
|
|
263
|
+
* Parsed CLI args (according to provided command spec)
|
|
264
|
+
*/
|
|
265
|
+
opts: OPTS;
|
|
266
|
+
/**
|
|
267
|
+
* Array of remaining CLI args (after parsed options). Individual commands
|
|
268
|
+
* can specify the number of items required via {@link Command.inputs}.
|
|
269
|
+
*/
|
|
270
|
+
inputs: string[];
|
|
271
|
+
}
|
|
175
272
|
//# sourceMappingURL=api.d.ts.map
|
package/cli.d.ts
ADDED
package/cli.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
|
|
2
|
+
import { StreamLogger } from "@thi.ng/logger/stream";
|
|
3
|
+
import { padRight } from "@thi.ng/strings/pad-right";
|
|
4
|
+
import { PRESET_ANSI16, PRESET_NONE } from "@thi.ng/text-format/presets";
|
|
5
|
+
import { parse } from "./parse.js";
|
|
6
|
+
import { usage } from "./usage.js";
|
|
7
|
+
const cliApp = async (config) => {
|
|
8
|
+
const argv = config.argv || process.argv;
|
|
9
|
+
const isColor = !process.env.NO_COLOR;
|
|
10
|
+
const usageOpts = {
|
|
11
|
+
prefix: "",
|
|
12
|
+
color: isColor,
|
|
13
|
+
...config.usage
|
|
14
|
+
};
|
|
15
|
+
try {
|
|
16
|
+
let cmdID;
|
|
17
|
+
let cmd;
|
|
18
|
+
let start = config.start ?? 2;
|
|
19
|
+
if (config.single) {
|
|
20
|
+
cmdID = Object.keys(config.commands)[0];
|
|
21
|
+
if (!cmdID)
|
|
22
|
+
illegalArgs("no command provided");
|
|
23
|
+
cmd = config.commands[cmdID];
|
|
24
|
+
} else {
|
|
25
|
+
cmdID = argv[start];
|
|
26
|
+
cmd = config.commands[cmdID];
|
|
27
|
+
usageOpts.prefix += __descriptions(config.commands);
|
|
28
|
+
if (!cmd)
|
|
29
|
+
__usageAndExit(config, usageOpts);
|
|
30
|
+
start++;
|
|
31
|
+
}
|
|
32
|
+
let parsed;
|
|
33
|
+
try {
|
|
34
|
+
parsed = parse({ ...config.opts, ...cmd.opts }, argv, {
|
|
35
|
+
showUsage: true,
|
|
36
|
+
usageOpts,
|
|
37
|
+
start
|
|
38
|
+
});
|
|
39
|
+
} catch (_) {
|
|
40
|
+
}
|
|
41
|
+
if (!parsed)
|
|
42
|
+
process.exit(1);
|
|
43
|
+
if (cmd.inputs !== void 0 && cmd.inputs !== parsed.rest.length) {
|
|
44
|
+
process.stderr.write(`expected ${cmd.inputs || 0} input(s)
|
|
45
|
+
`);
|
|
46
|
+
__usageAndExit(config, usageOpts);
|
|
47
|
+
}
|
|
48
|
+
const ctx = await config.ctx(
|
|
49
|
+
{
|
|
50
|
+
logger: new StreamLogger(process.stderr, config.name, "INFO"),
|
|
51
|
+
format: isColor ? PRESET_ANSI16 : PRESET_NONE,
|
|
52
|
+
opts: parsed.result,
|
|
53
|
+
inputs: parsed.rest
|
|
54
|
+
},
|
|
55
|
+
cmd
|
|
56
|
+
);
|
|
57
|
+
await cmd.fn(ctx);
|
|
58
|
+
if (config.post)
|
|
59
|
+
await config.post(ctx, cmd);
|
|
60
|
+
} catch (e) {
|
|
61
|
+
process.stderr.write(e.message + "\n\n");
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const __usageAndExit = (config, usageOpts) => {
|
|
66
|
+
process.stderr.write(usage(config.opts, usageOpts));
|
|
67
|
+
process.exit(1);
|
|
68
|
+
};
|
|
69
|
+
const __descriptions = (commands) => [
|
|
70
|
+
"\nAvailable commands:\n",
|
|
71
|
+
...Object.keys(commands).map(
|
|
72
|
+
(x) => `${padRight(16)(x)}: ${commands[x].desc}`
|
|
73
|
+
),
|
|
74
|
+
"\n"
|
|
75
|
+
].join("\n");
|
|
76
|
+
export {
|
|
77
|
+
cliApp
|
|
78
|
+
};
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/args",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Declarative, functional & typechecked CLI argument/options parser, value coercions etc.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -35,10 +35,12 @@
|
|
|
35
35
|
"test": "bun test"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@thi.ng/api": "^8.9.
|
|
39
|
-
"@thi.ng/checks": "^3.4.
|
|
40
|
-
"@thi.ng/errors": "^2.4.
|
|
41
|
-
"@thi.ng/
|
|
38
|
+
"@thi.ng/api": "^8.9.13",
|
|
39
|
+
"@thi.ng/checks": "^3.4.13",
|
|
40
|
+
"@thi.ng/errors": "^2.4.7",
|
|
41
|
+
"@thi.ng/logger": "^2.1.0",
|
|
42
|
+
"@thi.ng/strings": "^3.7.4",
|
|
43
|
+
"@thi.ng/text-format": "^2.0.0"
|
|
42
44
|
},
|
|
43
45
|
"devDependencies": {
|
|
44
46
|
"@microsoft/api-extractor": "^7.38.3",
|
|
@@ -58,6 +60,7 @@
|
|
|
58
60
|
"declarative",
|
|
59
61
|
"functional",
|
|
60
62
|
"hex",
|
|
63
|
+
"logger",
|
|
61
64
|
"nodejs",
|
|
62
65
|
"parser",
|
|
63
66
|
"tuple",
|
|
@@ -68,7 +71,7 @@
|
|
|
68
71
|
"access": "public"
|
|
69
72
|
},
|
|
70
73
|
"engines": {
|
|
71
|
-
"node": ">=
|
|
74
|
+
"node": ">=18"
|
|
72
75
|
},
|
|
73
76
|
"files": [
|
|
74
77
|
"./*.js",
|
|
@@ -84,6 +87,9 @@
|
|
|
84
87
|
"./args": {
|
|
85
88
|
"default": "./args.js"
|
|
86
89
|
},
|
|
90
|
+
"./cli": {
|
|
91
|
+
"default": "./cli.js"
|
|
92
|
+
},
|
|
87
93
|
"./coerce": {
|
|
88
94
|
"default": "./coerce.js"
|
|
89
95
|
},
|
|
@@ -97,5 +103,5 @@
|
|
|
97
103
|
"thi.ng": {
|
|
98
104
|
"year": 2018
|
|
99
105
|
},
|
|
100
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "25a42a81fac8603a1e440a7aa8bc343276211ff4\n"
|
|
101
107
|
}
|
package/usage.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isPlainObject } from "@thi.ng/checks/is-plain-object";
|
|
1
2
|
import { lengthAnsi } from "@thi.ng/strings/ansi";
|
|
2
3
|
import { capitalize, kebab } from "@thi.ng/strings/case";
|
|
3
4
|
import { padRight } from "@thi.ng/strings/pad-right";
|
|
@@ -17,7 +18,7 @@ const usage = (specs, opts = {}) => {
|
|
|
17
18
|
groups: ["flags", "main"],
|
|
18
19
|
...opts
|
|
19
20
|
};
|
|
20
|
-
const theme = opts.color
|
|
21
|
+
const theme = isPlainObject(opts.color) ? { ...DEFAULT_THEME, ...opts.color } : opts.color ? DEFAULT_THEME : {};
|
|
21
22
|
const indent = repeat(" ", opts.paramWidth);
|
|
22
23
|
const format = (ids) => ids.map((id) => argUsage(id, specs[id], opts, theme, indent));
|
|
23
24
|
const sortedIDs = Object.keys(specs).sort();
|