@tsed/cli 6.6.2 → 7.0.0-alpha.1

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.
Files changed (244) hide show
  1. package/lib/esm/commands/add/AddCmd.js +16 -16
  2. package/lib/esm/commands/generate/GenerateCmd.js +71 -220
  3. package/lib/esm/commands/generate/mappers/mapGenerateContext.js +29 -0
  4. package/lib/esm/commands/init/InitCmd.js +186 -168
  5. package/lib/esm/commands/init/config/FeaturesPrompt.js +79 -3
  6. package/lib/esm/commands/init/mappers/mapToContext.js +4 -3
  7. package/lib/esm/commands/run/RunCmd.js +22 -26
  8. package/lib/esm/commands/update/UpdateCmd.js +9 -13
  9. package/lib/esm/fn/exec.js +5 -0
  10. package/lib/esm/fn/render.js +5 -0
  11. package/lib/esm/index.js +7 -4
  12. package/lib/esm/interfaces/AlterPackageJson.js +1 -0
  13. package/lib/esm/interfaces/AlterProjectFiles.js +1 -0
  14. package/lib/esm/interfaces/AlterRenderFiles.js +1 -0
  15. package/lib/esm/interfaces/CliCommandHooks.js +1 -0
  16. package/lib/esm/interfaces/GenerateCmdContext.js +1 -0
  17. package/lib/esm/interfaces/InitCmdOptions.js +1 -0
  18. package/lib/esm/interfaces/RenderDataContext.js +1 -0
  19. package/lib/esm/interfaces/RuntimeTypes.js +1 -0
  20. package/lib/esm/interfaces/index.js +9 -0
  21. package/lib/esm/pipes/OutputFilePathPipe.js +40 -18
  22. package/lib/esm/pipes/RoutePipe.js +4 -8
  23. package/lib/esm/pipes/{ClassNamePipe.js → SymbolNamePipe.js} +14 -11
  24. package/lib/esm/pipes/index.js +1 -1
  25. package/lib/esm/platforms/{InitPlatformsModule.js → PlatformsModule.js} +4 -10
  26. package/lib/esm/platforms/supports/InitExpressPlatform.js +27 -10
  27. package/lib/esm/platforms/supports/InitFastifyPlatform.js +27 -10
  28. package/lib/esm/platforms/supports/InitKoaPlatform.js +16 -10
  29. package/lib/esm/processors/__fixtures__/createFakeProject.js +35 -0
  30. package/lib/esm/processors/transformBinFile.js +47 -0
  31. package/lib/esm/processors/transformConfigFile.js +26 -0
  32. package/lib/esm/processors/transformIndexFile.js +28 -0
  33. package/lib/esm/processors/transformServerFile.js +64 -0
  34. package/lib/esm/runtimes/RuntimesModule.js +7 -17
  35. package/lib/esm/runtimes/supports/BabelRuntime.js +5 -11
  36. package/lib/esm/runtimes/supports/BunRuntime.js +4 -10
  37. package/lib/esm/runtimes/supports/NodeRuntime.js +1 -1
  38. package/lib/esm/runtimes/supports/WebpackRuntime.js +1 -1
  39. package/lib/esm/services/CliProjectService.js +91 -0
  40. package/lib/esm/services/CliRunScript.js +4 -8
  41. package/lib/esm/services/CliTemplatesService.js +67 -0
  42. package/lib/esm/services/ProjectClient.js +139 -0
  43. package/lib/esm/services/mappers/mapDefaultTemplateOptions.js +30 -0
  44. package/lib/esm/templates/asyncFactory.template.js +38 -0
  45. package/lib/esm/templates/barrels.template.js +22 -0
  46. package/lib/esm/templates/command.template.js +56 -0
  47. package/lib/esm/templates/config.template.js +27 -0
  48. package/lib/esm/templates/controller.template.js +45 -0
  49. package/lib/esm/templates/decorator.template.js +182 -0
  50. package/lib/esm/templates/docker-compose.template.js +25 -0
  51. package/lib/esm/templates/dockerfile.template.js +236 -0
  52. package/lib/esm/templates/exception-filter.template.js +19 -0
  53. package/lib/esm/templates/factory.template.js +37 -0
  54. package/lib/esm/templates/index.command.template.js +18 -0
  55. package/lib/esm/templates/index.config.utils.template.js +17 -0
  56. package/{templates/init/src/controllers/pages/IndexController.ts.hbs → lib/esm/templates/index.controller.template.js} +14 -3
  57. package/lib/esm/templates/index.js +32 -0
  58. package/lib/esm/templates/index.logger.template.js +38 -0
  59. package/{templates/init/src/index.ts.hbs → lib/esm/templates/index.template.js} +17 -5
  60. package/lib/esm/templates/interceptor.template.js +31 -0
  61. package/lib/esm/templates/interface.template.js +13 -0
  62. package/lib/esm/templates/middleware.template.js +34 -0
  63. package/lib/esm/templates/model.template.js +16 -0
  64. package/lib/esm/templates/module.template.js +16 -0
  65. package/lib/esm/templates/pipe.template.js +19 -0
  66. package/lib/esm/templates/pm2.template.js +111 -0
  67. package/lib/esm/templates/prisma.service.template.js +23 -0
  68. package/{templates/init/README.md.hbs → lib/esm/templates/readme.template.js} +28 -13
  69. package/lib/esm/templates/repository.template.js +16 -0
  70. package/lib/esm/templates/response-filter.template.js +19 -0
  71. package/lib/esm/templates/server.template.js +37 -0
  72. package/lib/esm/templates/service.template.js +16 -0
  73. package/lib/esm/templates/tsconfig.spec.template.js +34 -0
  74. package/lib/esm/templates/tsconfig.template.js +31 -0
  75. package/lib/esm/templates/value.template.js +13 -0
  76. package/lib/esm/utils/defineTemplate.js +13 -0
  77. package/lib/tsconfig.esm.tsbuildinfo +1 -1
  78. package/lib/types/commands/add/AddCmd.d.ts +2 -2
  79. package/lib/types/commands/generate/GenerateCmd.d.ts +33 -87
  80. package/lib/types/commands/generate/mappers/mapGenerateContext.d.ts +2 -0
  81. package/lib/types/commands/init/InitCmd.d.ts +18 -20
  82. package/lib/types/commands/init/config/FeaturesPrompt.d.ts +10 -2
  83. package/lib/types/commands/init/mappers/mapToContext.d.ts +2 -2
  84. package/lib/types/commands/init/mappers/mapUniqFeatures.d.ts +1 -1
  85. package/lib/types/commands/init/prompts/getFeaturesPrompt.d.ts +1 -1
  86. package/lib/types/commands/update/UpdateCmd.d.ts +2 -2
  87. package/lib/types/fn/exec.d.ts +1 -0
  88. package/lib/types/fn/render.d.ts +2 -0
  89. package/lib/types/index.d.ts +7 -4
  90. package/lib/types/interfaces/AlterGenerateTasks.d.ts +5 -0
  91. package/lib/types/interfaces/AlterInitSubTasks.d.ts +5 -0
  92. package/lib/types/interfaces/AlterPackageJson.d.ts +5 -0
  93. package/lib/types/interfaces/AlterProjectFiles.d.ts +5 -0
  94. package/lib/types/interfaces/AlterRenderFiles.d.ts +10 -0
  95. package/lib/types/interfaces/CliCommandHooks.d.ts +11 -0
  96. package/lib/types/interfaces/GenerateCmdContext.d.ts +19 -0
  97. package/lib/types/interfaces/InitCmdOptions.d.ts +8 -0
  98. package/lib/types/interfaces/PlatformType.d.ts +7 -0
  99. package/lib/types/interfaces/RenderDataContext.d.ts +60 -0
  100. package/lib/types/interfaces/RuntimeTypes.d.ts +8 -0
  101. package/lib/types/interfaces/index.d.ts +9 -0
  102. package/lib/types/pipes/OutputFilePathPipe.d.ts +7 -4
  103. package/lib/types/pipes/{ClassNamePipe.d.ts → SymbolNamePipe.d.ts} +3 -3
  104. package/lib/types/pipes/index.d.ts +1 -1
  105. package/lib/types/platforms/{InitPlatformsModule.d.ts → PlatformsModule.d.ts} +1 -1
  106. package/lib/types/platforms/supports/InitBasePlatform.d.ts +3 -0
  107. package/lib/types/platforms/supports/InitExpressPlatform.d.ts +2 -0
  108. package/lib/types/platforms/supports/InitFastifyPlatform.d.ts +2 -0
  109. package/lib/types/platforms/supports/InitKoaPlatform.d.ts +2 -0
  110. package/lib/types/processors/__fixtures__/createFakeProject.d.ts +5 -0
  111. package/lib/types/processors/transformBinFile.d.ts +3 -0
  112. package/lib/types/processors/transformConfigFile.d.ts +3 -0
  113. package/lib/types/processors/transformIndexFile.d.ts +3 -0
  114. package/lib/types/processors/transformServerFile.d.ts +3 -0
  115. package/lib/types/runtimes/RuntimesModule.d.ts +5 -5
  116. package/lib/types/services/CliProjectService.d.ts +15 -0
  117. package/lib/types/services/CliTemplatesService.d.ts +29 -0
  118. package/lib/types/services/ProjectClient.d.ts +36 -0
  119. package/lib/types/services/mappers/mapDefaultTemplateOptions.d.ts +11 -0
  120. package/lib/types/templates/asyncFactory.template.d.ts +2 -0
  121. package/lib/types/templates/barrels.template.d.ts +2 -0
  122. package/lib/types/templates/command.template.d.ts +2 -0
  123. package/lib/types/templates/config.template.d.ts +2 -0
  124. package/lib/types/templates/controller.template.d.ts +2 -0
  125. package/lib/types/templates/decorator.template.d.ts +2 -0
  126. package/lib/types/templates/docker-compose.template.d.ts +2 -0
  127. package/lib/types/templates/dockerfile.template.d.ts +1 -0
  128. package/lib/types/templates/exception-filter.template.d.ts +2 -0
  129. package/lib/types/templates/factory.template.d.ts +2 -0
  130. package/lib/types/templates/index.command.template.d.ts +2 -0
  131. package/lib/types/templates/index.config.utils.template.d.ts +2 -0
  132. package/lib/types/templates/index.controller.template.d.ts +2 -0
  133. package/lib/types/templates/index.d.ts +31 -0
  134. package/lib/types/templates/index.logger.template.d.ts +2 -0
  135. package/lib/types/templates/index.template.d.ts +2 -0
  136. package/lib/types/templates/interceptor.template.d.ts +2 -0
  137. package/lib/types/templates/interface.template.d.ts +2 -0
  138. package/lib/types/templates/middleware.template.d.ts +2 -0
  139. package/lib/types/templates/model.template.d.ts +2 -0
  140. package/lib/types/templates/module.template.d.ts +2 -0
  141. package/lib/types/templates/pipe.template.d.ts +2 -0
  142. package/lib/types/templates/pm2.template.d.ts +1 -0
  143. package/lib/types/templates/prisma.service.template.d.ts +2 -0
  144. package/lib/types/templates/readme.template.d.ts +2 -0
  145. package/lib/types/templates/repository.template.d.ts +2 -0
  146. package/lib/types/templates/response-filter.template.d.ts +2 -0
  147. package/lib/types/templates/server.template.d.ts +2 -0
  148. package/lib/types/templates/service.template.d.ts +2 -0
  149. package/lib/types/templates/tsconfig.spec.template.d.ts +2 -0
  150. package/lib/types/templates/tsconfig.template.d.ts +2 -0
  151. package/lib/types/templates/value.template.d.ts +2 -0
  152. package/lib/types/utils/defineTemplate.d.ts +39 -0
  153. package/package.json +18 -16
  154. package/templates/tsconfig.node.json +14 -0
  155. package/templates/webpack.config.js +55 -0
  156. package/lib/esm/commands/generate/ProviderTypes.js +0 -103
  157. package/lib/esm/commands/init/interfaces/InitOptions.js +0 -5
  158. package/lib/esm/services/ProvidersInfoService.js +0 -46
  159. package/lib/esm/services/Renderer.js +0 -162
  160. package/lib/esm/utils/fillImports.js +0 -38
  161. package/lib/esm/utils/hbs/array.js +0 -515
  162. package/lib/esm/utils/hbs/collection.js +0 -60
  163. package/lib/esm/utils/hbs/comparison.js +0 -431
  164. package/lib/esm/utils/hbs/index.js +0 -11
  165. package/lib/esm/utils/hbs/object.js +0 -236
  166. package/lib/esm/utils/hbs/switch.js +0 -10
  167. package/lib/esm/utils/renderer/insertAfter.js +0 -12
  168. package/lib/esm/utils/renderer/insertImport.js +0 -11
  169. package/lib/types/commands/generate/ProviderTypes.d.ts +0 -11
  170. package/lib/types/commands/init/interfaces/InitCmdContext.d.ts +0 -6
  171. package/lib/types/commands/init/interfaces/InitOptions.d.ts +0 -20
  172. package/lib/types/services/ProvidersInfoService.d.ts +0 -21
  173. package/lib/types/services/Renderer.d.ts +0 -44
  174. package/lib/types/utils/fillImports.d.ts +0 -1
  175. package/lib/types/utils/hbs/array.d.ts +0 -1
  176. package/lib/types/utils/hbs/collection.d.ts +0 -1
  177. package/lib/types/utils/hbs/comparison.d.ts +0 -1
  178. package/lib/types/utils/hbs/object.d.ts +0 -1
  179. package/lib/types/utils/hbs/switch.d.ts +0 -1
  180. package/lib/types/utils/renderer/insertAfter.d.ts +0 -1
  181. package/lib/types/utils/renderer/insertImport.d.ts +0 -1
  182. package/templates/generate/async.factory.hbs +0 -35
  183. package/templates/generate/command.hbs +0 -45
  184. package/templates/generate/controller.hbs +0 -10
  185. package/templates/generate/decorator.class.hbs +0 -14
  186. package/templates/generate/decorator.endpoint.hbs +0 -15
  187. package/templates/generate/decorator.generic.hbs +0 -19
  188. package/templates/generate/decorator.method.hbs +0 -16
  189. package/templates/generate/decorator.middleware.hbs +0 -26
  190. package/templates/generate/decorator.param.hbs +0 -15
  191. package/templates/generate/decorator.parameters.hbs +0 -9
  192. package/templates/generate/decorator.prop.hbs +0 -14
  193. package/templates/generate/decorator.property.hbs +0 -5
  194. package/templates/generate/exception-filter.hbs +0 -9
  195. package/templates/generate/factory.hbs +0 -11
  196. package/templates/generate/injectable.hbs +0 -6
  197. package/templates/generate/interceptor.hbs +0 -21
  198. package/templates/generate/interface.hbs +0 -3
  199. package/templates/generate/middleware.hbs +0 -9
  200. package/templates/generate/model.hbs +0 -6
  201. package/templates/generate/module.hbs +0 -6
  202. package/templates/generate/pipe.hbs +0 -9
  203. package/templates/generate/prisma.service.hbs +0 -13
  204. package/templates/generate/repository.hbs +0 -6
  205. package/templates/generate/response-filter.hbs +0 -9
  206. package/templates/generate/server/_partials/server-footer.hbs +0 -10
  207. package/templates/generate/server/_partials/server-header.hbs +0 -34
  208. package/templates/generate/server/express/server.hbs +0 -10
  209. package/templates/generate/server/fastify/server.hbs +0 -14
  210. package/templates/generate/server/koa/server.hbs +0 -8
  211. package/templates/generate/service.hbs +0 -6
  212. package/templates/generate/value.hbs +0 -3
  213. package/templates/init/.barrels.json.hbs +0 -9
  214. package/templates/init/.gitignore.hbs +0 -57
  215. package/templates/init/.npmrc.hbs +0 -2
  216. package/templates/init/docker/_partials/docker-body.hbs +0 -5
  217. package/templates/init/docker/_partials/docker-dev-tools.hbs +0 -2
  218. package/templates/init/docker/_partials/docker-header.hbs +0 -16
  219. package/templates/init/docker/bun/Dockerfile.hbs +0 -36
  220. package/templates/init/docker/npm/Dockerfile.hbs +0 -28
  221. package/templates/init/docker/pnpm/Dockerfile.hbs +0 -28
  222. package/templates/init/docker/yarn/Dockerfile.hbs +0 -28
  223. package/templates/init/docker/yarn_berry/Dockerfile.hbs +0 -31
  224. package/templates/init/docker-compose.yml.hbs +0 -14
  225. package/templates/init/pm2/bun/processes.config.cjs.hbs +0 -23
  226. package/templates/init/pm2/node-compiled/processes.config.cjs.hbs +0 -22
  227. package/templates/init/pm2/node-loader/processes.config.cjs.hbs +0 -24
  228. package/templates/init/src/bin/index.ts.hbs +0 -9
  229. package/templates/init/src/config/envs/index.ts.hbs +0 -7
  230. package/templates/init/src/config/index.ts.hbs +0 -38
  231. package/templates/init/src/config/logger/index.ts.hbs +0 -25
  232. package/templates/init/tsconfig.json.hbs +0 -16
  233. package/templates/init/tsconfig.node.json.hbs +0 -20
  234. package/templates/init/tsconfig.spec.json.hbs +0 -25
  235. package/templates/init/webpack.config.js.hbs +0 -65
  236. /package/lib/esm/{commands/init/interfaces/InitCmdContext.js → interfaces/AlterGenerateTasks.js} +0 -0
  237. /package/lib/{types/utils/hbs/index.d.ts → esm/interfaces/AlterInitSubTasks.js} +0 -0
  238. /package/templates/{init/.babelrc.hbs → .babelrc} +0 -0
  239. /package/templates/{init/.dockerignore.hbs → .dockerignore} +0 -0
  240. /package/templates/{init/.swcrc.hbs → .swcrc} +0 -0
  241. /package/templates/{init/.yarnrc.hbs → .yarnrc} +0 -0
  242. /package/templates/{init/nodemon.json.hbs → nodemon.json} +0 -0
  243. /package/templates/{init/tsconfig.base.json.hbs → tsconfig.base.json} +0 -0
  244. /package/templates/{init/views/swagger.ejs.hbs → views/swagger.ejs} +0 -0
@@ -1,17 +1,14 @@
1
- import { __decorate, __metadata, __param } from "tslib";
2
- import { PackageManagersModule, ProjectPackageJson } from "@tsed/cli-core";
3
- import { Inject, inject, Module } from "@tsed/di";
1
+ import { ProjectPackageJson } from "@tsed/cli-core";
2
+ import { inject, injectable, injectMany } from "@tsed/di";
4
3
  import { BabelRuntime } from "./supports/BabelRuntime.js";
5
4
  import { BaseRuntime } from "./supports/BaseRuntime.js";
6
5
  import { BunRuntime } from "./supports/BunRuntime.js";
7
6
  import { NodeRuntime } from "./supports/NodeRuntime.js";
8
7
  import { WebpackRuntime } from "./supports/WebpackRuntime.js";
9
- let RuntimesModule = class RuntimesModule {
10
- constructor(runtimes) {
11
- this.runtimes = runtimes;
8
+ export class RuntimesModule {
9
+ constructor() {
12
10
  this.projectPackageJson = inject(ProjectPackageJson);
13
- this.packagesManager = inject(PackageManagersModule);
14
- this.runtimes = runtimes.filter((manager) => manager.has());
11
+ this.runtimes = injectMany("runtime").filter((manager) => manager.has());
15
12
  }
16
13
  init(ctx) {
17
14
  ctx.runtime = ctx.runtime || this.get().name;
@@ -43,12 +40,5 @@ let RuntimesModule = class RuntimesModule {
43
40
  "start:prod": `cross-env NODE_ENV=production ${runtime.startProd("dist/index.js")}`
44
41
  };
45
42
  }
46
- };
47
- RuntimesModule = __decorate([
48
- Module({
49
- imports: [NodeRuntime, BabelRuntime, WebpackRuntime, BunRuntime]
50
- }),
51
- __param(0, Inject("runtime")),
52
- __metadata("design:paramtypes", [Array])
53
- ], RuntimesModule);
54
- export { RuntimesModule };
43
+ }
44
+ injectable(RuntimesModule).imports([NodeRuntime, BabelRuntime, WebpackRuntime, BunRuntime]);
@@ -1,8 +1,7 @@
1
- import { __decorate } from "tslib";
2
1
  import { dirname } from "node:path";
3
- import { Injectable } from "@tsed/di";
2
+ import { injectable } from "@tsed/di";
4
3
  import { NodeRuntime } from "./NodeRuntime.js";
5
- let BabelRuntime = class BabelRuntime extends NodeRuntime {
4
+ export class BabelRuntime extends NodeRuntime {
6
5
  constructor() {
7
6
  super(...arguments);
8
7
  this.name = "babel";
@@ -12,7 +11,7 @@ let BabelRuntime = class BabelRuntime extends NodeRuntime {
12
11
  return false;
13
12
  }
14
13
  files() {
15
- return ["/init/.babelrc.hbs"];
14
+ return [".babelrc"];
16
15
  }
17
16
  startDev(main) {
18
17
  return `babel-watch --extensions .ts ${main}`;
@@ -38,10 +37,5 @@ let BabelRuntime = class BabelRuntime extends NodeRuntime {
38
37
  typescript: "latest"
39
38
  };
40
39
  }
41
- };
42
- BabelRuntime = __decorate([
43
- Injectable({
44
- type: "runtime"
45
- })
46
- ], BabelRuntime);
47
- export { BabelRuntime };
40
+ }
41
+ injectable(BabelRuntime).type("runtime");
@@ -1,7 +1,6 @@
1
- import { __decorate } from "tslib";
2
- import { Injectable } from "@tsed/di";
1
+ import { injectable } from "@tsed/di";
3
2
  import { BaseRuntime } from "./BaseRuntime.js";
4
- let BunRuntime = class BunRuntime extends BaseRuntime {
3
+ export class BunRuntime extends BaseRuntime {
5
4
  constructor() {
6
5
  super(...arguments);
7
6
  this.name = "bun";
@@ -22,10 +21,5 @@ let BunRuntime = class BunRuntime extends BaseRuntime {
22
21
  typescript: "latest"
23
22
  };
24
23
  }
25
- };
26
- BunRuntime = __decorate([
27
- Injectable({
28
- type: "runtime"
29
- })
30
- ], BunRuntime);
31
- export { BunRuntime };
24
+ }
25
+ injectable(BunRuntime).type("runtime");
@@ -9,7 +9,7 @@ let NodeRuntime = class NodeRuntime extends BaseRuntime {
9
9
  this.order = 0;
10
10
  }
11
11
  files() {
12
- return ["/init/.swcrc.hbs", "/init/nodemon.json.hbs"];
12
+ return [".swcrc", "nodemon.json"];
13
13
  }
14
14
  startDev(main) {
15
15
  return `nodemon ${main}`;
@@ -12,7 +12,7 @@ let WebpackRuntime = class WebpackRuntime extends BabelRuntime {
12
12
  return true;
13
13
  }
14
14
  files() {
15
- return [...super.files(), "/init/webpack.config.js.hbs"];
15
+ return [...super.files(), "webpack.config.js"];
16
16
  }
17
17
  compile(src, out) {
18
18
  return "tsc && cross-env NODE_ENV=production webpack";
@@ -0,0 +1,91 @@
1
+ import { dirname, join, relative } from "node:path";
2
+ import { CliFs, inject } from "@tsed/cli-core";
3
+ import { constant, injectable } from "@tsed/di";
4
+ import { $asyncAlter } from "@tsed/hooks";
5
+ import { normalizePath } from "@tsed/normalize-path";
6
+ import { globbySync } from "globby";
7
+ import { PlatformsModule } from "../platforms/PlatformsModule.js";
8
+ import { InitExpressPlatform } from "../platforms/supports/InitExpressPlatform.js";
9
+ import { InitFastifyPlatform } from "../platforms/supports/InitFastifyPlatform.js";
10
+ import { InitKoaPlatform } from "../platforms/supports/InitKoaPlatform.js";
11
+ import { transformBinFile } from "../processors/transformBinFile.js";
12
+ import { transformConfigFile } from "../processors/transformConfigFile.js";
13
+ import { transformIndexFile } from "../processors/transformIndexFile.js";
14
+ import { transformServerFile } from "../processors/transformServerFile.js";
15
+ import { ProjectClient } from "../services/ProjectClient.js";
16
+ import { CliTemplatesService } from "./CliTemplatesService.js";
17
+ export class CliProjectService {
18
+ constructor() {
19
+ this.templates = inject(CliTemplatesService);
20
+ this.rootDir = constant("project.rootDir", process.cwd());
21
+ }
22
+ get srcDir() {
23
+ return join(...[this.rootDir, constant("project.srcDir")].filter(Boolean));
24
+ }
25
+ getRelativePath(path) {
26
+ return normalizePath(relative(dirname(join(this.srcDir, path)), this.rootDir));
27
+ }
28
+ getServerFileName() {
29
+ return this.get().getSource("Server.ts") ? "Server" : "server";
30
+ }
31
+ get() {
32
+ if (this.project) {
33
+ return this.project;
34
+ }
35
+ const fs = inject(CliFs);
36
+ this.project = new ProjectClient({
37
+ // tsConfigFilePath: join(this.rootDir, "tsconfig.json"),
38
+ rootDir: this.rootDir
39
+ });
40
+ const files = fs.globSync([join(constant("project.rootDir", process.cwd()), "**/*.ts")]);
41
+ files.forEach((file) => {
42
+ this.project.createSourceFile(file, fs.readFileSync(file, "utf8"), {
43
+ overwrite: true
44
+ });
45
+ });
46
+ return this.project;
47
+ }
48
+ async transformFiles(data) {
49
+ const project = this.get();
50
+ if (data.commandName === "init") {
51
+ transformIndexFile(project, data);
52
+ }
53
+ transformServerFile(project, data);
54
+ transformConfigFile(project, data);
55
+ transformBinFile(project, data);
56
+ if (data.platform) {
57
+ const platform = inject(PlatformsModule).get(data.platform);
58
+ platform.alterProjectFiles(project, data);
59
+ }
60
+ await $asyncAlter(`$alterProjectFiles`, project, [data]);
61
+ await Promise.all(project.getSourceFiles().map((sourceFile) => {
62
+ sourceFile.organizeImports();
63
+ return sourceFile.save();
64
+ }));
65
+ }
66
+ async createFromTemplate(templateId, ctx) {
67
+ const obj = await this.templates.render(templateId, ctx);
68
+ const project = this.get();
69
+ if (obj) {
70
+ const sourceFile = await project.createSource(obj.outputPath, obj.content, {
71
+ overwrite: true
72
+ });
73
+ return {
74
+ ...obj,
75
+ source: sourceFile
76
+ };
77
+ }
78
+ }
79
+ getDirectories(dir) {
80
+ const directories = globbySync("**/*", {
81
+ cwd: join(this.srcDir, dir),
82
+ ignore: ["__*"]
83
+ });
84
+ const set = new Set(directories.map((dir) => {
85
+ return dirname(dir);
86
+ }));
87
+ set.delete(".");
88
+ return [...set];
89
+ }
90
+ }
91
+ injectable(PlatformsModule).imports([InitExpressPlatform, InitKoaPlatform, InitFastifyPlatform]);
@@ -1,7 +1,6 @@
1
- import { __decorate } from "tslib";
2
1
  import { ProjectPackageJson } from "@tsed/cli-core";
3
- import { inject, Injectable } from "@tsed/di";
4
- let CliRunScript = class CliRunScript {
2
+ import { inject, injectable } from "@tsed/di";
3
+ export class CliRunScript {
5
4
  async run(cmd, args, options = {}) {
6
5
  // @ts-ignore
7
6
  const mod = await import("@npmcli/run-script");
@@ -15,8 +14,5 @@ let CliRunScript = class CliRunScript {
15
14
  banner: false
16
15
  });
17
16
  }
18
- };
19
- CliRunScript = __decorate([
20
- Injectable()
21
- ], CliRunScript);
22
- export { CliRunScript };
17
+ }
18
+ injectable(CliRunScript);
@@ -0,0 +1,67 @@
1
+ import { join } from "node:path";
2
+ import { CliFs } from "@tsed/cli-core";
3
+ import { constant, inject, injectable, injectMany } from "@tsed/di";
4
+ import { TEMPLATE_DIR } from "../constants/index.js";
5
+ import { mapDefaultTemplateOptions } from "./mappers/mapDefaultTemplateOptions.js";
6
+ export class CliTemplatesService {
7
+ constructor() {
8
+ this.rootDir = constant("project.rootDir", process.cwd());
9
+ this.fs = inject(CliFs);
10
+ }
11
+ get srcDir() {
12
+ return join(...[this.rootDir, constant("project.srcDir")].filter(Boolean));
13
+ }
14
+ find(id) {
15
+ const templates = injectMany("CLI_TEMPLATES").filter((template) => !template.hidden);
16
+ id = id?.toLowerCase();
17
+ const foundTemplates = templates.filter((template) => {
18
+ return template.label.toLowerCase().includes(id) || template.id.includes(id);
19
+ });
20
+ return foundTemplates.length ? foundTemplates : templates;
21
+ }
22
+ get(id) {
23
+ const templates = injectMany("CLI_TEMPLATES");
24
+ return templates.find((template) => template.id === id);
25
+ }
26
+ async render(templateId, data) {
27
+ const template = this.get(templateId);
28
+ if (template) {
29
+ const opts = mapDefaultTemplateOptions({
30
+ ...data,
31
+ type: templateId
32
+ });
33
+ const render = await template.render(opts.symbolName, opts);
34
+ if (render === undefined) {
35
+ return;
36
+ }
37
+ if (typeof render === "object") {
38
+ return render;
39
+ }
40
+ const filePath = opts.symbolPath ||
41
+ template.fileName?.replace("{{symbolName}}", opts.symbolName)?.replace("{{srcDir}}", this.srcDir) ||
42
+ opts.symbolName;
43
+ const outputPath = `${filePath}${template.ext ? "." + template.ext : ""}`;
44
+ return {
45
+ templateId,
46
+ content: render,
47
+ outputPath,
48
+ name: opts.name,
49
+ symbolName: opts.symbolName,
50
+ symbolPath: opts.symbolPath,
51
+ symbolPathBasename: opts.symbolPathBasename
52
+ };
53
+ }
54
+ else {
55
+ const from = data.from || TEMPLATE_DIR;
56
+ const fromPath = join(from, templateId.replace("{{srcDir}}", "src"));
57
+ if (this.fs.fileExistsSync(fromPath)) {
58
+ return {
59
+ templateId,
60
+ content: await inject(CliFs).readFile(fromPath),
61
+ outputPath: templateId.replace("{{srcDir}}", constant("project.srcDir", ""))
62
+ };
63
+ }
64
+ }
65
+ }
66
+ }
67
+ injectable(CliTemplatesService);
@@ -0,0 +1,139 @@
1
+ import { join } from "node:path";
2
+ import { CliDockerComposeYaml, CliFs, ProjectPackageJson } from "@tsed/cli-core";
3
+ import { isString } from "@tsed/core";
4
+ import { constant, inject } from "@tsed/di";
5
+ import { ObjectLiteralExpression, Project, SyntaxKind } from "ts-morph";
6
+ import { OutputFilePathPipe } from "../pipes/OutputFilePathPipe.js";
7
+ export class ProjectClient extends Project {
8
+ constructor({ rootDir, ...options }) {
9
+ super({
10
+ fileSystem: inject(CliFs),
11
+ ...options
12
+ });
13
+ this.pkg = inject(ProjectPackageJson);
14
+ this.fs = inject(CliFs);
15
+ this.dockerCompose = inject(CliDockerComposeYaml);
16
+ this.rootDir = rootDir;
17
+ }
18
+ get srcDir() {
19
+ return constant("project.srcDir", "/src");
20
+ }
21
+ get serverSourceFile() {
22
+ return this.getSource(join(this.srcDir, this.serverName));
23
+ }
24
+ get configSourceFile() {
25
+ return this.getSource(join(this.srcDir, `config/config.ts`));
26
+ }
27
+ get indexSourceFile() {
28
+ return this.getSource(join(this.srcDir, "index.ts"));
29
+ }
30
+ get binSourceFile() {
31
+ return this.getSource(join(this.srcDir, "bin/index.ts"));
32
+ }
33
+ get serverName() {
34
+ return inject(OutputFilePathPipe).getServerName();
35
+ }
36
+ getSource(path) {
37
+ const resolved = join(this.rootDir, path.replace("{{srcDir}}", this.srcDir));
38
+ return this.getSourceFile(resolved);
39
+ }
40
+ async createSource(path, sourceFileText, options) {
41
+ path = join(this.rootDir, path);
42
+ if (path.endsWith(".ts") || path.endsWith(".mts")) {
43
+ const source = this.createSourceFile(path, sourceFileText, options);
44
+ source.organizeImports();
45
+ await source.save();
46
+ return source;
47
+ }
48
+ await this.fs.writeFile(path, sourceFileText, { encoding: "utf-8" });
49
+ }
50
+ findClassDecorator(sourceFile, name) {
51
+ return sourceFile
52
+ .getClasses()
53
+ .flatMap((cls) => cls.getDecorators())
54
+ .find((decorator) => decorator.getName() === name);
55
+ }
56
+ addMountPath(path, specifier) {
57
+ if (!this.serverSourceFile) {
58
+ return;
59
+ }
60
+ const options = this.findConfigurationDecorationOptions();
61
+ if (!options) {
62
+ return;
63
+ }
64
+ let mount = this.getPropertyAssignment(options, {
65
+ name: "mount",
66
+ kind: SyntaxKind.ObjectLiteralExpression,
67
+ initializer: "{}"
68
+ });
69
+ const escape = '"' + ((path || "").startsWith("/") ? path : "/" + path) + '"';
70
+ const property = this.getPropertyAssignment(mount, {
71
+ name: escape,
72
+ kind: SyntaxKind.ArrayLiteralExpression,
73
+ initializer: "[]"
74
+ });
75
+ if (isString(specifier)) {
76
+ property.addElement(specifier);
77
+ }
78
+ options.formatText({
79
+ indentSize: 2
80
+ });
81
+ }
82
+ addNamespaceImport(sourceFile, moduleSpecifier, name) {
83
+ return sourceFile
84
+ .addImportDeclaration({
85
+ moduleSpecifier,
86
+ namespaceImport: name
87
+ })
88
+ .getNamespaceImport();
89
+ }
90
+ findConfiguration(kind) {
91
+ switch (kind) {
92
+ case "server":
93
+ return this.findConfigurationDecorationOptions();
94
+ case "config":
95
+ return this.findConfigConfiguration();
96
+ case "bin":
97
+ return this.findBinConfiguration();
98
+ default:
99
+ throw new Error(`Unknown configuration kind: ${kind}`);
100
+ }
101
+ }
102
+ getPropertyAssignment(input, { name, initializer, kind }) {
103
+ const assigment = input.getProperty(name)?.getChildAtIndex(2).asKind(kind);
104
+ if (!initializer) {
105
+ return assigment;
106
+ }
107
+ return (assigment ||
108
+ input
109
+ .addPropertyAssignment({
110
+ name,
111
+ initializer
112
+ })
113
+ .getInitializerIfKindOrThrow(kind));
114
+ }
115
+ findConfigurationDecorationOptions() {
116
+ if (!this.serverSourceFile) {
117
+ return;
118
+ }
119
+ return this.findClassDecorator(this.serverSourceFile, "Configuration")?.getArguments().at(0);
120
+ }
121
+ findConfigConfiguration() {
122
+ const sourceFile = this.configSourceFile;
123
+ if (!sourceFile) {
124
+ return;
125
+ }
126
+ return sourceFile.getVariableDeclaration("config")?.getInitializerIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
127
+ }
128
+ findBinConfiguration() {
129
+ if (!this.binSourceFile) {
130
+ return;
131
+ }
132
+ for (const child of this.binSourceFile.getStatements()) {
133
+ if (child.getKind() === SyntaxKind.ExpressionStatement && child.getText().includes("CliCore.bootstrap")) {
134
+ return child.getFirstDescendantByKind(SyntaxKind.ObjectLiteralExpression);
135
+ }
136
+ }
137
+ return undefined;
138
+ }
139
+ }
@@ -0,0 +1,30 @@
1
+ import { inject, ProjectPackageJson } from "@tsed/cli-core";
2
+ import { normalizePath } from "@tsed/normalize-path";
3
+ import { ProjectConvention } from "../../interfaces/ProjectConvention.js";
4
+ import { OutputFilePathPipe } from "../../pipes/OutputFilePathPipe.js";
5
+ import { SymbolNamePipe } from "../../pipes/SymbolNamePipe.js";
6
+ export function mapDefaultTemplateOptions(opts) {
7
+ const classNamePipe = inject(SymbolNamePipe);
8
+ const outputFilePathPipe = inject(OutputFilePathPipe);
9
+ const projectPackageJson = inject(ProjectPackageJson);
10
+ const { name = "" } = opts;
11
+ let { type = "" } = opts;
12
+ type = type.toLowerCase();
13
+ if (opts.name === "prisma" && opts.name) {
14
+ type = "prisma.service";
15
+ }
16
+ const symbolName = opts.symbolName || classNamePipe.transform({ name, type, format: ProjectConvention.DEFAULT });
17
+ const symbolPath = opts.symbolPath ||
18
+ normalizePath(outputFilePathPipe.transform({
19
+ name,
20
+ type,
21
+ subDir: opts.directory
22
+ }));
23
+ return {
24
+ ...projectPackageJson.fillWithPreferences(opts),
25
+ type,
26
+ symbolName,
27
+ symbolPath,
28
+ symbolPathBasename: opts.symbolPathBasename || normalizePath(classNamePipe.transform({ name, type }))
29
+ };
30
+ }
@@ -0,0 +1,38 @@
1
+ import { defineTemplate } from "../utils/defineTemplate.js";
2
+ import { camelCase, pascalCase } from "change-case";
3
+ export default defineTemplate({
4
+ id: "async.factory",
5
+ label: "Async Factory",
6
+ fileName: "{{symbolName}}.factory?",
7
+ outputDir: "{{srcDir}}/services",
8
+ render(symbolName) {
9
+ const camelName = camelCase(symbolName);
10
+ const optName = pascalCase(symbolName + "Options");
11
+ return `import {injectable} from "@tsed/di";
12
+
13
+ interface ${optName} {
14
+
15
+ }
16
+
17
+ declare global {
18
+ namespace TsED {
19
+ interface Configuration extends Record<string, any> {
20
+ ${camelName}: Options;
21
+ }
22
+ }
23
+ }
24
+
25
+ export const ${symbolName} = injectable(Symbol.for("${symbolName}"))
26
+ .factory(async () => {
27
+ const myConstant = constant<${optName}>("${camelName}");
28
+
29
+ // do something async
30
+ await Promise.resolve();
31
+
32
+ return {};
33
+ })
34
+ .token();
35
+
36
+ export type {{symbolName}} = typeof ${symbolName};`;
37
+ }
38
+ });
@@ -0,0 +1,22 @@
1
+ import { defineTemplate } from "../utils/defineTemplate.js";
2
+ import { $alter } from "@tsed/hooks";
3
+ export default defineTemplate({
4
+ id: "barrels",
5
+ label: "Barrels",
6
+ description: "Create barrels files (index.ts) to simplify imports.",
7
+ fileName: ".barrels",
8
+ ext: "json",
9
+ outputDir: ".",
10
+ preserveCase: true,
11
+ prompts() {
12
+ return [];
13
+ },
14
+ render(_, data) {
15
+ const barrels = $alter("$alterBarrels", {
16
+ directory: ["./src/controllers/rest", data.swagger || (data.oidc && "./src/controllers/pages")].filter(Boolean),
17
+ exclude: ["**/__mock__", "**/__mocks__", "**/*.spec.ts"],
18
+ delete: true
19
+ });
20
+ return JSON.stringify(barrels, null, 2);
21
+ }
22
+ });
@@ -0,0 +1,56 @@
1
+ import { defineTemplate } from "../utils/defineTemplate.js";
2
+ import { kebabCase } from "change-case";
3
+ export default defineTemplate({
4
+ id: "command",
5
+ label: "Command",
6
+ fileName: "{{symbolName}}.command",
7
+ outputDir: "{{srcDir}}/bin/commands",
8
+ render(symbolName) {
9
+ const symbolParamName = kebabCase(symbolName);
10
+ return `import {Command, CommandProvider, QuestionOptions} from "@tsed/cli-core";
11
+
12
+ export interface ${symbolName}Context {
13
+ }
14
+
15
+ @Command({
16
+ name: "${symbolParamName}",
17
+ description: "Command description",
18
+ args: {
19
+ },
20
+ options: {
21
+ },
22
+ allowUnknownOption: false
23
+ })
24
+ export class ${symbolName} implements CommandProvider {
25
+ /**
26
+ * Ask questions with Inquirer. Return an empty array or don't implement the method to skip this step
27
+ */
28
+ async $prompt(initialOptions: Partial<${symbolName}Context>): Promise<QuestionOptions> {
29
+ return [];
30
+ }
31
+
32
+ /**
33
+ * This method is called after the $prompt to create / map inputs to a proper context for the next step
34
+ */
35
+ $mapContext(ctx: Partial<${symbolName}Context>): ${symbolName}Context {
36
+ return {
37
+ ...ctx
38
+ // map something, based on ctx
39
+ };
40
+ }
41
+ /**
42
+ * This step run your tasks with Listr module
43
+ */
44
+ async $exec(ctx: ${symbolName}Context): Promise<any> {
45
+ return [
46
+ {
47
+ title: "Do something",
48
+ task: () => {
49
+ console.log('HELLO')
50
+ }
51
+ }
52
+ ];
53
+ }
54
+ }`;
55
+ }
56
+ });
@@ -0,0 +1,27 @@
1
+ import { defineTemplate } from "../utils/defineTemplate.js";
2
+ export default defineTemplate({
3
+ id: "config",
4
+ label: "Config",
5
+ description: "Create a new config file",
6
+ outputDir: "{{srcDir}}/config",
7
+ fileName: "config",
8
+ hidden: true,
9
+ preserveCase: true,
10
+ render() {
11
+ return `import {readFileSync} from "node:fs";
12
+ import loggerConfig from "./logger/index.js";
13
+
14
+ const pkg = JSON.parse(readFileSync("./package.json", {encoding: "utf8"}));
15
+ /**
16
+ * This is the shared configuration for the application
17
+ */
18
+ export const config: Partial<TsED.Configuration> = {
19
+ version: pkg.version,
20
+ ajv: {
21
+ returnsCoercedValues: true
22
+ },
23
+ logger: loggerConfig
24
+ };
25
+ `;
26
+ }
27
+ });
@@ -0,0 +1,45 @@
1
+ import { defineTemplate } from "../utils/defineTemplate.js";
2
+ import { RoutePipe } from "../pipes/index.js";
3
+ import { CliProjectService } from "../services/CliProjectService.js";
4
+ import { inject } from "@tsed/di";
5
+ export default defineTemplate({
6
+ id: "controller",
7
+ label: "Controller",
8
+ fileName: "{{symbolName}}.controller",
9
+ outputDir: "{{srcDir}}/controllers",
10
+ prompts: (data) => [
11
+ {
12
+ type: "list",
13
+ name: "directory",
14
+ message: "Which directory?",
15
+ when(state) {
16
+ return !!(["controller"].includes(state.type || data.type) || data.directory);
17
+ },
18
+ choices: inject(CliProjectService).getDirectories("controllers")
19
+ },
20
+ {
21
+ type: "input",
22
+ name: "route",
23
+ message: "Which route?",
24
+ when(state) {
25
+ return !!(["controller"].includes(state.type || data.type) || data.route);
26
+ },
27
+ default: (state) => {
28
+ return inject(RoutePipe).transform(data.getName(state));
29
+ }
30
+ }
31
+ ],
32
+ render(symbolName, data) {
33
+ const route = inject(RoutePipe).transform(data.route);
34
+ return `import {Controller} from "@tsed/di";
35
+ import {Get} from "@tsed/schema";
36
+
37
+ @Controller("${route}")
38
+ export class ${symbolName} {
39
+ @Get("/")
40
+ get() {
41
+ return "hello";
42
+ }
43
+ }`;
44
+ }
45
+ });