Skip to content

Commit 68db34f

Browse files
committed
feat: add new command (generate-templates)
1 parent 7ac5025 commit 68db34f

24 files changed

+500
-188
lines changed

cli/execute.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const execute = (params, commands, instance) => {
1313

1414
if (error) {
1515
reject(new Error(error));
16+
return;
1617
}
1718

1819
if (!usageOptions.length && command.name === root_command) {
@@ -91,9 +92,22 @@ const processArgs = (commands, args) => {
9192
if (error) return;
9293

9394
if (i === 0) {
94-
command = commands[arg] || commands[root_command];
95-
allFlagKeys = command.options.reduce((acc, option) => [...acc, ...option.flags.keys], []);
95+
command = commands[arg];
96+
97+
if (!command && !arg.startsWith("-")) {
98+
const tip = didYouMean(arg, _.keys(commands));
99+
error = `unknown command ${arg}${tip ? `\n(Did you mean ${tip} ?)` : ""}`;
100+
} else if (!command) {
101+
command = commands[root_command];
102+
}
103+
104+
if (command) {
105+
allFlagKeys = command.options.reduce((acc, option) => [...acc, ...option.flags.keys], []);
106+
}
96107
}
108+
109+
if (error) return;
110+
97111
if (arg.startsWith("-")) {
98112
const option = command.options.find((option) => option.flags.keys.includes(arg));
99113

@@ -127,6 +141,14 @@ const processArgs = (commands, args) => {
127141
});
128142
command = command || commands[root_command];
129143

144+
if (error) {
145+
return {
146+
command: null,
147+
usageOptions: [],
148+
error,
149+
};
150+
}
151+
130152
return {
131153
command,
132154
usageOptions,

cli/index.js

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,33 @@ const { displayVersion } = require("./operations/display-version");
88
const cli = (input) => {
99
const commands = {};
1010

11-
const addCommand = (command) => {
11+
const addCommand = (command, { addVersion = false, addHelp = true } = {}) => {
1212
commands[command.name] = {
1313
name: command.name,
1414
description: `${command.description || ""}`,
1515
options: _.compact(_.map(command.options, processOption)),
1616
};
1717

18+
if (addVersion) {
19+
commands[command.name].options.unshift(
20+
processOption({
21+
flags: "-v, --version",
22+
description: "output the current version",
23+
operation: () => displayVersion(instance),
24+
}),
25+
);
26+
}
27+
28+
if (addHelp) {
29+
commands[command.name].options.push(
30+
processOption({
31+
flags: "-h, --help",
32+
description: "display help for command",
33+
operation: () => displayHelp(commands, instance, commands[command.name]),
34+
}),
35+
);
36+
}
37+
1838
return instance;
1939
};
2040

@@ -25,10 +45,16 @@ const cli = (input) => {
2545
execute: (params) => execute(params, commands, instance),
2646
};
2747

28-
addCommand({
29-
name: root_command,
30-
options: [],
31-
});
48+
addCommand(
49+
{
50+
name: root_command,
51+
options: [],
52+
},
53+
{
54+
addVersion: false,
55+
addHelp: false,
56+
},
57+
);
3258

3359
_.forEach(input.options, (option) => {
3460
const processed = processOption(option);
@@ -55,7 +81,7 @@ const cli = (input) => {
5581
processOption({
5682
flags: "-h, --help",
5783
description: "display help for command",
58-
operation: () => displayHelp(commands, instance),
84+
operation: () => displayHelp(commands, instance, commands[root_command]),
5985
}),
6086
);
6187

cli/operations/display-help.js

Lines changed: 73 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,56 @@
11
const _ = require("lodash");
22
const { root_command } = require("../constants");
33

4-
const displayHelp = (commands, instance) => {
5-
const generateOptionsOutput = (options) =>
6-
options.reduce(
7-
(acc, option) => {
8-
const flags = `${option.flags.keys.join(", ")}${option.flags.value?.raw ? ` ${option.flags.value?.raw}` : ""}`;
9-
const description = `${option.description || ""}${
10-
option.default === undefined || (option.flags.isNoFlag && option.default === true)
11-
? ""
12-
: ` (default: ${typeof option.default === "string" ? `"${option.default}"` : option.default})`
13-
}`;
14-
15-
if (flags.length > acc.maxLength) {
16-
acc.maxLength = flags.length;
17-
}
18-
19-
acc.options.push({
20-
flags,
21-
description,
22-
});
23-
return acc;
24-
},
25-
{
26-
options: [],
27-
maxLength: 0,
28-
},
29-
);
4+
const generateOptionsOutput = (options) =>
5+
options.reduce(
6+
(acc, option) => {
7+
const flags = `${option.flags.keys.join(", ")}${option.flags.value?.raw ? ` ${option.flags.value?.raw}` : ""}`;
8+
const description = `${option.description || ""}${
9+
option.default === undefined || (option.flags.isNoFlag && option.default === true)
10+
? ""
11+
: ` (default: ${typeof option.default === "string" ? `"${option.default}"` : option.default})`
12+
}`;
13+
14+
if (flags.length > acc.maxLength) {
15+
acc.maxLength = flags.length;
16+
}
17+
18+
acc.options.push({
19+
flags,
20+
description,
21+
});
22+
return acc;
23+
},
24+
{
25+
options: [],
26+
maxLength: 0,
27+
},
28+
);
29+
30+
const generateOptionsTextOutput = (options, maxLength, spaces) =>
31+
options
32+
.map((option) => {
33+
const spacesText = Array(spaces).fill(" ").join("");
34+
const leftStr = `${spacesText}${option.flags.padEnd(maxLength, " ")} `;
35+
const leftStrFiller = Array(leftStr.length).fill(" ").join("");
36+
const descriptionLines = option.description.split("\n");
37+
38+
return (
39+
leftStr +
40+
descriptionLines
41+
.map((line, i) => {
42+
if (i === 0) {
43+
return line;
44+
}
45+
46+
return `\n${leftStrFiller}${line}`;
47+
})
48+
.join("")
49+
);
50+
})
51+
.join("\n");
3052

53+
const displayAllHelp = (commands, instance) => {
3154
const { options, maxLength: maxOptionLength } = generateOptionsOutput(commands[root_command].options);
3255

3356
const { commands: commandLabels, maxLength: maxCommandLength } = _.filter(
@@ -57,29 +80,6 @@ const displayHelp = (commands, instance) => {
5780
},
5881
);
5982

60-
const generateOptionsTextOutput = (options, maxLength, spaces) =>
61-
options
62-
.map((option) => {
63-
const spacesText = Array(spaces).fill(" ").join("");
64-
const leftStr = `${spacesText}${option.flags.padEnd(maxLength, " ")} `;
65-
const leftStrFiller = Array(leftStr.length).fill(" ").join("");
66-
const descriptionLines = option.description.split("\n");
67-
68-
return (
69-
leftStr +
70-
descriptionLines
71-
.map((line, i) => {
72-
if (i === 0) {
73-
return line;
74-
}
75-
76-
return `\n${leftStrFiller}${line}`;
77-
})
78-
.join("")
79-
);
80-
})
81-
.join("\n");
82-
8383
const optionsOutput = generateOptionsTextOutput(options, maxOptionLength, 2);
8484

8585
const commandsOutput = commandLabels
@@ -128,6 +128,30 @@ ${instance.input.description}`
128128
${outputTest}`);
129129
};
130130

131+
const displayHelp = (commands, instance, command) => {
132+
if (command.name === root_command) return displayAllHelp(commands, instance);
133+
134+
const { options, maxLength: maxOptionLength } = generateOptionsOutput(command.options);
135+
const optionsOutput = generateOptionsTextOutput(options, maxOptionLength, 2);
136+
137+
const outputTest = [
138+
optionsOutput &&
139+
`Options:
140+
${optionsOutput}`,
141+
]
142+
.filter(Boolean)
143+
.join("\n\n");
144+
145+
console.log(`Usage: ${instance.input.name} ${command.name}${optionsOutput ? " [options]" : ""}
146+
${
147+
command.description &&
148+
`
149+
${command.description}`
150+
}
151+
152+
${outputTest}`);
153+
};
154+
131155
module.exports = {
132156
displayHelp,
133157
};

index.d.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
type HttpClientType = "axios" | "fetch";
2+
13
interface GenerateApiParamsBase {
24
/**
35
* default 'api.ts'
@@ -34,7 +36,7 @@ interface GenerateApiParamsBase {
3436
/**
3537
* generated http client type
3638
*/
37-
httpClientType?: "axios" | "fetch";
39+
httpClientType?: HttpClientType;
3840
/**
3941
* use "default" response status code as success response too.
4042
* some swagger schemas use "default" response status code as success response type by default.
@@ -499,3 +501,15 @@ export interface GenerateApiOutput {
499501
}
500502

501503
export declare function generateApi(params: GenerateApiParams): Promise<GenerateApiOutput>;
504+
505+
export interface GenerateTemplatesParams {
506+
cleanOutput?: boolean;
507+
output?: string;
508+
httpClientType?: HttpClientType;
509+
modular?: boolean;
510+
silent?: boolean;
511+
}
512+
513+
export interface GenerateTemplatesOutput extends Pick<GenerateApiOutput, "files" | "createFile"> {}
514+
515+
export declare function generateTemplates(params: GenerateTemplatesParams): Promise<GenerateTemplatesOutput>;

0 commit comments

Comments
 (0)