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 +7 -6
- package/dist/index.js +44 -30
- package/package.json +15 -20
- package/readme.md +19 -7
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
|
-
*
|
|
8
|
-
*
|
|
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:
|
|
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
|
-
*
|
|
131
|
-
*
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
*
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
1081
|
-
return getHelpMarkdownInternal(
|
|
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
|
|
1135
|
-
* to work around a "[DEP0176]
|
|
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
|
-
*
|
|
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(
|
|
1160
|
-
|
|
1161
|
-
return ensureExecutable(
|
|
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
|
|
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 "
|
|
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
|
-
|
|
1218
|
+
command: z.string().optional(),
|
|
1208
1219
|
depth: z.number().optional(),
|
|
1209
|
-
helpFlag: z.string().optional()
|
|
1210
|
-
|
|
1211
|
-
|
|
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": "
|
|
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.
|
|
42
|
-
"type-fest": "^5.
|
|
43
|
-
"which": "^
|
|
44
|
-
"zod": "^4.3
|
|
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.
|
|
48
|
-
"@types/node": "~22.
|
|
47
|
+
"@kitschpatrol/shared-config": "^7.6.0",
|
|
48
|
+
"@types/node": "~22.19.19",
|
|
49
49
|
"@types/yargs": "^17.0.35",
|
|
50
|
-
"bumpp": "^11.0
|
|
50
|
+
"bumpp": "^11.1.0",
|
|
51
51
|
"commander": "^14.0.3",
|
|
52
|
-
"mdat": "^2.
|
|
52
|
+
"mdat": "^2.3.4",
|
|
53
53
|
"meow": "^14.1.0",
|
|
54
|
-
"
|
|
54
|
+
"shx": "^0.4.0",
|
|
55
|
+
"tsdown": "^0.22.0",
|
|
55
56
|
"typescript": "~5.9.3",
|
|
56
|
-
"vitest": "^4.1.
|
|
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.
|
|
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": "
|
|
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
|
|
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
|
[](https://npmjs.com/package/mdat-plugin-cli-help)
|
|
10
|
-
[](https://opensource.org/
|
|
10
|
+
[](https://opensource.org/license/mit/)
|
|
11
11
|
[](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({
|
|
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({
|
|
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({
|
|
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
|
-
[
|
|
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)
|
|
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 -->
|