zudojs-cli 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/README.md +69 -9
  2. package/dist/src/adapters/frontend/angular.adapter.d.ts +0 -1
  3. package/dist/src/adapters/frontend/angular.adapter.js +14 -97
  4. package/dist/src/adapters/frontend/astro.adapter.d.ts +0 -1
  5. package/dist/src/adapters/frontend/astro.adapter.js +4 -64
  6. package/dist/src/adapters/frontend/fallback/fallback.helper.d.ts +41 -0
  7. package/dist/src/adapters/frontend/fallback/fallback.helper.js +57 -0
  8. package/dist/src/adapters/frontend/fallback/framework/angular/angular.fallback.d.ts +18 -0
  9. package/dist/src/adapters/frontend/fallback/framework/angular/angular.fallback.js +107 -0
  10. package/dist/src/adapters/frontend/fallback/framework/angular/angularWorkspace.fallback.d.ts +23 -0
  11. package/dist/src/adapters/frontend/fallback/framework/angular/angularWorkspace.fallback.js +125 -0
  12. package/dist/src/adapters/frontend/fallback/framework/angular/index.d.ts +8 -0
  13. package/dist/src/adapters/frontend/fallback/framework/angular/index.js +8 -0
  14. package/dist/src/adapters/frontend/fallback/framework/astro.fallback.d.ts +14 -0
  15. package/dist/src/adapters/frontend/fallback/framework/astro.fallback.js +76 -0
  16. package/dist/src/adapters/frontend/fallback/framework/index.d.ts +13 -0
  17. package/dist/src/adapters/frontend/fallback/framework/index.js +13 -0
  18. package/dist/src/adapters/frontend/fallback/framework/next.fallback.d.ts +13 -0
  19. package/dist/src/adapters/frontend/fallback/framework/next.fallback.js +105 -0
  20. package/dist/src/adapters/frontend/fallback/framework/nuxt.fallback.d.ts +14 -0
  21. package/dist/src/adapters/frontend/fallback/framework/nuxt.fallback.js +56 -0
  22. package/dist/src/adapters/frontend/fallback/framework/sveltekit.fallback.d.ts +15 -0
  23. package/dist/src/adapters/frontend/fallback/framework/sveltekit.fallback.js +94 -0
  24. package/dist/src/adapters/frontend/fallback/index.d.ts +12 -0
  25. package/dist/src/adapters/frontend/fallback/index.js +12 -0
  26. package/dist/src/adapters/frontend/fallback/vite/index.d.ts +11 -0
  27. package/dist/src/adapters/frontend/fallback/vite/index.js +11 -0
  28. package/dist/src/adapters/frontend/fallback/vite/react.fallback.d.ts +13 -0
  29. package/dist/src/adapters/frontend/fallback/vite/react.fallback.js +77 -0
  30. package/dist/src/adapters/frontend/fallback/vite/svelte.fallback.d.ts +14 -0
  31. package/dist/src/adapters/frontend/fallback/vite/svelte.fallback.js +95 -0
  32. package/dist/src/adapters/frontend/fallback/vite/vanilla.fallback.d.ts +13 -0
  33. package/dist/src/adapters/frontend/fallback/vite/vanilla.fallback.js +71 -0
  34. package/dist/src/adapters/frontend/fallback/vite/vue.fallback.d.ts +14 -0
  35. package/dist/src/adapters/frontend/fallback/vite/vue.fallback.js +78 -0
  36. package/dist/src/adapters/frontend/next.adapter.d.ts +0 -1
  37. package/dist/src/adapters/frontend/next.adapter.js +16 -95
  38. package/dist/src/adapters/frontend/nuxt.adapter.d.ts +1 -2
  39. package/dist/src/adapters/frontend/nuxt.adapter.js +32 -43
  40. package/dist/src/adapters/frontend/react-native.adapter.js +1 -1
  41. package/dist/src/adapters/frontend/react.adapter.d.ts +0 -1
  42. package/dist/src/adapters/frontend/react.adapter.js +7 -89
  43. package/dist/src/adapters/frontend/svelte.adapter.d.ts +0 -1
  44. package/dist/src/adapters/frontend/svelte.adapter.js +4 -86
  45. package/dist/src/adapters/frontend/sveltekit.adapter.d.ts +0 -1
  46. package/dist/src/adapters/frontend/sveltekit.adapter.js +4 -57
  47. package/dist/src/adapters/frontend/vanilla.adapter.d.ts +0 -1
  48. package/dist/src/adapters/frontend/vanilla.adapter.js +4 -47
  49. package/dist/src/adapters/frontend/vue.adapter.d.ts +0 -1
  50. package/dist/src/adapters/frontend/vue.adapter.js +4 -76
  51. package/dist/src/bin/bin.menu.d.ts +22 -0
  52. package/dist/src/bin/bin.menu.js +40 -0
  53. package/dist/src/bin/bin.runner.d.ts +38 -0
  54. package/dist/src/bin/bin.runner.js +51 -0
  55. package/dist/src/bin/index.d.ts +9 -0
  56. package/dist/src/bin/index.js +9 -0
  57. package/dist/src/bin/zudojs.js +15 -4
  58. package/dist/src/cliApplication/cliApplication.core.d.ts +4 -2
  59. package/dist/src/cliApplication/cliApplication.core.js +48 -36
  60. package/dist/src/cliApplication/cliApplication.logger.d.ts +5 -0
  61. package/dist/src/cliApplication/cliApplication.logger.js +5 -3
  62. package/dist/src/cliApplication/invocation/index.d.ts +12 -0
  63. package/dist/src/cliApplication/invocation/index.js +12 -0
  64. package/dist/src/cliApplication/invocation/invocation.hint.d.ts +30 -0
  65. package/dist/src/cliApplication/invocation/invocation.hint.js +74 -0
  66. package/dist/src/cliApplication/invocation/invocation.locate.d.ts +34 -0
  67. package/dist/src/cliApplication/invocation/invocation.locate.js +53 -0
  68. package/dist/src/cliApplication/invocation/invocation.name.d.ts +37 -0
  69. package/dist/src/cliApplication/invocation/invocation.name.js +69 -0
  70. package/dist/src/cliApplication/invocation/invocation.sanitize.d.ts +19 -0
  71. package/dist/src/cliApplication/invocation/invocation.sanitize.js +32 -0
  72. package/dist/src/cliParser/cliParser.core.js +3 -1
  73. package/dist/src/cliParser/cliParser.helper.d.ts +7 -0
  74. package/dist/src/cliParser/cliParser.helper.js +19 -2
  75. package/dist/src/cliParser/cliParser.longOption.js +2 -2
  76. package/dist/src/commands/add.command.d.ts +7 -3
  77. package/dist/src/commands/add.command.js +96 -57
  78. package/dist/src/commands/create.command.js +29 -42
  79. package/dist/src/commands/doctor.command.d.ts +2 -1
  80. package/dist/src/commands/doctor.command.js +52 -4
  81. package/dist/src/commands/generate.command.js +31 -16
  82. package/dist/src/commands/info.command.js +11 -1
  83. package/dist/src/constants/index.d.ts +21 -3
  84. package/dist/src/constants/index.js +40 -5
  85. package/dist/src/constants/zudojsVersions.generated.d.ts +9 -0
  86. package/dist/src/constants/zudojsVersions.generated.js +48 -0
  87. package/dist/src/constants/zudojsVersions.helper.d.ts +21 -0
  88. package/dist/src/constants/zudojsVersions.helper.js +29 -0
  89. package/dist/src/generators/frontend/frontendGenerator.core.js +9 -10
  90. package/dist/src/generators/frontend/frontendPipeline.d.ts +6 -1
  91. package/dist/src/generators/frontend/frontendPipeline.js +9 -1
  92. package/dist/src/generators/fullstack/fullstackComposer.core.js +7 -1
  93. package/dist/src/generators/index.d.ts +1 -2
  94. package/dist/src/generators/index.js +1 -2
  95. package/dist/src/generators/infrastructure/infrastructure.generator.js +13 -5
  96. package/dist/src/generators/integration/integrationGenerator.core.d.ts +2 -0
  97. package/dist/src/generators/integration/integrationGenerator.core.js +31 -2
  98. package/dist/src/generators/module/module.generator.js +36 -4
  99. package/dist/src/generators/resource/index.d.ts +8 -0
  100. package/dist/src/generators/resource/index.js +8 -0
  101. package/dist/src/generators/resource/resource.generator.d.ts +27 -0
  102. package/dist/src/generators/resource/resource.generator.js +87 -0
  103. package/dist/src/generators/resource/resource.layout.d.ts +26 -0
  104. package/dist/src/generators/resource/resource.layout.js +46 -0
  105. package/dist/src/generators/resource/resource.plan.d.ts +27 -0
  106. package/dist/src/generators/resource/resource.plan.js +46 -0
  107. package/dist/src/generators/resource/resource.run.d.ts +25 -0
  108. package/dist/src/generators/resource/resource.run.js +52 -0
  109. package/dist/src/prompts/cancel.prompt.d.ts +5 -1
  110. package/dist/src/prompts/cancel.prompt.js +4 -0
  111. package/dist/src/prompts/menu/index.d.ts +13 -0
  112. package/dist/src/prompts/menu/index.js +13 -0
  113. package/dist/src/prompts/menu/menu.adapter.d.ts +16 -0
  114. package/dist/src/prompts/menu/menu.adapter.js +56 -0
  115. package/dist/src/prompts/menu/menu.constant.d.ts +20 -0
  116. package/dist/src/prompts/menu/menu.constant.js +29 -0
  117. package/dist/src/prompts/menu/menu.flow.d.ts +18 -0
  118. package/dist/src/prompts/menu/menu.flow.js +82 -0
  119. package/dist/src/prompts/menu/menu.select.d.ts +26 -0
  120. package/dist/src/prompts/menu/menu.select.js +118 -0
  121. package/dist/src/prompts/menu/menu.type.d.ts +66 -0
  122. package/dist/src/prompts/menu/menu.type.js +8 -0
  123. package/dist/src/recipes/apply/index.d.ts +9 -0
  124. package/dist/src/recipes/apply/index.js +9 -0
  125. package/dist/src/recipes/apply/recipeApply.app.d.ts +20 -0
  126. package/dist/src/recipes/apply/recipeApply.app.js +79 -0
  127. package/dist/src/recipes/apply/recipeApply.context.d.ts +14 -0
  128. package/dist/src/recipes/apply/recipeApply.context.js +76 -0
  129. package/dist/src/recipes/apply/recipeApply.files.d.ts +39 -0
  130. package/dist/src/recipes/apply/recipeApply.files.js +84 -0
  131. package/dist/src/recipes/apply/recipeApply.project.d.ts +11 -0
  132. package/dist/src/recipes/apply/recipeApply.project.js +50 -0
  133. package/dist/src/recipes/apply/recipeApply.report.d.ts +20 -0
  134. package/dist/src/recipes/apply/recipeApply.report.js +51 -0
  135. package/dist/src/recipes/catalog/database/database.files.d.ts +15 -0
  136. package/dist/src/recipes/catalog/database/database.files.js +98 -0
  137. package/dist/src/recipes/catalog/database/database.recipe.d.ts +9 -0
  138. package/dist/src/recipes/catalog/database/database.recipe.js +50 -0
  139. package/dist/src/recipes/catalog/database/index.d.ts +6 -0
  140. package/dist/src/recipes/catalog/database/index.js +6 -0
  141. package/dist/src/recipes/catalog/email.recipe.d.ts +9 -0
  142. package/dist/src/recipes/catalog/email.recipe.js +122 -0
  143. package/dist/src/recipes/catalog/index.d.ts +11 -0
  144. package/dist/src/recipes/catalog/index.js +11 -0
  145. package/dist/src/recipes/catalog/openapi.recipe.d.ts +8 -0
  146. package/dist/src/recipes/catalog/openapi.recipe.js +25 -0
  147. package/dist/src/recipes/catalog/platform/cache.recipe.d.ts +7 -0
  148. package/dist/src/recipes/catalog/platform/cache.recipe.js +55 -0
  149. package/dist/src/recipes/catalog/platform/index.d.ts +9 -0
  150. package/dist/src/recipes/catalog/platform/index.js +9 -0
  151. package/dist/src/recipes/catalog/platform/messaging.recipe.d.ts +7 -0
  152. package/dist/src/recipes/catalog/platform/messaging.recipe.js +46 -0
  153. package/dist/src/recipes/catalog/platform/observability.recipe.d.ts +8 -0
  154. package/dist/src/recipes/catalog/platform/observability.recipe.js +49 -0
  155. package/dist/src/recipes/catalog/platform/queue.recipe.d.ts +7 -0
  156. package/dist/src/recipes/catalog/platform/queue.recipe.js +61 -0
  157. package/dist/src/recipes/catalog/platform/scheduler.recipe.d.ts +7 -0
  158. package/dist/src/recipes/catalog/platform/scheduler.recipe.js +56 -0
  159. package/dist/src/recipes/catalog/redis.recipe.d.ts +8 -0
  160. package/dist/src/recipes/catalog/redis.recipe.js +79 -0
  161. package/dist/src/recipes/catalog/storage.recipe.d.ts +7 -0
  162. package/dist/src/recipes/catalog/storage.recipe.js +49 -0
  163. package/dist/src/recipes/catalog/websockets.recipe.d.ts +10 -0
  164. package/dist/src/recipes/catalog/websockets.recipe.js +84 -0
  165. package/dist/src/recipes/docker/docker.compose.d.ts +19 -0
  166. package/dist/src/recipes/docker/docker.compose.js +90 -0
  167. package/dist/src/recipes/docker/docker.recipe.d.ts +10 -0
  168. package/dist/src/recipes/docker/docker.recipe.js +51 -0
  169. package/dist/src/recipes/docker/docker.refresh.d.ts +13 -0
  170. package/dist/src/recipes/docker/docker.refresh.js +37 -0
  171. package/dist/src/recipes/docker/index.d.ts +7 -0
  172. package/dist/src/recipes/docker/index.js +7 -0
  173. package/dist/src/recipes/index.d.ts +8 -0
  174. package/dist/src/recipes/index.js +8 -0
  175. package/dist/src/recipes/recipe.registry.d.ts +17 -0
  176. package/dist/src/recipes/recipe.registry.js +46 -0
  177. package/dist/src/recipes/recipe.type.d.ts +93 -0
  178. package/dist/src/recipes/recipe.type.js +12 -0
  179. package/dist/src/resolvers/dependency/dependencyVersions.constant.d.ts +100 -5
  180. package/dist/src/resolvers/dependency/dependencyVersions.constant.js +103 -34
  181. package/dist/src/resolvers/dependency/index.d.ts +1 -1
  182. package/dist/src/resolvers/dependency/index.js +1 -1
  183. package/dist/src/resolvers/project.resolver.d.ts +14 -1
  184. package/dist/src/resolvers/project.resolver.js +11 -3
  185. package/dist/src/scaffolders/scaffolder.helper.js +12 -1
  186. package/dist/src/templates/backendApp/backendApp.core.d.ts +45 -0
  187. package/dist/src/templates/backendApp/backendApp.core.js +66 -0
  188. package/dist/src/templates/backendApp/backendApp.modules.d.ts +26 -0
  189. package/dist/src/templates/backendApp/backendApp.modules.js +25 -0
  190. package/dist/src/templates/backendApp/backendApp.project.d.ts +26 -0
  191. package/dist/src/templates/backendApp/backendApp.project.js +87 -0
  192. package/dist/src/templates/backendApp/index.d.ts +8 -0
  193. package/dist/src/templates/backendApp/index.js +8 -0
  194. package/dist/src/templates/backendApp/parts/config.template.d.ts +28 -0
  195. package/dist/src/templates/backendApp/parts/config.template.js +118 -0
  196. package/dist/src/templates/backendApp/parts/httpUtils.template.d.ts +10 -0
  197. package/dist/src/templates/backendApp/parts/httpUtils.template.js +103 -0
  198. package/dist/src/templates/backendApp/parts/index.d.ts +9 -0
  199. package/dist/src/templates/backendApp/parts/index.js +9 -0
  200. package/dist/src/templates/backendApp/parts/integrations.template.d.ts +16 -0
  201. package/dist/src/templates/backendApp/parts/integrations.template.js +115 -0
  202. package/dist/src/templates/backendApp/parts/wiring.template.d.ts +26 -0
  203. package/dist/src/templates/backendApp/parts/wiring.template.js +111 -0
  204. package/dist/src/templates/microservice/microservice.template.d.ts +4 -1
  205. package/dist/src/templates/microservice/microservice.template.js +74 -90
  206. package/dist/src/templates/modular-monolith/modularMonolith.template.js +25 -77
  207. package/dist/src/templates/monolith/monolith.template.d.ts +11 -26
  208. package/dist/src/templates/monolith/monolith.template.js +49 -146
  209. package/dist/src/templates/resource/index.d.ts +9 -0
  210. package/dist/src/templates/resource/index.js +9 -0
  211. package/dist/src/templates/resource/layers/index.d.ts +9 -0
  212. package/dist/src/templates/resource/layers/index.js +9 -0
  213. package/dist/src/templates/resource/layers/resourceData.template.d.ts +9 -0
  214. package/dist/src/templates/resource/layers/resourceData.template.js +108 -0
  215. package/dist/src/templates/resource/layers/resourcePrisma.template.d.ts +15 -0
  216. package/dist/src/templates/resource/layers/resourcePrisma.template.js +89 -0
  217. package/dist/src/templates/resource/layers/resourceRoutes.template.d.ts +13 -0
  218. package/dist/src/templates/resource/layers/resourceRoutes.template.js +128 -0
  219. package/dist/src/templates/resource/layers/resourceService.template.d.ts +13 -0
  220. package/dist/src/templates/resource/layers/resourceService.template.js +95 -0
  221. package/dist/src/templates/resource/resource.files.d.ts +33 -0
  222. package/dist/src/templates/resource/resource.files.js +99 -0
  223. package/dist/src/templates/resource/resource.names.d.ts +38 -0
  224. package/dist/src/templates/resource/resource.names.js +60 -0
  225. package/dist/src/templates/resource/resource.type.d.ts +19 -0
  226. package/dist/src/templates/resource/resource.type.js +15 -0
  227. package/dist/src/templates/shared/appRuntime.template.js +28 -11
  228. package/dist/src/templates/shared/capability.template.d.ts +13 -4
  229. package/dist/src/templates/shared/capability.template.js +21 -5
  230. package/dist/src/templates/shared/dockerfile.template.d.ts +12 -4
  231. package/dist/src/templates/shared/dockerfile.template.js +68 -29
  232. package/dist/src/templates/shared/pnpm.template.d.ts +8 -2
  233. package/dist/src/templates/shared/pnpm.template.js +9 -1
  234. package/dist/src/templates/shared/server.template.d.ts +23 -22
  235. package/dist/src/templates/shared/server.template.js +79 -53
  236. package/dist/src/types/scaffold.type.d.ts +6 -0
  237. package/dist/src/types/scaffold.type.js +2 -1
  238. package/dist/src/utils/utils.name.js +6 -0
  239. package/dist/src/utils/utils.writeGuard.d.ts +5 -0
  240. package/dist/src/utils/utils.writeGuard.js +23 -0
  241. package/dist/src/wiring/index.d.ts +10 -0
  242. package/dist/src/wiring/index.js +10 -0
  243. package/dist/src/wiring/wiring.dependencies.d.ts +29 -0
  244. package/dist/src/wiring/wiring.dependencies.js +83 -0
  245. package/dist/src/wiring/wiring.edits.d.ts +51 -0
  246. package/dist/src/wiring/wiring.edits.js +90 -0
  247. package/dist/src/wiring/wiring.markers.d.ts +53 -0
  248. package/dist/src/wiring/wiring.markers.js +87 -0
  249. package/package.json +20 -15
@@ -3,44 +3,30 @@
3
3
  *
4
4
  * Template file generators for monolith architecture projects.
5
5
  *
6
- * Generated structure:
6
+ * Generated structure (see `templates/backendApp` for the wired source):
7
7
  * ```
8
8
  * project/
9
9
  * ├── src/
10
- * │ ├── index.ts # exports only
11
- * │ ├── app.ts # application assembly
12
- * │ ├── server.ts # entry point
13
- * │ ├── configs/
14
- * │ ├── constants/
15
- * │ ├── controllers/
16
- * │ ├── databases/
17
- * │ ├── dtos/
18
- * │ ├── enums/
19
- * │ ├── errors/
20
- * │ ├── events/
21
- * │ ├── interfaces/
22
- * │ ├── jobs/
23
- * │ ├── loaders/
24
- * │ ├── loggers/
25
- * │ ├── middlewares/
26
- * │ ├── models/
27
- * │ ├── modules/
28
- * │ ├── repositories/
29
- * │ ├── routes/
30
- * │ ├── services/
31
- * │ ├── types/
32
- * │ ├── utils/
33
- * │ └── validators/
34
- * ├── tests/
10
+ * │ ├── index.ts # exports only
11
+ * │ ├── app.ts # runtime assembly (modules + integrations)
12
+ * │ ├── server.ts # config → router → registerRoutes → HTTP
13
+ * │ ├── container.ts # composition root
14
+ * │ ├── configs/ # typed configuration from the environment
15
+ * │ ├── controllers/ dtos/ repositories/ services/ routes/
16
+ * │ ├── integrations/ # lifecycle-managed clients (zudojs add)
17
+ * │ ├── modules/ # runtime modules
18
+ * │ └── utils/ # HTTP helpers
19
+ * ├── tests/examples.test.ts
35
20
  * ├── package.json
36
21
  * ├── tsconfig.json
37
22
  * └── README.md
38
23
  * ```
39
24
  */
40
25
  import { renderDatabaseEnv } from "../../adapters/databases/databaseAdapter.resolver.js";
41
- import { ZUDOJS_PACKAGES_VERSION } from "../../constants/index.js";
26
+ import { zudojsDependencies } from "../../constants/index.js";
42
27
  import { normalizeName, toPascalCase } from "../../utils/utils.name.js";
43
- import { RUNTIME_APP_DEPENDENCIES, capabilityPackages, moduleSpec, renderAppFile, renderModuleFile, renderServerFile, renderServiceFile, renderPnpmWorkspaceFile, resolveProjectCapabilities, } from "../shared/index.js";
28
+ import { RUNTIME_APP_DEPENDENCIES, capabilityPackages, moduleSpec, renderModuleFile, renderServiceFile, renderPnpmWorkspaceFile, resolveProjectCapabilities, } from "../shared/index.js";
29
+ import { APP_SOURCE_DEPENDENCIES, APP_TEST_DEPENDENCIES, applyDatabaseSetting, backendDevDependencies, backendTsconfig, emptyBarrels, runCommand, renderBackendAppSource, } from "../backendApp/index.js";
44
30
  export function generateMonolithFiles(options) {
45
31
  const name = options.projectName;
46
32
  const nameSlug = name.replace(/[^a-z0-9-]+/gi, "-").toLowerCase();
@@ -49,25 +35,15 @@ export function generateMonolithFiles(options) {
49
35
  const capabilities = resolveProjectCapabilities(options);
50
36
  const deps = [
51
37
  ...RUNTIME_APP_DEPENDENCIES,
52
- "@zudojs/config",
53
- "@zudojs/errors",
38
+ ...APP_SOURCE_DEPENDENCIES,
54
39
  "@zudojs/types",
55
40
  "@zudojs/validation",
56
- "@zudojs/schema",
57
- "@zudojs/http",
58
41
  ...capabilityPackages(capabilities),
59
42
  ];
60
43
  if (options.enableCQRS) {
61
44
  deps.push("@zudojs/events");
62
45
  }
63
- const devDeps = {
64
- tsx: "^4.7.0",
65
- typescript: "^5.7.0",
66
- "@types/node": "^24.0.0",
67
- vitest: "^3.0.0",
68
- };
69
46
  const files = {};
70
- // Root files
71
47
  files["package.json"] =
72
48
  JSON.stringify({
73
49
  name: nameSlug,
@@ -88,38 +64,16 @@ export function generateMonolithFiles(options) {
88
64
  test: "vitest run",
89
65
  lint: "tsc --noEmit",
90
66
  },
91
- dependencies: Object.fromEntries([...new Set(deps)].map((d) => [d, ZUDOJS_PACKAGES_VERSION])),
92
- devDependencies: devDeps,
67
+ dependencies: zudojsDependencies(deps),
68
+ devDependencies: {
69
+ ...backendDevDependencies(),
70
+ ...zudojsDependencies(APP_TEST_DEPENDENCIES),
71
+ },
93
72
  }, null, 2) + "\n";
94
- // tsconfig
95
- files["tsconfig.json"] = `{
96
- "compilerOptions": {
97
- "target": "ES2024",
98
- "module": "Node16",
99
- "moduleResolution": "Node16",
100
- "outDir": "dist",
101
- "rootDir": "src",
102
- "strict": true,
103
- "skipLibCheck": true,
104
- "esModuleInterop": true,
105
- "resolveJsonModule": true,
106
- "lib": ["ES2024"],
107
- "types": ["node"]
108
- },
109
- "include": ["src/**/*"],
110
- "exclude": ["node_modules", "dist", "**/*.test.ts"]
111
- }
112
- `;
73
+ files["tsconfig.json"] = backendTsconfig();
113
74
  if (options.packageManager === "pnpm") {
114
75
  files["pnpm-workspace.yaml"] = renderPnpmWorkspaceFile();
115
76
  }
116
- // Environment
117
- files[".env.example"] = `NODE_ENV=development
118
- PORT=3000
119
-
120
- ${renderDatabaseEnv(options.database, nameSlug)}
121
- JWT_SECRET=change-this-in-production
122
- `;
123
77
  files[".gitignore"] = `node_modules/
124
78
  dist/
125
79
  .env
@@ -133,56 +87,53 @@ A Zudojs framework application.
133
87
  ## Getting Started
134
88
 
135
89
  \`\`\`bash
136
- ${options.packageManager === "npm" ? "npm run dev" : options.packageManager === "yarn" ? "yarn dev" : options.packageManager === "bun" ? "bun run dev" : "pnpm run dev"}
90
+ cp .env.example .env
91
+ ${runCommand(options.packageManager, "dev")}
92
+ \`\`\`
93
+
94
+ The server answers \`GET /health\` and the example resource at
95
+ \`/api/v1/examples\`${options.enableOpenAPI ? "; the OpenAPI document is at `/openapi.json` and the docs page at `/docs`" : ""}.
96
+
97
+ ## Generate and add
98
+
99
+ \`\`\`bash
100
+ npx zudojs generate resource users # DTO, repository, service, controller, routes, test — registered
101
+ npx zudojs add redis # also: database, websockets, email, docker, queue, ...
137
102
  \`\`\`
138
103
 
139
104
  ## Structure
140
105
 
141
106
  \`\`\`
142
107
  src/
143
- ├── server.ts # Entry point
144
- ├── app.ts # Application assembly
145
- ├── configs/ # Configuration
146
- ├── constants/ # Shared constants
147
- ├── controllers/ # HTTP controllers
148
- ├── databases/ # Database connections
149
- ├── dtos/ # Data transfer objects
150
- ├── enums/ # Enumerations
151
- ├── errors/ # Error types
152
- ├── events/ # Domain events
153
- ├── interfaces/ # Shared interfaces
154
- ├── jobs/ # Background jobs
155
- ├── loaders/ # Module loaders
156
- ├── loggers/ # Logger configuration
157
- ├── middlewares/ # HTTP middleware
158
- ├── models/ # Data models
108
+ ├── server.ts # Entry point: config, router, HTTP server
109
+ ├── app.ts # Runtime assembly (modules + integrations)
110
+ ├── container.ts # Composition root
111
+ ├── configs/ # Typed configuration (.env)
112
+ ├── controllers/ # HTTP handlers
113
+ ├── dtos/ # @zudojs/schema request/response schemas
114
+ ├── integrations/ # Redis, database, WebSockets, email (zudojs add)
159
115
  ├── modules/ # Runtime modules
160
- ├── repositories/ # Data repositories
161
- ├── routes/ # HTTP routes
162
- ├── services/ # Application services
163
- ├── types/ # Shared types
164
- ├── utils/ # Utilities
165
- └── validators/ # Input validators
116
+ ├── repositories/ # Data access
117
+ ├── routes/ # registerRoutes and per-resource routes
118
+ ├── services/ # Use cases
119
+ └── utils/ # HTTP helpers
166
120
  \`\`\`
167
121
 
168
122
  ## License
169
123
 
170
124
  MIT
171
125
  `;
172
- // src/ entry points
173
- files["src/index.ts"] = `export { createApp } from "./app.js";
174
- `;
175
- files["src/server.ts"] = renderServerFile("./app.js", {
176
- healthControllerImport: "./controllers/index.js",
177
- });
178
126
  // Normalized: the name becomes a file path segment and a class name.
179
127
  const moduleName = normalizeName(options.services[0] ?? "app") || "app";
180
128
  const serviceClassName = `${toPascalCase(moduleName)}Service`;
181
129
  const appModule = moduleSpec(moduleName, "./modules/index.js");
182
- files["src/app.ts"] = renderAppFile({
130
+ Object.assign(files, emptyBarrels(), applyDatabaseSetting(renderBackendAppSource({
183
131
  applicationName: nameSlug,
132
+ title: name,
133
+ defaultPort: 3000,
134
+ openapi: options.enableOpenAPI === true,
184
135
  modules: [appModule],
185
- });
136
+ }), renderDatabaseEnv(options.database, nameSlug)));
186
137
  files[`src/modules/${moduleName}.module.ts`] = renderModuleFile({
187
138
  module: appModule,
188
139
  service: {
@@ -192,57 +143,9 @@ MIT
192
143
  });
193
144
  files["src/modules/index.ts"] =
194
145
  `export { ${appModule.className} } from "./${moduleName}.module.js";\n`;
195
- // Shared directories with empty index.ts
196
- const sharedDirs = [
197
- "configs",
198
- "constants",
199
- "controllers",
200
- "databases",
201
- "dtos",
202
- "enums",
203
- "errors",
204
- "events",
205
- "interfaces",
206
- "jobs",
207
- "loaders",
208
- "loggers",
209
- "middlewares",
210
- "models",
211
- "repositories",
212
- "routes",
213
- "types",
214
- "utils",
215
- "validators",
216
- ];
217
- for (const dir of sharedDirs) {
218
- files[`src/${dir}/index.ts`] = "";
219
- }
220
- // Services
221
146
  files[`src/services/${moduleName}.service.ts`] = renderServiceFile(moduleName);
222
147
  files["src/services/index.ts"] =
223
148
  `export { ${serviceClassName} } from "./${moduleName}.service.js";\n`;
224
- // Controllers
225
- files["src/controllers/health.controller.ts"] =
226
- `export class HealthController {
227
- check() {
228
- return { status: "ok", timestamp: new Date().toISOString() };
229
- }
230
- }
231
- `;
232
- files["src/controllers/index.ts"] =
233
- `export { HealthController } from "./health.controller.js";
234
- `;
235
- // Tests. The file name must match vitest's default `include`
236
- // (`**/*.{test,spec}.?(c|m)[jt]s?(x)`); `tests/index.ts` did not, so the
237
- // generated `test` script exited 1 with "No test files found".
238
- files["tests/app.test.ts"] = `import { describe, it, expect } from "vitest";
239
-
240
- describe("Application", () => {
241
- it("should be configured correctly", () => {
242
- expect(true).toBe(true);
243
- });
244
- });
245
- `;
246
149
  return files;
247
150
  }
248
151
  //# sourceMappingURL=monolith.template.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * zudojs-cli — Resource templates: the DTO → repository → service →
3
+ * controller → routes chain, its test, and how it is registered.
4
+ */
5
+ export * from "./resource.names.js";
6
+ export * from "./resource.type.js";
7
+ export * from "./resource.files.js";
8
+ export * from "./layers/index.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * zudojs-cli — Resource templates: the DTO → repository → service →
3
+ * controller → routes chain, its test, and how it is registered.
4
+ */
5
+ export * from "./resource.names.js";
6
+ export * from "./resource.type.js";
7
+ export * from "./resource.files.js";
8
+ export * from "./layers/index.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * zudojs-cli — Resource layer templates: DTO, repositories, service,
3
+ * controller, routes and test.
4
+ */
5
+ export * from "./resourceData.template.js";
6
+ export * from "./resourcePrisma.template.js";
7
+ export * from "./resourceService.template.js";
8
+ export * from "./resourceRoutes.template.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * zudojs-cli — Resource layer templates: DTO, repositories, service,
3
+ * controller, routes and test.
4
+ */
5
+ export * from "./resourceData.template.js";
6
+ export * from "./resourcePrisma.template.js";
7
+ export * from "./resourceService.template.js";
8
+ export * from "./resourceRoutes.template.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * zudojs-cli — A resource's DTO schemas and in-memory repository.
3
+ */
4
+ import type { ResourceNames } from "../resource.names.js";
5
+ /** `dtos/<slug>.dto.ts`: @zudojs/schema schemas and their inferred types. */
6
+ export declare function renderResourceDto(n: ResourceNames): string;
7
+ /** `repositories/<slug>.repository.ts`: the contract and a memory store. */
8
+ export declare function renderResourceRepository(n: ResourceNames): string;
9
+ //# sourceMappingURL=resourceData.template.d.ts.map
@@ -0,0 +1,108 @@
1
+ /**
2
+ * zudojs-cli — A resource's DTO schemas and in-memory repository.
3
+ */
4
+ /** `dtos/<slug>.dto.ts`: @zudojs/schema schemas and their inferred types. */
5
+ export function renderResourceDto(n) {
6
+ return `import { schema, type Infer } from "@zudojs/schema";
7
+
8
+ /** A ${n.label} as the API returns it. */
9
+ export const ${n.entity}Schema = schema.object({
10
+ id: schema.string().uuid(),
11
+ name: schema.string(),
12
+ createdAt: schema.string(),
13
+ updatedAt: schema.string(),
14
+ });
15
+
16
+ /** Body of \`POST ${n.routePath}\`. Unknown fields are dropped. */
17
+ export const Create${n.entity}Schema = schema.object({
18
+ name: schema.string().min(1).max(200),
19
+ });
20
+
21
+ /** Body of \`PATCH ${n.routePath}/:id\`. Every field is optional. */
22
+ export const Update${n.entity}Schema = schema.object({
23
+ name: schema.string().min(1).max(200).optional(),
24
+ });
25
+
26
+ /** Path parameters of the \`${n.routePath}/:id\` routes. */
27
+ export const ${n.entity}ParamsSchema = schema.object({
28
+ id: schema.string().uuid(),
29
+ });
30
+
31
+ export type ${n.entity} = Infer<typeof ${n.entity}Schema>;
32
+ export type Create${n.entity}Input = Infer<typeof Create${n.entity}Schema>;
33
+ export type Update${n.entity}Input = Infer<typeof Update${n.entity}Schema>;
34
+ `;
35
+ }
36
+ /** `repositories/<slug>.repository.ts`: the contract and a memory store. */
37
+ export function renderResourceRepository(n) {
38
+ const types = `Create${n.entity}Input, ${n.entity}, Update${n.entity}Input`;
39
+ return `import { randomUUID } from "node:crypto";
40
+
41
+ import { ConflictError } from "@zudojs/errors";
42
+
43
+ import type { ${types} } from "../dtos/${n.slug}.dto.js";
44
+
45
+ /** Storage contract for ${n.label} records; the service depends on this only. */
46
+ export interface ${n.pascal}Repository {
47
+ findAll(): Promise<readonly ${n.entity}[]>;
48
+ findById(id: string): Promise<${n.entity} | undefined>;
49
+ create(input: Create${n.entity}Input): Promise<${n.entity}>;
50
+ update(id: string, input: Update${n.entity}Input): Promise<${n.entity} | undefined>;
51
+ delete(id: string): Promise<boolean>;
52
+ }
53
+
54
+ /** Most records the in-memory store keeps, so it cannot exhaust memory. */
55
+ const MAX_RECORDS = 10_000;
56
+
57
+ /**
58
+ * Keeps ${n.label} records in process memory: for development and tests.
59
+ * Data is lost on restart. Swap the implementation in container.ts.
60
+ */
61
+ export class InMemory${n.pascal}Repository implements ${n.pascal}Repository {
62
+ private readonly records = new Map<string, ${n.entity}>();
63
+
64
+ public async findAll(): Promise<readonly ${n.entity}[]> {
65
+ return [...this.records.values()];
66
+ }
67
+
68
+ public async findById(id: string): Promise<${n.entity} | undefined> {
69
+ return this.records.get(id);
70
+ }
71
+
72
+ public async create(input: Create${n.entity}Input): Promise<${n.entity}> {
73
+ if (this.records.size >= MAX_RECORDS) {
74
+ throw new ConflictError("The in-memory ${n.label} store is full.");
75
+ }
76
+ const now = new Date().toISOString();
77
+ const record: ${n.entity} = {
78
+ id: randomUUID(),
79
+ name: input.name,
80
+ createdAt: now,
81
+ updatedAt: now,
82
+ };
83
+ this.records.set(record.id, record);
84
+ return record;
85
+ }
86
+
87
+ public async update(
88
+ id: string,
89
+ input: Update${n.entity}Input,
90
+ ): Promise<${n.entity} | undefined> {
91
+ const existing = this.records.get(id);
92
+ if (existing === undefined) return undefined;
93
+ const updated: ${n.entity} = {
94
+ ...existing,
95
+ name: input.name ?? existing.name,
96
+ updatedAt: new Date().toISOString(),
97
+ };
98
+ this.records.set(id, updated);
99
+ return updated;
100
+ }
101
+
102
+ public async delete(id: string): Promise<boolean> {
103
+ return this.records.delete(id);
104
+ }
105
+ }
106
+ `;
107
+ }
108
+ //# sourceMappingURL=resourceData.template.js.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * zudojs-cli — A resource's Prisma-backed repository and model.
3
+ *
4
+ * Generated only in an app that has Prisma (`zudojs add database`). The
5
+ * repository reads the client from `src/integrations/database.ts`, which
6
+ * the runtime connects on start.
7
+ */
8
+ import type { ResourceNames } from "../resource.names.js";
9
+ /** `repositories/<slug>.prisma.repository.ts`. */
10
+ export declare function renderPrismaRepository(n: ResourceNames, appSrcFromRepositories: string): string;
11
+ /** The Prisma model block appended to prisma/schema.prisma. */
12
+ export declare function renderPrismaModel(n: ResourceNames): string;
13
+ /** Whether `schema` already declares a model named `entity`. */
14
+ export declare function hasPrismaModel(schema: string, entity: string): boolean;
15
+ //# sourceMappingURL=resourcePrisma.template.d.ts.map
@@ -0,0 +1,89 @@
1
+ /**
2
+ * zudojs-cli — A resource's Prisma-backed repository and model.
3
+ *
4
+ * Generated only in an app that has Prisma (`zudojs add database`). The
5
+ * repository reads the client from `src/integrations/database.ts`, which
6
+ * the runtime connects on start.
7
+ */
8
+ /** `repositories/<slug>.prisma.repository.ts`. */
9
+ export function renderPrismaRepository(n, appSrcFromRepositories) {
10
+ const types = `Create${n.entity}Input, ${n.entity}, Update${n.entity}Input`;
11
+ const delegate = `prisma().${n.entityCamel}`;
12
+ return `import { prisma } from "${appSrcFromRepositories}/integrations/database.js";
13
+ import type { ${types} } from "../dtos/${n.slug}.dto.js";
14
+ import type { ${n.pascal}Repository } from "./${n.slug}.repository.js";
15
+
16
+ interface ${n.entity}Row {
17
+ readonly id: string;
18
+ readonly name: string;
19
+ readonly createdAt: Date;
20
+ readonly updatedAt: Date;
21
+ }
22
+
23
+ function to${n.entity}(row: ${n.entity}Row): ${n.entity} {
24
+ return {
25
+ id: row.id,
26
+ name: row.name,
27
+ createdAt: row.createdAt.toISOString(),
28
+ updatedAt: row.updatedAt.toISOString(),
29
+ };
30
+ }
31
+
32
+ /** Most rows \`findAll\` returns; add pagination before raising it. */
33
+ const LIST_LIMIT = 1000;
34
+
35
+ /** Stores ${n.label} records in the \`${n.slug.replace(/-/g, "_")}\` table through Prisma. */
36
+ export class Prisma${n.pascal}Repository implements ${n.pascal}Repository {
37
+ public async findAll(): Promise<readonly ${n.entity}[]> {
38
+ const rows = await ${delegate}.findMany({
39
+ orderBy: { createdAt: "asc" },
40
+ take: LIST_LIMIT,
41
+ });
42
+ return rows.map(to${n.entity});
43
+ }
44
+
45
+ public async findById(id: string): Promise<${n.entity} | undefined> {
46
+ const row = await ${delegate}.findUnique({ where: { id } });
47
+ return row === null ? undefined : to${n.entity}(row);
48
+ }
49
+
50
+ public async create(input: Create${n.entity}Input): Promise<${n.entity}> {
51
+ return to${n.entity}(await ${delegate}.create({ data: { name: input.name } }));
52
+ }
53
+
54
+ public async update(
55
+ id: string,
56
+ input: Update${n.entity}Input,
57
+ ): Promise<${n.entity} | undefined> {
58
+ const result = await ${delegate}.updateMany({
59
+ where: { id },
60
+ data: input.name === undefined ? {} : { name: input.name },
61
+ });
62
+ return result.count === 0 ? undefined : this.findById(id);
63
+ }
64
+
65
+ public async delete(id: string): Promise<boolean> {
66
+ const result = await ${delegate}.deleteMany({ where: { id } });
67
+ return result.count > 0;
68
+ }
69
+ }
70
+ `;
71
+ }
72
+ /** The Prisma model block appended to prisma/schema.prisma. */
73
+ export function renderPrismaModel(n) {
74
+ return `
75
+ model ${n.entity} {
76
+ id String @id @default(uuid())
77
+ name String
78
+ createdAt DateTime @default(now())
79
+ updatedAt DateTime @updatedAt
80
+
81
+ @@map("${n.slug.replace(/-/g, "_")}")
82
+ }
83
+ `;
84
+ }
85
+ /** Whether `schema` already declares a model named `entity`. */
86
+ export function hasPrismaModel(schema, entity) {
87
+ return new RegExp(`^model\\s+${entity}\\s*\\{`, "m").test(schema);
88
+ }
89
+ //# sourceMappingURL=resourcePrisma.template.js.map
@@ -0,0 +1,13 @@
1
+ /**
2
+ * zudojs-cli — A resource's CRUD routes (with OpenAPI metadata) and test.
3
+ */
4
+ import type { ResourceNames } from "../resource.names.js";
5
+ /** `routes/<slug>.routes.ts`: `register<Pascal>Routes(router, controller)`. */
6
+ export declare function renderResourceRoutes(n: ResourceNames): string;
7
+ /**
8
+ * `tests/<slug>.test.ts`: drives the routes over real HTTP with
9
+ * `createHttpTestClient`, backed by the in-memory repository.
10
+ * `baseFromTests` is the import prefix from the tests folder to the layers.
11
+ */
12
+ export declare function renderResourceTest(n: ResourceNames, baseFromTests: string): string;
13
+ //# sourceMappingURL=resourceRoutes.template.d.ts.map