@tsed/cli 6.6.3 → 7.0.0-alpha.2

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 (246) hide show
  1. package/lib/esm/commands/add/AddCmd.js +16 -16
  2. package/lib/esm/commands/generate/GenerateCmd.js +69 -222
  3. package/lib/esm/commands/generate/mappers/mapGenerateContext.js +29 -0
  4. package/lib/esm/commands/init/InitCmd.js +190 -171
  5. package/lib/esm/commands/init/config/FeaturesPrompt.js +101 -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/fn/taskOutput.js +7 -0
  12. package/lib/esm/index.js +7 -4
  13. package/lib/esm/interfaces/AlterPackageJson.js +1 -0
  14. package/lib/esm/interfaces/AlterProjectFiles.js +1 -0
  15. package/lib/esm/interfaces/AlterRenderFiles.js +1 -0
  16. package/lib/esm/interfaces/CliCommandHooks.js +1 -0
  17. package/lib/esm/interfaces/GenerateCmdContext.js +1 -0
  18. package/lib/esm/interfaces/InitCmdOptions.js +1 -0
  19. package/lib/esm/interfaces/RenderDataContext.js +1 -0
  20. package/lib/esm/interfaces/RuntimeTypes.js +1 -0
  21. package/lib/esm/interfaces/index.js +9 -0
  22. package/lib/esm/pipes/OutputFilePathPipe.js +40 -18
  23. package/lib/esm/pipes/RoutePipe.js +4 -8
  24. package/lib/esm/pipes/{ClassNamePipe.js → SymbolNamePipe.js} +14 -11
  25. package/lib/esm/pipes/index.js +1 -1
  26. package/lib/esm/platforms/{InitPlatformsModule.js → PlatformsModule.js} +4 -10
  27. package/lib/esm/platforms/supports/InitExpressPlatform.js +27 -10
  28. package/lib/esm/platforms/supports/InitFastifyPlatform.js +27 -10
  29. package/lib/esm/platforms/supports/InitKoaPlatform.js +16 -10
  30. package/lib/esm/processors/__fixtures__/createFakeProject.js +35 -0
  31. package/lib/esm/processors/transformBinFile.js +47 -0
  32. package/lib/esm/processors/transformConfigFile.js +105 -0
  33. package/lib/esm/processors/transformIndexFile.js +23 -0
  34. package/lib/esm/processors/transformServerFile.js +60 -0
  35. package/lib/esm/runtimes/RuntimesModule.js +7 -17
  36. package/lib/esm/runtimes/supports/BabelRuntime.js +5 -11
  37. package/lib/esm/runtimes/supports/BunRuntime.js +4 -10
  38. package/lib/esm/runtimes/supports/NodeRuntime.js +1 -1
  39. package/lib/esm/runtimes/supports/WebpackRuntime.js +1 -1
  40. package/lib/esm/services/CliProjectService.js +96 -0
  41. package/lib/esm/services/CliRunScript.js +4 -8
  42. package/lib/esm/services/CliTemplatesService.js +68 -0
  43. package/lib/esm/services/ProjectClient.js +161 -0
  44. package/lib/esm/services/mappers/mapDefaultTemplateOptions.js +30 -0
  45. package/lib/esm/templates/asyncFactory.template.js +38 -0
  46. package/lib/esm/templates/barrels.template.js +22 -0
  47. package/lib/esm/templates/command.template.js +56 -0
  48. package/lib/esm/templates/config.template.js +27 -0
  49. package/lib/esm/templates/controller.template.js +45 -0
  50. package/lib/esm/templates/decorator.template.js +182 -0
  51. package/lib/esm/templates/docker-compose.template.js +25 -0
  52. package/lib/esm/templates/dockerfile.template.js +236 -0
  53. package/lib/esm/templates/exception-filter.template.js +19 -0
  54. package/lib/esm/templates/factory.template.js +37 -0
  55. package/lib/esm/templates/index.command.template.js +18 -0
  56. package/lib/esm/templates/index.config.utils.template.js +17 -0
  57. package/{templates/init/src/controllers/pages/IndexController.ts.hbs → lib/esm/templates/index.controller.template.js} +14 -3
  58. package/lib/esm/templates/index.js +32 -0
  59. package/lib/esm/templates/index.logger.template.js +38 -0
  60. package/{templates/init/src/index.ts.hbs → lib/esm/templates/index.template.js} +17 -5
  61. package/lib/esm/templates/interceptor.template.js +31 -0
  62. package/lib/esm/templates/interface.template.js +13 -0
  63. package/lib/esm/templates/middleware.template.js +34 -0
  64. package/lib/esm/templates/model.template.js +16 -0
  65. package/lib/esm/templates/module.template.js +16 -0
  66. package/lib/esm/templates/pipe.template.js +19 -0
  67. package/lib/esm/templates/pm2.template.js +111 -0
  68. package/lib/esm/templates/prisma.service.template.js +23 -0
  69. package/{templates/init/README.md.hbs → lib/esm/templates/readme.template.js} +28 -13
  70. package/lib/esm/templates/repository.template.js +16 -0
  71. package/lib/esm/templates/response-filter.template.js +19 -0
  72. package/lib/esm/templates/server.template.js +37 -0
  73. package/lib/esm/templates/service.template.js +16 -0
  74. package/lib/esm/templates/tsconfig.spec.template.js +34 -0
  75. package/lib/esm/templates/tsconfig.template.js +31 -0
  76. package/lib/esm/templates/value.template.js +13 -0
  77. package/lib/esm/utils/defineTemplate.js +13 -0
  78. package/lib/tsconfig.esm.tsbuildinfo +1 -1
  79. package/lib/types/commands/add/AddCmd.d.ts +2 -2
  80. package/lib/types/commands/generate/GenerateCmd.d.ts +33 -87
  81. package/lib/types/commands/generate/mappers/mapGenerateContext.d.ts +2 -0
  82. package/lib/types/commands/init/InitCmd.d.ts +18 -20
  83. package/lib/types/commands/init/config/FeaturesPrompt.d.ts +11 -2
  84. package/lib/types/commands/init/mappers/mapToContext.d.ts +2 -2
  85. package/lib/types/commands/init/mappers/mapUniqFeatures.d.ts +1 -1
  86. package/lib/types/commands/init/prompts/getFeaturesPrompt.d.ts +1 -1
  87. package/lib/types/commands/update/UpdateCmd.d.ts +2 -2
  88. package/lib/types/fn/exec.d.ts +1 -0
  89. package/lib/types/fn/render.d.ts +2 -0
  90. package/lib/types/fn/taskOutput.d.ts +1 -0
  91. package/lib/types/index.d.ts +7 -4
  92. package/lib/types/interfaces/AlterGenerateTasks.d.ts +5 -0
  93. package/lib/types/interfaces/AlterInitSubTasks.d.ts +5 -0
  94. package/lib/types/interfaces/AlterPackageJson.d.ts +5 -0
  95. package/lib/types/interfaces/AlterProjectFiles.d.ts +5 -0
  96. package/lib/types/interfaces/AlterRenderFiles.d.ts +10 -0
  97. package/lib/types/interfaces/CliCommandHooks.d.ts +11 -0
  98. package/lib/types/interfaces/GenerateCmdContext.d.ts +19 -0
  99. package/lib/types/interfaces/InitCmdOptions.d.ts +8 -0
  100. package/lib/types/interfaces/PlatformType.d.ts +7 -0
  101. package/lib/types/interfaces/RenderDataContext.d.ts +61 -0
  102. package/lib/types/interfaces/RuntimeTypes.d.ts +8 -0
  103. package/lib/types/interfaces/index.d.ts +9 -0
  104. package/lib/types/pipes/OutputFilePathPipe.d.ts +7 -4
  105. package/lib/types/pipes/{ClassNamePipe.d.ts → SymbolNamePipe.d.ts} +3 -3
  106. package/lib/types/pipes/index.d.ts +1 -1
  107. package/lib/types/platforms/{InitPlatformsModule.d.ts → PlatformsModule.d.ts} +1 -1
  108. package/lib/types/platforms/supports/InitBasePlatform.d.ts +3 -0
  109. package/lib/types/platforms/supports/InitExpressPlatform.d.ts +2 -0
  110. package/lib/types/platforms/supports/InitFastifyPlatform.d.ts +2 -0
  111. package/lib/types/platforms/supports/InitKoaPlatform.d.ts +2 -0
  112. package/lib/types/processors/__fixtures__/createFakeProject.d.ts +5 -0
  113. package/lib/types/processors/transformBinFile.d.ts +3 -0
  114. package/lib/types/processors/transformConfigFile.d.ts +3 -0
  115. package/lib/types/processors/transformIndexFile.d.ts +3 -0
  116. package/lib/types/processors/transformServerFile.d.ts +3 -0
  117. package/lib/types/runtimes/RuntimesModule.d.ts +5 -5
  118. package/lib/types/services/CliProjectService.d.ts +16 -0
  119. package/lib/types/services/CliTemplatesService.d.ts +29 -0
  120. package/lib/types/services/ProjectClient.d.ts +40 -0
  121. package/lib/types/services/mappers/mapDefaultTemplateOptions.d.ts +11 -0
  122. package/lib/types/templates/asyncFactory.template.d.ts +2 -0
  123. package/lib/types/templates/barrels.template.d.ts +2 -0
  124. package/lib/types/templates/command.template.d.ts +2 -0
  125. package/lib/types/templates/config.template.d.ts +2 -0
  126. package/lib/types/templates/controller.template.d.ts +2 -0
  127. package/lib/types/templates/decorator.template.d.ts +2 -0
  128. package/lib/types/templates/docker-compose.template.d.ts +2 -0
  129. package/lib/types/templates/dockerfile.template.d.ts +1 -0
  130. package/lib/types/templates/exception-filter.template.d.ts +2 -0
  131. package/lib/types/templates/factory.template.d.ts +2 -0
  132. package/lib/types/templates/index.command.template.d.ts +2 -0
  133. package/lib/types/templates/index.config.utils.template.d.ts +2 -0
  134. package/lib/types/templates/index.controller.template.d.ts +2 -0
  135. package/lib/types/templates/index.d.ts +31 -0
  136. package/lib/types/templates/index.logger.template.d.ts +2 -0
  137. package/lib/types/templates/index.template.d.ts +2 -0
  138. package/lib/types/templates/interceptor.template.d.ts +2 -0
  139. package/lib/types/templates/interface.template.d.ts +2 -0
  140. package/lib/types/templates/middleware.template.d.ts +2 -0
  141. package/lib/types/templates/model.template.d.ts +2 -0
  142. package/lib/types/templates/module.template.d.ts +2 -0
  143. package/lib/types/templates/pipe.template.d.ts +2 -0
  144. package/lib/types/templates/pm2.template.d.ts +1 -0
  145. package/lib/types/templates/prisma.service.template.d.ts +2 -0
  146. package/lib/types/templates/readme.template.d.ts +2 -0
  147. package/lib/types/templates/repository.template.d.ts +2 -0
  148. package/lib/types/templates/response-filter.template.d.ts +2 -0
  149. package/lib/types/templates/server.template.d.ts +2 -0
  150. package/lib/types/templates/service.template.d.ts +2 -0
  151. package/lib/types/templates/tsconfig.spec.template.d.ts +2 -0
  152. package/lib/types/templates/tsconfig.template.d.ts +2 -0
  153. package/lib/types/templates/value.template.d.ts +2 -0
  154. package/lib/types/utils/defineTemplate.d.ts +39 -0
  155. package/package.json +14 -12
  156. package/templates/tsconfig.node.json +14 -0
  157. package/templates/webpack.config.js +55 -0
  158. package/lib/esm/commands/generate/ProviderTypes.js +0 -103
  159. package/lib/esm/commands/init/interfaces/InitOptions.js +0 -5
  160. package/lib/esm/services/ProvidersInfoService.js +0 -46
  161. package/lib/esm/services/Renderer.js +0 -162
  162. package/lib/esm/utils/fillImports.js +0 -38
  163. package/lib/esm/utils/hbs/array.js +0 -515
  164. package/lib/esm/utils/hbs/collection.js +0 -60
  165. package/lib/esm/utils/hbs/comparison.js +0 -431
  166. package/lib/esm/utils/hbs/index.js +0 -11
  167. package/lib/esm/utils/hbs/object.js +0 -236
  168. package/lib/esm/utils/hbs/switch.js +0 -10
  169. package/lib/esm/utils/renderer/insertAfter.js +0 -12
  170. package/lib/esm/utils/renderer/insertImport.js +0 -11
  171. package/lib/types/commands/generate/ProviderTypes.d.ts +0 -11
  172. package/lib/types/commands/init/interfaces/InitCmdContext.d.ts +0 -6
  173. package/lib/types/commands/init/interfaces/InitOptions.d.ts +0 -20
  174. package/lib/types/services/ProvidersInfoService.d.ts +0 -21
  175. package/lib/types/services/Renderer.d.ts +0 -44
  176. package/lib/types/utils/fillImports.d.ts +0 -1
  177. package/lib/types/utils/hbs/array.d.ts +0 -1
  178. package/lib/types/utils/hbs/collection.d.ts +0 -1
  179. package/lib/types/utils/hbs/comparison.d.ts +0 -1
  180. package/lib/types/utils/hbs/object.d.ts +0 -1
  181. package/lib/types/utils/hbs/switch.d.ts +0 -1
  182. package/lib/types/utils/renderer/insertAfter.d.ts +0 -1
  183. package/lib/types/utils/renderer/insertImport.d.ts +0 -1
  184. package/templates/generate/async.factory.hbs +0 -35
  185. package/templates/generate/command.hbs +0 -45
  186. package/templates/generate/controller.hbs +0 -10
  187. package/templates/generate/decorator.class.hbs +0 -14
  188. package/templates/generate/decorator.endpoint.hbs +0 -15
  189. package/templates/generate/decorator.generic.hbs +0 -19
  190. package/templates/generate/decorator.method.hbs +0 -16
  191. package/templates/generate/decorator.middleware.hbs +0 -26
  192. package/templates/generate/decorator.param.hbs +0 -15
  193. package/templates/generate/decorator.parameters.hbs +0 -9
  194. package/templates/generate/decorator.prop.hbs +0 -14
  195. package/templates/generate/decorator.property.hbs +0 -5
  196. package/templates/generate/exception-filter.hbs +0 -9
  197. package/templates/generate/factory.hbs +0 -11
  198. package/templates/generate/injectable.hbs +0 -6
  199. package/templates/generate/interceptor.hbs +0 -21
  200. package/templates/generate/interface.hbs +0 -3
  201. package/templates/generate/middleware.hbs +0 -9
  202. package/templates/generate/model.hbs +0 -6
  203. package/templates/generate/module.hbs +0 -6
  204. package/templates/generate/pipe.hbs +0 -9
  205. package/templates/generate/prisma.service.hbs +0 -13
  206. package/templates/generate/repository.hbs +0 -6
  207. package/templates/generate/response-filter.hbs +0 -9
  208. package/templates/generate/server/_partials/server-footer.hbs +0 -10
  209. package/templates/generate/server/_partials/server-header.hbs +0 -34
  210. package/templates/generate/server/express/server.hbs +0 -10
  211. package/templates/generate/server/fastify/server.hbs +0 -14
  212. package/templates/generate/server/koa/server.hbs +0 -8
  213. package/templates/generate/service.hbs +0 -6
  214. package/templates/generate/value.hbs +0 -3
  215. package/templates/init/.barrels.json.hbs +0 -9
  216. package/templates/init/.gitignore.hbs +0 -57
  217. package/templates/init/.npmrc.hbs +0 -2
  218. package/templates/init/docker/_partials/docker-body.hbs +0 -5
  219. package/templates/init/docker/_partials/docker-dev-tools.hbs +0 -2
  220. package/templates/init/docker/_partials/docker-header.hbs +0 -16
  221. package/templates/init/docker/bun/Dockerfile.hbs +0 -36
  222. package/templates/init/docker/npm/Dockerfile.hbs +0 -28
  223. package/templates/init/docker/pnpm/Dockerfile.hbs +0 -28
  224. package/templates/init/docker/yarn/Dockerfile.hbs +0 -28
  225. package/templates/init/docker/yarn_berry/Dockerfile.hbs +0 -31
  226. package/templates/init/docker-compose.yml.hbs +0 -14
  227. package/templates/init/pm2/bun/processes.config.cjs.hbs +0 -23
  228. package/templates/init/pm2/node-compiled/processes.config.cjs.hbs +0 -22
  229. package/templates/init/pm2/node-loader/processes.config.cjs.hbs +0 -24
  230. package/templates/init/src/bin/index.ts.hbs +0 -9
  231. package/templates/init/src/config/envs/index.ts.hbs +0 -7
  232. package/templates/init/src/config/index.ts.hbs +0 -38
  233. package/templates/init/src/config/logger/index.ts.hbs +0 -25
  234. package/templates/init/tsconfig.json.hbs +0 -16
  235. package/templates/init/tsconfig.node.json.hbs +0 -20
  236. package/templates/init/tsconfig.spec.json.hbs +0 -25
  237. package/templates/init/webpack.config.js.hbs +0 -65
  238. /package/lib/esm/{commands/init/interfaces/InitCmdContext.js → interfaces/AlterGenerateTasks.js} +0 -0
  239. /package/lib/{types/utils/hbs/index.d.ts → esm/interfaces/AlterInitSubTasks.js} +0 -0
  240. /package/templates/{init/.babelrc.hbs → .babelrc} +0 -0
  241. /package/templates/{init/.dockerignore.hbs → .dockerignore} +0 -0
  242. /package/templates/{init/.swcrc.hbs → .swcrc} +0 -0
  243. /package/templates/{init/.yarnrc.hbs → .yarnrc} +0 -0
  244. /package/templates/{init/nodemon.json.hbs → nodemon.json} +0 -0
  245. /package/templates/{init/tsconfig.base.json.hbs → tsconfig.base.json} +0 -0
  246. /package/templates/{init/views/swagger.ejs.hbs → views/swagger.ejs} +0 -0
@@ -0,0 +1,105 @@
1
+ export function transformConfigFile(project, data) {
2
+ if (!data.config && data.commandName === "init") {
3
+ project.addConfigSource("EnvsConfigSource", {
4
+ moduleSpecifier: "@tsedio/config-envs/envs"
5
+ });
6
+ }
7
+ if (data.config) {
8
+ if (data.configDotenv) {
9
+ project.addConfigSource("DotenvConfigSource", {
10
+ moduleSpecifier: "@tsedio/config-envs/dotenv"
11
+ });
12
+ }
13
+ else if (data.configEnvs) {
14
+ project.addConfigSource("EnvsConfigSource", {
15
+ moduleSpecifier: "@tsedio/config-envs/envs"
16
+ });
17
+ }
18
+ if (data.configJson) {
19
+ project.addConfigSource("JsonConfigSource", {
20
+ moduleSpecifier: "@tsedio/config-envs/json",
21
+ content: `withOptions(JsonConfigSource, {
22
+ path: "./config.json"
23
+ })`
24
+ });
25
+ }
26
+ if (data.configYaml) {
27
+ project.addConfigSource("YamlConfigSource", {
28
+ moduleSpecifier: "@tsedio/config-envs/yaml",
29
+ content: `withOptions(YamlConfigSource, {
30
+ path: "./config.yaml"
31
+ })`
32
+ });
33
+ }
34
+ if (data.configAwsSecrets) {
35
+ project.addConfigSource("AwsSecretsConfigSource", {
36
+ moduleSpecifier: "@tsedio/config-source-aws-secrets",
37
+ content: `withOptions(AwsSecretsConfigSource, {
38
+ name: "aws",
39
+ path: "/my-app/config", // Path prefix in Secrets Manager
40
+ region: "us-east-1", // AWS region
41
+ watch: true // Enable secrets watching
42
+ // validationSchema: object({}) // Optional: add a validation schema
43
+ // maxConcurrency: 10
44
+ })`
45
+ });
46
+ }
47
+ if (data.configVault) {
48
+ project.addConfigSource("VaultConfigSource", {
49
+ moduleSpecifier: "@tsedio/config-vault",
50
+ content: ` withOptions(VaultConfigSource, {
51
+ name: "vault",
52
+ endpoint: "http://localhost:8200", // Vault server URL
53
+ token: "your-vault-token", // Your Vault token
54
+ secretPath: "secret/data/myapp", // Path to your secret (KV v2 or v1, see below)
55
+ refreshInterval: 10000 // ⏱️ Polling interval in ms (default: 10s)
56
+ // Additional node-vault options
57
+
58
+ // validationSchema: object({}) // Optional: add a validation schema
59
+ })`
60
+ });
61
+ }
62
+ if (data.configIoredis) {
63
+ project.addConfigSource("IoredisConfigSource", {
64
+ moduleSpecifier: "@tsedio/config-ioredis",
65
+ content: `withOptions(IoredisConfigSource, {
66
+ name: "redis",
67
+ prefixKey: "my-config", // Optional: All config keys will be prefixed
68
+ url: "redis://localhost:6379" // Or use any Redis/Cluster options
69
+ // validationSchema: object({}) // Optional: add a validation schema
70
+ })`
71
+ });
72
+ }
73
+ if (data.configMongo) {
74
+ project.addConfigSource("MongoConfigSource", {
75
+ moduleSpecifier: "@tsedio/config-mongo",
76
+ content: `withOptions(MongoConfigSource, {
77
+ name: "mongo",
78
+ url: "mongodb://localhost:27017", // MongoDB connection URL
79
+ database: "my_database", // Database name
80
+ collection: "config" // Collection used for config storage
81
+
82
+ // Additional MongoDB client options can be provided here
83
+
84
+ // ConfigSource options
85
+ // validationSchema: object({}) // Optional: add a validation schema
86
+ })`
87
+ });
88
+ }
89
+ if (data.configPostgres) {
90
+ project.addConfigSource("PostgresConfigSource", {
91
+ moduleSpecifier: "@tsedio/config-postgres",
92
+ content: `withOptions(PostgresConfigSource, {
93
+ name: "postgres",
94
+ connectionString: "postgresql://postgres:postgres@localhost:5432/my_database", // PostgreSQL connection string
95
+ table: "config" // Table used for config storage
96
+
97
+ // Additional PostgresSQL client options can be provided here
98
+
99
+ // ConfigSource options
100
+ // validationSchema: object({}) // Optional: add a validation schema
101
+ })`
102
+ });
103
+ }
104
+ }
105
+ }
@@ -0,0 +1,23 @@
1
+ import { ts } from "@ts-morph/common";
2
+ import { pascalCase } from "change-case";
3
+ var SyntaxKind = ts.SyntaxKind;
4
+ export function transformIndexFile(project, data) {
5
+ const sourceFile = project.indexSourceFile;
6
+ sourceFile.addImportDeclaration({
7
+ moduleSpecifier: "./" + project.serverName.replace(".ts", ".js"),
8
+ namedImports: ["Server"]
9
+ });
10
+ const platformName = "Platform" + pascalCase(data.platform);
11
+ sourceFile.addImportDeclaration({
12
+ moduleSpecifier: "@tsed/platform-" + data.platform.toLowerCase(),
13
+ namedImports: [platformName]
14
+ });
15
+ sourceFile.getImportDeclaration((declaration) => declaration.getModuleSpecifierValue() === "@tsed/platform-http")?.remove();
16
+ sourceFile.getDescendantsOfKind(SyntaxKind.Identifier).map((identifier) => {
17
+ if (identifier.getText() === "PlatformBuilder") {
18
+ identifier.replaceWithText(identifier.getText().replace("PlatformBuilder", platformName));
19
+ return identifier.rename(platformName);
20
+ }
21
+ return identifier;
22
+ });
23
+ }
@@ -0,0 +1,60 @@
1
+ import { SyntaxKind } from "ts-morph";
2
+ import { ArchitectureConvention } from "../interfaces/index.js";
3
+ export function transformServerFile(project, data) {
4
+ const isFeature = data.architecture === ArchitectureConvention.FEATURE;
5
+ const sourceFile = project.serverSourceFile;
6
+ const options = project.findConfiguration("server");
7
+ if (!options) {
8
+ return;
9
+ }
10
+ if (data.commandName === "init") {
11
+ sourceFile.addImportDeclaration({
12
+ moduleSpecifier: "@tsed/platform-" + data.platform.toLowerCase()
13
+ });
14
+ }
15
+ if (data.swagger) {
16
+ sourceFile.addImportDeclaration({
17
+ moduleSpecifier: "@tsed/swagger"
18
+ });
19
+ project.getPropertyAssignment(options, {
20
+ name: "swagger",
21
+ kind: SyntaxKind.ArrayLiteralExpression,
22
+ initializer: JSON.stringify([
23
+ {
24
+ path: "/doc",
25
+ specVersion: "3.1.0"
26
+ }
27
+ ], null, 2)
28
+ });
29
+ }
30
+ if (data.scalar) {
31
+ sourceFile.addImportDeclaration({
32
+ moduleSpecifier: "@tsed/scalar"
33
+ });
34
+ project.getPropertyAssignment(options, {
35
+ name: "scalar",
36
+ kind: SyntaxKind.ArrayLiteralExpression,
37
+ initializer: JSON.stringify([
38
+ {
39
+ path: "/scalar/doc",
40
+ specVersion: "3.1.0"
41
+ }
42
+ ], null, 2)
43
+ });
44
+ }
45
+ if (data.commandName === "init") {
46
+ sourceFile.addImportDeclaration({
47
+ moduleSpecifier: "./config/index.js",
48
+ namedImports: [{ name: "config" }]
49
+ });
50
+ project.addNamespaceImport(sourceFile, isFeature ? "./rest/index.js" : "./controllers/rest/index.js", "rest");
51
+ project.addMountPath(data.route || "/rest", "...Object.values(rest)");
52
+ if (data.swagger || data.oidc) {
53
+ sourceFile.addImportDeclaration({
54
+ moduleSpecifier: isFeature ? "./pages/index.js" : "./controllers/pages/index.js",
55
+ namespaceImport: "pages"
56
+ });
57
+ project.addMountPath("/", "...Object.values(pages)");
58
+ }
59
+ }
60
+ }
@@ -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,96 @@
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 { taskOutput } from "../fn/taskOutput.js";
8
+ import { PlatformsModule } from "../platforms/PlatformsModule.js";
9
+ import { transformBinFile } from "../processors/transformBinFile.js";
10
+ import { transformConfigFile } from "../processors/transformConfigFile.js";
11
+ import { transformIndexFile } from "../processors/transformIndexFile.js";
12
+ import { transformServerFile } from "../processors/transformServerFile.js";
13
+ import { ProjectClient } from "../services/ProjectClient.js";
14
+ import { CliTemplatesService } from "./CliTemplatesService.js";
15
+ export class CliProjectService {
16
+ constructor() {
17
+ this.templates = inject(CliTemplatesService);
18
+ this.rootDir = constant("project.rootDir", process.cwd());
19
+ }
20
+ get srcDir() {
21
+ return join(...[this.rootDir, constant("project.srcDir")].filter(Boolean));
22
+ }
23
+ getRelativePath(path) {
24
+ return normalizePath(relative(dirname(join(this.srcDir, path)), this.rootDir));
25
+ }
26
+ getServerFileName() {
27
+ return this.get().getSource("Server.ts") ? "Server" : "server";
28
+ }
29
+ create() {
30
+ taskOutput("Create typescript project");
31
+ const fs = inject(CliFs);
32
+ this.project = new ProjectClient({
33
+ rootDir: this.rootDir
34
+ });
35
+ const files = fs.globSync([join(constant("project.rootDir", process.cwd()), "**/*.ts")]);
36
+ files.forEach((file) => {
37
+ this.project.createSourceFile(file, fs.readFileSync(file, "utf8"), {
38
+ overwrite: true
39
+ });
40
+ });
41
+ }
42
+ get() {
43
+ if (!this.project) {
44
+ this.create();
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
+ sourceFile.formatText({
64
+ indentSize: 2
65
+ });
66
+ return sourceFile.save();
67
+ }));
68
+ }
69
+ async createFromTemplate(templateId, ctx) {
70
+ const startTime = Date.now();
71
+ const obj = await this.templates.render(templateId, ctx);
72
+ taskOutput(`Template ${templateId} rendered in ${Date.now() - startTime}ms`);
73
+ const project = this.get();
74
+ if (obj) {
75
+ const sourceFile = await project.createSource(obj.outputPath, obj.content, {
76
+ overwrite: true
77
+ });
78
+ return {
79
+ ...obj,
80
+ source: sourceFile
81
+ };
82
+ }
83
+ }
84
+ getDirectories(dir) {
85
+ const directories = globbySync("**/*", {
86
+ cwd: join(this.srcDir, dir),
87
+ ignore: ["__*"]
88
+ });
89
+ const set = new Set(directories.map((dir) => {
90
+ return dirname(dir);
91
+ }));
92
+ set.delete(".");
93
+ return [...set];
94
+ }
95
+ }
96
+ injectable(CliProjectService);
@@ -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,68 @@
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 (await this.fs.fileExists(fromPath)) {
58
+ const content = await inject(CliFs).readFile(fromPath);
59
+ return {
60
+ templateId,
61
+ content,
62
+ outputPath: templateId.replace("{{srcDir}}", constant("project.srcDir", ""))
63
+ };
64
+ }
65
+ }
66
+ }
67
+ }
68
+ injectable(CliTemplatesService);
@@ -0,0 +1,161 @@
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
+ addConfigSource(name, { content = name, moduleSpecifier }) {
140
+ const sourceFile = this.configSourceFile;
141
+ const options = this.findConfiguration("config");
142
+ if (!options) {
143
+ return;
144
+ }
145
+ const extendsConfig = this.getPropertyAssignment(options, {
146
+ name: "extends",
147
+ kind: SyntaxKind.ArrayLiteralExpression,
148
+ initializer: "[]"
149
+ });
150
+ const has = extendsConfig.getElements().some((expression) => {
151
+ return expression.getText().includes(name);
152
+ });
153
+ if (!has) {
154
+ sourceFile.addImportDeclaration({
155
+ moduleSpecifier,
156
+ namedImports: [{ name: name }]
157
+ });
158
+ extendsConfig.addElement("\n" + content);
159
+ }
160
+ }
161
+ }