mdat-plugin-cli-help 1.0.7 → 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 -50
- package/package.json +15 -16
- 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,14 +1,12 @@
|
|
|
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
|
-
|
|
12
10
|
//#region src/utilities/help-object-to-markdown.ts
|
|
13
11
|
/**
|
|
14
12
|
* Converts a ProgramInfo object extracted by one of the help parsers into a big
|
|
@@ -118,7 +116,23 @@ function findEmptyColumns(rows) {
|
|
|
118
116
|
}
|
|
119
117
|
return emptyColumnsIndexes;
|
|
120
118
|
}
|
|
121
|
-
|
|
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
|
+
}
|
|
122
136
|
//#endregion
|
|
123
137
|
//#region src/utilities/parsers/meow.ts
|
|
124
138
|
const flag$1 = createToken({
|
|
@@ -342,7 +356,6 @@ function helpStringToObject$2(helpString) {
|
|
|
342
356
|
if (programInfo === void 0) throw new Error("Could not parse help string");
|
|
343
357
|
return programInfo;
|
|
344
358
|
}
|
|
345
|
-
|
|
346
359
|
//#endregion
|
|
347
360
|
//#region src/utilities/parsers/yargs.ts
|
|
348
361
|
const flag = createToken({
|
|
@@ -658,7 +671,6 @@ function helpStringToObject$1(helpString) {
|
|
|
658
671
|
if (programInfo === void 0) throw new Error("Could not parse help string");
|
|
659
672
|
return programInfo;
|
|
660
673
|
}
|
|
661
|
-
|
|
662
674
|
//#endregion
|
|
663
675
|
//#region src/utilities/parsers/index.ts
|
|
664
676
|
var parsers_default = {
|
|
@@ -682,7 +694,6 @@ function getCommandParts(wholeCommand) {
|
|
|
682
694
|
subcommand
|
|
683
695
|
};
|
|
684
696
|
}
|
|
685
|
-
|
|
686
697
|
//#endregion
|
|
687
698
|
//#region src/utilities/help-string-to-object.ts
|
|
688
699
|
/**
|
|
@@ -695,17 +706,16 @@ function getCommandParts(wholeCommand) {
|
|
|
695
706
|
*/
|
|
696
707
|
function helpStringToObject(helpString) {
|
|
697
708
|
for (const [parserName, helpStringToObjectFunction] of Object.entries(parsers_default)) {
|
|
698
|
-
log.
|
|
709
|
+
log.debug(`Trying to parse help string with ${parserName} parser...`);
|
|
699
710
|
try {
|
|
700
711
|
return helpStringToObjectFunction(helpString);
|
|
701
712
|
} catch (error) {
|
|
702
|
-
if (error instanceof Error) log.
|
|
713
|
+
if (error instanceof Error) log.error(`Error in "${parserName}" parser: ${String(error)}`);
|
|
703
714
|
continue;
|
|
704
715
|
}
|
|
705
716
|
}
|
|
706
717
|
log.error("Could not parse help string with any parser");
|
|
707
718
|
}
|
|
708
|
-
|
|
709
719
|
//#endregion
|
|
710
720
|
//#region src/utilities/get-help-markdown.ts
|
|
711
721
|
/**
|
|
@@ -722,7 +732,7 @@ async function getHelpMarkdown(cliCommand, helpFlag = "--help", depth) {
|
|
|
722
732
|
}
|
|
723
733
|
async function renderHelpMarkdownObject(cliCommand, helpFlag, depth, programInfo) {
|
|
724
734
|
if (depth <= 0) {
|
|
725
|
-
log.
|
|
735
|
+
log.warn(`Max CLI command help depth reached, stopping recursion`);
|
|
726
736
|
return "";
|
|
727
737
|
}
|
|
728
738
|
let markdown = helpObjectToMarkdown(programInfo, depth);
|
|
@@ -758,26 +768,6 @@ async function getHelpString(resolvedCommand) {
|
|
|
758
768
|
if (rawHelpString === void 0 || rawHelpString === "") throw new Error(`No result from running CLI help command: "${resolvedCommand}"\n`);
|
|
759
769
|
return rawHelpString;
|
|
760
770
|
}
|
|
761
|
-
|
|
762
|
-
//#endregion
|
|
763
|
-
//#region src/utilities/get-package-json.ts
|
|
764
|
-
let packageJson;
|
|
765
|
-
/**
|
|
766
|
-
* Convenience function for rules
|
|
767
|
-
* Load as package json only as needed, memoize
|
|
768
|
-
* Rules could call this themselves, but this is more convenient and efficient
|
|
769
|
-
* @throws {Error} If no package.json is found
|
|
770
|
-
*/
|
|
771
|
-
async function getPackageJson() {
|
|
772
|
-
const { packageFile } = await loadConfig();
|
|
773
|
-
if (packageFile === void 0) throw new Error("No packageFile found or set in config");
|
|
774
|
-
packageJson ??= await readPackage({ cwd: path.dirname(packageFile) });
|
|
775
|
-
return {
|
|
776
|
-
packageJson,
|
|
777
|
-
packagePath: packageFile
|
|
778
|
-
};
|
|
779
|
-
}
|
|
780
|
-
|
|
781
771
|
//#endregion
|
|
782
772
|
//#region src/utilities/is-executable.ts
|
|
783
773
|
/**
|
|
@@ -798,7 +788,6 @@ async function isExecutable(filePath, strictExtensions = false) {
|
|
|
798
788
|
return false;
|
|
799
789
|
}
|
|
800
790
|
}
|
|
801
|
-
|
|
802
791
|
//#endregion
|
|
803
792
|
//#region src/utilities/infer-command.ts
|
|
804
793
|
/**
|
|
@@ -811,17 +800,23 @@ async function inferCommand(cliCommand) {
|
|
|
811
800
|
cliCommand ??= await getFirstBinFromPackage();
|
|
812
801
|
return ensureExecutable(cliCommand);
|
|
813
802
|
}
|
|
803
|
+
function firstOf(value) {
|
|
804
|
+
if (value === void 0) return void 0;
|
|
805
|
+
return Array.isArray(value) ? value[0] : value;
|
|
806
|
+
}
|
|
814
807
|
async function getFirstBinFromPackage() {
|
|
815
|
-
const {
|
|
816
|
-
const
|
|
817
|
-
if (
|
|
818
|
-
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)));
|
|
819
814
|
if (looksLikePath(binPath)) {
|
|
820
|
-
log.
|
|
815
|
+
log.debug(`Inferred <!-- cli-help --> command to run from package.json: ${binPath}`);
|
|
821
816
|
return binPath;
|
|
822
817
|
}
|
|
823
818
|
}
|
|
824
|
-
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'}) -->`);
|
|
825
820
|
}
|
|
826
821
|
function looksLikePath(maybePath) {
|
|
827
822
|
const parsed = path.parse(maybePath);
|
|
@@ -834,27 +829,26 @@ async function ensureExecutable(filePath) {
|
|
|
834
829
|
throw new Error(`The cli-help rule noticed that "${resolvedPath}" is not executable.`);
|
|
835
830
|
}
|
|
836
831
|
async function getCommandPathFromPackage(commandName) {
|
|
837
|
-
const {
|
|
838
|
-
|
|
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)) {
|
|
839
835
|
if (key === commandName) return value;
|
|
840
836
|
if (path.normalize(value) === path.normalize(commandName)) return value;
|
|
841
837
|
}
|
|
842
838
|
}
|
|
843
|
-
|
|
844
839
|
//#endregion
|
|
845
840
|
//#region src/index.ts
|
|
846
|
-
const cliHelpRule = { async content(options) {
|
|
841
|
+
const cliHelpRule = defineConfig({ cli: { async content(options, _context) {
|
|
847
842
|
const validOptions = z.object({
|
|
848
843
|
cliCommand: z.string().optional(),
|
|
849
844
|
depth: z.number().optional(),
|
|
850
845
|
helpFlag: z.string().optional()
|
|
851
846
|
}).optional().parse(options);
|
|
852
847
|
return getHelpMarkdown(await inferCommand(validOptions?.cliCommand), validOptions?.helpFlag, validOptions?.depth);
|
|
853
|
-
} };
|
|
854
|
-
var src_default = {
|
|
855
|
-
cli: cliHelpRule,
|
|
856
|
-
"cli-help": cliHelpRule
|
|
857
|
-
};
|
|
858
|
-
|
|
848
|
+
} } });
|
|
849
|
+
var src_default = defineConfig({
|
|
850
|
+
cli: cliHelpRule.cli,
|
|
851
|
+
"cli-help": cliHelpRule.cli
|
|
852
|
+
});
|
|
859
853
|
//#endregion
|
|
860
|
-
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",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"email": "eric@ericmika.com",
|
|
22
22
|
"url": "https://ericmika.com"
|
|
23
23
|
},
|
|
24
|
+
"sideEffects": false,
|
|
24
25
|
"type": "module",
|
|
25
26
|
"exports": {
|
|
26
27
|
".": {
|
|
@@ -35,30 +36,28 @@
|
|
|
35
36
|
],
|
|
36
37
|
"dependencies": {
|
|
37
38
|
"@types/which": "^3.0.4",
|
|
38
|
-
"chevrotain": "^
|
|
39
|
+
"chevrotain": "^12.0.0",
|
|
39
40
|
"execa": "^9.6.1",
|
|
40
|
-
"
|
|
41
|
-
"type-fest": "^5.
|
|
41
|
+
"lognow": "^0.5.2",
|
|
42
|
+
"type-fest": "^5.5.0",
|
|
42
43
|
"which": "^6.0.1",
|
|
43
|
-
"zod": "^3.
|
|
44
|
+
"zod": "^4.3.6"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
|
-
"@kitschpatrol/shared-config": "^6.
|
|
47
|
-
"@types/node": "~
|
|
48
|
-
"bumpp": "^
|
|
49
|
-
"mdat": "^
|
|
47
|
+
"@kitschpatrol/shared-config": "^6.2.0",
|
|
48
|
+
"@types/node": "~22.17.2",
|
|
49
|
+
"bumpp": "^11.0.1",
|
|
50
|
+
"mdat": "^2.0.0",
|
|
50
51
|
"meow": "^14.1.0",
|
|
51
|
-
"
|
|
52
|
-
"tsdown": "^0.20.3",
|
|
52
|
+
"tsdown": "^0.21.7",
|
|
53
53
|
"typescript": "~5.9.3",
|
|
54
|
-
"vitest": "^4.
|
|
54
|
+
"vitest": "^4.1.2"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
|
-
"mdat": "^
|
|
58
|
-
"remark-mdat": "^1.1.0"
|
|
57
|
+
"mdat": "^2.0.0"
|
|
59
58
|
},
|
|
60
59
|
"engines": {
|
|
61
|
-
"node": ">=
|
|
60
|
+
"node": ">=22.17.0"
|
|
62
61
|
},
|
|
63
62
|
"devEngines": {
|
|
64
63
|
"runtime": {
|
|
@@ -72,6 +71,6 @@
|
|
|
72
71
|
"fix": "ksc fix",
|
|
73
72
|
"lint": "ksc lint",
|
|
74
73
|
"release": "bumpp --commit 'Release: %s' && pnpm run build && NPM_AUTH_TOKEN=$(op read 'op://Personal/npm/token') && pnpm publish",
|
|
75
|
-
"test": "vitest --no-file-parallelism"
|
|
74
|
+
"test": "vitest run --no-file-parallelism"
|
|
76
75
|
}
|
|
77
76
|
}
|
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:
|