mdat-plugin-cli-help 2.1.2 → 3.0.1

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 CHANGED
@@ -1,15 +1,16 @@
1
- import * as _$mdat from "mdat";
2
1
  import { ILogBasic, ILogLayer } from "lognow";
3
2
 
4
3
  //#region src/utilities/log.d.ts
5
4
  /**
6
- * Set the logger instance for the module.
7
- * Export this for library consumers to inject their own logger.
8
- * @param logger - Accepts either a LogLayer instance or a Console- or Stream-like log target
5
+ * Set the logger instance for the module. Export this for library consumers to
6
+ * inject their own logger.
7
+ *
8
+ * @param logger - Accepts either a LogLayer instance or a Console- or
9
+ * Stream-like log target
9
10
  */
10
- declare function setLogger(logger?: ILogBasic | ILogLayer): void;
11
+ declare function setLogger(logger?: ILogBasic | ILogLayer<unknown>): void;
11
12
  //#endregion
12
13
  //#region src/index.d.ts
13
- declare const _default: _$mdat.Config;
14
+ declare const _default: import("mdat").Config;
14
15
  //#endregion
15
16
  export { _default as default, setLogger };
package/dist/index.js CHANGED
@@ -126,9 +126,11 @@ let log = createLogger({
126
126
  name: "mdat-plugin-cli-help"
127
127
  });
128
128
  /**
129
- * Set the logger instance for the module.
130
- * Export this for library consumers to inject their own logger.
131
- * @param logger - Accepts either a LogLayer instance or a Console- or Stream-like log target
129
+ * Set the logger instance for the module. Export this for library consumers to
130
+ * inject their own logger.
131
+ *
132
+ * @param logger - Accepts either a LogLayer instance or a Console- or
133
+ * Stream-like log target
132
134
  */
133
135
  function setLogger(logger) {
134
136
  log = injectionHelper(logger);
@@ -379,28 +381,29 @@ var CliHelpToObjectVisitor$2 = class extends parser$2.getBaseCstVisitorConstruct
379
381
  };
380
382
  }
381
383
  /**
382
- * Clean a Commander default value: strip `(default: ...)` wrapper, env info, and quotes.
384
+ * Clean a Commander default value: strip `(default: ...)` wrapper, env info,
385
+ * and quotes.
383
386
  */
384
387
  cleanDefault(text) {
385
- if (text === void 0) return void 0;
388
+ if (text === void 0) return;
386
389
  let cleaned = text.replaceAll(/^\(default:\s*/g, "").replaceAll(/\)$/g, "").trim();
387
390
  cleaned = cleaned.replaceAll(/,\s*env:\s*\S+$/g, "").trim();
388
391
  cleaned = cleaned.replaceAll(/^["']|["']$/g, "");
389
392
  return cleaned || void 0;
390
393
  }
391
394
  getArray(context) {
392
- if (context === void 0) return void 0;
395
+ if (context === void 0) return;
393
396
  return context.map((entry) => entry.image);
394
397
  }
395
398
  getString(context) {
396
- if (context === void 0) return void 0;
399
+ if (context === void 0) return;
397
400
  return context.map((entry) => entry.image).join(" ");
398
401
  }
399
402
  /**
400
403
  * Trim leading/trailing whitespace from description text.
401
404
  */
402
405
  trimDescription(text) {
403
- if (text === void 0) return void 0;
406
+ if (text === void 0) return;
404
407
  return text.trim() || void 0;
405
408
  }
406
409
  };
@@ -441,8 +444,8 @@ function helpStringToObject$3(helpString) {
441
444
  * (typically 30+ spaces). The lexer's ROW_MODE exits on newline, so we must
442
445
  * unwrap these before tokenizing.
443
446
  *
444
- * Detection: a continuation line has 4+ leading spaces and does NOT start a
445
- * new row (which would be exactly 2 spaces + a non-space character).
447
+ * Detection: a continuation line has 4+ leading spaces and does NOT start a new
448
+ * row (which would be exactly 2 spaces + a non-space character).
446
449
  */
447
450
  const continuationLinePattern = /^ {4,}/;
448
451
  const newRowPattern = /^ {2}\S/;
@@ -647,11 +650,11 @@ var CliHelpToObjectVisitor$1 = class extends parser$1.getBaseCstVisitorConstruct
647
650
  return text.replaceAll(/^[\s[]*(default:)?\s*|[\s\]]*$/g, "");
648
651
  }
649
652
  getArray(context) {
650
- if (context === void 0) return void 0;
653
+ if (context === void 0) return;
651
654
  return context.map((entry) => entry.image);
652
655
  }
653
656
  getString(context, clean = false) {
654
- if (context === void 0) return void 0;
657
+ if (context === void 0) return;
655
658
  return context.map((entry) => clean ? this.clean(entry.image) : entry.image).join(" ");
656
659
  }
657
660
  };
@@ -950,11 +953,11 @@ var CliHelpToObjectVisitor = class extends parser.getBaseCstVisitorConstructor()
950
953
  return text.replaceAll(/^[\s[]*(default:)?\s*|[\s\]]*$/g, "");
951
954
  }
952
955
  getArray(context) {
953
- if (context === void 0) return void 0;
956
+ if (context === void 0) return;
954
957
  return context.map((entry) => entry.image);
955
958
  }
956
959
  getString(context, clean = false) {
957
- if (context === void 0) return void 0;
960
+ if (context === void 0) return;
958
961
  return context.map((entry) => clean ? this.clean(entry.image) : entry.image).join(" ");
959
962
  }
960
963
  positionalParentCommandToArguments(object) {
@@ -966,7 +969,7 @@ var CliHelpToObjectVisitor = class extends parser.getBaseCstVisitorConstructor()
966
969
  };
967
970
  }
968
971
  splitChoices(text) {
969
- if (text === void 0) return void 0;
972
+ if (text === void 0) return;
970
973
  return this.clean(text.replaceAll(/^\[choices:\s/g, "")).split(", ");
971
974
  }
972
975
  };
@@ -1073,12 +1076,15 @@ function helpStringToObject(helpString) {
1073
1076
  /**
1074
1077
  * Get help output from a CLI command and return it as markdown
1075
1078
  *
1076
- * @param cliCommand - The executable path (may contain spaces, e.g. on Windows)
1079
+ * @param command - The executable path (may contain spaces, e.g. on Windows)
1077
1080
  * @param helpFlag - The flag to pass to get help output
1078
1081
  * @param depth - Max recursion depth for subcommands
1082
+ * @param subcommands - Initial subcommand path to invoke before the help flag
1083
+ * (e.g. `['remote', 'add']` produces `command remote add --help`). Discovered
1084
+ * subcommands are appended to this path during recursion.
1079
1085
  */
1080
- async function getHelpMarkdown(cliCommand, helpFlag = "--help", depth) {
1081
- return getHelpMarkdownInternal(cliCommand, [], helpFlag, depth ?? Number.MAX_SAFE_INTEGER);
1086
+ async function getHelpMarkdown(command, helpFlag = "--help", depth, subcommands = []) {
1087
+ return getHelpMarkdownInternal(command, subcommands, helpFlag, depth ?? Number.MAX_SAFE_INTEGER);
1082
1088
  }
1083
1089
  async function getHelpMarkdownInternal(executable, subcommands, helpFlag, depth) {
1084
1090
  const rawHelpString = await getHelpString(executable, [...subcommands, helpFlag]);
@@ -1131,8 +1137,9 @@ async function getHelpString(command, args) {
1131
1137
  //#endregion
1132
1138
  //#region src/utilities/is-executable.ts
1133
1139
  /**
1134
- * This file is vendored with modification from https://github.com/sindresorhus/is-executable
1135
- * to work around a "[DEP0176] DeprecationWarning: fs.X_OK is deprecated, use fs.constants.X_OK instead"
1140
+ * This file is vendored with modification from
1141
+ * https://github.com/sindresorhus/is-executable to work around a "[DEP0176]
1142
+ * DeprecationWarning: fs.X_OK is deprecated, use fs.constants.X_OK instead"
1136
1143
  * error from Node.
1137
1144
  */
1138
1145
  const isWindows = process.platform === "win32";
@@ -1152,16 +1159,19 @@ async function isExecutable(filePath, strictExtensions = false) {
1152
1159
  //#region src/utilities/infer-command.ts
1153
1160
  /**
1154
1161
  * Accommodate missing or sloppy cli help command input
1155
- * @param cliCommand - Can be nothing, a command name on the path like `git`, or a path to an executable like `./bin/cli.js`
1162
+ *
1163
+ * @param command - Can be nothing, a command name on the path like `git`, or a
1164
+ * path to an executable like `./bin/cli.js`
1165
+ *
1156
1166
  * @returns The path to a verified executable
1157
1167
  * @throws {Error} If nothing can be inferred or resolved
1158
1168
  */
1159
- async function inferCommand(cliCommand) {
1160
- cliCommand ??= await getFirstBinFromPackage();
1161
- return ensureExecutable(cliCommand);
1169
+ async function inferCommand(command) {
1170
+ command ??= await getFirstBinFromPackage();
1171
+ return ensureExecutable(command);
1162
1172
  }
1163
1173
  function firstOf(value) {
1164
- if (value === void 0) return void 0;
1174
+ if (value === void 0) return;
1165
1175
  return Array.isArray(value) ? value[0] : value;
1166
1176
  }
1167
1177
  async function getFirstBinFromPackage() {
@@ -1176,7 +1186,7 @@ async function getFirstBinFromPackage() {
1176
1186
  return binPath;
1177
1187
  }
1178
1188
  }
1179
- throw new Error(`Could not infer which command to run for the <!-- cli-help --> rule. Please pass a "cliCommand" option to the expansion comment, e.g. <!-- cli-help({cliCommand: './dist/bin.js'}) -->`);
1189
+ throw new Error(`Could not infer which command to run for the <!-- cli-help --> rule. Please pass a "command" option to the expansion comment, e.g. <!-- cli-help({command: './dist/bin.js'}) -->`);
1180
1190
  }
1181
1191
  function looksLikePath(maybePath) {
1182
1192
  const parsed = path.parse(maybePath);
@@ -1202,13 +1212,17 @@ async function getCommandPathFromPackage(commandName) {
1202
1212
  }
1203
1213
  //#endregion
1204
1214
  //#region src/index.ts
1215
+ const WHITESPACE_REGEX = /\s+/;
1205
1216
  const cliHelpRule = defineConfig({ cli: { async content(options, _context) {
1206
1217
  const validOptions = z.object({
1207
- cliCommand: z.string().optional(),
1218
+ command: z.string().optional(),
1208
1219
  depth: z.number().optional(),
1209
- helpFlag: z.string().optional()
1210
- }).optional().parse(options);
1211
- return getHelpMarkdown(await inferCommand(validOptions?.cliCommand), validOptions?.helpFlag, validOptions?.depth);
1220
+ helpFlag: z.string().optional(),
1221
+ subcommand: z.string().optional()
1222
+ }).strict().optional().parse(options);
1223
+ const resolvedCommand = await inferCommand(validOptions?.command);
1224
+ const subcommands = validOptions?.subcommand?.split(WHITESPACE_REGEX).filter(Boolean) ?? [];
1225
+ return getHelpMarkdown(resolvedCommand, validOptions?.helpFlag, validOptions?.depth, subcommands);
1212
1226
  } } });
1213
1227
  var src_default = defineConfig({
1214
1228
  cli: cliHelpRule.cli,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdat-plugin-cli-help",
3
- "version": "2.1.2",
3
+ "version": "3.0.1",
4
4
  "description": "Mdat plugin to generate tabular help documentation for CLI tools in Markdown files.",
5
5
  "keywords": [
6
6
  "markdown",
@@ -38,44 +38,39 @@
38
38
  "@types/which": "^3.0.4",
39
39
  "chevrotain": "^12.0.0",
40
40
  "execa": "^9.6.1",
41
- "lognow": "^0.6.1",
42
- "type-fest": "^5.5.0",
43
- "which": "^6.0.1",
44
- "zod": "^4.3.6"
41
+ "lognow": "^0.6.2",
42
+ "type-fest": "^5.6.0",
43
+ "which": "^7.0.0",
44
+ "zod": "^4.4.3"
45
45
  },
46
46
  "devDependencies": {
47
- "@kitschpatrol/shared-config": "^7.1.0",
48
- "@types/node": "~22.17.2",
47
+ "@kitschpatrol/shared-config": "^7.6.0",
48
+ "@types/node": "~22.19.19",
49
49
  "@types/yargs": "^17.0.35",
50
- "bumpp": "^11.0.1",
50
+ "bumpp": "^11.1.0",
51
51
  "commander": "^14.0.3",
52
- "mdat": "^2.2.1",
52
+ "mdat": "^2.3.4",
53
53
  "meow": "^14.1.0",
54
- "tsdown": "^0.21.7",
54
+ "shx": "^0.4.0",
55
+ "tsdown": "^0.22.0",
55
56
  "typescript": "~5.9.3",
56
- "vitest": "^4.1.3",
57
+ "vitest": "^4.1.6",
57
58
  "yargs": "^18.0.0"
58
59
  },
59
60
  "peerDependencies": {
60
61
  "mdat": "^2.0.0"
61
62
  },
62
63
  "engines": {
63
- "node": ">=22.17.0"
64
- },
65
- "devEngines": {
66
- "runtime": {
67
- "name": "node",
68
- "version": ">=22.21.0"
69
- }
64
+ "node": ">=22.22.2"
70
65
  },
71
66
  "scripts": {
72
67
  "bench": "vitest bench --run --no-file-parallelism --compare test/benchmarks/baseline.json",
73
68
  "bench:baseline": "vitest bench --run --no-file-parallelism --outputJson test/benchmarks/baseline.json",
74
69
  "build": "tsdown --no-fixed-extension --tsconfig tsconfig.build.json",
75
- "clean": "git rm -f pnpm-lock.yaml ; git clean -fdX",
70
+ "clean": "shx rm -f pnpm-lock.yaml && git clean -fdX -e !.claude/",
76
71
  "fix": "ksc fix",
77
72
  "lint": "ksc lint",
78
- "release": "bumpp --commit 'Release: %s' && pnpm run build && NPM_AUTH_TOKEN=$(op read 'op://Personal/npm/token') && pnpm publish",
73
+ "release": "bumpp --commit 'Release: %s' && pnpm build && NPM_AUTH_TOKEN=$(op read 'op://Personal/npm/token') pnpm publish",
79
74
  "test": "vitest run --no-file-parallelism"
80
75
  }
81
76
  }
package/readme.md CHANGED
@@ -7,7 +7,7 @@
7
7
  <!-- badges -->
8
8
 
9
9
  [![NPM Package mdat-plugin-cli-help](https://img.shields.io/npm/v/mdat-plugin-cli-help.svg)](https://npmjs.com/package/mdat-plugin-cli-help)
10
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/license/mit/)
11
11
  [![CI](https://github.com/kitschpatrol/mdat-plugin-cli-help/actions/workflows/ci.yml/badge.svg)](https://github.com/kitschpatrol/mdat-plugin-cli-help/actions/workflows/ci.yml)
12
12
 
13
13
  <!-- /badges -->
@@ -58,13 +58,13 @@ export default defineConfig({
58
58
  Assuming you have an executable with a `--help` flag on your path or in your project's scope:
59
59
 
60
60
  ```markdown
61
- <!-- cli-help({ cliCommand: "mdat", depth: 1 }) -->
61
+ <!-- cli-help({ command: "mdat", depth: 1 }) -->
62
62
  ```
63
63
 
64
64
  Then run the `mdat` CLI command on your Markdown file to expand the rule and embed the tabular help output:
65
65
 
66
66
  ````markdown
67
- <!-- cli-help({ cliCommand: "mdat", depth: 1 }) -->
67
+ <!-- cli-help({ command: "mdat", depth: 1 }) -->
68
68
 
69
69
  #### Command: `mdat`
70
70
 
@@ -105,12 +105,20 @@ mdat [command]
105
105
  <!-- /cli-help -->
106
106
  ````
107
107
 
108
+ To generate help for a specific subcommand, pass `subcommand`. Whitespace-separated for nested paths:
109
+
110
+ ```markdown
111
+ <!-- cli-help({ command: "mdat", subcommand: "readme", depth: 1 }) -->
112
+ ```
113
+
114
+ This invokes `mdat readme --help`. Discovered sub-subcommands are appended to this path during recursion.
115
+
108
116
  The command is also aliased under the `<!-- cli -->` keyword.
109
117
 
110
118
  This would have equivalent output to the above:
111
119
 
112
120
  ```markdown
113
- <!-- cli({ cliCommand: "mdat", depth: 1 }) -->
121
+ <!-- cli({ command: "mdat", depth: 1 }) -->
114
122
  ```
115
123
 
116
124
  If you embed the rule without any arguments, it will look for the binary file listed in the closest `package.json` file and run it with `--help`. This is what you want if you're documenting a package's CLI options in its readme.md file:
@@ -157,13 +165,17 @@ Currently, the parser implementation lives in this repository because I really o
157
165
 
158
166
  ## Maintainers
159
167
 
160
- [@kitschpatrol](https://github.com/kitschpatrol)
168
+ [kitschpatrol](https://github.com/kitschpatrol)
161
169
 
162
170
  <!-- contributing -->
163
171
 
164
172
  ## Contributing
165
173
 
166
- [Issues](https://github.com/kitschpatrol/mdat-plugin-cli-help/issues) and pull requests are welcome.
174
+ [Issues](https://github.com/kitschpatrol/mdat-plugin-cli-help/issues) are welcome and appreciated.
175
+
176
+ Please open an issue to discuss changes before submitting a pull request. Unsolicited PRs (especially AI-generated ones) are unlikely to be merged.
177
+
178
+ This repository uses [@kitschpatrol/shared-config](https://github.com/kitschpatrol/shared-config) (via its `ksc` CLI) for linting and formatting, plus [MDAT](https://github.com/kitschpatrol/mdat) for readme placeholder expansion.
167
179
 
168
180
  <!-- /contributing -->
169
181
 
@@ -171,6 +183,6 @@ Currently, the parser implementation lives in this repository because I really o
171
183
 
172
184
  ## License
173
185
 
174
- [MIT](license.txt) © Eric Mika
186
+ [MIT](license.txt) © [Eric Mika](https://ericmika.com)
175
187
 
176
188
  <!-- /license -->