@expressots/cli 1.3.4 → 1.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/app.container.js +1 -1
- package/bin/generate/cli.js +4 -7
- package/bin/generate/form.js +6 -1
- package/bin/generate/templates/module-default.tpl +3 -0
- package/bin/new/cli.js +11 -3
- package/bin/new/form.js +16 -3
- package/bin/utils/add-controller-to-module.js +13 -7
- package/bin/utils/add-module-to-container.js +26 -14
- package/bin/utils/center-text.js +1 -1
- package/bin/utils/verify-file-exists.js +2 -2
- package/package.json +20 -13
package/bin/app.container.js
CHANGED
package/bin/generate/cli.js
CHANGED
|
@@ -16,6 +16,8 @@ const coerceSchematicAliases = (arg) => {
|
|
|
16
16
|
return "provider";
|
|
17
17
|
case "e":
|
|
18
18
|
return "entity";
|
|
19
|
+
case "m":
|
|
20
|
+
return "module";
|
|
19
21
|
default:
|
|
20
22
|
return arg;
|
|
21
23
|
}
|
|
@@ -34,6 +36,7 @@ const generateProject = () => {
|
|
|
34
36
|
"service",
|
|
35
37
|
"provider",
|
|
36
38
|
"entity",
|
|
39
|
+
"module",
|
|
37
40
|
],
|
|
38
41
|
describe: "The schematic to generate",
|
|
39
42
|
type: "string",
|
|
@@ -45,13 +48,7 @@ const generateProject = () => {
|
|
|
45
48
|
alias: "d",
|
|
46
49
|
});
|
|
47
50
|
yargs.positional("method", {
|
|
48
|
-
choices: [
|
|
49
|
-
"get",
|
|
50
|
-
"post",
|
|
51
|
-
"put",
|
|
52
|
-
"patch",
|
|
53
|
-
"delete",
|
|
54
|
-
],
|
|
51
|
+
choices: ["get", "post", "put", "patch", "delete"],
|
|
55
52
|
describe: "HTTP method",
|
|
56
53
|
type: "string",
|
|
57
54
|
alias: "m",
|
package/bin/generate/form.js
CHANGED
|
@@ -77,12 +77,17 @@ const createTemplate = async ({ schematic, path: target, method, }) => {
|
|
|
77
77
|
else {
|
|
78
78
|
routeSchema = path.replace(/\/$/, "");
|
|
79
79
|
}
|
|
80
|
+
let templateBasedSchematic = schematic;
|
|
81
|
+
if (schematic === "module") {
|
|
82
|
+
templateBasedSchematic = "module-default";
|
|
83
|
+
}
|
|
80
84
|
writeTemplate({
|
|
81
85
|
outputPath: `${usecaseDir}/${path}/${file}`,
|
|
82
86
|
template: {
|
|
83
|
-
path: `./templates/${
|
|
87
|
+
path: `./templates/${templateBasedSchematic}.tpl`,
|
|
84
88
|
data: {
|
|
85
89
|
className,
|
|
90
|
+
moduleName: className,
|
|
86
91
|
route: routeSchema,
|
|
87
92
|
construct: (0, boost_ts_1.anyCaseToKebabCase)(className),
|
|
88
93
|
method: getHttpMethod(method),
|
package/bin/new/cli.js
CHANGED
|
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createProject = void 0;
|
|
4
4
|
const form_1 = require("./form");
|
|
5
5
|
const createProject = () => {
|
|
6
|
+
const packageManagers = ["npm", "yarn", "pnpm"];
|
|
7
|
+
if (process.platform !== "win32") {
|
|
8
|
+
packageManagers.push("bun");
|
|
9
|
+
}
|
|
6
10
|
return {
|
|
7
11
|
command: "new <project-name> [package-manager] [template] [directory]",
|
|
8
12
|
describe: "Create a new project",
|
|
@@ -21,7 +25,7 @@ const createProject = () => {
|
|
|
21
25
|
.option("package-manager", {
|
|
22
26
|
describe: "The package manager to use",
|
|
23
27
|
type: "string",
|
|
24
|
-
choices:
|
|
28
|
+
choices: packageManagers,
|
|
25
29
|
alias: "p",
|
|
26
30
|
})
|
|
27
31
|
.option("directory", {
|
|
@@ -33,8 +37,12 @@ const createProject = () => {
|
|
|
33
37
|
.implies("template", "package-manager");
|
|
34
38
|
return yargs;
|
|
35
39
|
},
|
|
36
|
-
handler: async ({ projectName, packageManager, template, directory }) => {
|
|
37
|
-
return await (0, form_1.projectForm)(projectName, [
|
|
40
|
+
handler: async ({ projectName, packageManager, template, directory, }) => {
|
|
41
|
+
return await (0, form_1.projectForm)(projectName, [
|
|
42
|
+
packageManager,
|
|
43
|
+
template,
|
|
44
|
+
directory,
|
|
45
|
+
]);
|
|
38
46
|
},
|
|
39
47
|
};
|
|
40
48
|
};
|
package/bin/new/form.js
CHANGED
|
@@ -73,7 +73,10 @@ const projectForm = async (projectName, args) => {
|
|
|
73
73
|
// Resolving the argument order problem
|
|
74
74
|
for (const arg of args) {
|
|
75
75
|
if (args.length >= 3) {
|
|
76
|
-
if (arg === "npm" ||
|
|
76
|
+
if (arg === "npm" ||
|
|
77
|
+
arg === "yarn" ||
|
|
78
|
+
arg === "pnpm" ||
|
|
79
|
+
arg === "bun") {
|
|
77
80
|
packageManager = arg;
|
|
78
81
|
}
|
|
79
82
|
else if (arg === "non-opinionated" || arg === "opinionated") {
|
|
@@ -107,7 +110,7 @@ const projectForm = async (projectName, args) => {
|
|
|
107
110
|
type: "list",
|
|
108
111
|
name: "packageManager",
|
|
109
112
|
message: "Package manager",
|
|
110
|
-
choices: ["npm", "yarn", "pnpm"],
|
|
113
|
+
choices: ["npm", "yarn", "pnpm", "bun"],
|
|
111
114
|
},
|
|
112
115
|
{
|
|
113
116
|
type: "list",
|
|
@@ -141,10 +144,17 @@ const projectForm = async (projectName, args) => {
|
|
|
141
144
|
Opinionated: "opinionated",
|
|
142
145
|
};
|
|
143
146
|
if (answer.confirm) {
|
|
147
|
+
// Check if package manager is bun and OS is Windows
|
|
148
|
+
if (answer.packageManager === "bun" && process.platform === "win32") {
|
|
149
|
+
(0, cli_ui_1.printError)("bun is not supported on Windows. Please use", "npm, yarn or pnpm");
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
144
152
|
await checkIfPackageManagerExists(answer.packageManager);
|
|
145
153
|
console.log("\n");
|
|
146
154
|
const progressBar = new cli_progress_1.SingleBar({
|
|
147
|
-
format: "Progress |" +
|
|
155
|
+
format: "Progress |" +
|
|
156
|
+
chalk_1.default.green("{bar}") +
|
|
157
|
+
"| {percentage}% || {doing}",
|
|
148
158
|
hideCursor: true,
|
|
149
159
|
}, cli_progress_1.Presets.shades_classic);
|
|
150
160
|
progressBar.start(100, 0, {
|
|
@@ -188,6 +198,9 @@ const projectForm = async (projectName, args) => {
|
|
|
188
198
|
case "pnpm":
|
|
189
199
|
console.log(chalk_1.default.bold.gray("$ pnpm run dev"));
|
|
190
200
|
break;
|
|
201
|
+
case "bun":
|
|
202
|
+
console.log(chalk_1.default.bold.gray("$ bun dev"));
|
|
203
|
+
break;
|
|
191
204
|
}
|
|
192
205
|
console.log("\n");
|
|
193
206
|
console.log(chalk_1.default.bold.green((0, center_text_1.centerText)("Happy coding!")));
|
|
@@ -6,11 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.addControllerToModule = void 0;
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
8
|
async function addControllerToModule(filePath, controllerName, controllerPath) {
|
|
9
|
-
const fileContent = await node_fs_1.default.promises.readFile(filePath,
|
|
9
|
+
const fileContent = await node_fs_1.default.promises.readFile(filePath, "utf8");
|
|
10
10
|
const imports = [];
|
|
11
11
|
const notImports = [];
|
|
12
|
-
fileContent.split(
|
|
13
|
-
if (line.startsWith(
|
|
12
|
+
fileContent.split("\n").forEach((line) => {
|
|
13
|
+
if (line.startsWith("import")) {
|
|
14
14
|
imports.push(line);
|
|
15
15
|
}
|
|
16
16
|
else {
|
|
@@ -27,14 +27,20 @@ async function addControllerToModule(filePath, controllerName, controllerPath) {
|
|
|
27
27
|
if (!moduleDeclarationMatch) {
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
|
-
const controllers = moduleDeclarationMatch[1]
|
|
30
|
+
const controllers = moduleDeclarationMatch[1]
|
|
31
|
+
.trim()
|
|
32
|
+
.split(",")
|
|
33
|
+
.map((c) => c.trim())
|
|
34
|
+
.filter((c) => c);
|
|
31
35
|
if (controllers.includes(controllerName)) {
|
|
32
36
|
return;
|
|
33
37
|
}
|
|
34
38
|
controllers.push(controllerName);
|
|
35
|
-
const newControllers = controllers.join(
|
|
39
|
+
const newControllers = controllers.join(", ");
|
|
36
40
|
const newModuleDeclaration = `CreateModule([${newControllers}]`;
|
|
37
|
-
const newFileContent = [...imports, ...notImports]
|
|
38
|
-
|
|
41
|
+
const newFileContent = [...imports, ...notImports]
|
|
42
|
+
.join("\n")
|
|
43
|
+
.replace(moduleDeclarationRegex, newModuleDeclaration);
|
|
44
|
+
await node_fs_1.default.promises.writeFile(filePath, newFileContent, "utf8");
|
|
39
45
|
}
|
|
40
46
|
exports.addControllerToModule = addControllerToModule;
|
|
@@ -14,14 +14,17 @@ async function validateAppContainer() {
|
|
|
14
14
|
const { sourceRoot } = await compiler_1.default.loadConfig();
|
|
15
15
|
const imports = [];
|
|
16
16
|
const notImports = [];
|
|
17
|
-
const path = (0, glob_1.globSync)(`./${sourceRoot}/${APP_CONTAINER}`, {
|
|
17
|
+
const path = (0, glob_1.globSync)(`./${sourceRoot}/${APP_CONTAINER}`, {
|
|
18
|
+
absolute: true,
|
|
19
|
+
ignore: "**/node_modules/**",
|
|
20
|
+
});
|
|
18
21
|
if (!path.length) {
|
|
19
|
-
(0, cli_ui_1.printError)(
|
|
22
|
+
(0, cli_ui_1.printError)("Module not added to Container. Container file not found!", APP_CONTAINER);
|
|
20
23
|
process.exit(1);
|
|
21
24
|
}
|
|
22
|
-
const fileContent = await node_fs_1.default.promises.readFile(path[0],
|
|
23
|
-
fileContent.split(
|
|
24
|
-
if (line.startsWith(
|
|
25
|
+
const fileContent = await node_fs_1.default.promises.readFile(path[0], "utf8");
|
|
26
|
+
fileContent.split("\n").forEach((line) => {
|
|
27
|
+
if (line.startsWith("import")) {
|
|
25
28
|
imports.push(line);
|
|
26
29
|
}
|
|
27
30
|
else {
|
|
@@ -32,17 +35,21 @@ async function validateAppContainer() {
|
|
|
32
35
|
const moduleDeclarationRegex = /.create\(\s*\[([\s\S]*?)]/;
|
|
33
36
|
const moduleDeclarationMatch = fileContent.match(moduleDeclarationRegex);
|
|
34
37
|
if (!moduleDeclarationMatch) {
|
|
35
|
-
(0, cli_ui_1.printError)(
|
|
38
|
+
(0, cli_ui_1.printError)("Container format incorrect!", APP_CONTAINER);
|
|
36
39
|
process.exit(1);
|
|
37
40
|
}
|
|
38
|
-
const modules = moduleDeclarationMatch[1]
|
|
41
|
+
const modules = moduleDeclarationMatch[1]
|
|
42
|
+
.trim()
|
|
43
|
+
.split(",")
|
|
44
|
+
.filter((m) => m.trim() !== "")
|
|
45
|
+
.map((m) => m.trim());
|
|
39
46
|
return {
|
|
40
47
|
regex: moduleDeclarationRegex,
|
|
41
48
|
path: path[0],
|
|
42
49
|
content: moduleDeclarationMatch,
|
|
43
50
|
modules,
|
|
44
51
|
imports,
|
|
45
|
-
notImports
|
|
52
|
+
notImports,
|
|
46
53
|
};
|
|
47
54
|
}
|
|
48
55
|
async function addModuleToContainer(name, modulePath, path) {
|
|
@@ -59,7 +66,7 @@ async function addModuleToContainer(name, modulePath, path) {
|
|
|
59
66
|
let newImport = "";
|
|
60
67
|
const modulePathRegex = /^[^/]=$/;
|
|
61
68
|
if (!modulePathRegex.test(modulePath)) {
|
|
62
|
-
if (path.split(
|
|
69
|
+
if (path.split("/").length > 1) {
|
|
63
70
|
newImport = `import { ${moduleName}Module } from "${usecaseDir}${modulePath}/${name}.module";`;
|
|
64
71
|
}
|
|
65
72
|
else {
|
|
@@ -69,16 +76,21 @@ async function addModuleToContainer(name, modulePath, path) {
|
|
|
69
76
|
else {
|
|
70
77
|
newImport = `import { ${moduleName}Module } from "${usecaseDir}${name}/${name}.module";`;
|
|
71
78
|
}
|
|
72
|
-
if (containerData.imports.includes(newImport) &&
|
|
79
|
+
if (containerData.imports.includes(newImport) &&
|
|
80
|
+
containerData.modules.includes(`${moduleName}Module`)) {
|
|
73
81
|
return;
|
|
74
82
|
}
|
|
75
83
|
containerData.imports.push(newImport);
|
|
76
84
|
containerData.modules.push(`${moduleName}Module`);
|
|
77
|
-
const newModule = containerData.modules.join(
|
|
85
|
+
const newModule = containerData.modules.join(", ");
|
|
78
86
|
const newModuleDeclaration = `.create([${newModule}]`;
|
|
79
|
-
const newFileContent = [
|
|
80
|
-
|
|
87
|
+
const newFileContent = [
|
|
88
|
+
...containerData.imports,
|
|
89
|
+
...containerData.notImports,
|
|
90
|
+
]
|
|
91
|
+
.join("\n")
|
|
92
|
+
.replace(containerData.regex, newModuleDeclaration);
|
|
81
93
|
console.log(" ", chalk_1.default.greenBright(`[container]`.padEnd(14)), chalk_1.default.bold.white(`${moduleName}Module added to ${APP_CONTAINER}! ✔️`));
|
|
82
|
-
await node_fs_1.default.promises.writeFile(containerData.path, newFileContent,
|
|
94
|
+
await node_fs_1.default.promises.writeFile(containerData.path, newFileContent, "utf8");
|
|
83
95
|
}
|
|
84
96
|
exports.addModuleToContainer = addModuleToContainer;
|
package/bin/utils/center-text.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.centerText = void 0;
|
|
|
4
4
|
function centerText(text) {
|
|
5
5
|
const terminalWidth = process.stdout.columns;
|
|
6
6
|
const padding = Math.floor((terminalWidth - text.length) / 2);
|
|
7
|
-
const centeredText =
|
|
7
|
+
const centeredText = " ".repeat(padding) + text;
|
|
8
8
|
return centeredText;
|
|
9
9
|
}
|
|
10
10
|
exports.centerText = centerText;
|
|
@@ -18,9 +18,9 @@ async function verifyIfFileExists(path) {
|
|
|
18
18
|
default: true,
|
|
19
19
|
},
|
|
20
20
|
]);
|
|
21
|
-
const fileName = path.split(
|
|
21
|
+
const fileName = path.split("/").pop();
|
|
22
22
|
if (!answer.confirm) {
|
|
23
|
-
(0, cli_ui_1.printError)(
|
|
23
|
+
(0, cli_ui_1.printError)("File not created!", fileName);
|
|
24
24
|
process.exit(1);
|
|
25
25
|
}
|
|
26
26
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expressots/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Expressots CLI - modern, fast, lightweight nodejs web framework (@cli)",
|
|
5
5
|
"author": "Richard Zampieri",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,26 +31,31 @@
|
|
|
31
31
|
"Scaffolding"
|
|
32
32
|
],
|
|
33
33
|
"scripts": {
|
|
34
|
+
"prepare": "husky install",
|
|
34
35
|
"start:build": "npm run build && npm run start",
|
|
35
36
|
"start": "node ./bin/cli.js",
|
|
36
37
|
"start:dev": "tsnd ./src/cli.ts",
|
|
37
38
|
"build": "npm run clean && tsc -p tsconfig.json && yarn cp:templates && chmod +x ./bin/cli.js",
|
|
38
39
|
"cp:templates": "cp -r ./src/generate/templates ./bin/generate/templates",
|
|
39
40
|
"clean": "rimraf ./bin",
|
|
40
|
-
"
|
|
41
|
+
"format": "prettier --write \"./src/**/*.ts\" --cache",
|
|
42
|
+
"lint": "eslint \"./src/**/*.ts\"",
|
|
43
|
+
"lint:fix": "eslint \"./src/**/*.ts\" --fix",
|
|
41
44
|
"release": "release-it",
|
|
42
|
-
"
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:watch": "vitest",
|
|
47
|
+
"test:coverage": "vitest run --coverage"
|
|
43
48
|
},
|
|
44
49
|
"dependencies": {
|
|
45
|
-
"@expressots/boost-ts": "
|
|
46
|
-
"chalk-animation": "
|
|
47
|
-
"cli-progress": "
|
|
48
|
-
"degit": "
|
|
49
|
-
"glob": "
|
|
50
|
-
"inquirer": "
|
|
51
|
-
"mustache": "
|
|
52
|
-
"ts-node": "
|
|
53
|
-
"yargs": "
|
|
50
|
+
"@expressots/boost-ts": "1.1.1",
|
|
51
|
+
"chalk-animation": "2.0.3",
|
|
52
|
+
"cli-progress": "3.11.2",
|
|
53
|
+
"degit": "2.8.4",
|
|
54
|
+
"glob": "10.2.6",
|
|
55
|
+
"inquirer": "8.0.0",
|
|
56
|
+
"mustache": "4.2.0",
|
|
57
|
+
"ts-node": "10.9.1",
|
|
58
|
+
"yargs": "17.6.2"
|
|
54
59
|
},
|
|
55
60
|
"devDependencies": {
|
|
56
61
|
"@commitlint/cli": "^17.7.1",
|
|
@@ -74,7 +79,9 @@
|
|
|
74
79
|
"release-it": "^16.1.5",
|
|
75
80
|
"rimraf": "^4.1.2",
|
|
76
81
|
"ts-node-dev": "^2.0.0",
|
|
77
|
-
"typescript": "^4.9.5"
|
|
82
|
+
"typescript": "^4.9.5",
|
|
83
|
+
"vite": "^4.4.9",
|
|
84
|
+
"vitest": "^0.34.4"
|
|
78
85
|
},
|
|
79
86
|
"release-it": {
|
|
80
87
|
"git": {
|