mdat-plugin-cli-help 1.0.8 → 2.0.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/dist/index.d.ts +12 -10
- package/dist/index.js +44 -39
- package/package.json +9 -11
- package/readme.md +8 -11
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import * as _$
|
|
1
|
+
import * as _$mdat from "mdat";
|
|
2
|
+
import { ILogBasic, ILogLayer } from "lognow";
|
|
2
3
|
|
|
4
|
+
//#region src/utilities/log.d.ts
|
|
5
|
+
/**
|
|
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
|
|
9
|
+
*/
|
|
10
|
+
declare function setLogger(logger?: ILogBasic | ILogLayer): void;
|
|
11
|
+
//#endregion
|
|
3
12
|
//#region src/index.d.ts
|
|
4
|
-
declare const _default:
|
|
5
|
-
cli: {
|
|
6
|
-
content(options?: _$type_fest0.JsonValue | undefined): Promise<string>;
|
|
7
|
-
};
|
|
8
|
-
'cli-help': {
|
|
9
|
-
content(options?: _$type_fest0.JsonValue | undefined): Promise<string>;
|
|
10
|
-
};
|
|
11
|
-
};
|
|
13
|
+
declare const _default: _$mdat.Config;
|
|
12
14
|
//#endregion
|
|
13
|
-
export { _default as default };
|
|
15
|
+
export { _default as default, setLogger };
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
+
import { defineConfig, getContextMetadata } from "mdat";
|
|
1
2
|
import { z } from "zod";
|
|
2
3
|
import { execaCommand } from "execa";
|
|
3
|
-
import {
|
|
4
|
+
import { createLogger, injectionHelper } from "lognow";
|
|
4
5
|
import { CstParser, Lexer, createToken } from "chevrotain";
|
|
5
6
|
import path from "node:path";
|
|
6
7
|
import which from "which";
|
|
7
|
-
import { loadConfig } from "mdat";
|
|
8
|
-
import { readPackage } from "read-pkg";
|
|
9
8
|
import fs from "node:fs/promises";
|
|
10
9
|
import process from "node:process";
|
|
11
10
|
//#region src/utilities/help-object-to-markdown.ts
|
|
@@ -118,6 +117,23 @@ function findEmptyColumns(rows) {
|
|
|
118
117
|
return emptyColumnsIndexes;
|
|
119
118
|
}
|
|
120
119
|
//#endregion
|
|
120
|
+
//#region src/utilities/log.ts
|
|
121
|
+
/**
|
|
122
|
+
* The default logger instance for the library.
|
|
123
|
+
*/
|
|
124
|
+
let log = createLogger({
|
|
125
|
+
logToConsole: { showTime: false },
|
|
126
|
+
name: "mdat-plugin-cli-help"
|
|
127
|
+
});
|
|
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
|
|
132
|
+
*/
|
|
133
|
+
function setLogger(logger) {
|
|
134
|
+
log = injectionHelper(logger);
|
|
135
|
+
}
|
|
136
|
+
//#endregion
|
|
121
137
|
//#region src/utilities/parsers/meow.ts
|
|
122
138
|
const flag$1 = createToken({
|
|
123
139
|
name: "flag",
|
|
@@ -690,11 +706,11 @@ function getCommandParts(wholeCommand) {
|
|
|
690
706
|
*/
|
|
691
707
|
function helpStringToObject(helpString) {
|
|
692
708
|
for (const [parserName, helpStringToObjectFunction] of Object.entries(parsers_default)) {
|
|
693
|
-
log.
|
|
709
|
+
log.debug(`Trying to parse help string with ${parserName} parser...`);
|
|
694
710
|
try {
|
|
695
711
|
return helpStringToObjectFunction(helpString);
|
|
696
712
|
} catch (error) {
|
|
697
|
-
if (error instanceof Error) log.
|
|
713
|
+
if (error instanceof Error) log.error(`Error in "${parserName}" parser: ${String(error)}`);
|
|
698
714
|
continue;
|
|
699
715
|
}
|
|
700
716
|
}
|
|
@@ -716,7 +732,7 @@ async function getHelpMarkdown(cliCommand, helpFlag = "--help", depth) {
|
|
|
716
732
|
}
|
|
717
733
|
async function renderHelpMarkdownObject(cliCommand, helpFlag, depth, programInfo) {
|
|
718
734
|
if (depth <= 0) {
|
|
719
|
-
log.
|
|
735
|
+
log.warn(`Max CLI command help depth reached, stopping recursion`);
|
|
720
736
|
return "";
|
|
721
737
|
}
|
|
722
738
|
let markdown = helpObjectToMarkdown(programInfo, depth);
|
|
@@ -753,24 +769,6 @@ async function getHelpString(resolvedCommand) {
|
|
|
753
769
|
return rawHelpString;
|
|
754
770
|
}
|
|
755
771
|
//#endregion
|
|
756
|
-
//#region src/utilities/get-package-json.ts
|
|
757
|
-
let packageJson;
|
|
758
|
-
/**
|
|
759
|
-
* Convenience function for rules
|
|
760
|
-
* Load as package json only as needed, memoize
|
|
761
|
-
* Rules could call this themselves, but this is more convenient and efficient
|
|
762
|
-
* @throws {Error} If no package.json is found
|
|
763
|
-
*/
|
|
764
|
-
async function getPackageJson() {
|
|
765
|
-
const { packageFile } = await loadConfig();
|
|
766
|
-
if (packageFile === void 0) throw new Error("No packageFile found or set in config");
|
|
767
|
-
packageJson ??= await readPackage({ cwd: path.dirname(packageFile) });
|
|
768
|
-
return {
|
|
769
|
-
packageJson,
|
|
770
|
-
packagePath: packageFile
|
|
771
|
-
};
|
|
772
|
-
}
|
|
773
|
-
//#endregion
|
|
774
772
|
//#region src/utilities/is-executable.ts
|
|
775
773
|
/**
|
|
776
774
|
* This file is vendored with modification from https://github.com/sindresorhus/is-executable
|
|
@@ -802,17 +800,23 @@ async function inferCommand(cliCommand) {
|
|
|
802
800
|
cliCommand ??= await getFirstBinFromPackage();
|
|
803
801
|
return ensureExecutable(cliCommand);
|
|
804
802
|
}
|
|
803
|
+
function firstOf(value) {
|
|
804
|
+
if (value === void 0) return void 0;
|
|
805
|
+
return Array.isArray(value) ? value[0] : value;
|
|
806
|
+
}
|
|
805
807
|
async function getFirstBinFromPackage() {
|
|
806
|
-
const {
|
|
807
|
-
const
|
|
808
|
-
if (
|
|
809
|
-
const
|
|
808
|
+
const { nodePackageJson } = await getContextMetadata();
|
|
809
|
+
const nodePackage = firstOf(nodePackageJson);
|
|
810
|
+
if (nodePackage?.source !== void 0 && nodePackage.data.bin !== void 0) {
|
|
811
|
+
const packageDirectory = path.dirname(nodePackage.source);
|
|
812
|
+
const packageBin = nodePackage.data.bin;
|
|
813
|
+
const binPath = typeof packageBin === "string" ? path.resolve(packageDirectory, packageBin) : path.resolve(packageDirectory, String(Object.values(packageBin).at(0)));
|
|
810
814
|
if (looksLikePath(binPath)) {
|
|
811
|
-
log.
|
|
815
|
+
log.debug(`Inferred <!-- cli-help --> command to run from package.json: ${binPath}`);
|
|
812
816
|
return binPath;
|
|
813
817
|
}
|
|
814
818
|
}
|
|
815
|
-
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
|
|
819
|
+
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'}) -->`);
|
|
816
820
|
}
|
|
817
821
|
function looksLikePath(maybePath) {
|
|
818
822
|
const parsed = path.parse(maybePath);
|
|
@@ -825,25 +829,26 @@ async function ensureExecutable(filePath) {
|
|
|
825
829
|
throw new Error(`The cli-help rule noticed that "${resolvedPath}" is not executable.`);
|
|
826
830
|
}
|
|
827
831
|
async function getCommandPathFromPackage(commandName) {
|
|
828
|
-
const {
|
|
829
|
-
|
|
832
|
+
const { nodePackageJson } = await getContextMetadata();
|
|
833
|
+
const binObject = firstOf(nodePackageJson)?.data.bin;
|
|
834
|
+
if (binObject !== void 0 && typeof binObject !== "string") for (const [key, value] of Object.entries(binObject)) {
|
|
830
835
|
if (key === commandName) return value;
|
|
831
836
|
if (path.normalize(value) === path.normalize(commandName)) return value;
|
|
832
837
|
}
|
|
833
838
|
}
|
|
834
839
|
//#endregion
|
|
835
840
|
//#region src/index.ts
|
|
836
|
-
const cliHelpRule = { async content(options) {
|
|
841
|
+
const cliHelpRule = defineConfig({ cli: { async content(options, _context) {
|
|
837
842
|
const validOptions = z.object({
|
|
838
843
|
cliCommand: z.string().optional(),
|
|
839
844
|
depth: z.number().optional(),
|
|
840
845
|
helpFlag: z.string().optional()
|
|
841
846
|
}).optional().parse(options);
|
|
842
847
|
return getHelpMarkdown(await inferCommand(validOptions?.cliCommand), validOptions?.helpFlag, validOptions?.depth);
|
|
843
|
-
} };
|
|
844
|
-
var src_default = {
|
|
845
|
-
cli: cliHelpRule,
|
|
846
|
-
"cli-help": cliHelpRule
|
|
847
|
-
};
|
|
848
|
+
} } });
|
|
849
|
+
var src_default = defineConfig({
|
|
850
|
+
cli: cliHelpRule.cli,
|
|
851
|
+
"cli-help": cliHelpRule.cli
|
|
852
|
+
});
|
|
848
853
|
//#endregion
|
|
849
|
-
export { src_default as default };
|
|
854
|
+
export { src_default as default, setLogger };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mdat-plugin-cli-help",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Mdat plugin to generate tabular help documentation for CLI tools in Markdown files.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"markdown",
|
|
@@ -36,30 +36,28 @@
|
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@types/which": "^3.0.4",
|
|
39
|
-
"chevrotain": "^
|
|
39
|
+
"chevrotain": "^12.0.0",
|
|
40
40
|
"execa": "^9.6.1",
|
|
41
|
-
"
|
|
41
|
+
"lognow": "^0.5.2",
|
|
42
42
|
"type-fest": "^5.5.0",
|
|
43
43
|
"which": "^6.0.1",
|
|
44
|
-
"zod": "^3.
|
|
44
|
+
"zod": "^4.3.6"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@kitschpatrol/shared-config": "^6.
|
|
48
|
-
"@types/node": "~
|
|
47
|
+
"@kitschpatrol/shared-config": "^6.2.0",
|
|
48
|
+
"@types/node": "~22.17.2",
|
|
49
49
|
"bumpp": "^11.0.1",
|
|
50
|
-
"mdat": "^
|
|
50
|
+
"mdat": "^2.0.0",
|
|
51
51
|
"meow": "^14.1.0",
|
|
52
|
-
"remark-mdat": "^1.2.5",
|
|
53
52
|
"tsdown": "^0.21.7",
|
|
54
53
|
"typescript": "~5.9.3",
|
|
55
54
|
"vitest": "^4.1.2"
|
|
56
55
|
},
|
|
57
56
|
"peerDependencies": {
|
|
58
|
-
"mdat": "^
|
|
59
|
-
"remark-mdat": "^1.1.0"
|
|
57
|
+
"mdat": "^2.0.0"
|
|
60
58
|
},
|
|
61
59
|
"engines": {
|
|
62
|
-
"node": ">=
|
|
60
|
+
"node": ">=22.17.0"
|
|
63
61
|
},
|
|
64
62
|
"devEngines": {
|
|
65
63
|
"runtime": {
|
package/readme.md
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
<!--+ Warning: Content inside HTML comment blocks was generated by mdat and may be overwritten. +-->
|
|
2
|
-
|
|
3
1
|
<!-- title -->
|
|
4
2
|
|
|
5
3
|
# mdat-plugin-cli-help
|
|
@@ -10,6 +8,7 @@
|
|
|
10
8
|
|
|
11
9
|
[](https://npmjs.com/package/mdat-plugin-cli-help)
|
|
12
10
|
[](https://opensource.org/licenses/MIT)
|
|
11
|
+
[](https://github.com/kitschpatrol/mdat-plugin-cli-help/actions/workflows/ci.yml)
|
|
13
12
|
|
|
14
13
|
<!-- /badges -->
|
|
15
14
|
|
|
@@ -46,14 +45,12 @@ pnpm add -D mdat-plugin-cli-help
|
|
|
46
45
|
Register the plugin in your mdat config file, e.g. `mdat.config.ts`:
|
|
47
46
|
|
|
48
47
|
```ts
|
|
49
|
-
import
|
|
48
|
+
import { defineConfig } from 'mdat'
|
|
50
49
|
import cliHelp from 'mdat-plugin-cli-help'
|
|
51
50
|
|
|
52
|
-
export default {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
},
|
|
56
|
-
} satisfies Config
|
|
51
|
+
export default defineConfig({
|
|
52
|
+
...cliHelp,
|
|
53
|
+
})
|
|
57
54
|
```
|
|
58
55
|
|
|
59
56
|
## Usage
|
|
@@ -61,13 +58,13 @@ export default {
|
|
|
61
58
|
Assuming you have an executable with a `--help` flag on your path or in your project's scope:
|
|
62
59
|
|
|
63
60
|
```markdown
|
|
64
|
-
<!-- cli-help
|
|
61
|
+
<!-- cli-help({ cliCommand: "mdat", depth: 1 }) -->
|
|
65
62
|
```
|
|
66
63
|
|
|
67
64
|
Then run the `mdat` CLI command on your Markdown file to expand the rule and embed the tabular help output:
|
|
68
65
|
|
|
69
66
|
````markdown
|
|
70
|
-
<!-- cli-help
|
|
67
|
+
<!-- cli-help({ cliCommand: "mdat", depth: 1 }) -->
|
|
71
68
|
|
|
72
69
|
#### Command: `mdat`
|
|
73
70
|
|
|
@@ -113,7 +110,7 @@ The command is also aliased under the `<!-- cli -->` keyword.
|
|
|
113
110
|
This would have equivalent output to the above:
|
|
114
111
|
|
|
115
112
|
```markdown
|
|
116
|
-
<!-- cli
|
|
113
|
+
<!-- cli({ cliCommand: "mdat", depth: 1 }) -->
|
|
117
114
|
```
|
|
118
115
|
|
|
119
116
|
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:
|