@expressots/cli 1.5.0 → 1.6.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.js CHANGED
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.CLI_VERSION = void 0;
8
8
  const yargs_1 = __importDefault(require("yargs"));
9
9
  const helpers_1 = require("yargs/helpers");
10
+ const project_commands_1 = require("./commands/project.commands");
10
11
  const generate_1 = require("./generate");
11
12
  const info_1 = require("./info");
12
13
  const new_1 = require("./new");
@@ -15,6 +16,7 @@ exports.CLI_VERSION = "1.3.4";
15
16
  console.log(`\n[🐎 Expressots]\n`);
16
17
  (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
17
18
  .scriptName("expressots")
19
+ .command(project_commands_1.runCommandModule)
18
20
  .command((0, new_1.createProject)())
19
21
  .command((0, providers_1.generateProviders)())
20
22
  .command((0, generate_1.generateProject)())
@@ -0,0 +1,8 @@
1
+ import { CommandModule } from "yargs";
2
+ export declare const runCommandModule: CommandModule<{}, {
3
+ command: string;
4
+ }>;
5
+ declare const runCommand: ({ command }: {
6
+ command: string;
7
+ }) => Promise<void>;
8
+ export { runCommand };
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runCommand = exports.runCommandModule = void 0;
7
+ const child_process_1 = require("child_process");
8
+ const fs_1 = require("fs");
9
+ const path_1 = __importDefault(require("path"));
10
+ const compiler_1 = __importDefault(require("../utils/compiler"));
11
+ /**
12
+ * Load the configuration from the compiler
13
+ * @param compiler The compiler to load the configuration from
14
+ * @returns The configuration
15
+ */
16
+ const opinionatedConfig = [
17
+ "--transpile-only",
18
+ "-r",
19
+ "dotenv/config",
20
+ "-r",
21
+ "tsconfig-paths/register",
22
+ "./src/main.ts",
23
+ ];
24
+ const nonOpinionatedConfig = [
25
+ "--transpile-only",
26
+ "-r",
27
+ "dotenv/config",
28
+ "./src/main.ts",
29
+ ];
30
+ /**
31
+ * Helper function to execute a command
32
+ * @param command The command to execute
33
+ * @param args The arguments to pass to the command
34
+ * @param cwd The current working directory to execute the command in
35
+ * @returns A promise that resolves when the command completes successfully
36
+ */
37
+ function execCmd(command, args, cwd = process.cwd()) {
38
+ return new Promise((resolve, reject) => {
39
+ const proc = (0, child_process_1.spawn)(command, args, {
40
+ stdio: "inherit",
41
+ shell: true,
42
+ cwd,
43
+ });
44
+ proc.on("close", (code) => {
45
+ if (code === 0) {
46
+ resolve();
47
+ }
48
+ else {
49
+ reject(new Error(`Command failed with code ${code}`));
50
+ }
51
+ });
52
+ });
53
+ }
54
+ // Helper to delete the dist directory
55
+ const cleanDist = async () => {
56
+ await fs_1.promises.rm("./dist", { recursive: true, force: true });
57
+ };
58
+ // Helper to compile TypeScript
59
+ const compileTypescript = async () => {
60
+ await execCmd("npx", ["tsc", "-p", "tsconfig.build.json"]);
61
+ };
62
+ // Helper to copy files
63
+ const copyFiles = async () => {
64
+ const { opinionated } = await compiler_1.default.loadConfig();
65
+ let filesToCopy = [];
66
+ if (opinionated) {
67
+ filesToCopy = [
68
+ "./register-path.js",
69
+ "tsconfig.build.json",
70
+ "package.json",
71
+ ];
72
+ }
73
+ else {
74
+ filesToCopy = ["tsconfig.json", "package.json"];
75
+ }
76
+ filesToCopy.forEach((file) => {
77
+ fs_1.promises.copyFile(file, path_1.default.join("./dist", path_1.default.basename(file)));
78
+ });
79
+ };
80
+ // eslint-disable-next-line @typescript-eslint/ban-types
81
+ exports.runCommandModule = {
82
+ command: "run <command>",
83
+ describe: "Runs a specified command (dev, build, prod)",
84
+ builder: (yargs) => {
85
+ return yargs.positional("command", {
86
+ describe: "The command to run",
87
+ type: "string",
88
+ choices: ["dev", "build", "prod"],
89
+ });
90
+ },
91
+ handler: async (argv) => {
92
+ const { command } = argv;
93
+ // Now call your original runCommand function with the command
94
+ // Ensure runCommand is properly defined to handle these commands
95
+ await runCommand({ command });
96
+ },
97
+ };
98
+ const runCommand = async ({ command }) => {
99
+ const { opinionated } = await compiler_1.default.loadConfig();
100
+ try {
101
+ switch (command) {
102
+ case "dev":
103
+ // Use execSync or spawn to run ts-node-dev programmatically
104
+ execCmd("tsnd", opinionated ? opinionatedConfig : nonOpinionatedConfig);
105
+ break;
106
+ case "build":
107
+ await cleanDist();
108
+ await compileTypescript();
109
+ await copyFiles();
110
+ break;
111
+ case "prod":
112
+ let config = [];
113
+ if (opinionated) {
114
+ config = [
115
+ "-r",
116
+ "dotenv/config",
117
+ "-r",
118
+ "./dist/register-path.js",
119
+ "./dist/src/main.js",
120
+ ];
121
+ }
122
+ else {
123
+ config = ["-r", "dotenv/config", "./dist/main.js"];
124
+ }
125
+ // Ensure environment variables are set
126
+ execCmd("node", config);
127
+ break;
128
+ default:
129
+ console.log(`Unknown command: ${command}`);
130
+ }
131
+ }
132
+ catch (error) {
133
+ console.error("Error executing command:", error);
134
+ }
135
+ };
136
+ exports.runCommand = runCommand;
@@ -16,8 +16,10 @@ const coerceSchematicAliases = (arg) => {
16
16
  return "provider";
17
17
  case "e":
18
18
  return "entity";
19
- case "m":
19
+ case "mo":
20
20
  return "module";
21
+ case "m":
22
+ return "middleware";
21
23
  default:
22
24
  return arg;
23
25
  }
@@ -37,6 +39,7 @@ const generateProject = () => {
37
39
  "provider",
38
40
  "entity",
39
41
  "module",
42
+ "middleware",
40
43
  ],
41
44
  describe: "The schematic to generate",
42
45
  type: "string",
@@ -271,7 +271,6 @@ const splitTarget = async ({ target, schematic, }) => {
271
271
  if (target.includes("/") ||
272
272
  target.includes("\\") ||
273
273
  target.includes("//")) {
274
- //pathContent = target.split("/").filter((item) => item !== "");
275
274
  if (schematic === "service")
276
275
  schematic = "controller";
277
276
  if (schematic === "service" ||
@@ -366,6 +365,10 @@ const schematicFolder = (schematic) => {
366
365
  return "providers";
367
366
  case "entity":
368
367
  return "entities";
368
+ case "middleware":
369
+ return "providers/middlewares";
370
+ case "module":
371
+ return "useCases";
369
372
  }
370
373
  return undefined;
371
374
  };
@@ -0,0 +1,10 @@
1
+ import { ExpressoMiddleware } from "@expressots/core";
2
+ import { NextFunction, Request, Response } from "express";
3
+ import { provide } from "inversify-binding-decorators";
4
+
5
+ @provide({{className}}Middleware)
6
+ export class {{className}}Middleware extends ExpressoMiddleware {
7
+ use(req: Request, res: Response, next: NextFunction): void | Promise<void> {
8
+ throw new Error("Method not implemented.");
9
+ }
10
+ }
@@ -1,3 +1,4 @@
1
+ import { ContainerModule } from "inversify";
1
2
  import { CreateModule } from "@expressots/core";
2
3
 
3
- export const {{moduleName}}Module = CreateModule([]);
4
+ export const {{moduleName}}Module: ContainerModule = CreateModule([]);
@@ -1,4 +1,5 @@
1
+ import { ContainerModule } from "inversify";
1
2
  import { CreateModule } from "@expressots/core";
2
3
  import { {{className}}Controller } from "{{{path}}}";
3
4
 
4
- export const {{moduleName}}Module = CreateModule([{{className}}Controller]);
5
+ export const {{moduleName}}Module: ContainerModule = CreateModule([{{className}}Controller]);
package/bin/new/cli.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import { CommandModule } from "yargs";
2
- type CommandModuleArgs = {};
2
+ type CommandModuleArgs = object;
3
3
  declare const createProject: () => CommandModule<CommandModuleArgs, any>;
4
4
  export { createProject };
package/bin/new/cli.js CHANGED
@@ -2,41 +2,43 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createProject = void 0;
4
4
  const form_1 = require("./form");
5
+ const packageManagers = [
6
+ "npm",
7
+ "yarn",
8
+ "pnpm",
9
+ ...(process.platform !== "win32" ? ["bun"] : []),
10
+ ];
11
+ const commandOptions = (yargs) => {
12
+ return yargs
13
+ .positional("project-name", {
14
+ describe: "The name of the project",
15
+ type: "string",
16
+ })
17
+ .option("template", {
18
+ describe: "The project template to use",
19
+ type: "string",
20
+ choices: ["opinionated", "non-opinionated"],
21
+ alias: "t",
22
+ })
23
+ .option("package-manager", {
24
+ describe: "The package manager to use",
25
+ type: "string",
26
+ choices: packageManagers,
27
+ alias: "p",
28
+ })
29
+ .option("directory", {
30
+ describe: "The directory for new project",
31
+ type: "string",
32
+ alias: "d",
33
+ })
34
+ .implies("package-manager", "template")
35
+ .implies("template", "package-manager");
36
+ };
5
37
  const createProject = () => {
6
- const packageManagers = ["npm", "yarn", "pnpm"];
7
- if (process.platform !== "win32") {
8
- packageManagers.push("bun");
9
- }
10
38
  return {
11
39
  command: "new <project-name> [package-manager] [template] [directory]",
12
40
  describe: "Create a new project",
13
- builder: (yargs) => {
14
- yargs
15
- .positional("project-name", {
16
- describe: "The name of the project",
17
- type: "string",
18
- })
19
- .option("template", {
20
- describe: "The project template to use",
21
- type: "string",
22
- choices: ["non-opinionated", "opinionated"],
23
- alias: "t",
24
- })
25
- .option("package-manager", {
26
- describe: "The package manager to use",
27
- type: "string",
28
- choices: packageManagers,
29
- alias: "p",
30
- })
31
- .option("directory", {
32
- describe: "The directory for new project",
33
- type: "string",
34
- alias: "d",
35
- })
36
- .implies("package-manager", "template")
37
- .implies("template", "package-manager");
38
- return yargs;
39
- },
41
+ builder: commandOptions,
40
42
  handler: async ({ projectName, packageManager, template, directory, }) => {
41
43
  return await (0, form_1.projectForm)(projectName, [
42
44
  packageManager,
package/bin/new/form.js CHANGED
@@ -61,8 +61,8 @@ function changePackageName({ directory, name, }) {
61
61
  }
62
62
  var Template;
63
63
  (function (Template) {
64
- Template["non-opinionated"] = "Non-Opinionated :: A simple ExpressoTS project.";
65
- Template["opinionated"] = "Opinionated :: A complete ExpressoTS project with an opinionated structure and features.";
64
+ Template["non-opinionated"] = "Non-Opinionated :: Allows users to choose where to scaffold resources, offering flexible project organization.";
65
+ Template["opinionated"] = "Opinionated :: Automatically scaffolds resources into a preset project structure. (Recommended)";
66
66
  })(Template || (Template = {}));
67
67
  const projectForm = async (projectName, args) => {
68
68
  let answer;
@@ -117,8 +117,8 @@ const projectForm = async (projectName, args) => {
117
117
  name: "template",
118
118
  message: "Select a template",
119
119
  choices: [
120
- "Non-Opinionated :: A simple ExpressoTS project.",
121
- "Opinionated :: A complete ExpressoTS project with an opinionated structure and features.",
120
+ `Opinionated :: Automatically scaffolds resources into a preset project structure. (${chalk_1.default.yellow("Recommended")})`,
121
+ "Non-Opinionated :: Allows users to choose where to scaffold resources, offering flexible project organization.",
122
122
  ],
123
123
  },
124
124
  {
@@ -185,7 +185,7 @@ const projectForm = async (projectName, args) => {
185
185
  progressBar.update(100);
186
186
  progressBar.stop();
187
187
  console.log("\n");
188
- console.log("🐎 Project ", chalk_1.default.green(answer.name), "created successfully!");
188
+ console.log("🐎 Project", chalk_1.default.green(answer.name), "created successfully!");
189
189
  console.log("🤙 Run the following commands to start the project:\n");
190
190
  console.log(chalk_1.default.bold.gray(`$ cd ${answer.name}`));
191
191
  switch (answer.packageManager) {
@@ -206,6 +206,7 @@ const projectForm = async (projectName, args) => {
206
206
  console.log(chalk_1.default.bold.green((0, center_text_1.centerText)("Happy coding!")));
207
207
  console.log(chalk_1.default.bold.gray((0, center_text_1.centerText)("Please consider donating to support the project.\n")));
208
208
  console.log(chalk_1.default.bold.white((0, center_text_1.centerText)("💖 Sponsor: https://github.com/sponsors/expressots")));
209
+ console.log("\n");
209
210
  }
210
211
  };
211
212
  exports.projectForm = projectForm;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expressots/cli",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Expressots CLI - modern, fast, lightweight nodejs web framework (@cli)",
5
5
  "author": "Richard Zampieri",
6
6
  "license": "MIT",
@@ -77,7 +77,8 @@
77
77
  "husky": "^8.0.3",
78
78
  "prettier": "^2.8.4",
79
79
  "release-it": "^16.1.5",
80
- "rimraf": "^4.1.2",
80
+ "rimraf": "^5.0.5",
81
+ "shx": "^0.3.4",
81
82
  "ts-node-dev": "^2.0.0",
82
83
  "typescript": "^4.9.5",
83
84
  "vite": "^4.4.9",