@tsed/cli 6.6.3 → 7.0.0-alpha.10

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 (259) hide show
  1. package/lib/esm/bin/tsed.js +23 -2
  2. package/lib/esm/commands/add/AddCmd.js +16 -16
  3. package/lib/esm/commands/generate/GenerateCmd.js +72 -224
  4. package/lib/esm/commands/generate/mappers/mapGenerateContext.js +29 -0
  5. package/lib/esm/commands/index.js +2 -1
  6. package/lib/esm/commands/init/InitCmd.js +193 -172
  7. package/lib/esm/commands/init/config/FeaturesPrompt.js +106 -9
  8. package/lib/esm/commands/init/mappers/mapToContext.js +8 -3
  9. package/lib/esm/commands/init/prompts/getFeaturesPrompt.js +0 -12
  10. package/lib/esm/commands/init/utils/hasFeature.js +3 -0
  11. package/lib/esm/commands/run/RunCmd.js +22 -26
  12. package/lib/esm/commands/template/CreateTemplateCommand.js +101 -0
  13. package/lib/esm/commands/update/UpdateCmd.js +9 -13
  14. package/lib/esm/fn/exec.js +5 -0
  15. package/lib/esm/fn/render.js +5 -0
  16. package/lib/esm/fn/taskOutput.js +7 -0
  17. package/lib/esm/index.js +10 -5
  18. package/lib/esm/interfaces/AlterPackageJson.js +1 -0
  19. package/lib/esm/interfaces/AlterProjectFiles.js +1 -0
  20. package/lib/esm/interfaces/AlterRenderFiles.js +1 -0
  21. package/lib/esm/interfaces/CliCommandHooks.js +1 -0
  22. package/lib/esm/interfaces/GenerateCmdContext.js +1 -0
  23. package/lib/esm/interfaces/InitCmdOptions.js +1 -0
  24. package/lib/esm/interfaces/RenderDataContext.js +1 -0
  25. package/lib/esm/interfaces/RuntimeTypes.js +1 -0
  26. package/lib/esm/interfaces/index.js +9 -0
  27. package/lib/esm/pipes/OutputFilePathPipe.js +40 -18
  28. package/lib/esm/pipes/RoutePipe.js +4 -8
  29. package/lib/esm/pipes/{ClassNamePipe.js → SymbolNamePipe.js} +14 -11
  30. package/lib/esm/pipes/index.js +1 -1
  31. package/lib/esm/platforms/{InitPlatformsModule.js → PlatformsModule.js} +4 -10
  32. package/lib/esm/platforms/supports/InitExpressPlatform.js +27 -10
  33. package/lib/esm/platforms/supports/InitFastifyPlatform.js +27 -10
  34. package/lib/esm/platforms/supports/InitKoaPlatform.js +16 -10
  35. package/lib/esm/processors/__fixtures__/createFakeProject.js +35 -0
  36. package/lib/esm/processors/transformBinFile.js +47 -0
  37. package/lib/esm/processors/transformConfigFile.js +105 -0
  38. package/lib/esm/processors/transformIndexFile.js +23 -0
  39. package/lib/esm/processors/transformServerFile.js +60 -0
  40. package/lib/esm/runtimes/RuntimesModule.js +7 -17
  41. package/lib/esm/runtimes/supports/BabelRuntime.js +5 -11
  42. package/lib/esm/runtimes/supports/BunRuntime.js +4 -10
  43. package/lib/esm/runtimes/supports/NodeRuntime.js +1 -1
  44. package/lib/esm/runtimes/supports/WebpackRuntime.js +1 -1
  45. package/lib/esm/services/CliProjectService.js +95 -0
  46. package/lib/esm/services/CliRunScript.js +4 -8
  47. package/lib/esm/services/CliTemplatesService.js +119 -0
  48. package/lib/esm/services/ProjectClient.js +162 -0
  49. package/lib/esm/services/mappers/addContextMethods.js +17 -0
  50. package/lib/esm/services/mappers/mapDefaultTemplateOptions.js +36 -0
  51. package/lib/esm/templates/asyncFactory.template.js +38 -0
  52. package/lib/esm/templates/barrels.template.js +27 -0
  53. package/lib/esm/templates/command.template.js +56 -0
  54. package/lib/esm/templates/config.template.js +27 -0
  55. package/lib/esm/templates/controller.template.js +44 -0
  56. package/lib/esm/templates/decorator.template.js +184 -0
  57. package/lib/esm/templates/docker-compose.template.js +25 -0
  58. package/lib/esm/templates/dockerfile.template.js +236 -0
  59. package/lib/esm/templates/exception-filter.template.js +19 -0
  60. package/lib/esm/templates/factory.template.js +37 -0
  61. package/lib/esm/templates/index.command.template.js +22 -0
  62. package/lib/esm/templates/index.config.utils.template.js +17 -0
  63. package/{templates/init/src/controllers/pages/IndexController.ts.hbs → lib/esm/templates/index.controller.template.js} +14 -3
  64. package/lib/esm/templates/index.js +32 -0
  65. package/lib/esm/templates/index.logger.template.js +41 -0
  66. package/{templates/init/src/index.ts.hbs → lib/esm/templates/index.template.js} +17 -5
  67. package/lib/esm/templates/interceptor.template.js +31 -0
  68. package/lib/esm/templates/interface.template.js +13 -0
  69. package/lib/esm/templates/middleware.template.js +36 -0
  70. package/lib/esm/templates/model.template.js +16 -0
  71. package/lib/esm/templates/module.template.js +16 -0
  72. package/lib/esm/templates/new-template.template.js +67 -0
  73. package/lib/esm/templates/pipe.template.js +19 -0
  74. package/lib/esm/templates/pm2.template.js +111 -0
  75. package/lib/esm/templates/prisma.service.template.js +23 -0
  76. package/{templates/init/README.md.hbs → lib/esm/templates/readme.template.js} +28 -13
  77. package/lib/esm/templates/repository.template.js +16 -0
  78. package/lib/esm/templates/response-filter.template.js +19 -0
  79. package/lib/esm/templates/server.template.js +37 -0
  80. package/lib/esm/templates/service.template.js +16 -0
  81. package/lib/esm/templates/tsconfig.spec.template.js +35 -0
  82. package/lib/esm/templates/value.template.js +13 -0
  83. package/lib/esm/utils/defineTemplate.js +13 -0
  84. package/lib/tsconfig.esm.tsbuildinfo +1 -1
  85. package/lib/types/bin/tsed.d.ts +1 -1
  86. package/lib/types/commands/add/AddCmd.d.ts +2 -2
  87. package/lib/types/commands/generate/GenerateCmd.d.ts +9 -98
  88. package/lib/types/commands/generate/mappers/mapGenerateContext.d.ts +2 -0
  89. package/lib/types/commands/index.d.ts +2 -1
  90. package/lib/types/commands/init/InitCmd.d.ts +18 -20
  91. package/lib/types/commands/init/config/FeaturesPrompt.d.ts +19 -3
  92. package/lib/types/commands/init/mappers/mapToContext.d.ts +2 -2
  93. package/lib/types/commands/init/mappers/mapUniqFeatures.d.ts +1 -1
  94. package/lib/types/commands/init/prompts/getFeaturesPrompt.d.ts +1 -7
  95. package/lib/types/commands/init/utils/hasFeature.d.ts +1 -0
  96. package/lib/types/commands/template/CreateTemplateCommand.d.ts +62 -0
  97. package/lib/types/commands/update/UpdateCmd.d.ts +2 -2
  98. package/lib/types/fn/exec.d.ts +1 -0
  99. package/lib/types/fn/render.d.ts +2 -0
  100. package/lib/types/fn/taskOutput.d.ts +1 -0
  101. package/lib/types/index.d.ts +10 -5
  102. package/lib/types/interfaces/AlterGenerateTasks.d.ts +5 -0
  103. package/lib/types/interfaces/AlterInitSubTasks.d.ts +5 -0
  104. package/lib/types/interfaces/AlterPackageJson.d.ts +5 -0
  105. package/lib/types/interfaces/AlterProjectFiles.d.ts +5 -0
  106. package/lib/types/interfaces/AlterRenderFiles.d.ts +10 -0
  107. package/lib/types/interfaces/CliCommandHooks.d.ts +11 -0
  108. package/lib/types/interfaces/GenerateCmdContext.d.ts +21 -0
  109. package/lib/types/interfaces/InitCmdOptions.d.ts +8 -0
  110. package/lib/types/interfaces/PlatformType.d.ts +7 -0
  111. package/lib/types/interfaces/RenderDataContext.d.ts +62 -0
  112. package/lib/types/interfaces/RuntimeTypes.d.ts +8 -0
  113. package/lib/types/interfaces/index.d.ts +9 -0
  114. package/lib/types/pipes/OutputFilePathPipe.d.ts +7 -4
  115. package/lib/types/pipes/{ClassNamePipe.d.ts → SymbolNamePipe.d.ts} +4 -4
  116. package/lib/types/pipes/index.d.ts +1 -1
  117. package/lib/types/platforms/{InitPlatformsModule.d.ts → PlatformsModule.d.ts} +1 -1
  118. package/lib/types/platforms/supports/InitBasePlatform.d.ts +3 -0
  119. package/lib/types/platforms/supports/InitExpressPlatform.d.ts +2 -0
  120. package/lib/types/platforms/supports/InitFastifyPlatform.d.ts +2 -0
  121. package/lib/types/platforms/supports/InitKoaPlatform.d.ts +2 -0
  122. package/lib/types/processors/__fixtures__/createFakeProject.d.ts +5 -0
  123. package/lib/types/processors/transformBinFile.d.ts +3 -0
  124. package/lib/types/processors/transformConfigFile.d.ts +3 -0
  125. package/lib/types/processors/transformIndexFile.d.ts +3 -0
  126. package/lib/types/processors/transformServerFile.d.ts +3 -0
  127. package/lib/types/runtimes/RuntimesModule.d.ts +5 -5
  128. package/lib/types/services/CliProjectService.d.ts +16 -0
  129. package/lib/types/services/CliTemplatesService.d.ts +35 -0
  130. package/lib/types/services/ProjectClient.d.ts +40 -0
  131. package/lib/types/services/mappers/addContextMethods.d.ts +12 -0
  132. package/lib/types/services/mappers/mapDefaultTemplateOptions.d.ts +11 -0
  133. package/lib/types/templates/asyncFactory.template.d.ts +16 -0
  134. package/lib/types/templates/barrels.template.d.ts +16 -0
  135. package/lib/types/templates/command.template.d.ts +16 -0
  136. package/lib/types/templates/config.template.d.ts +16 -0
  137. package/lib/types/templates/controller.template.d.ts +17 -0
  138. package/lib/types/templates/decorator.template.d.ts +17 -0
  139. package/lib/types/templates/docker-compose.template.d.ts +16 -0
  140. package/lib/types/templates/dockerfile.template.d.ts +1 -0
  141. package/lib/types/templates/exception-filter.template.d.ts +16 -0
  142. package/lib/types/templates/factory.template.d.ts +16 -0
  143. package/lib/types/templates/index.command.template.d.ts +16 -0
  144. package/lib/types/templates/index.config.utils.template.d.ts +16 -0
  145. package/lib/types/templates/index.controller.template.d.ts +16 -0
  146. package/lib/types/templates/index.d.ts +31 -0
  147. package/lib/types/templates/index.logger.template.d.ts +16 -0
  148. package/lib/types/templates/index.template.d.ts +16 -0
  149. package/lib/types/templates/interceptor.template.d.ts +16 -0
  150. package/lib/types/templates/interface.template.d.ts +16 -0
  151. package/lib/types/templates/middleware.template.d.ts +17 -0
  152. package/lib/types/templates/model.template.d.ts +16 -0
  153. package/lib/types/templates/module.template.d.ts +16 -0
  154. package/lib/types/templates/new-template.template.d.ts +9 -0
  155. package/lib/types/templates/pipe.template.d.ts +16 -0
  156. package/lib/types/templates/pm2.template.d.ts +1 -0
  157. package/lib/types/templates/prisma.service.template.d.ts +16 -0
  158. package/lib/types/templates/readme.template.d.ts +16 -0
  159. package/lib/types/templates/repository.template.d.ts +16 -0
  160. package/lib/types/templates/response-filter.template.d.ts +16 -0
  161. package/lib/types/templates/server.template.d.ts +16 -0
  162. package/lib/types/templates/service.template.d.ts +16 -0
  163. package/lib/types/templates/tsconfig.spec.template.d.ts +16 -0
  164. package/lib/types/templates/value.template.d.ts +16 -0
  165. package/lib/types/utils/defineTemplate.d.ts +67 -0
  166. package/package.json +14 -12
  167. package/templates/{init/tsconfig.json.hbs → tsconfig.json} +2 -7
  168. package/templates/tsconfig.node.json +14 -0
  169. package/templates/webpack.config.js +55 -0
  170. package/lib/esm/Cli.js +0 -57
  171. package/lib/esm/commands/generate/ProviderTypes.js +0 -103
  172. package/lib/esm/commands/init/interfaces/InitOptions.js +0 -5
  173. package/lib/esm/services/ProvidersInfoService.js +0 -46
  174. package/lib/esm/services/Renderer.js +0 -162
  175. package/lib/esm/utils/fillImports.js +0 -38
  176. package/lib/esm/utils/hbs/array.js +0 -515
  177. package/lib/esm/utils/hbs/collection.js +0 -60
  178. package/lib/esm/utils/hbs/comparison.js +0 -431
  179. package/lib/esm/utils/hbs/index.js +0 -11
  180. package/lib/esm/utils/hbs/object.js +0 -236
  181. package/lib/esm/utils/hbs/switch.js +0 -10
  182. package/lib/esm/utils/renderer/insertAfter.js +0 -12
  183. package/lib/esm/utils/renderer/insertImport.js +0 -11
  184. package/lib/types/Cli.d.ts +0 -26
  185. package/lib/types/commands/generate/ProviderTypes.d.ts +0 -11
  186. package/lib/types/commands/init/interfaces/InitCmdContext.d.ts +0 -6
  187. package/lib/types/commands/init/interfaces/InitOptions.d.ts +0 -20
  188. package/lib/types/services/ProvidersInfoService.d.ts +0 -21
  189. package/lib/types/services/Renderer.d.ts +0 -44
  190. package/lib/types/utils/fillImports.d.ts +0 -1
  191. package/lib/types/utils/hbs/array.d.ts +0 -1
  192. package/lib/types/utils/hbs/collection.d.ts +0 -1
  193. package/lib/types/utils/hbs/comparison.d.ts +0 -1
  194. package/lib/types/utils/hbs/object.d.ts +0 -1
  195. package/lib/types/utils/hbs/switch.d.ts +0 -1
  196. package/lib/types/utils/renderer/insertAfter.d.ts +0 -1
  197. package/lib/types/utils/renderer/insertImport.d.ts +0 -1
  198. package/templates/generate/async.factory.hbs +0 -35
  199. package/templates/generate/command.hbs +0 -45
  200. package/templates/generate/controller.hbs +0 -10
  201. package/templates/generate/decorator.class.hbs +0 -14
  202. package/templates/generate/decorator.endpoint.hbs +0 -15
  203. package/templates/generate/decorator.generic.hbs +0 -19
  204. package/templates/generate/decorator.method.hbs +0 -16
  205. package/templates/generate/decorator.middleware.hbs +0 -26
  206. package/templates/generate/decorator.param.hbs +0 -15
  207. package/templates/generate/decorator.parameters.hbs +0 -9
  208. package/templates/generate/decorator.prop.hbs +0 -14
  209. package/templates/generate/decorator.property.hbs +0 -5
  210. package/templates/generate/exception-filter.hbs +0 -9
  211. package/templates/generate/factory.hbs +0 -11
  212. package/templates/generate/injectable.hbs +0 -6
  213. package/templates/generate/interceptor.hbs +0 -21
  214. package/templates/generate/interface.hbs +0 -3
  215. package/templates/generate/middleware.hbs +0 -9
  216. package/templates/generate/model.hbs +0 -6
  217. package/templates/generate/module.hbs +0 -6
  218. package/templates/generate/pipe.hbs +0 -9
  219. package/templates/generate/prisma.service.hbs +0 -13
  220. package/templates/generate/repository.hbs +0 -6
  221. package/templates/generate/response-filter.hbs +0 -9
  222. package/templates/generate/server/_partials/server-footer.hbs +0 -10
  223. package/templates/generate/server/_partials/server-header.hbs +0 -34
  224. package/templates/generate/server/express/server.hbs +0 -10
  225. package/templates/generate/server/fastify/server.hbs +0 -14
  226. package/templates/generate/server/koa/server.hbs +0 -8
  227. package/templates/generate/service.hbs +0 -6
  228. package/templates/generate/value.hbs +0 -3
  229. package/templates/init/.barrels.json.hbs +0 -9
  230. package/templates/init/.gitignore.hbs +0 -57
  231. package/templates/init/.npmrc.hbs +0 -2
  232. package/templates/init/docker/_partials/docker-body.hbs +0 -5
  233. package/templates/init/docker/_partials/docker-dev-tools.hbs +0 -2
  234. package/templates/init/docker/_partials/docker-header.hbs +0 -16
  235. package/templates/init/docker/bun/Dockerfile.hbs +0 -36
  236. package/templates/init/docker/npm/Dockerfile.hbs +0 -28
  237. package/templates/init/docker/pnpm/Dockerfile.hbs +0 -28
  238. package/templates/init/docker/yarn/Dockerfile.hbs +0 -28
  239. package/templates/init/docker/yarn_berry/Dockerfile.hbs +0 -31
  240. package/templates/init/docker-compose.yml.hbs +0 -14
  241. package/templates/init/pm2/bun/processes.config.cjs.hbs +0 -23
  242. package/templates/init/pm2/node-compiled/processes.config.cjs.hbs +0 -22
  243. package/templates/init/pm2/node-loader/processes.config.cjs.hbs +0 -24
  244. package/templates/init/src/bin/index.ts.hbs +0 -9
  245. package/templates/init/src/config/envs/index.ts.hbs +0 -7
  246. package/templates/init/src/config/index.ts.hbs +0 -38
  247. package/templates/init/src/config/logger/index.ts.hbs +0 -25
  248. package/templates/init/tsconfig.node.json.hbs +0 -20
  249. package/templates/init/tsconfig.spec.json.hbs +0 -25
  250. package/templates/init/webpack.config.js.hbs +0 -65
  251. /package/lib/esm/{commands/init/interfaces/InitCmdContext.js → interfaces/AlterGenerateTasks.js} +0 -0
  252. /package/lib/{types/utils/hbs/index.d.ts → esm/interfaces/AlterInitSubTasks.js} +0 -0
  253. /package/templates/{init/.babelrc.hbs → .babelrc} +0 -0
  254. /package/templates/{init/.dockerignore.hbs → .dockerignore} +0 -0
  255. /package/templates/{init/.swcrc.hbs → .swcrc} +0 -0
  256. /package/templates/{init/.yarnrc.hbs → .yarnrc} +0 -0
  257. /package/templates/{init/nodemon.json.hbs → nodemon.json} +0 -0
  258. /package/templates/{init/tsconfig.base.json.hbs → tsconfig.base.json} +0 -0
  259. /package/templates/{init/views/swagger.ejs.hbs → views/swagger.ejs} +0 -0
@@ -0,0 +1,162 @@
1
+ import { dirname, 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.ensureDir(dirname(path));
49
+ await this.fs.writeFile(path, sourceFileText, { encoding: "utf-8" });
50
+ }
51
+ findClassDecorator(sourceFile, name) {
52
+ return sourceFile
53
+ .getClasses()
54
+ .flatMap((cls) => cls.getDecorators())
55
+ .find((decorator) => decorator.getName() === name);
56
+ }
57
+ addMountPath(path, specifier) {
58
+ if (!this.serverSourceFile) {
59
+ return;
60
+ }
61
+ const options = this.findConfigurationDecorationOptions();
62
+ if (!options) {
63
+ return;
64
+ }
65
+ let mount = this.getPropertyAssignment(options, {
66
+ name: "mount",
67
+ kind: SyntaxKind.ObjectLiteralExpression,
68
+ initializer: "{}"
69
+ });
70
+ const escape = '"' + ((path || "").startsWith("/") ? path : "/" + path) + '"';
71
+ const property = this.getPropertyAssignment(mount, {
72
+ name: escape,
73
+ kind: SyntaxKind.ArrayLiteralExpression,
74
+ initializer: "[]"
75
+ });
76
+ if (isString(specifier)) {
77
+ property.addElement(specifier);
78
+ }
79
+ options.formatText({
80
+ indentSize: 2
81
+ });
82
+ }
83
+ addNamespaceImport(sourceFile, moduleSpecifier, name) {
84
+ return sourceFile
85
+ .addImportDeclaration({
86
+ moduleSpecifier,
87
+ namespaceImport: name
88
+ })
89
+ .getNamespaceImport();
90
+ }
91
+ findConfiguration(kind) {
92
+ switch (kind) {
93
+ case "server":
94
+ return this.findConfigurationDecorationOptions();
95
+ case "config":
96
+ return this.findConfigConfiguration();
97
+ case "bin":
98
+ return this.findBinConfiguration();
99
+ default:
100
+ throw new Error(`Unknown configuration kind: ${kind}`);
101
+ }
102
+ }
103
+ getPropertyAssignment(input, { name, initializer, kind }) {
104
+ const assigment = input.getProperty(name)?.getChildAtIndex(2).asKind(kind);
105
+ if (!initializer) {
106
+ return assigment;
107
+ }
108
+ return (assigment ||
109
+ input
110
+ .addPropertyAssignment({
111
+ name,
112
+ initializer
113
+ })
114
+ .getInitializerIfKindOrThrow(kind));
115
+ }
116
+ addConfigSource(name, { content = name, moduleSpecifier }) {
117
+ const sourceFile = this.configSourceFile;
118
+ const options = this.findConfiguration("config");
119
+ if (!options) {
120
+ return;
121
+ }
122
+ const extendsConfig = this.getPropertyAssignment(options, {
123
+ name: "extends",
124
+ kind: SyntaxKind.ArrayLiteralExpression,
125
+ initializer: "[]"
126
+ });
127
+ const has = extendsConfig.getElements().some((expression) => {
128
+ return expression.getText().includes(name);
129
+ });
130
+ if (!has) {
131
+ sourceFile.addImportDeclaration({
132
+ moduleSpecifier,
133
+ namedImports: [{ name: name }]
134
+ });
135
+ extendsConfig.addElement("\n" + content);
136
+ }
137
+ }
138
+ findConfigurationDecorationOptions() {
139
+ if (!this.serverSourceFile) {
140
+ return;
141
+ }
142
+ return this.findClassDecorator(this.serverSourceFile, "Configuration")?.getArguments().at(0);
143
+ }
144
+ findConfigConfiguration() {
145
+ const sourceFile = this.configSourceFile;
146
+ if (!sourceFile) {
147
+ return;
148
+ }
149
+ return sourceFile.getVariableDeclaration("config")?.getInitializerIfKindOrThrow(SyntaxKind.ObjectLiteralExpression);
150
+ }
151
+ findBinConfiguration() {
152
+ if (!this.binSourceFile) {
153
+ return;
154
+ }
155
+ for (const child of this.binSourceFile.getStatements()) {
156
+ if (child.getKind() === SyntaxKind.ExpressionStatement && child.getText().includes("CliCore.bootstrap")) {
157
+ return child.getFirstDescendantByKind(SyntaxKind.ObjectLiteralExpression);
158
+ }
159
+ }
160
+ return undefined;
161
+ }
162
+ }
@@ -0,0 +1,17 @@
1
+ import { inject } from "@tsed/cli-core";
2
+ import { isString } from "@tsed/core";
3
+ import { pascalCase } from "change-case";
4
+ import { RoutePipe } from "../../pipes/RoutePipe.js";
5
+ import { CliProjectService } from "../CliProjectService.js";
6
+ export function addContextMethods(context) {
7
+ const getName = (state) => context.name || pascalCase(state.name || context.name || state.type || context.type || "");
8
+ return {
9
+ getName,
10
+ getRoute: (state) => {
11
+ return inject(RoutePipe).transform(isString(state) ? state : getName(state));
12
+ },
13
+ getDirectories: (dir) => {
14
+ return inject(CliProjectService).getDirectories(dir);
15
+ }
16
+ };
17
+ }
@@ -0,0 +1,36 @@
1
+ import { inject, ProjectPackageJson } from "@tsed/cli-core";
2
+ import { isString } from "@tsed/core";
3
+ import { normalizePath } from "@tsed/normalize-path";
4
+ import { pascalCase } from "change-case";
5
+ import { ProjectConvention } from "../../interfaces/ProjectConvention.js";
6
+ import { OutputFilePathPipe } from "../../pipes/OutputFilePathPipe.js";
7
+ import { RoutePipe } from "../../pipes/RoutePipe.js";
8
+ import { SymbolNamePipe } from "../../pipes/SymbolNamePipe.js";
9
+ import { CliProjectService } from "../CliProjectService.js";
10
+ import { addContextMethods } from "./addContextMethods.js";
11
+ export function mapDefaultTemplateOptions(opts) {
12
+ const classNamePipe = inject(SymbolNamePipe);
13
+ const outputFilePathPipe = inject(OutputFilePathPipe);
14
+ const projectPackageJson = inject(ProjectPackageJson);
15
+ const { name = "" } = opts;
16
+ let { type = "" } = opts;
17
+ type = type.toLowerCase();
18
+ if (opts.name === "prisma" && opts.name) {
19
+ type = "prisma.service";
20
+ }
21
+ const symbolName = opts.symbolName || classNamePipe.transform({ name, type, format: ProjectConvention.DEFAULT });
22
+ const symbolPath = opts.symbolPath ||
23
+ normalizePath(outputFilePathPipe.transform({
24
+ name,
25
+ type,
26
+ subDir: opts.directory
27
+ }));
28
+ return {
29
+ ...projectPackageJson.fillWithPreferences(opts),
30
+ type,
31
+ symbolName,
32
+ symbolPath,
33
+ symbolPathBasename: opts.symbolPathBasename || normalizePath(classNamePipe.transform({ name, type })),
34
+ ...addContextMethods(opts)
35
+ };
36
+ }
@@ -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,27 @@
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
+ hidden: true,
11
+ preserveCase: true,
12
+ prompts() {
13
+ return [];
14
+ },
15
+ render(_, context) {
16
+ const barrels = $alter("$alterBarrels", {
17
+ directory: [
18
+ "./src/controllers/rest",
19
+ context.commands && "./src/bin/commands",
20
+ (context.swagger || context.oidc) && "./src/controllers/pages"
21
+ ].filter(Boolean),
22
+ exclude: ["**/__mock__", "**/__mocks__", "**/*.spec.ts"],
23
+ delete: true
24
+ });
25
+ return JSON.stringify(barrels, null, 2);
26
+ }
27
+ });
@@ -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,44 @@
1
+ import { defineTemplate } from "../utils/defineTemplate.js";
2
+ export default defineTemplate({
3
+ id: "controller",
4
+ label: "Controller",
5
+ fileName: "{{symbolName}}.controller",
6
+ outputDir: "{{srcDir}}/controllers",
7
+ prompts(context) {
8
+ return [
9
+ {
10
+ type: "list",
11
+ name: "directory",
12
+ message: "Which directory?",
13
+ when(state) {
14
+ return !!(["controller"].includes(state.type || context.type) || context.directory);
15
+ },
16
+ choices: context.getDirectories("controllers")
17
+ },
18
+ {
19
+ type: "input",
20
+ name: "route",
21
+ message: "Which route?",
22
+ when(state) {
23
+ return !!(["controller"].includes(state.type || context.type) || context.route);
24
+ },
25
+ default: (state) => {
26
+ return context.getRoute(state);
27
+ }
28
+ }
29
+ ];
30
+ },
31
+ render(symbolName, context) {
32
+ const route = context.getRoute(context.route);
33
+ return `import {Controller} from "@tsed/di";
34
+ import {Get} from "@tsed/schema";
35
+
36
+ @Controller("${route}")
37
+ export class ${symbolName} {
38
+ @Get("/")
39
+ get() {
40
+ return "hello";
41
+ }
42
+ }`;
43
+ }
44
+ });
@@ -0,0 +1,184 @@
1
+ import { defineTemplate } from "../utils/defineTemplate.js";
2
+ export default defineTemplate({
3
+ id: "decorator",
4
+ label: "Decorator",
5
+ fileName: "{{symbolName}}",
6
+ outputDir: "{{srcDir}}/decorators",
7
+ prompts(context) {
8
+ return [
9
+ {
10
+ type: "list",
11
+ name: "templateType",
12
+ message: "What kind of decorator do you want to create?",
13
+ when(state) {
14
+ return !!(["decorator"].includes(state.type || context.type) || context.templateType);
15
+ },
16
+ choices: [
17
+ { name: "Class Decorator", value: "class" },
18
+ { name: "Generic Decorator (class, property)", value: "generic" },
19
+ { name: "Method Decorator", value: "method" },
20
+ { name: "Parameter Decorator", value: "param" },
21
+ { name: "Property Decorator", value: "property" },
22
+ { name: "Property Decorator (with @Property)", value: "prop" },
23
+ { name: "Parameters Decorator", value: "parameters" },
24
+ { name: "Endpoint Decorator", value: "endpoint" },
25
+ { name: "Middleware Decorator", value: "middleware" }
26
+ ],
27
+ default: "class"
28
+ }
29
+ ];
30
+ },
31
+ render(symbolName, context) {
32
+ const type = context.templateType || "class";
33
+ switch (type) {
34
+ case "class":
35
+ return `
36
+ export interface ${symbolName}Options {
37
+
38
+ }
39
+
40
+ export function ${symbolName}(options: ${symbolName}Options): ClassDecorator {
41
+ return (target: any): any => {
42
+ return class extends target {
43
+ constructor(...args: any[]) {
44
+ super(...args);
45
+ }
46
+ };
47
+ };
48
+ }
49
+ `;
50
+ case "generic":
51
+ return `import {DecoratorTypes, UnsupportedDecoratorType, decoratorTypeOf} from "@tsed/core";
52
+
53
+ export interface ${symbolName}Options {
54
+
55
+ }
56
+
57
+ export function ${symbolName}(options: ${symbolName}Options): any {
58
+ return (...args: DecoratorParameters): any => {
59
+ switch(decoratorTypeOf(args)) {
60
+ case DecoratorTypes.CLASS:
61
+ case DecoratorTypes.PROP:
62
+ console.log("do something")
63
+ break;
64
+
65
+ default:
66
+ throw new UnsupportedDecoratorType(${symbolName}, args);
67
+ }
68
+ };
69
+ }
70
+ `;
71
+ case "method":
72
+ return `
73
+ export interface ${symbolName}Options {
74
+
75
+ }
76
+
77
+ export function ${symbolName}(options: ${symbolName}Options): MethodDecorator {
78
+ return (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> | void => {
79
+ console.log("do something");
80
+ return descriptor;
81
+ };
82
+ }
83
+ `;
84
+ case "param":
85
+ return `import {ParamTypes, useDecorators} from "@tsed/core";
86
+ import {UsePipe} from "@tsed/platform-params";
87
+
88
+ export interface ${symbolName}Options {
89
+
90
+ }
91
+
92
+ export function ${symbolName}(options: ${symbolName}Options): ParameterDecorator {
93
+ return useDecorators(
94
+ UsePipe(${symbolName}Pipe),
95
+ ParamTypes("${symbolName.toLowerCase()}")
96
+ );
97
+ }
98
+ `;
99
+ case "property":
100
+ return `
101
+ export function ${symbolName}(): PropertyDecorator {
102
+ return (target: Object, propertyKey: string | symbol): void => {
103
+ console.log("do something");
104
+ };
105
+ }
106
+ `;
107
+ case "prop":
108
+ return `import {useDecorators} from "@tsed/core";
109
+ import {Property} from "@tsed/schema";
110
+
111
+ export interface ${symbolName}Options {
112
+
113
+ }
114
+
115
+ export function ${symbolName}(options: ${symbolName}Options = {}): PropertyDecorator {
116
+ return useDecorators(
117
+ Property()
118
+ );
119
+ }
120
+ `;
121
+ case "parameters":
122
+ return `
123
+ export interface ${symbolName}Options {
124
+
125
+ }
126
+
127
+ export function ${symbolName}(options: ${symbolName}Options): ParameterDecorator {
128
+ return (target: Object, propertyKey: string | symbol, parameterIndex: number): void => {
129
+ console.log("do something");
130
+ };
131
+ }
132
+ `;
133
+ case "endpoint":
134
+ return `import {useDecorators} from "@tsed/core";
135
+ import {Get} from "@tsed/schema";
136
+
137
+ export interface ${symbolName}Options {
138
+
139
+ }
140
+
141
+ export function ${symbolName}(options: ${symbolName}Options = {}): MethodDecorator {
142
+ return useDecorators(
143
+ Get("/")
144
+ );
145
+ }
146
+ `;
147
+ case "middleware":
148
+ return `import {Context} from "@tsed/platform-params";
149
+ import {Middleware, MiddlewareMethods} from "@tsed/platform-middlewares";
150
+ import {Next} from "@tsed/common";
151
+
152
+ export interface ${symbolName}Options {
153
+
154
+ }
155
+
156
+ export function ${symbolName}(options: ${symbolName}Options = {}): ClassDecorator {
157
+ return (target: any) => {
158
+ @Middleware()
159
+ class ${symbolName}Middleware implements MiddlewareMethods {
160
+ use(@Context() ctx: Context, @Next() next: Next) {
161
+ // do something
162
+ return next();
163
+ }
164
+ }
165
+
166
+ return target;
167
+ };
168
+ }
169
+ `;
170
+ default:
171
+ return `
172
+ export interface ${symbolName}Options {
173
+
174
+ }
175
+
176
+ export function ${symbolName}(options: ${symbolName}Options): any {
177
+ return (...args: any[]): any => {
178
+ console.log("do something");
179
+ };
180
+ }
181
+ `;
182
+ }
183
+ }
184
+ });
@@ -0,0 +1,25 @@
1
+ import { defineTemplate } from "../utils/defineTemplate.js";
2
+ export default defineTemplate({
3
+ id: "docker-compose.yml",
4
+ label: "Docker Compose",
5
+ description: "Create a docker-compose.yml file.",
6
+ fileName: "docker-compose",
7
+ outputDir: ".",
8
+ ext: "yml",
9
+ preserveCase: true,
10
+ render(_, context) {
11
+ return `services:
12
+ server:
13
+ build:
14
+ context: .
15
+ dockerfile: ./Dockerfile
16
+ args:
17
+ - http_proxy
18
+ - https_proxy
19
+ - no_proxy
20
+ image: ${context.projectName}/server:latest
21
+ ports:
22
+ - "8081:8081"
23
+ `;
24
+ }
25
+ });