cli-forge 0.2.0 → 0.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/bin/cli.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ declare const mycli: import("../src").CLI<{
3
+ unmatched: string[];
4
+ '--'?: string[];
5
+ }>;
6
+ export default mycli;
package/bin/cli.js ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const src_1 = require("../src");
5
+ const generate_documentation_1 = require("./commands/generate-documentation");
6
+ const init_1 = require("./commands/init");
7
+ const mycli = (0, src_1.cli)('cli-forge').commands(generate_documentation_1.generateDocumentationCommand, init_1.initCommand);
8
+ exports.default = mycli;
9
+ mycli.forge();
10
+ //# sourceMappingURL=cli.js.map
package/bin/cli.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../../packages/cli-forge/bin/cli.ts"],"names":[],"mappings":";;;AAEA,gCAA6B;AAC7B,8EAAiF;AACjF,0CAA8C;AAE9C,MAAM,KAAK,GAAG,IAAA,SAAG,EAAC,WAAW,CAAC,CAAC,QAAQ,CACrC,qDAA4B,EAC5B,kBAAW,CACZ,CAAC;AAEF,kBAAe,KAAK,CAAC;AAErB,KAAK,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { ParsedArgs } from '@cli-forge/parser';
2
+ import { CLI } from '../../src/lib/cli-forge';
3
+ export declare function withGenerateDocumentationArgs<T extends ParsedArgs>(cmd: CLI<T>): CLI<T & {
4
+ cli: string;
5
+ } & {
6
+ output: string;
7
+ } & {
8
+ format: string;
9
+ } & {
10
+ export: string;
11
+ }>;
12
+ export declare const generateDocumentationCommand: CLI;
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateDocumentationCommand = void 0;
4
+ exports.withGenerateDocumentationArgs = withGenerateDocumentationArgs;
5
+ const node_fs_1 = require("node:fs");
6
+ const node_path_1 = require("node:path");
7
+ const src_1 = require("../../src");
8
+ const documentation_1 = require("../../src/lib/documentation");
9
+ const cli_forge_1 = require("../../src/lib/cli-forge");
10
+ const fs_1 = require("../utils/fs");
11
+ function withGenerateDocumentationArgs(cmd) {
12
+ return cmd
13
+ .positional('cli', {
14
+ type: 'string',
15
+ description: 'Path to the cli that docs should be generated for.',
16
+ required: true,
17
+ })
18
+ .option('output', {
19
+ alias: ['o'],
20
+ type: 'string',
21
+ description: 'Where should the documentation be output?',
22
+ default: 'docs',
23
+ })
24
+ .option('format', {
25
+ type: 'string',
26
+ description: 'What format should the documentation be output in? (json, md)',
27
+ default: 'md',
28
+ })
29
+ .option('export', {
30
+ type: 'string',
31
+ description: 'The name of the export that contains the CLI instance. By default, docs will be generated for the default export.',
32
+ });
33
+ }
34
+ exports.generateDocumentationCommand = (0, src_1.default)('generate-documentation', {
35
+ description: 'Generate documentation for the given CLI',
36
+ builder: (b) => withGenerateDocumentationArgs(b),
37
+ handler: async (args) => {
38
+ if (args.cli.startsWith('./')) {
39
+ args.cli = (0, node_path_1.join)(process.cwd(), args.cli);
40
+ }
41
+ const cliModule = await Promise.resolve(`${args.cli}`).then(s => require(s));
42
+ const cli = cliModule[args.export || 'default'] ?? cliModule;
43
+ if (!(cli instanceof cli_forge_1.InternalCLI)) {
44
+ throw new Error(`${args.cli}${args.export ? '#' + args.export : ''} is not a CLI.`);
45
+ }
46
+ const documentation = (0, documentation_1.generateDocumentation)(cli);
47
+ if (args.format === 'md') {
48
+ await generateMarkdownDocumentation(documentation, args);
49
+ }
50
+ else if (args.format === 'json') {
51
+ const outfile = args.output.endsWith('json')
52
+ ? args.output
53
+ : (0, node_path_1.join)(args.output, cli.name + '.json');
54
+ const outdir = (0, node_path_1.dirname)(outfile);
55
+ (0, fs_1.ensureDirSync)(outdir);
56
+ (0, node_fs_1.writeFileSync)(outfile, JSON.stringify(documentation, null, 2));
57
+ }
58
+ },
59
+ });
60
+ async function generateMarkdownDocumentation(docs, args) {
61
+ const md = await importMarkdownFactory();
62
+ await generateMarkdownForSingleCommand(docs, (0, node_path_1.join)(args.output, docs.name), md);
63
+ }
64
+ async function generateMarkdownForSingleCommand(docs, out, md) {
65
+ const subcommands = docs.subcommands;
66
+ const outdir = subcommands.length ? out : (0, node_path_1.dirname)(out);
67
+ const outname = subcommands.length ? 'index' : docs.name;
68
+ (0, fs_1.ensureDirSync)(outdir);
69
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(outdir, outname + '.md'), md.h1(docs.name, ...[
70
+ docs.description,
71
+ getPositionalArgsFragment(docs.positionals, md),
72
+ getFlagArgsFragment(docs.options, md),
73
+ getSubcommandsFragment(docs.subcommands, md),
74
+ ].filter(isTruthy)));
75
+ for (const subcommand of docs.subcommands) {
76
+ await generateMarkdownForSingleCommand(subcommand, (0, node_path_1.join)(outdir, subcommand.name), md);
77
+ }
78
+ }
79
+ function formatOption(option, md) {
80
+ return md.h3(option.key, ...[
81
+ md.bold('Type:') +
82
+ ' ' +
83
+ (option.type === 'array'
84
+ ? `${option.items}[]`
85
+ : option.type),
86
+ option.description,
87
+ option.default ? md.bold('Default:') + ' ' + option.default : undefined,
88
+ option.required ? md.bold('Required') : undefined,
89
+ option.alias?.length
90
+ ? md.h4('Aliases', md.ul(...option.alias))
91
+ : undefined,
92
+ ].filter(isTruthy));
93
+ }
94
+ function getPositionalArgsFragment(positionals, md) {
95
+ if (positionals?.length === 0) {
96
+ return undefined;
97
+ }
98
+ return md.h2('Positional Arguments', ...positionals.map((positional) => formatOption(positional, md)));
99
+ }
100
+ function getFlagArgsFragment(options, md) {
101
+ if (Object.keys(options).length === 0) {
102
+ return undefined;
103
+ }
104
+ return md.h2('Flags', ...Object.values(options).map((option) => formatOption(option, md)));
105
+ }
106
+ function getSubcommandsFragment(subcommands, md) {
107
+ if (subcommands.length === 0) {
108
+ return undefined;
109
+ }
110
+ return md.h2('Subcommands', ...subcommands.map((subcommand) => md.link(`./${subcommand.name}`, subcommand.name)));
111
+ }
112
+ function isTruthy(value) {
113
+ return !!value;
114
+ }
115
+ async function importMarkdownFactory() {
116
+ try {
117
+ return await Promise.resolve().then(() => require('markdown-factory'));
118
+ }
119
+ catch {
120
+ throw new Error('Could not find markdown-factory. Please install it to generate markdown documentation.');
121
+ }
122
+ }
123
+ //# sourceMappingURL=generate-documentation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-documentation.js","sourceRoot":"","sources":["../../../../../packages/cli-forge/bin/commands/generate-documentation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { ParsedArgs } from '@cli-forge/parser';
2
+ import { CLI } from '../../src';
3
+ export declare function withInitArgs<T extends ParsedArgs>(cmd: CLI<T>): CLI<T & {
4
+ cliName: string;
5
+ } & {
6
+ output: string;
7
+ } & {
8
+ format: string;
9
+ }>;
10
+ export declare const initCommand: CLI<{
11
+ unmatched: string[];
12
+ '--'?: string[];
13
+ } & {
14
+ cliName: string;
15
+ } & {
16
+ output: string;
17
+ } & {
18
+ format: string;
19
+ }>;
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initCommand = void 0;
4
+ exports.withInitArgs = withInitArgs;
5
+ const node_child_process_1 = require("node:child_process");
6
+ const node_fs_1 = require("node:fs");
7
+ const node_path_1 = require("node:path");
8
+ const package_json_1 = require("../../package.json");
9
+ const src_1 = require("../../src");
10
+ // import { CLI } from '../../src/lib/cli-forge';
11
+ const fs_1 = require("../utils/fs");
12
+ function withInitArgs(cmd) {
13
+ return cmd
14
+ .positional('cliName', {
15
+ type: 'string',
16
+ description: 'Name of the CLI to generate.',
17
+ required: true,
18
+ })
19
+ .option('output', {
20
+ alias: ['o'],
21
+ type: 'string',
22
+ description: 'Where should the CLI be created?',
23
+ })
24
+ .option('format', {
25
+ type: 'string',
26
+ default: 'ts',
27
+ description: 'What format should the CLI be in? (js, ts)',
28
+ });
29
+ }
30
+ exports.initCommand = (0, src_1.default)('init', {
31
+ description: 'Generate a new CLI',
32
+ builder: (b) => withInitArgs(b),
33
+ handler: async (args) => {
34
+ args.output ??= process.cwd();
35
+ (0, fs_1.ensureDirSync)(args.output);
36
+ const packageJsonPath = (0, node_path_1.join)(args.output, 'package.json');
37
+ const cliPath = (0, node_path_1.join)(args.output, 'bin', `${args.cliName}.${args.format}`);
38
+ const packageJsonContent = readJsonOr(packageJsonPath, { name: args.cliName });
39
+ packageJsonContent.bin ??= {};
40
+ packageJsonContent.bin[args.cliName] = (0, node_path_1.relative)(args.output, cliPath);
41
+ packageJsonContent.dependencies ??= {};
42
+ packageJsonContent.dependencies['cli-forge'] ??= package_json_1.version;
43
+ (0, node_fs_1.writeFileSync)(packageJsonPath, JSON.stringify(packageJsonContent, null, 2));
44
+ (0, fs_1.ensureDirSync)((0, node_path_1.dirname)(cliPath));
45
+ (0, node_fs_1.writeFileSync)(cliPath, args.format === 'ts'
46
+ ? TS_CLI_CONTENTS(args.cliName)
47
+ : JS_CLI_CONTENTS(args.cliName));
48
+ const installCommand = (0, node_fs_1.existsSync)((0, node_path_1.join)(args.output, 'yarn.lock'))
49
+ ? 'yarn'
50
+ : (0, node_fs_1.existsSync)((0, node_path_1.join)(args.output, 'pnpm-lock.yaml'))
51
+ ? 'pnpm'
52
+ : (0, node_fs_1.existsSync)((0, node_path_1.join)(args.output, 'bun.lockb'))
53
+ ? 'bun'
54
+ : 'npm';
55
+ (0, node_child_process_1.execSync)(`${installCommand} install`);
56
+ },
57
+ });
58
+ const COMMON_CONTENTS = (name) => `const myCLI = cli('${name}')
59
+ .command('hello', {
60
+ builder: (args) => args.positional('name', {type: 'string'}),
61
+ handler: (args) => {
62
+ console.log('hello', args.name);
63
+ }
64
+ })`;
65
+ const JS_CLI_CONTENTS = (name) => `const { cli } = require('cli-forge');
66
+
67
+ ${COMMON_CONTENTS(name)}
68
+
69
+ module.exports = myCLI;
70
+
71
+ if (require.main === module) {
72
+ myCLI.forge();
73
+ }
74
+ `;
75
+ const TS_CLI_CONTENTS = (name) => `import { cli } from 'cli-forge';
76
+
77
+ ${COMMON_CONTENTS(name)}
78
+
79
+ export default myCLI;
80
+
81
+ if (require.main === module) {
82
+ myCLI.forge();
83
+ }
84
+ `;
85
+ function readJsonOr(filePath, alt) {
86
+ try {
87
+ const contents = (0, node_fs_1.readFileSync)(filePath, 'utf-8');
88
+ return JSON.parse(contents);
89
+ }
90
+ catch {
91
+ return alt;
92
+ }
93
+ }
94
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../../../packages/cli-forge/bin/commands/init.ts"],"names":[],"mappings":";;;AAWA,oCAiBC;AA1BD,2DAA8C;AAC9C,qCAAkE;AAClE,yCAAoD;AAEpD,qDAAkE;AAClE,mCAAqC;AACrC,iDAAiD;AACjD,oCAA4C;AAE5C,SAAgB,YAAY,CAAuB,GAAW;IAC5D,OAAO,GAAG;SACP,UAAU,CAAC,SAAS,EAAE;QACrB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,8BAA8B;QAC3C,QAAQ,EAAE,IAAI;KACf,CAAC;SACD,MAAM,CAAC,QAAQ,EAAE;QAChB,KAAK,EAAE,CAAC,GAAG,CAAC;QACZ,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,kCAAkC;KAChD,CAAC;SACD,MAAM,CAAC,QAAQ,EAAE;QAChB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,4CAA4C;KAC1D,CAAC,CAAC;AACP,CAAC;AAEY,QAAA,WAAW,GAAG,IAAA,aAAG,EAAC,MAAM,EAAE;IACrC,WAAW,EAAE,oBAAoB;IACjC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtB,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC;QAC9B,IAAA,kBAAa,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,eAAe,GAAG,IAAA,gBAAI,EAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,IAAA,gBAAI,EAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3E,MAAM,kBAAkB,GAMpB,UAAU,CAAC,eAAe,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACxD,kBAAkB,CAAC,GAAG,KAAK,EAAE,CAAC;QAC9B,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAA,oBAAQ,EAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtE,kBAAkB,CAAC,YAAY,KAAK,EAAE,CAAC;QACvC,kBAAkB,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,sBAAiB,CAAC;QACnE,IAAA,uBAAa,EAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5E,IAAA,kBAAa,EAAC,IAAA,mBAAO,EAAC,OAAO,CAAC,CAAC,CAAC;QAChC,IAAA,uBAAa,EACX,OAAO,EACP,IAAI,CAAC,MAAM,KAAK,IAAI;YAClB,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC;YAC/B,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAClC,CAAC;QACF,MAAM,cAAc,GAAG,IAAA,oBAAU,EAAC,IAAA,gBAAI,EAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YAC/D,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,IAAA,oBAAU,EAAC,IAAA,gBAAI,EAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;gBACjD,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,IAAA,oBAAU,EAAC,IAAA,gBAAI,EAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;oBAC5C,CAAC,CAAC,KAAK;oBACP,CAAC,CAAC,KAAK,CAAC;QAEV,IAAA,6BAAQ,EAAC,GAAG,cAAc,UAAU,CAAC,CAAC;IACxC,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,sBAAsB,IAAI;;;;;;KAM/D,CAAC;AAEN,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC;;EAExC,eAAe,CAAC,IAAI,CAAC;;;;;;;CAOtB,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC;;EAExC,eAAe,CAAC,IAAI,CAAC;;;;;;;CAOtB,CAAC;AAEF,SAAS,UAAU,CAAI,QAAgB,EAAE,GAAM;IAC7C,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAA,sBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function ensureDirSync(dir: string): void;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureDirSync = ensureDirSync;
4
+ const node_fs_1 = require("node:fs");
5
+ function ensureDirSync(dir) {
6
+ try {
7
+ (0, node_fs_1.mkdirSync)(dir, { recursive: true });
8
+ }
9
+ catch (e) {
10
+ if (!(0, node_fs_1.existsSync)(dir)) {
11
+ throw new Error(`Could not create directory: ${dir}`, { cause: e });
12
+ }
13
+ }
14
+ }
15
+ //# sourceMappingURL=fs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../../../../packages/cli-forge/bin/utils/fs.ts"],"names":[],"mappings":";;AAEA,sCAQC;AAVD,qCAAgD;AAEhD,SAAgB,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,IAAA,mBAAS,EAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,IAAA,oBAAU,EAAC,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,9 +1,17 @@
1
1
  {
2
2
  "name": "cli-forge",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "dependencies": {
5
5
  "tslib": "^2.3.0",
6
- "@cli-forge/parser": "0.2.0"
6
+ "@cli-forge/parser": "0.4.0"
7
+ },
8
+ "peerDependencies": {
9
+ "markdown-factory": "0.2.0"
10
+ },
11
+ "peerDependenciesMeta": {
12
+ "markdown-factory": {
13
+ "optional": true
14
+ }
7
15
  },
8
16
  "type": "commonjs",
9
17
  "main": "./src/index.js",
@@ -14,6 +22,9 @@
14
22
  "directory": "packages/cli-forge",
15
23
  "url": "https://github.com/AgentEnder/cli-forge"
16
24
  },
25
+ "bin": {
26
+ "cli-forge": "./bin/cli.js"
27
+ },
17
28
  "publishConfig": {
18
29
  "access": "public"
19
30
  },
package/src/index.d.ts CHANGED
@@ -1 +1 @@
1
- export * from './lib/cli-forge';
1
+ export { default, cli, CLI, Command } from './lib/cli-forge';
package/src/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- tslib_1.__exportStar(require("./lib/cli-forge"), exports);
3
+ exports.cli = exports.default = void 0;
4
+ var cli_forge_1 = require("./lib/cli-forge");
5
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return cli_forge_1.default; } });
6
+ Object.defineProperty(exports, "cli", { enumerable: true, get: function () { return cli_forge_1.cli; } });
5
7
  //# sourceMappingURL=index.js.map
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/cli-forge/src/index.ts"],"names":[],"mappings":";;;AAAA,0DAAgC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/cli-forge/src/index.ts"],"names":[],"mappings":";;;AAAA,6CAA6D;AAApD,oGAAA,OAAO,OAAA;AAAE,gGAAA,GAAG,OAAA"}
@@ -1,47 +1,34 @@
1
1
  import { ArrayOptionConfig, OptionConfig, ParsedArgs } from '@cli-forge/parser';
2
- export type CLICommandOptions<TInitial extends ParsedArgs, TArgs extends TInitial> = {
2
+ export interface CLIHandlerContext {
3
+ command: CLI<any>;
4
+ }
5
+ export type CLICommandOptions<TInitial extends ParsedArgs, TArgs extends TInitial = TInitial> = {
3
6
  description?: string;
4
7
  builder?: (parser: CLI<TInitial>) => CLI<TArgs>;
5
- handler: (args: TArgs) => void | Promise<void>;
8
+ handler: (args: TArgs, context: CLIHandlerContext) => void | Promise<void>;
6
9
  };
7
- /**
8
- * The base class for a CLI application. This class is used to define the structure of the CLI.
9
- *
10
- * {@link cli} is provided as a small helper function to create a new CLI instance.
11
- *
12
- * @example
13
- * ```ts
14
- * import { cli } from 'cli-forge';
15
- *
16
- * cli('basic-cli').command('hello', {
17
- * builder: (args) =>
18
- * args.option('name', {
19
- * type: 'string',
20
- * }),
21
- * handler: (args) => {
22
- * console.log(`Hello, ${args.name}!`);
23
- * }).forge();
24
- * ```
25
- */
26
- export declare class CLI<T extends ParsedArgs = ParsedArgs> {
10
+ export type Command<TInitial extends ParsedArgs = any, TArgs extends TInitial = TInitial> = ({
27
11
  name: string;
28
- protected configuration?: CLICommandOptions<T, T> | undefined;
29
- private commands;
30
- private commandChain;
31
- private requiresCommand;
32
- private parser;
33
- /**
34
- * @param name What should the name of the cli command be?
35
- * @param configuration Configuration for the current CLI command.
36
- */
37
- constructor(name: string, configuration?: CLICommandOptions<T, T> | undefined);
12
+ } & CLICommandOptions<TInitial, TArgs>) | CLI<TArgs>;
13
+ export interface CLI<TArgs extends ParsedArgs = ParsedArgs> {
14
+ command<TCommandArgs extends TArgs>(cmd: Command<TArgs, TCommandArgs>): CLI<TArgs>;
38
15
  /**
39
16
  * Registers a new command with the CLI.
40
17
  * @param key What should the new command be called?
41
18
  * @param options Settings for the new command. See {@link CLICommandOptions}.
42
19
  * @returns Updated CLI instance with the new command registered.
43
20
  */
44
- command<TArgs extends T>(key: string, options: CLICommandOptions<T, TArgs>): this;
21
+ command<TCommandArgs extends TArgs>(key: string, options: CLICommandOptions<TArgs, TCommandArgs>): CLI<TArgs>;
22
+ /**
23
+ * Registers multiple subcommands with the CLI.
24
+ * @param commands Several commands to register. Can be the result of a call to {@link cli} or a configuration object.
25
+ */
26
+ commands(commands: Command[]): CLI<TArgs>;
27
+ /**
28
+ * Registers multiple subcommands with the CLI.
29
+ * @param commands Several commands to register. Can be the result of a call to {@link cli} or a configuration object.
30
+ */
31
+ commands(...commands: Command[]): CLI<TArgs>;
45
32
  /**
46
33
  * Registers a new option for the CLI command. This option will be accessible
47
34
  * within the command handler, as well as any subcommands.
@@ -50,12 +37,14 @@ export declare class CLI<T extends ParsedArgs = ParsedArgs> {
50
37
  * @param config Configuration for the option. See {@link OptionConfig}.
51
38
  * @returns Updated CLI instance with the new option registered.
52
39
  */
53
- option<TOption extends string, TOptionConfig extends OptionConfig>(name: TOption, config: TOptionConfig): CLI<T & { [key in TOption]: TOptionConfig["coerce"] extends (value: string) => infer TCoerce ? TCoerce : {
54
- string: string;
55
- number: number;
56
- boolean: boolean;
57
- array: (TOptionConfig extends ArrayOptionConfig<string | number> ? TOptionConfig["items"] extends "string" ? string : number : never)[];
58
- }[TOptionConfig["type"]]; }>;
40
+ option<TOption extends string, TOptionConfig extends OptionConfig>(name: TOption, config: TOptionConfig): CLI<TArgs & {
41
+ [key in TOption]: TOptionConfig['coerce'] extends (value: string) => infer TCoerce ? TCoerce : {
42
+ string: string;
43
+ number: number;
44
+ boolean: boolean;
45
+ array: (TOptionConfig extends ArrayOptionConfig<string | number> ? TOptionConfig['items'] extends 'string' ? string : number : never)[];
46
+ }[TOptionConfig['type']];
47
+ }>;
59
48
  /**
60
49
  * Registers a new positional argument for the CLI command. This argument will be accessible
61
50
  * within the command handler, as well as any subcommands.
@@ -63,17 +52,71 @@ export declare class CLI<T extends ParsedArgs = ParsedArgs> {
63
52
  * @param config Configuration for the positional argument. See {@link OptionConfig}.
64
53
  * @returns Updated CLI instance with the new positional argument registered.
65
54
  */
66
- positional<TOption extends string, TOptionConfig extends OptionConfig>(name: TOption, config: TOptionConfig): CLI<T & { [key in TOption]: {
67
- string: string;
68
- number: number;
69
- boolean: boolean;
70
- array: (TOptionConfig extends ArrayOptionConfig<string | number> ? TOptionConfig["items"] extends "string" ? string : number : never)[];
71
- }[TOptionConfig["type"]]; }>;
55
+ positional<TOption extends string, TOptionConfig extends OptionConfig>(name: TOption, config: TOptionConfig): CLI<TArgs & {
56
+ [key in TOption]: TOptionConfig['coerce'] extends (value: string) => infer TCoerce ? TCoerce : {
57
+ string: string;
58
+ number: number;
59
+ boolean: boolean;
60
+ array: (TOptionConfig extends ArrayOptionConfig<string | number> ? TOptionConfig['items'] extends 'string' ? string : number : never)[];
61
+ }[TOptionConfig['type']];
62
+ }>;
72
63
  /**
73
64
  * Requires a command to be provided when executing the CLI. Useful if your parent command
74
65
  * cannot be executed on its own.
75
66
  * @returns Updated CLI instance.
76
67
  */
68
+ demandCommand(): CLI<TArgs>;
69
+ /**
70
+ * Prints help text to stdout.
71
+ */
72
+ printHelp(): void;
73
+ /**
74
+ * Parses argv and executes the CLI
75
+ * @param args argv. Defaults to process.argv.slice(2)
76
+ * @returns Promise that resolves when the handler completes.
77
+ */
78
+ forge(args?: string[]): Promise<void>;
79
+ }
80
+ /**
81
+ * The base class for a CLI application. This class is used to define the structure of the CLI.
82
+ *
83
+ * {@link cli} is provided as a small helper function to create a new CLI instance.
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * import { cli } from 'cli-forge';
88
+ *
89
+ * cli('basic-cli').command('hello', {
90
+ * builder: (args) =>
91
+ * args.option('name', {
92
+ * type: 'string',
93
+ * }),
94
+ * handler: (args) => {
95
+ * console.log(`Hello, ${args.name}!`);
96
+ * }).forge();
97
+ * ```
98
+ */
99
+ export declare class InternalCLI<TArgs extends ParsedArgs = ParsedArgs> implements CLI<TArgs> {
100
+ name: string;
101
+ private registeredCommands;
102
+ private commandChain;
103
+ private requiresCommand;
104
+ private _configuration?;
105
+ private parser;
106
+ /**
107
+ * @param name What should the name of the cli command be?
108
+ * @param configuration Configuration for the current CLI command.
109
+ */
110
+ constructor(name: string);
111
+ get configuration(): CLICommandOptions<any, any> | undefined;
112
+ private set configuration(value);
113
+ withRootCommandConfiguration<TRootCommandArgs extends TArgs>(configuration: CLICommandOptions<TArgs, TRootCommandArgs>): InternalCLI<TArgs>;
114
+ command<TCommandArgs extends TArgs>(cmd: Command<TArgs, TCommandArgs>): CLI<TArgs>;
115
+ command<TCommandArgs extends TArgs>(key: string, options: CLICommandOptions<TArgs, TCommandArgs>): CLI<TArgs>;
116
+ commands(commands: Command[]): typeof this;
117
+ commands(...commands: Command[]): typeof this;
118
+ option<TOption extends string, TOptionConfig extends OptionConfig>(name: TOption, config: TOptionConfig): any;
119
+ positional<TOption extends string, TOptionConfig extends OptionConfig>(name: TOption, config: TOptionConfig): any;
77
120
  demandCommand(): this;
78
121
  /**
79
122
  * Gets help text for the current command as a string.
@@ -89,18 +132,24 @@ export declare class CLI<T extends ParsedArgs = ParsedArgs> {
89
132
  * @param cmd The command to run.
90
133
  * @param args The arguments to pass to the command.
91
134
  */
92
- runCommand<T extends ParsedArgs>(cmd: CLI<T>, args: T): Promise<void>;
135
+ runCommand<T extends ParsedArgs>(cmd: InternalCLI<T>, args: T): Promise<void>;
93
136
  /**
94
137
  * Parses argv and executes the CLI
95
138
  * @param args argv. Defaults to process.argv.slice(2)
96
139
  * @returns Promise that resolves when the handler completes.
97
140
  */
98
141
  forge(args?: string[]): Promise<void>;
142
+ getParser(): import("@cli-forge/parser").ReadonlyArgvParser<TArgs & {
143
+ help: boolean;
144
+ }>;
145
+ getSubcommands(): Readonly<Record<string, InternalCLI>>;
146
+ clone(): InternalCLI<TArgs>;
99
147
  }
100
148
  /**
101
- * Constructs a CLI instance. See {@link CLI} for more information.
149
+ * Constructs a CLI instance. See {@link InternalCLI} for more information.
102
150
  * @param name Name for the top level CLI
103
- * @returns
151
+ * @param rootCommandConfiguration Configuration used when running the bare CLI. e.g. npx my-cli, rather than npx my-cli [cmd]
152
+ * @returns A {@link InternalCLI} instance.
104
153
  */
105
- export declare function cli(name: string): CLI<ParsedArgs>;
154
+ export declare function cli<TArgs extends ParsedArgs>(name: string, rootCommandConfiguration?: CLICommandOptions<ParsedArgs, TArgs>): CLI<TArgs>;
106
155
  export default cli;
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CLI = void 0;
3
+ exports.InternalCLI = void 0;
4
4
  exports.cli = cli;
5
- const tslib_1 = require("tslib");
6
5
  const parser_1 = require("@cli-forge/parser");
7
6
  /**
8
7
  * The base class for a CLI application. This class is used to define the structure of the CLI.
@@ -23,88 +22,100 @@ const parser_1 = require("@cli-forge/parser");
23
22
  * }).forge();
24
23
  * ```
25
24
  */
26
- class CLI {
25
+ class InternalCLI {
26
+ name;
27
+ registeredCommands = {};
28
+ commandChain = [];
29
+ requiresCommand = false;
30
+ _configuration;
31
+ parser = new parser_1.ArgvParser({
32
+ unmatchedParser: (arg) => {
33
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
34
+ let currentCommand = this;
35
+ for (const command of this.commandChain) {
36
+ currentCommand = currentCommand.registeredCommands[command];
37
+ }
38
+ const command = currentCommand.registeredCommands[arg];
39
+ if (command && command.configuration) {
40
+ command.configuration.builder?.(command);
41
+ this.commandChain.push(arg);
42
+ return true;
43
+ }
44
+ return false;
45
+ },
46
+ }).option('help', {
47
+ type: 'boolean',
48
+ alias: ['h'],
49
+ description: 'Show help for the current command',
50
+ });
27
51
  /**
28
52
  * @param name What should the name of the cli command be?
29
53
  * @param configuration Configuration for the current CLI command.
30
54
  */
31
- constructor(name, configuration) {
55
+ constructor(name) {
32
56
  this.name = name;
57
+ }
58
+ get configuration() {
59
+ return this._configuration;
60
+ }
61
+ set configuration(value) {
62
+ this._configuration = value;
63
+ }
64
+ withRootCommandConfiguration(configuration) {
33
65
  this.configuration = configuration;
34
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
- this.commands = {};
36
- this.commandChain = [];
37
- this.requiresCommand = false;
38
- this.parser = new parser_1.ArgvParser({
39
- unmatchedParser: (arg) => {
40
- var _a, _b;
41
- // eslint-disable-next-line @typescript-eslint/no-this-alias, @typescript-eslint/no-explicit-any
42
- let currentCommand = this;
43
- for (const command of this.commandChain) {
44
- currentCommand = currentCommand.commands[command];
45
- }
46
- const command = currentCommand.commands[arg];
47
- if (command && command.configuration) {
48
- (_b = (_a = command.configuration).builder) === null || _b === void 0 ? void 0 : _b.call(_a, command);
49
- this.commandChain.push(arg);
50
- return true;
51
- }
52
- return false;
53
- },
54
- }).option('help', {
55
- type: 'boolean',
56
- alias: ['-h'],
57
- description: 'Show help for the current command',
58
- });
66
+ return this;
59
67
  }
60
- /**
61
- * Registers a new command with the CLI.
62
- * @param key What should the new command be called?
63
- * @param options Settings for the new command. See {@link CLICommandOptions}.
64
- * @returns Updated CLI instance with the new command registered.
65
- */
66
- command(key, options) {
67
- if (key === '$0') {
68
- this.configuration = Object.assign(Object.assign({}, this.configuration), {
69
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
- builder: options.builder,
71
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
- handler: options.handler, description: options.description });
73
- }
74
- this.commands[key] = new CLI(key, options);
75
- this.commands[key].parser = this.parser;
68
+ command(keyOrCommand, options) {
69
+ if (typeof keyOrCommand === 'string') {
70
+ const key = keyOrCommand;
71
+ if (!options) {
72
+ throw new Error('options must be provided when calling `command` with a string');
73
+ }
74
+ if (key === '$0') {
75
+ this.configuration = {
76
+ ...this.configuration,
77
+ builder: options.builder,
78
+ handler: options.handler,
79
+ description: options.description,
80
+ };
81
+ }
82
+ this.registeredCommands[key] = new InternalCLI(key).withRootCommandConfiguration(options);
83
+ this.registeredCommands[key].parser = this.parser;
84
+ }
85
+ else if (keyOrCommand instanceof InternalCLI) {
86
+ const cmd = keyOrCommand;
87
+ this.registeredCommands[cmd.name] = cmd;
88
+ }
89
+ else {
90
+ const { name, ...configuration } = keyOrCommand;
91
+ this.command(name, configuration);
92
+ }
93
+ return this;
94
+ }
95
+ commands(...a0) {
96
+ const commands = a0.flat();
97
+ for (const val of commands) {
98
+ if (val instanceof InternalCLI) {
99
+ this.registeredCommands[val.name] = val;
100
+ // Include any options that were defined via cli(...).option() instead of via builder
101
+ this.parser.augment(val.parser);
102
+ val.parser = this.parser;
103
+ }
104
+ else {
105
+ const { name, ...configuration } = val;
106
+ this.command(name, configuration);
107
+ }
108
+ }
76
109
  return this;
77
110
  }
78
- /**
79
- * Registers a new option for the CLI command. This option will be accessible
80
- * within the command handler, as well as any subcommands.
81
- *
82
- * @param name The name of the option.
83
- * @param config Configuration for the option. See {@link OptionConfig}.
84
- * @returns Updated CLI instance with the new option registered.
85
- */
86
111
  option(name, config) {
87
112
  this.parser.option(name, config);
88
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
113
  return this;
90
114
  }
91
- /**
92
- * Registers a new positional argument for the CLI command. This argument will be accessible
93
- * within the command handler, as well as any subcommands.
94
- * @param name The name of the positional argument.
95
- * @param config Configuration for the positional argument. See {@link OptionConfig}.
96
- * @returns Updated CLI instance with the new positional argument registered.
97
- */
98
115
  positional(name, config) {
99
- this.parser.option(name, config);
100
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
116
+ this.parser.positional(name, config);
101
117
  return this;
102
118
  }
103
- /**
104
- * Requires a command to be provided when executing the CLI. Useful if your parent command
105
- * cannot be executed on its own.
106
- * @returns Updated CLI instance.
107
- */
108
119
  demandCommand() {
109
120
  this.requiresCommand = true;
110
121
  return this;
@@ -114,24 +125,27 @@ class CLI {
114
125
  * @returns Help text for the current command.
115
126
  */
116
127
  formatHelp() {
117
- var _a, _b;
118
128
  const help = [];
119
129
  // eslint-disable-next-line @typescript-eslint/no-this-alias
120
130
  let command = this;
121
131
  for (const key of this.commandChain) {
122
- command = command.commands[key];
132
+ command = command.registeredCommands[key];
123
133
  }
124
- help.push(`Usage: ${[this.name, ...this.commandChain].join(' ')}`);
125
- if ((_a = command.configuration) === null || _a === void 0 ? void 0 : _a.description) {
134
+ help.push(`Usage: ${[
135
+ this.name,
136
+ ...this.commandChain,
137
+ ...command.parser.configuredPositionals.map((p) => `[${p.key}]`),
138
+ ].join(' ')}`);
139
+ if (command.configuration?.description) {
126
140
  help.push(command.configuration.description);
127
141
  }
128
- if (Object.keys(command.commands).length > 0) {
142
+ if (Object.keys(command.registeredCommands).length > 0) {
129
143
  help.push('');
130
144
  help.push('Commands:');
131
145
  }
132
- for (const key in command.commands) {
133
- const subcommand = command.commands[key];
134
- help.push(` ${key}${((_b = subcommand.configuration) === null || _b === void 0 ? void 0 : _b.description)
146
+ for (const key in command.registeredCommands) {
147
+ const subcommand = command.registeredCommands[key];
148
+ help.push(` ${key}${subcommand.configuration?.description
135
149
  ? ' - ' + subcommand.configuration.description
136
150
  : ''}`);
137
151
  }
@@ -140,11 +154,10 @@ class CLI {
140
154
  help.push('Options:');
141
155
  }
142
156
  for (const key in this.parser.configuredOptions) {
143
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
144
157
  const option = this.parser.configuredOptions[key];
145
158
  help.push(` --${key}${option.description ? ' - ' + option.description : ''}`);
146
159
  }
147
- if (Object.keys(command.commands).length > 0) {
160
+ if (Object.keys(command.registeredCommands).length > 0) {
148
161
  help.push(' ');
149
162
  help.push(`Run \`${[this.name, ...this.commandChain].join(' ')} [command] --help\` for more information on a command`);
150
163
  }
@@ -161,62 +174,82 @@ class CLI {
161
174
  * @param cmd The command to run.
162
175
  * @param args The arguments to pass to the command.
163
176
  */
164
- runCommand(cmd, args) {
165
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
166
- var _a;
167
- try {
168
- if (cmd.requiresCommand) {
169
- throw new Error(`${[this.name, ...this.commandChain].join(' ')} requires a command`);
170
- }
171
- if ((_a = cmd.configuration) === null || _a === void 0 ? void 0 : _a.handler) {
172
- yield cmd.configuration.handler(args);
173
- }
174
- else {
175
- throw new Error(`${[this.name, ...this.commandChain].join(' ')} is not implemented.`);
176
- }
177
+ async runCommand(cmd, args) {
178
+ try {
179
+ if (cmd.requiresCommand) {
180
+ throw new Error(`${[this.name, ...this.commandChain].join(' ')} requires a command`);
177
181
  }
178
- catch (_b) {
179
- process.exitCode = 1;
180
- this.printHelp();
182
+ if (cmd.configuration?.handler) {
183
+ await cmd.configuration.handler(args, {
184
+ command: cmd,
185
+ });
181
186
  }
182
- });
187
+ else {
188
+ throw new Error(`${[this.name, ...this.commandChain].join(' ')} is not implemented.`);
189
+ }
190
+ }
191
+ catch (e) {
192
+ process.exitCode = 1;
193
+ console.error(e);
194
+ this.printHelp();
195
+ }
183
196
  }
184
197
  /**
185
198
  * Parses argv and executes the CLI
186
199
  * @param args argv. Defaults to process.argv.slice(2)
187
200
  * @returns Promise that resolves when the handler completes.
188
201
  */
189
- forge() {
190
- return tslib_1.__awaiter(this, arguments, void 0, function* (args = process.argv.slice(2)) {
191
- var _a, _b, _c;
192
- // Parsing the args does two things:
193
- // - builds argv to pass to handler
194
- // - fills the command chain + registers commands
195
- const argv = this.parser.parse(args);
196
- // eslint-disable-next-line @typescript-eslint/no-this-alias, @typescript-eslint/no-explicit-any
197
- let currentCommand = this;
198
- for (const command of this.commandChain) {
199
- currentCommand = currentCommand.commands[command];
200
- }
201
- if (argv.help) {
202
- this.printHelp();
203
- return;
204
- }
205
- const finalArgV = currentCommand === this
206
- ? ((_c = (_b = (_a = this.configuration) === null || _a === void 0 ? void 0 : _a.builder) === null || _b === void 0 ? void 0 : _b.call(_a, this).parser) !== null && _c !== void 0 ? _c : this.parser).parse(args)
207
- : argv;
208
- yield this.runCommand(currentCommand, finalArgV);
209
- });
202
+ async forge(args = process.argv.slice(2)) {
203
+ // Parsing the args does two things:
204
+ // - builds argv to pass to handler
205
+ // - fills the command chain + registers commands
206
+ const argv = this.parser.parse(args);
207
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
208
+ let currentCommand = this;
209
+ for (const command of this.commandChain) {
210
+ currentCommand = currentCommand.registeredCommands[command];
211
+ }
212
+ if (argv.help) {
213
+ this.printHelp();
214
+ return;
215
+ }
216
+ const finalArgV = currentCommand === this
217
+ ? (this.configuration?.builder?.(this)
218
+ ?.parser ?? this.parser).parse(args)
219
+ : argv;
220
+ await this.runCommand(currentCommand, finalArgV);
221
+ }
222
+ getParser() {
223
+ return this.parser.asReadonly();
224
+ }
225
+ getSubcommands() {
226
+ return this.registeredCommands;
227
+ }
228
+ clone() {
229
+ const clone = new InternalCLI(this.name);
230
+ if (this.configuration) {
231
+ clone.withRootCommandConfiguration(this.configuration);
232
+ }
233
+ clone.registeredCommands = { ...this.registeredCommands };
234
+ clone.commandChain = [...this.commandChain];
235
+ clone.requiresCommand = this.requiresCommand;
236
+ clone.parser = this.parser.clone();
237
+ return clone;
210
238
  }
211
239
  }
212
- exports.CLI = CLI;
240
+ exports.InternalCLI = InternalCLI;
213
241
  /**
214
- * Constructs a CLI instance. See {@link CLI} for more information.
242
+ * Constructs a CLI instance. See {@link InternalCLI} for more information.
215
243
  * @param name Name for the top level CLI
216
- * @returns
244
+ * @param rootCommandConfiguration Configuration used when running the bare CLI. e.g. npx my-cli, rather than npx my-cli [cmd]
245
+ * @returns A {@link InternalCLI} instance.
217
246
  */
218
- function cli(name) {
219
- return new CLI(name);
247
+ function cli(name, rootCommandConfiguration) {
248
+ const cli = new InternalCLI(name);
249
+ if (rootCommandConfiguration) {
250
+ cli.withRootCommandConfiguration(rootCommandConfiguration);
251
+ }
252
+ return cli;
220
253
  }
221
254
  exports.default = cli;
222
255
  //# sourceMappingURL=cli-forge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli-forge.js","sourceRoot":"","sources":["../../../../../packages/cli-forge/src/lib/cli-forge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-forge.js","sourceRoot":"","sources":["../../../../../packages/cli-forge/src/lib/cli-forge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { OptionConfig } from '@cli-forge/parser';
2
+ import { InternalCLI } from './cli-forge';
3
+ export type Documentation = {
4
+ name: string;
5
+ description?: string;
6
+ options: Readonly<Record<string, OptionConfig & {
7
+ key: string;
8
+ }>>;
9
+ positionals: readonly Readonly<OptionConfig & {
10
+ key: string;
11
+ }>[];
12
+ subcommands: Documentation[];
13
+ };
14
+ export declare function generateDocumentation(cli: InternalCLI): {
15
+ name: string;
16
+ description: string | undefined;
17
+ options: Readonly<{
18
+ unmatched: OptionConfig<any> & {
19
+ key: string;
20
+ position?: number;
21
+ };
22
+ '--'?: (OptionConfig<any> & {
23
+ key: string;
24
+ position?: number;
25
+ }) | undefined;
26
+ help: OptionConfig<any> & {
27
+ key: string;
28
+ position?: number;
29
+ };
30
+ }>;
31
+ positionals: readonly Readonly<OptionConfig<any> & {
32
+ key: string;
33
+ position?: number;
34
+ }>[];
35
+ subcommands: Documentation[];
36
+ };
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateDocumentation = generateDocumentation;
4
+ function generateDocumentation(cli) {
5
+ // Ensure current command's options are built.
6
+ if (cli.configuration?.builder) {
7
+ cli.configuration.builder(cli);
8
+ }
9
+ const parser = cli.getParser();
10
+ const options = parser.configuredOptions;
11
+ const positionals = parser.configuredPositionals;
12
+ const subcommands = Object.values(cli.getSubcommands()).map((cmd) => generateDocumentation(cmd.clone()));
13
+ return {
14
+ name: cli.name,
15
+ description: cli.configuration?.description,
16
+ options,
17
+ positionals,
18
+ subcommands,
19
+ };
20
+ }
21
+ //# sourceMappingURL=documentation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentation.js","sourceRoot":"","sources":["../../../../../packages/cli-forge/src/lib/documentation.ts"],"names":[],"mappings":";;AAWA,sDAoBC;AApBD,SAAgB,qBAAqB,CAAC,GAAgB;IACpD,8CAA8C;IAC9C,IAAI,GAAG,CAAC,aAAa,EAAE,OAAO,EAAE,CAAC;QAC/B,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC;IAE/B,MAAM,OAAO,GAAG,MAAM,CAAC,iBAAiB,CAAC;IACzC,MAAM,WAAW,GAAG,MAAM,CAAC,qBAAqB,CAAC;IACjD,MAAM,WAAW,GAAoB,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,GAAG,CAC1E,CAAC,GAAG,EAAE,EAAE,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAC5C,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,aAAa,EAAE,WAAW;QAC3C,OAAO;QACP,WAAW;QACX,WAAW;KACZ,CAAC;AACJ,CAAC"}