@thi.ng/args 2.3.71 → 2.4.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2025-06-09T17:24:08Z
3
+ - **Last updated**: 2025-06-27T11:09:55Z
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.
@@ -11,6 +11,13 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
11
11
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
12
12
  and/or version bumps of transitive dependencies.
13
13
 
14
+ ## [2.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/args@2.4.0) (2025-06-27)
15
+
16
+ #### 🚀 Features
17
+
18
+ - add word-wrapping for command descriptions ([46a73a3](https://github.com/thi-ng/umbrella/commit/46a73a3))
19
+ - refactor usage internals for better re-use
20
+
14
21
  ### [2.3.34](https://github.com/thi-ng/umbrella/tree/@thi.ng/args@2.3.34) (2024-06-21)
15
22
 
16
23
  #### ♻️ Refactoring
package/README.md CHANGED
@@ -27,7 +27,7 @@
27
27
 
28
28
  ## About
29
29
 
30
- Declarative, functional & typechecked CLI argument/options parser, value coercions etc..
30
+ Declarative, functional CLI argument/options parser, value coercions, sub-commands etc..
31
31
 
32
32
  Includes built-in support for the following argument types (of course custom arg types are supported too):
33
33
 
@@ -71,7 +71,7 @@ For Node.js REPL:
71
71
  const args = await import("@thi.ng/args");
72
72
  ```
73
73
 
74
- Package sizes (brotli'd, pre-treeshake): ESM: 2.75 KB
74
+ Package sizes (brotli'd, pre-treeshake): ESM: 2.80 KB
75
75
 
76
76
  ## Dependencies
77
77
 
@@ -243,7 +243,7 @@ can be disabled (see
243
243
  [`UsageOpts`](https://docs.thi.ng/umbrella/args/interfaces/UsageOpts.html)).
244
244
 
245
245
  ```text
246
- ts-node index.ts --help
246
+ bun index.ts --help
247
247
 
248
248
  -f, --force Force operation
249
249
 
@@ -266,7 +266,7 @@ represented in the result. Parsing stops with the first non-argument value (here
266
266
  result object.
267
267
 
268
268
  ```bash
269
- ts-node index.ts \
269
+ bun index.ts \
270
270
  -f -t png --bg ff00ff --size 640x480 \
271
271
  -D author=toxi -D date=2018-03-24 \
272
272
  --xtra '{"foo": [23]}' \
package/api.d.ts CHANGED
@@ -227,7 +227,7 @@ export interface CLIAppConfig<OPTS extends object, CTX extends CommandCtx<OPTS,
227
227
  }
228
228
  export interface Command<OPTS extends BASE, BASE extends object, CTX extends CommandCtx<OPTS, BASE> = CommandCtx<OPTS, BASE>> {
229
229
  /**
230
- * Command description (short, single line)
230
+ * Command description (any length, will be word wrapped if needed)
231
231
  */
232
232
  desc: string;
233
233
  /**
package/cli.js CHANGED
@@ -3,7 +3,7 @@ import { StreamLogger } from "@thi.ng/logger/stream";
3
3
  import { padRight } from "@thi.ng/strings/pad-right";
4
4
  import { PRESET_ANSI16, PRESET_NONE } from "@thi.ng/text-format/presets";
5
5
  import { parse } from "./parse.js";
6
- import { usage } from "./usage.js";
6
+ import { __wrapWithIndent, usage } from "./usage.js";
7
7
  const cliApp = async (config) => {
8
8
  const argv = config.argv || process.argv;
9
9
  const isColor = !process.env.NO_COLOR;
@@ -23,7 +23,10 @@ const cliApp = async (config) => {
23
23
  } else {
24
24
  cmdID = argv[start];
25
25
  cmd = config.commands[cmdID];
26
- usageOpts.prefix += __descriptions(config.commands);
26
+ usageOpts.prefix += __descriptions(
27
+ config.commands,
28
+ config.usage.lineWidth
29
+ );
27
30
  if (!cmd) __usageAndExit(config, usageOpts);
28
31
  start++;
29
32
  }
@@ -62,13 +65,21 @@ const __usageAndExit = (config, usageOpts) => {
62
65
  process.stderr.write(usage(config.opts, usageOpts));
63
66
  process.exit(1);
64
67
  };
65
- const __descriptions = (commands) => [
66
- "\nAvailable commands:\n",
67
- ...Object.keys(commands).map(
68
- (x) => `${padRight(16)(x)}: ${commands[x].desc}`
69
- ),
70
- "\n"
71
- ].join("\n");
68
+ const __descriptions = (commands, lineWidth = 80) => {
69
+ const names = Object.keys(commands);
70
+ const maxLength = Math.max(...names.map((x) => x.length));
71
+ return [
72
+ "\nAvailable commands:\n",
73
+ ...names.map(
74
+ (x) => `${padRight(maxLength)(x)} : ${__wrapWithIndent(
75
+ commands[x].desc,
76
+ maxLength + 3,
77
+ lineWidth
78
+ )}`
79
+ ),
80
+ "\n"
81
+ ].join("\n");
82
+ };
72
83
  export {
73
84
  cliApp
74
85
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@thi.ng/args",
3
- "version": "2.3.71",
4
- "description": "Declarative, functional & typechecked CLI argument/options parser, value coercions etc.",
3
+ "version": "2.4.0",
4
+ "description": "Declarative, functional CLI argument/options parser, value coercions, sub-commands etc.",
5
5
  "type": "module",
6
6
  "module": "./index.js",
7
7
  "typings": "./index.d.ts",
@@ -107,5 +107,5 @@
107
107
  "tag": "cli",
108
108
  "year": 2018
109
109
  },
110
- "gitHead": "b076434a497b291ad33e81b1a15f6a71e2c82cc2\n"
110
+ "gitHead": "7fa97c11435e6f616bac62b731050784694ee08d\n"
111
111
  }
package/usage.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import type { IObjectOf } from "@thi.ng/api";
2
2
  import { type Args, type UsageOpts } from "./api.js";
3
3
  export declare const usage: <T extends IObjectOf<any>>(specs: Args<T>, opts?: Partial<UsageOpts>) => string;
4
+ /** @internal */
5
+ export declare const __wrapWithIndent: (body: string, indent: number, width: number) => string;
4
6
  //# sourceMappingURL=usage.d.ts.map
package/usage.js CHANGED
@@ -19,8 +19,9 @@ const usage = (specs, opts = {}) => {
19
19
  ...opts
20
20
  };
21
21
  const theme = isPlainObject(opts.color) ? { ...DEFAULT_THEME, ...opts.color } : opts.color ? DEFAULT_THEME : {};
22
- const indent = repeat(" ", opts.paramWidth);
23
- const format = (ids) => ids.map((id) => __argUsage(id, specs[id], opts, theme, indent));
22
+ const format = (ids) => ids.map(
23
+ (id) => __argUsage(id, specs[id], opts, theme, opts.paramWidth)
24
+ );
24
25
  const sortedIDs = Object.keys(specs).sort();
25
26
  const groups = opts.groups ? opts.groups.map(
26
27
  (gid) => [
@@ -51,7 +52,7 @@ const __argUsage = (id, spec, opts, theme, indent) => {
51
52
  isRequired && prefixes.push("required");
52
53
  spec.multi && prefixes.push("multiple");
53
54
  const body = __argPrefix(prefixes, theme, isRequired) + (spec.desc || "") + __argDefault(spec, opts, theme);
54
- return padRight(opts.paramWidth)(params, lengthAnsi(params)) + __wrap(body, opts.lineWidth - opts.paramWidth).map((l, i) => i > 0 ? indent + l : l).join("\n");
55
+ return padRight(opts.paramWidth)(params, lengthAnsi(params)) + __wrapWithIndent(body, indent, opts.lineWidth);
55
56
  };
56
57
  const __argHint = (spec, theme) => spec.hint ? __ansi(" " + spec.hint, theme.hint) : "";
57
58
  const __argAlias = (spec, theme, hint) => spec.alias ? `${__ansi("-" + spec.alias, theme.param)}${hint}, ` : "";
@@ -71,6 +72,11 @@ const __wrap = (str, width) => str ? wordWrapLines(str, {
71
72
  splitter: SPLIT_ANSI,
72
73
  hard: false
73
74
  }) : [];
75
+ const __wrapWithIndent = (body, indent, width) => {
76
+ const prefix = repeat(" ", indent);
77
+ return __wrap(body, width - indent).map((l, i) => i ? prefix + l : l).join("\n");
78
+ };
74
79
  export {
80
+ __wrapWithIndent,
75
81
  usage
76
82
  };