@akanjs/devkit 1.0.7-canary.5 → 1.0.8
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/cjs/src/commandDecorators/command.js +15 -1
- package/cjs/src/commandDecorators/helpFormatter.js +211 -0
- package/cjs/src/commandDecorators/index.js +2 -0
- package/esm/src/commandDecorators/command.js +15 -1
- package/esm/src/commandDecorators/helpFormatter.js +177 -0
- package/esm/src/commandDecorators/index.js +1 -0
- package/package.json +2 -2
- package/src/commandDecorators/helpFormatter.d.ts +3 -0
- package/src/commandDecorators/index.d.ts +1 -0
- package/src/commandDecorators/targetMeta.d.ts +1 -0
|
@@ -38,6 +38,7 @@ var import_fs = __toESM(require("fs"));
|
|
|
38
38
|
var import__ = require("..");
|
|
39
39
|
var import_executors = require("../executors");
|
|
40
40
|
var import_argMeta = require("./argMeta");
|
|
41
|
+
var import_helpFormatter = require("./helpFormatter");
|
|
41
42
|
var import_targetMeta = require("./targetMeta");
|
|
42
43
|
const import_meta = {};
|
|
43
44
|
const camelToKebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
@@ -221,7 +222,17 @@ const runCommands = async (...commands) => {
|
|
|
221
222
|
const __dirname = (0, import__.getDirname)(import_meta.url);
|
|
222
223
|
const hasPackageJson = import_fs.default.existsSync(`${__dirname}/../package.json`);
|
|
223
224
|
process.env.AKAN_VERSION = hasPackageJson ? JSON.parse(import_fs.default.readFileSync(`${__dirname}/../package.json`, "utf8")).version : "0.0.1";
|
|
224
|
-
|
|
225
|
+
const hasHelpFlag = process.argv.includes("--help") || process.argv.includes("-h");
|
|
226
|
+
const hasCommand = process.argv.length > 2 && !process.argv[2].startsWith("-");
|
|
227
|
+
if (hasHelpFlag || !hasCommand) {
|
|
228
|
+
if (process.argv.length === 2 || process.argv.length === 3 && hasHelpFlag) {
|
|
229
|
+
import_common.Logger.rawLog((0, import_helpFormatter.formatHelp)(commands, process.env.AKAN_VERSION));
|
|
230
|
+
process.exit(0);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
import_commander.program.version(process.env.AKAN_VERSION).description("Akan CLI").configureHelp({
|
|
234
|
+
helpWidth: 100
|
|
235
|
+
});
|
|
225
236
|
const akanBasePackageJson = import_fs.default.existsSync("./node_modules/@akanjs/base/package.json") ? JSON.parse(import_fs.default.readFileSync("./node_modules/@akanjs/base/package.json", "utf8")) : null;
|
|
226
237
|
if (akanBasePackageJson && akanBasePackageJson.version !== process.env.AKAN_VERSION) {
|
|
227
238
|
import_common.Logger.rawLog(
|
|
@@ -266,6 +277,9 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`
|
|
|
266
277
|
}
|
|
267
278
|
}
|
|
268
279
|
programCommand = programCommand.option(`-v, --verbose [boolean]`, `verbose output`);
|
|
280
|
+
programCommand.helpInformation = () => {
|
|
281
|
+
return (0, import_helpFormatter.formatCommandHelp)(command, targetMeta.key);
|
|
282
|
+
};
|
|
269
283
|
programCommand.action(async (...args) => {
|
|
270
284
|
import_common.Logger.rawLog();
|
|
271
285
|
const cmdArgs = args.slice(0, args.length - 2);
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var helpFormatter_exports = {};
|
|
29
|
+
__export(helpFormatter_exports, {
|
|
30
|
+
formatCommandHelp: () => formatCommandHelp,
|
|
31
|
+
formatHelp: () => formatHelp
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(helpFormatter_exports);
|
|
34
|
+
var import_chalk = __toESM(require("chalk"));
|
|
35
|
+
var import_argMeta = require("./argMeta");
|
|
36
|
+
var import_targetMeta = require("./targetMeta");
|
|
37
|
+
const camelToKebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
38
|
+
const groupCommands = (commands) => {
|
|
39
|
+
const groups = /* @__PURE__ */ new Map();
|
|
40
|
+
for (const command of commands) {
|
|
41
|
+
const className = command.name.replace("Command", "");
|
|
42
|
+
const groupName = className;
|
|
43
|
+
if (!groups.has(groupName)) {
|
|
44
|
+
groups.set(groupName, { name: groupName, commands: [] });
|
|
45
|
+
}
|
|
46
|
+
const targetMetas = (0, import_targetMeta.getTargetMetas)(command);
|
|
47
|
+
for (const targetMeta of targetMetas) {
|
|
48
|
+
if (targetMeta.targetOption.devOnly)
|
|
49
|
+
continue;
|
|
50
|
+
const [allArgMetas] = (0, import_argMeta.getArgMetas)(command, targetMeta.key);
|
|
51
|
+
const args = allArgMetas.filter((arg) => arg.type !== "Option").map((arg) => {
|
|
52
|
+
if (arg.type === "Workspace")
|
|
53
|
+
return "";
|
|
54
|
+
if (arg.type === "Module")
|
|
55
|
+
return "[sys:module]";
|
|
56
|
+
if (arg.type === "Argument") {
|
|
57
|
+
return `[${arg.name}]`;
|
|
58
|
+
}
|
|
59
|
+
return `[${arg.type.toLowerCase()}]`;
|
|
60
|
+
}).filter(Boolean);
|
|
61
|
+
const group = groups.get(groupName);
|
|
62
|
+
if (group) {
|
|
63
|
+
group.commands.push({
|
|
64
|
+
key: camelToKebabCase(targetMeta.key),
|
|
65
|
+
args,
|
|
66
|
+
desc: targetMeta.targetOption.desc
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return groups;
|
|
72
|
+
};
|
|
73
|
+
const formatHelp = (commands, version) => {
|
|
74
|
+
const groups = groupCommands(commands);
|
|
75
|
+
const lines = [];
|
|
76
|
+
lines.push("");
|
|
77
|
+
lines.push(import_chalk.default.bold.cyan(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
78
|
+
lines.push(
|
|
79
|
+
import_chalk.default.bold.cyan(" \u2551") + import_chalk.default.bold.white(" Akan.js Framework CLI ") + import_chalk.default.bold.cyan(" \u2551")
|
|
80
|
+
);
|
|
81
|
+
lines.push(import_chalk.default.bold.cyan(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
|
|
82
|
+
lines.push("");
|
|
83
|
+
lines.push(import_chalk.default.gray(` Version: ${version}`));
|
|
84
|
+
lines.push("");
|
|
85
|
+
lines.push(import_chalk.default.bold.yellow(" USAGE"));
|
|
86
|
+
lines.push("");
|
|
87
|
+
lines.push(import_chalk.default.gray(" $ ") + import_chalk.default.white("akan") + import_chalk.default.gray(" <command> [options]"));
|
|
88
|
+
lines.push("");
|
|
89
|
+
lines.push(import_chalk.default.bold.yellow(" COMMANDS"));
|
|
90
|
+
lines.push("");
|
|
91
|
+
for (const [groupName, group] of groups) {
|
|
92
|
+
if (group.commands.length === 0)
|
|
93
|
+
continue;
|
|
94
|
+
lines.push(import_chalk.default.bold.magenta(` ${groupName}`));
|
|
95
|
+
lines.push("");
|
|
96
|
+
for (const cmd of group.commands) {
|
|
97
|
+
const cmdName = import_chalk.default.green(cmd.key);
|
|
98
|
+
const cmdArgs = cmd.args.length > 0 ? import_chalk.default.gray(` ${cmd.args.join(" ")}`) : "";
|
|
99
|
+
if (cmd.desc) {
|
|
100
|
+
const maxLineLength = 70;
|
|
101
|
+
const cmdPrefix = ` ${cmdName}${cmdArgs}`;
|
|
102
|
+
const indent = " ";
|
|
103
|
+
if (cmdPrefix.length + cmd.desc.length + 3 < maxLineLength) {
|
|
104
|
+
lines.push(`${cmdPrefix} ${import_chalk.default.gray(cmd.desc)}`);
|
|
105
|
+
} else {
|
|
106
|
+
lines.push(cmdPrefix);
|
|
107
|
+
lines.push(`${indent}${import_chalk.default.gray(cmd.desc)}`);
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
lines.push(` ${cmdName}${cmdArgs}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
lines.push("");
|
|
114
|
+
}
|
|
115
|
+
lines.push(import_chalk.default.bold.yellow(" OPTIONS"));
|
|
116
|
+
lines.push("");
|
|
117
|
+
lines.push(` ${import_chalk.default.green("-v, --verbose")} ${import_chalk.default.gray("Enable verbose output")}`);
|
|
118
|
+
lines.push(` ${import_chalk.default.green("-h, --help")} ${import_chalk.default.gray("Display this help message")}`);
|
|
119
|
+
lines.push(` ${import_chalk.default.green("-V, --version")} ${import_chalk.default.gray("Output version number")}`);
|
|
120
|
+
lines.push("");
|
|
121
|
+
lines.push(import_chalk.default.bold.yellow(" EXAMPLES"));
|
|
122
|
+
lines.push("");
|
|
123
|
+
lines.push(import_chalk.default.gray(" # Create a new workspace"));
|
|
124
|
+
lines.push(import_chalk.default.white(" $ akan create-workspace myproject"));
|
|
125
|
+
lines.push("");
|
|
126
|
+
lines.push(import_chalk.default.gray(" # Start development server"));
|
|
127
|
+
lines.push(import_chalk.default.white(" $ akan start myapp"));
|
|
128
|
+
lines.push("");
|
|
129
|
+
lines.push(import_chalk.default.gray(" # Create a new module"));
|
|
130
|
+
lines.push(import_chalk.default.white(" $ akan create-module userProfile"));
|
|
131
|
+
lines.push("");
|
|
132
|
+
lines.push(import_chalk.default.gray(" Documentation: ") + import_chalk.default.cyan("https://akanjs.com/docs"));
|
|
133
|
+
lines.push(import_chalk.default.gray(" Report issues: ") + import_chalk.default.cyan("https://github.com/akan-team/akanjs/issues"));
|
|
134
|
+
lines.push("");
|
|
135
|
+
return lines.join("\n");
|
|
136
|
+
};
|
|
137
|
+
const formatCommandHelp = (command, key) => {
|
|
138
|
+
const [allArgMetas, argMetas] = (0, import_argMeta.getArgMetas)(command, key);
|
|
139
|
+
const kebabKey = camelToKebabCase(key);
|
|
140
|
+
const lines = [];
|
|
141
|
+
const targetMetas = (0, import_targetMeta.getTargetMetas)(command);
|
|
142
|
+
const targetMeta = targetMetas.find((t) => t.key === key);
|
|
143
|
+
const commandDesc = targetMeta?.targetOption.desc;
|
|
144
|
+
lines.push("");
|
|
145
|
+
lines.push(import_chalk.default.bold.cyan(` Command: ${kebabKey}`));
|
|
146
|
+
if (commandDesc) {
|
|
147
|
+
lines.push(import_chalk.default.gray(` ${commandDesc}`));
|
|
148
|
+
}
|
|
149
|
+
lines.push("");
|
|
150
|
+
const args = allArgMetas.filter((arg) => arg.type !== "Option").map((arg) => {
|
|
151
|
+
if (arg.type === "Workspace")
|
|
152
|
+
return "";
|
|
153
|
+
if (arg.type === "Module")
|
|
154
|
+
return "[sys:module]";
|
|
155
|
+
if (arg.type === "Argument") {
|
|
156
|
+
return `[${camelToKebabCase(arg.name)}]`;
|
|
157
|
+
}
|
|
158
|
+
return `[${arg.type.toLowerCase()}]`;
|
|
159
|
+
}).filter(Boolean).join(" ");
|
|
160
|
+
lines.push(import_chalk.default.bold.yellow(" USAGE"));
|
|
161
|
+
lines.push("");
|
|
162
|
+
lines.push(import_chalk.default.gray(" $ ") + import_chalk.default.white(`akan ${kebabKey}`) + (args ? import_chalk.default.gray(` ${args}`) : ""));
|
|
163
|
+
lines.push("");
|
|
164
|
+
const nonOptionArgs = allArgMetas.filter((arg) => arg.type !== "Option");
|
|
165
|
+
if (nonOptionArgs.length > 0) {
|
|
166
|
+
lines.push(import_chalk.default.bold.yellow(" ARGUMENTS"));
|
|
167
|
+
lines.push("");
|
|
168
|
+
for (const arg of nonOptionArgs) {
|
|
169
|
+
if (arg.type === "Workspace")
|
|
170
|
+
continue;
|
|
171
|
+
let argName;
|
|
172
|
+
let argDesc;
|
|
173
|
+
let example = "";
|
|
174
|
+
if (arg.type === "Argument") {
|
|
175
|
+
argName = camelToKebabCase(arg.name);
|
|
176
|
+
argDesc = arg.argsOption.desc ?? "";
|
|
177
|
+
example = arg.argsOption.example ? import_chalk.default.gray(` (e.g., ${String(arg.argsOption.example)})`) : "";
|
|
178
|
+
} else if (arg.type === "Module") {
|
|
179
|
+
argName = "sys:module";
|
|
180
|
+
argDesc = "Module in format: app-name:module-name or lib-name:module-name";
|
|
181
|
+
} else {
|
|
182
|
+
argName = arg.type.toLowerCase();
|
|
183
|
+
argDesc = `${arg.type} name in this workspace`;
|
|
184
|
+
}
|
|
185
|
+
lines.push(` ${import_chalk.default.green(argName)} ${import_chalk.default.gray(argDesc)}${example}`);
|
|
186
|
+
}
|
|
187
|
+
lines.push("");
|
|
188
|
+
}
|
|
189
|
+
const optionArgs = argMetas.filter((a) => a.type === "Option");
|
|
190
|
+
if (optionArgs.length > 0) {
|
|
191
|
+
lines.push(import_chalk.default.bold.yellow(" OPTIONS"));
|
|
192
|
+
lines.push("");
|
|
193
|
+
for (const arg of optionArgs) {
|
|
194
|
+
const opt = arg.argsOption;
|
|
195
|
+
const flag = opt.flag ? `-${opt.flag}, ` : "";
|
|
196
|
+
const kebabName = camelToKebabCase(arg.name);
|
|
197
|
+
const optName = `${flag}--${kebabName}`;
|
|
198
|
+
const optDesc = opt.desc ?? "";
|
|
199
|
+
const defaultVal = opt.default !== void 0 ? import_chalk.default.gray(` [default: ${String(opt.default)}]`) : "";
|
|
200
|
+
const choices = opt.enum ? import_chalk.default.gray(` (${opt.enum.join(", ")})`) : "";
|
|
201
|
+
lines.push(` ${import_chalk.default.green(optName)} ${import_chalk.default.gray(optDesc)}${defaultVal}${choices}`);
|
|
202
|
+
}
|
|
203
|
+
lines.push("");
|
|
204
|
+
}
|
|
205
|
+
return lines.join("\n");
|
|
206
|
+
};
|
|
207
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
208
|
+
0 && (module.exports = {
|
|
209
|
+
formatCommandHelp,
|
|
210
|
+
formatHelp
|
|
211
|
+
});
|
|
@@ -18,6 +18,7 @@ __reExport(commandDecorators_exports, require("./argMeta"), module.exports);
|
|
|
18
18
|
__reExport(commandDecorators_exports, require("./commandMeta"), module.exports);
|
|
19
19
|
__reExport(commandDecorators_exports, require("./targetMeta"), module.exports);
|
|
20
20
|
__reExport(commandDecorators_exports, require("./types"), module.exports);
|
|
21
|
+
__reExport(commandDecorators_exports, require("./helpFormatter"), module.exports);
|
|
21
22
|
__reExport(commandDecorators_exports, require("./command"), module.exports);
|
|
22
23
|
// Annotate the CommonJS export names for ESM import in node:
|
|
23
24
|
0 && (module.exports = {
|
|
@@ -25,5 +26,6 @@ __reExport(commandDecorators_exports, require("./command"), module.exports);
|
|
|
25
26
|
...require("./commandMeta"),
|
|
26
27
|
...require("./targetMeta"),
|
|
27
28
|
...require("./types"),
|
|
29
|
+
...require("./helpFormatter"),
|
|
28
30
|
...require("./command")
|
|
29
31
|
});
|
|
@@ -6,6 +6,7 @@ import fs from "fs";
|
|
|
6
6
|
import { getDirname } from "..";
|
|
7
7
|
import { AppExecutor, Executor, LibExecutor, ModuleExecutor, PkgExecutor, WorkspaceExecutor } from "../executors";
|
|
8
8
|
import { getArgMetas } from "./argMeta";
|
|
9
|
+
import { formatCommandHelp, formatHelp } from "./helpFormatter";
|
|
9
10
|
import { getTargetMetas } from "./targetMeta";
|
|
10
11
|
const camelToKebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
11
12
|
const handleOption = (programCommand, argMeta) => {
|
|
@@ -188,7 +189,17 @@ const runCommands = async (...commands) => {
|
|
|
188
189
|
const __dirname = getDirname(import.meta.url);
|
|
189
190
|
const hasPackageJson = fs.existsSync(`${__dirname}/../package.json`);
|
|
190
191
|
process.env.AKAN_VERSION = hasPackageJson ? JSON.parse(fs.readFileSync(`${__dirname}/../package.json`, "utf8")).version : "0.0.1";
|
|
191
|
-
|
|
192
|
+
const hasHelpFlag = process.argv.includes("--help") || process.argv.includes("-h");
|
|
193
|
+
const hasCommand = process.argv.length > 2 && !process.argv[2].startsWith("-");
|
|
194
|
+
if (hasHelpFlag || !hasCommand) {
|
|
195
|
+
if (process.argv.length === 2 || process.argv.length === 3 && hasHelpFlag) {
|
|
196
|
+
Logger.rawLog(formatHelp(commands, process.env.AKAN_VERSION));
|
|
197
|
+
process.exit(0);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
program.version(process.env.AKAN_VERSION).description("Akan CLI").configureHelp({
|
|
201
|
+
helpWidth: 100
|
|
202
|
+
});
|
|
192
203
|
const akanBasePackageJson = fs.existsSync("./node_modules/@akanjs/base/package.json") ? JSON.parse(fs.readFileSync("./node_modules/@akanjs/base/package.json", "utf8")) : null;
|
|
193
204
|
if (akanBasePackageJson && akanBasePackageJson.version !== process.env.AKAN_VERSION) {
|
|
194
205
|
Logger.rawLog(
|
|
@@ -233,6 +244,9 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`
|
|
|
233
244
|
}
|
|
234
245
|
}
|
|
235
246
|
programCommand = programCommand.option(`-v, --verbose [boolean]`, `verbose output`);
|
|
247
|
+
programCommand.helpInformation = () => {
|
|
248
|
+
return formatCommandHelp(command, targetMeta.key);
|
|
249
|
+
};
|
|
236
250
|
programCommand.action(async (...args) => {
|
|
237
251
|
Logger.rawLog();
|
|
238
252
|
const cmdArgs = args.slice(0, args.length - 2);
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { getArgMetas } from "./argMeta";
|
|
3
|
+
import { getTargetMetas } from "./targetMeta";
|
|
4
|
+
const camelToKebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
5
|
+
const groupCommands = (commands) => {
|
|
6
|
+
const groups = /* @__PURE__ */ new Map();
|
|
7
|
+
for (const command of commands) {
|
|
8
|
+
const className = command.name.replace("Command", "");
|
|
9
|
+
const groupName = className;
|
|
10
|
+
if (!groups.has(groupName)) {
|
|
11
|
+
groups.set(groupName, { name: groupName, commands: [] });
|
|
12
|
+
}
|
|
13
|
+
const targetMetas = getTargetMetas(command);
|
|
14
|
+
for (const targetMeta of targetMetas) {
|
|
15
|
+
if (targetMeta.targetOption.devOnly)
|
|
16
|
+
continue;
|
|
17
|
+
const [allArgMetas] = getArgMetas(command, targetMeta.key);
|
|
18
|
+
const args = allArgMetas.filter((arg) => arg.type !== "Option").map((arg) => {
|
|
19
|
+
if (arg.type === "Workspace")
|
|
20
|
+
return "";
|
|
21
|
+
if (arg.type === "Module")
|
|
22
|
+
return "[sys:module]";
|
|
23
|
+
if (arg.type === "Argument") {
|
|
24
|
+
return `[${arg.name}]`;
|
|
25
|
+
}
|
|
26
|
+
return `[${arg.type.toLowerCase()}]`;
|
|
27
|
+
}).filter(Boolean);
|
|
28
|
+
const group = groups.get(groupName);
|
|
29
|
+
if (group) {
|
|
30
|
+
group.commands.push({
|
|
31
|
+
key: camelToKebabCase(targetMeta.key),
|
|
32
|
+
args,
|
|
33
|
+
desc: targetMeta.targetOption.desc
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return groups;
|
|
39
|
+
};
|
|
40
|
+
const formatHelp = (commands, version) => {
|
|
41
|
+
const groups = groupCommands(commands);
|
|
42
|
+
const lines = [];
|
|
43
|
+
lines.push("");
|
|
44
|
+
lines.push(chalk.bold.cyan(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
|
|
45
|
+
lines.push(
|
|
46
|
+
chalk.bold.cyan(" \u2551") + chalk.bold.white(" Akan.js Framework CLI ") + chalk.bold.cyan(" \u2551")
|
|
47
|
+
);
|
|
48
|
+
lines.push(chalk.bold.cyan(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
|
|
49
|
+
lines.push("");
|
|
50
|
+
lines.push(chalk.gray(` Version: ${version}`));
|
|
51
|
+
lines.push("");
|
|
52
|
+
lines.push(chalk.bold.yellow(" USAGE"));
|
|
53
|
+
lines.push("");
|
|
54
|
+
lines.push(chalk.gray(" $ ") + chalk.white("akan") + chalk.gray(" <command> [options]"));
|
|
55
|
+
lines.push("");
|
|
56
|
+
lines.push(chalk.bold.yellow(" COMMANDS"));
|
|
57
|
+
lines.push("");
|
|
58
|
+
for (const [groupName, group] of groups) {
|
|
59
|
+
if (group.commands.length === 0)
|
|
60
|
+
continue;
|
|
61
|
+
lines.push(chalk.bold.magenta(` ${groupName}`));
|
|
62
|
+
lines.push("");
|
|
63
|
+
for (const cmd of group.commands) {
|
|
64
|
+
const cmdName = chalk.green(cmd.key);
|
|
65
|
+
const cmdArgs = cmd.args.length > 0 ? chalk.gray(` ${cmd.args.join(" ")}`) : "";
|
|
66
|
+
if (cmd.desc) {
|
|
67
|
+
const maxLineLength = 70;
|
|
68
|
+
const cmdPrefix = ` ${cmdName}${cmdArgs}`;
|
|
69
|
+
const indent = " ";
|
|
70
|
+
if (cmdPrefix.length + cmd.desc.length + 3 < maxLineLength) {
|
|
71
|
+
lines.push(`${cmdPrefix} ${chalk.gray(cmd.desc)}`);
|
|
72
|
+
} else {
|
|
73
|
+
lines.push(cmdPrefix);
|
|
74
|
+
lines.push(`${indent}${chalk.gray(cmd.desc)}`);
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
lines.push(` ${cmdName}${cmdArgs}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
lines.push("");
|
|
81
|
+
}
|
|
82
|
+
lines.push(chalk.bold.yellow(" OPTIONS"));
|
|
83
|
+
lines.push("");
|
|
84
|
+
lines.push(` ${chalk.green("-v, --verbose")} ${chalk.gray("Enable verbose output")}`);
|
|
85
|
+
lines.push(` ${chalk.green("-h, --help")} ${chalk.gray("Display this help message")}`);
|
|
86
|
+
lines.push(` ${chalk.green("-V, --version")} ${chalk.gray("Output version number")}`);
|
|
87
|
+
lines.push("");
|
|
88
|
+
lines.push(chalk.bold.yellow(" EXAMPLES"));
|
|
89
|
+
lines.push("");
|
|
90
|
+
lines.push(chalk.gray(" # Create a new workspace"));
|
|
91
|
+
lines.push(chalk.white(" $ akan create-workspace myproject"));
|
|
92
|
+
lines.push("");
|
|
93
|
+
lines.push(chalk.gray(" # Start development server"));
|
|
94
|
+
lines.push(chalk.white(" $ akan start myapp"));
|
|
95
|
+
lines.push("");
|
|
96
|
+
lines.push(chalk.gray(" # Create a new module"));
|
|
97
|
+
lines.push(chalk.white(" $ akan create-module userProfile"));
|
|
98
|
+
lines.push("");
|
|
99
|
+
lines.push(chalk.gray(" Documentation: ") + chalk.cyan("https://akanjs.com/docs"));
|
|
100
|
+
lines.push(chalk.gray(" Report issues: ") + chalk.cyan("https://github.com/akan-team/akanjs/issues"));
|
|
101
|
+
lines.push("");
|
|
102
|
+
return lines.join("\n");
|
|
103
|
+
};
|
|
104
|
+
const formatCommandHelp = (command, key) => {
|
|
105
|
+
const [allArgMetas, argMetas] = getArgMetas(command, key);
|
|
106
|
+
const kebabKey = camelToKebabCase(key);
|
|
107
|
+
const lines = [];
|
|
108
|
+
const targetMetas = getTargetMetas(command);
|
|
109
|
+
const targetMeta = targetMetas.find((t) => t.key === key);
|
|
110
|
+
const commandDesc = targetMeta?.targetOption.desc;
|
|
111
|
+
lines.push("");
|
|
112
|
+
lines.push(chalk.bold.cyan(` Command: ${kebabKey}`));
|
|
113
|
+
if (commandDesc) {
|
|
114
|
+
lines.push(chalk.gray(` ${commandDesc}`));
|
|
115
|
+
}
|
|
116
|
+
lines.push("");
|
|
117
|
+
const args = allArgMetas.filter((arg) => arg.type !== "Option").map((arg) => {
|
|
118
|
+
if (arg.type === "Workspace")
|
|
119
|
+
return "";
|
|
120
|
+
if (arg.type === "Module")
|
|
121
|
+
return "[sys:module]";
|
|
122
|
+
if (arg.type === "Argument") {
|
|
123
|
+
return `[${camelToKebabCase(arg.name)}]`;
|
|
124
|
+
}
|
|
125
|
+
return `[${arg.type.toLowerCase()}]`;
|
|
126
|
+
}).filter(Boolean).join(" ");
|
|
127
|
+
lines.push(chalk.bold.yellow(" USAGE"));
|
|
128
|
+
lines.push("");
|
|
129
|
+
lines.push(chalk.gray(" $ ") + chalk.white(`akan ${kebabKey}`) + (args ? chalk.gray(` ${args}`) : ""));
|
|
130
|
+
lines.push("");
|
|
131
|
+
const nonOptionArgs = allArgMetas.filter((arg) => arg.type !== "Option");
|
|
132
|
+
if (nonOptionArgs.length > 0) {
|
|
133
|
+
lines.push(chalk.bold.yellow(" ARGUMENTS"));
|
|
134
|
+
lines.push("");
|
|
135
|
+
for (const arg of nonOptionArgs) {
|
|
136
|
+
if (arg.type === "Workspace")
|
|
137
|
+
continue;
|
|
138
|
+
let argName;
|
|
139
|
+
let argDesc;
|
|
140
|
+
let example = "";
|
|
141
|
+
if (arg.type === "Argument") {
|
|
142
|
+
argName = camelToKebabCase(arg.name);
|
|
143
|
+
argDesc = arg.argsOption.desc ?? "";
|
|
144
|
+
example = arg.argsOption.example ? chalk.gray(` (e.g., ${String(arg.argsOption.example)})`) : "";
|
|
145
|
+
} else if (arg.type === "Module") {
|
|
146
|
+
argName = "sys:module";
|
|
147
|
+
argDesc = "Module in format: app-name:module-name or lib-name:module-name";
|
|
148
|
+
} else {
|
|
149
|
+
argName = arg.type.toLowerCase();
|
|
150
|
+
argDesc = `${arg.type} name in this workspace`;
|
|
151
|
+
}
|
|
152
|
+
lines.push(` ${chalk.green(argName)} ${chalk.gray(argDesc)}${example}`);
|
|
153
|
+
}
|
|
154
|
+
lines.push("");
|
|
155
|
+
}
|
|
156
|
+
const optionArgs = argMetas.filter((a) => a.type === "Option");
|
|
157
|
+
if (optionArgs.length > 0) {
|
|
158
|
+
lines.push(chalk.bold.yellow(" OPTIONS"));
|
|
159
|
+
lines.push("");
|
|
160
|
+
for (const arg of optionArgs) {
|
|
161
|
+
const opt = arg.argsOption;
|
|
162
|
+
const flag = opt.flag ? `-${opt.flag}, ` : "";
|
|
163
|
+
const kebabName = camelToKebabCase(arg.name);
|
|
164
|
+
const optName = `${flag}--${kebabName}`;
|
|
165
|
+
const optDesc = opt.desc ?? "";
|
|
166
|
+
const defaultVal = opt.default !== void 0 ? chalk.gray(` [default: ${String(opt.default)}]`) : "";
|
|
167
|
+
const choices = opt.enum ? chalk.gray(` (${opt.enum.join(", ")})`) : "";
|
|
168
|
+
lines.push(` ${chalk.green(optName)} ${chalk.gray(optDesc)}${defaultVal}${choices}`);
|
|
169
|
+
}
|
|
170
|
+
lines.push("");
|
|
171
|
+
}
|
|
172
|
+
return lines.join("\n");
|
|
173
|
+
};
|
|
174
|
+
export {
|
|
175
|
+
formatCommandHelp,
|
|
176
|
+
formatHelp
|
|
177
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/devkit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"sourceType": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dotenv": "^16.4.7",
|
|
29
29
|
"esbuild": "^0.19.2",
|
|
30
30
|
"esbuild-plugin-d.ts": "^1.3.1",
|
|
31
|
-
"eslint": "^9.
|
|
31
|
+
"eslint": "^9.0.0",
|
|
32
32
|
"form-data": "^4.0.1",
|
|
33
33
|
"ignore": "^7.0.5",
|
|
34
34
|
"ink": "^6.1.0",
|
|
@@ -9,6 +9,7 @@ interface TargetOption {
|
|
|
9
9
|
type: "public" | "cloud" | "dev";
|
|
10
10
|
short?: string | true;
|
|
11
11
|
devOnly?: boolean;
|
|
12
|
+
desc?: string;
|
|
12
13
|
}
|
|
13
14
|
export declare const Target: {
|
|
14
15
|
Public: (targetOption?: Omit<TargetOption, "type">) => (prototype: object, key: string, descriptor: PropertyDescriptor) => void;
|