@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.
@@ -6,4 +6,4 @@ const appContainer = new AppContainer();
6
6
 
7
7
  const container = appContainer.create([// Add your modules here, UserModule, UserModule, UserModule]);
8
8
 
9
- export { container };*/
9
+ export { container };*/
@@ -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",
@@ -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/${schematic}.tpl`,
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),
@@ -0,0 +1,3 @@
1
+ import { CreateModule } from "@expressots/core";
2
+
3
+ export const {{moduleName}}Module = CreateModule([]);
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: ["npm", "yarn", "pnpm"],
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, [packageManager, template, directory]);
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" || arg === "yarn" || arg === "pnpm") {
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 |" + chalk_1.default.green("{bar}") + "| {percentage}% || {doing}",
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, 'utf8');
9
+ const fileContent = await node_fs_1.default.promises.readFile(filePath, "utf8");
10
10
  const imports = [];
11
11
  const notImports = [];
12
- fileContent.split('\n').forEach((line) => {
13
- if (line.startsWith('import')) {
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].trim().split(',').map((c) => c.trim()).filter((c) => c);
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].join('\n').replace(moduleDeclarationRegex, newModuleDeclaration);
38
- await node_fs_1.default.promises.writeFile(filePath, newFileContent, 'utf8');
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}`, { absolute: true, ignore: '**/node_modules/**' });
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)('Module not added to Container. Container file not found!', APP_CONTAINER);
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], 'utf8');
23
- fileContent.split('\n').forEach((line) => {
24
- if (line.startsWith('import')) {
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)('Container format incorrect!', APP_CONTAINER);
38
+ (0, cli_ui_1.printError)("Container format incorrect!", APP_CONTAINER);
36
39
  process.exit(1);
37
40
  }
38
- const modules = moduleDeclarationMatch[1].trim().split(',').filter((m) => m.trim() !== "").map((m) => m.trim());
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('/').length > 1) {
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) && containerData.modules.includes(`${moduleName}Module`)) {
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 = [...containerData.imports, ...containerData.notImports]
80
- .join('\n').replace(containerData.regex, newModuleDeclaration);
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, 'utf8');
94
+ await node_fs_1.default.promises.writeFile(containerData.path, newFileContent, "utf8");
83
95
  }
84
96
  exports.addModuleToContainer = addModuleToContainer;
@@ -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 = ' '.repeat(padding) + text;
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('/').pop();
21
+ const fileName = path.split("/").pop();
22
22
  if (!answer.confirm) {
23
- (0, cli_ui_1.printError)('File not created!', fileName);
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.4",
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
- "lint": "eslint .eslintrc.js --ext .ts,.tsx,.js,.jsx .",
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
- "prepare": "husky install"
45
+ "test": "vitest run",
46
+ "test:watch": "vitest",
47
+ "test:coverage": "vitest run --coverage"
43
48
  },
44
49
  "dependencies": {
45
- "@expressots/boost-ts": "^1.1.1",
46
- "chalk-animation": "^1",
47
- "cli-progress": "^3.11.2",
48
- "degit": "^2.8.4",
49
- "glob": "^10.2.6",
50
- "inquirer": "^8.0.0",
51
- "mustache": "^4.2.0",
52
- "ts-node": "^10.9.1",
53
- "yargs": "^17.6.2"
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": {