nestjs-ddd-cli 3.2.1 → 3.3.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 (214) hide show
  1. package/README.md +118 -9
  2. package/ddd.schema.json +11 -1
  3. package/dist/commands/doctor-enhanced.d.ts +1 -0
  4. package/dist/commands/doctor-enhanced.js +94 -79
  5. package/dist/commands/doctor-enhanced.js.map +1 -1
  6. package/dist/commands/doctor.d.ts +9 -0
  7. package/dist/commands/doctor.js +68 -21
  8. package/dist/commands/doctor.js.map +1 -1
  9. package/dist/commands/generate-all.js +238 -176
  10. package/dist/commands/generate-all.js.map +1 -1
  11. package/dist/commands/generate-controller.d.ts +1 -0
  12. package/dist/commands/generate-controller.js +71 -0
  13. package/dist/commands/generate-controller.js.map +1 -0
  14. package/dist/commands/generate-domain-service.d.ts +1 -1
  15. package/dist/commands/generate-domain-service.js +6 -4
  16. package/dist/commands/generate-domain-service.js.map +1 -1
  17. package/dist/commands/generate-dto.d.ts +4 -0
  18. package/dist/commands/generate-dto.js +162 -0
  19. package/dist/commands/generate-dto.js.map +1 -0
  20. package/dist/commands/generate-entity.js +44 -35
  21. package/dist/commands/generate-entity.js.map +1 -1
  22. package/dist/commands/generate-event.js +10 -4
  23. package/dist/commands/generate-event.js.map +1 -1
  24. package/dist/commands/generate-migration-deployment.d.ts +15 -0
  25. package/dist/commands/generate-migration-deployment.js +326 -0
  26. package/dist/commands/generate-migration-deployment.js.map +1 -0
  27. package/dist/commands/generate-migration-deployment.spec.d.ts +1 -0
  28. package/dist/commands/generate-migration-deployment.spec.js +337 -0
  29. package/dist/commands/generate-migration-deployment.spec.js.map +1 -0
  30. package/dist/commands/generate-module.js +41 -31
  31. package/dist/commands/generate-module.js.map +1 -1
  32. package/dist/commands/generate-query.js +23 -4
  33. package/dist/commands/generate-query.js.map +1 -1
  34. package/dist/commands/generate-repository.d.ts +1 -1
  35. package/dist/commands/generate-repository.js +17 -34
  36. package/dist/commands/generate-repository.js.map +1 -1
  37. package/dist/commands/generate-service.js +19 -4
  38. package/dist/commands/generate-service.js.map +1 -1
  39. package/dist/commands/generate-usecase.js +12 -31
  40. package/dist/commands/generate-usecase.js.map +1 -1
  41. package/dist/commands/generate-value-object.js +3 -14
  42. package/dist/commands/generate-value-object.js.map +1 -1
  43. package/dist/commands/init-project.d.ts +3 -0
  44. package/dist/commands/init-project.js +19 -9
  45. package/dist/commands/init-project.js.map +1 -1
  46. package/dist/commands/interactive-scaffold.js +10 -0
  47. package/dist/commands/interactive-scaffold.js.map +1 -1
  48. package/dist/commands/migration.d.ts +3 -0
  49. package/dist/commands/migration.js +83 -48
  50. package/dist/commands/migration.js.map +1 -1
  51. package/dist/commands/recipe.d.ts +2 -0
  52. package/dist/commands/recipe.js +282 -91
  53. package/dist/commands/recipe.js.map +1 -1
  54. package/dist/commands/recipes/banklink-connector-contract.recipe.d.ts +1 -0
  55. package/dist/commands/recipes/banklink-connector-contract.recipe.js +161 -0
  56. package/dist/commands/recipes/banklink-connector-contract.recipe.js.map +1 -0
  57. package/dist/commands/recipes/bounded-json-http.recipe.d.ts +2 -0
  58. package/dist/commands/recipes/bounded-json-http.recipe.js +53 -0
  59. package/dist/commands/recipes/bounded-json-http.recipe.js.map +1 -0
  60. package/dist/commands/recipes/business-reference-identifiers.recipe.d.ts +1 -0
  61. package/dist/commands/recipes/business-reference-identifiers.recipe.js +223 -0
  62. package/dist/commands/recipes/business-reference-identifiers.recipe.js.map +1 -0
  63. package/dist/commands/recipes/event-backbone.recipe.d.ts +1 -0
  64. package/dist/commands/recipes/event-backbone.recipe.js +1118 -0
  65. package/dist/commands/recipes/event-backbone.recipe.js.map +1 -0
  66. package/dist/commands/recipes/external-projection-worker.recipe.d.ts +6 -0
  67. package/dist/commands/recipes/external-projection-worker.recipe.js +211 -0
  68. package/dist/commands/recipes/external-projection-worker.recipe.js.map +1 -0
  69. package/dist/commands/recipes/index.d.ts +12 -0
  70. package/dist/commands/recipes/index.js +12 -0
  71. package/dist/commands/recipes/index.js.map +1 -1
  72. package/dist/commands/recipes/jest-cjs-compat.recipe.d.ts +3 -0
  73. package/dist/commands/recipes/jest-cjs-compat.recipe.js +130 -0
  74. package/dist/commands/recipes/jest-cjs-compat.recipe.js.map +1 -0
  75. package/dist/commands/recipes/joi-env.recipe.d.ts +1 -0
  76. package/dist/commands/recipes/joi-env.recipe.js +301 -0
  77. package/dist/commands/recipes/joi-env.recipe.js.map +1 -0
  78. package/dist/commands/recipes/kafka-consumer.recipe.d.ts +1 -0
  79. package/dist/commands/recipes/kafka-consumer.recipe.js +65 -0
  80. package/dist/commands/recipes/kafka-consumer.recipe.js.map +1 -0
  81. package/dist/commands/recipes/oauth2-client-credentials.recipe.d.ts +1 -0
  82. package/dist/commands/recipes/oauth2-client-credentials.recipe.js +60 -0
  83. package/dist/commands/recipes/oauth2-client-credentials.recipe.js.map +1 -0
  84. package/dist/commands/recipes/oauth2-token-introspection.recipe.d.ts +1 -0
  85. package/dist/commands/recipes/oauth2-token-introspection.recipe.js +67 -0
  86. package/dist/commands/recipes/oauth2-token-introspection.recipe.js.map +1 -0
  87. package/dist/commands/recipes/oidc-bff-session.recipe.d.ts +1 -0
  88. package/dist/commands/recipes/oidc-bff-session.recipe.js +57 -0
  89. package/dist/commands/recipes/oidc-bff-session.recipe.js.map +1 -0
  90. package/dist/commands/recipes/oidc-dashboard.recipe.d.ts +1 -0
  91. package/dist/commands/recipes/oidc-dashboard.recipe.js +463 -0
  92. package/dist/commands/recipes/oidc-dashboard.recipe.js.map +1 -0
  93. package/dist/commands/recipes/oidc-resource-server.recipe.d.ts +1 -0
  94. package/dist/commands/recipes/oidc-resource-server.recipe.js +85 -0
  95. package/dist/commands/recipes/oidc-resource-server.recipe.js.map +1 -0
  96. package/dist/commands/recipes/platform-context.recipe.d.ts +1 -0
  97. package/dist/commands/recipes/platform-context.recipe.js +229 -0
  98. package/dist/commands/recipes/platform-context.recipe.js.map +1 -0
  99. package/dist/commands/recipes/platform-parc-authorization.recipe.d.ts +1 -0
  100. package/dist/commands/recipes/platform-parc-authorization.recipe.js +339 -0
  101. package/dist/commands/recipes/platform-parc-authorization.recipe.js.map +1 -0
  102. package/dist/commands/recipes/platform-parc-bound-authorization.recipe.d.ts +1 -0
  103. package/dist/commands/recipes/platform-parc-bound-authorization.recipe.js +56 -0
  104. package/dist/commands/recipes/platform-parc-bound-authorization.recipe.js.map +1 -0
  105. package/dist/commands/recipes/platform-service-access-request-context.recipe.d.ts +1 -0
  106. package/dist/commands/recipes/platform-service-access-request-context.recipe.js +103 -0
  107. package/dist/commands/recipes/platform-service-access-request-context.recipe.js.map +1 -0
  108. package/dist/commands/recipes/platform-service-runtime.recipe.d.ts +1 -0
  109. package/dist/commands/recipes/platform-service-runtime.recipe.js +415 -0
  110. package/dist/commands/recipes/platform-service-runtime.recipe.js.map +1 -0
  111. package/dist/index.js +82 -11
  112. package/dist/index.js.map +1 -1
  113. package/dist/templates/ai-context/CLAUDE.md.hbs +54 -3
  114. package/dist/templates/ai-context/conventions.md.hbs +20 -8
  115. package/dist/templates/command/create-command.hbs +8 -3
  116. package/dist/templates/command/delete-command.hbs +1 -1
  117. package/dist/templates/command/update-command.hbs +1 -1
  118. package/dist/templates/controller/application-controller.hbs +7 -0
  119. package/dist/templates/controller/controller.hbs +6 -0
  120. package/dist/templates/dto/create-dto.hbs +17 -5
  121. package/dist/templates/dto/filter-dto.hbs +1 -1
  122. package/dist/templates/dto/response-dto.hbs +1 -1
  123. package/dist/templates/entity/entity.hbs +4 -0
  124. package/dist/templates/mapper/mapper.hbs +6 -2
  125. package/dist/templates/orm-entity/orm-entity.hbs +9 -1
  126. package/dist/templates/prisma/prisma-mapper.hbs +6 -0
  127. package/dist/templates/prisma/prisma-repository.hbs +57 -5
  128. package/dist/templates/prisma/prisma-schema.hbs +2 -0
  129. package/dist/templates/query/get-all.query.hbs +10 -2
  130. package/dist/templates/recipes/bounded-json-http/README.md.hbs +36 -0
  131. package/dist/templates/recipes/external-projection-worker/README.md.hbs +157 -0
  132. package/dist/templates/recipes/external-projection-worker/canonical-json.ts.hbs +123 -0
  133. package/dist/templates/recipes/external-projection-worker/enqueuer.ts.hbs +167 -0
  134. package/dist/templates/recipes/external-projection-worker/index.ts.hbs +6 -0
  135. package/dist/templates/recipes/external-projection-worker/migration.ts.hbs +88 -0
  136. package/dist/templates/recipes/external-projection-worker/module.ts.hbs +36 -0
  137. package/dist/templates/recipes/external-projection-worker/store.ts.hbs +354 -0
  138. package/dist/templates/recipes/external-projection-worker/types.ts.hbs +134 -0
  139. package/dist/templates/recipes/external-projection-worker/worker.ts.hbs +296 -0
  140. package/dist/templates/recipes/kafka-consumer/README.md.hbs +50 -0
  141. package/dist/templates/recipes/kafka-consumer/kafka-consumer.ts.hbs +135 -0
  142. package/dist/templates/recipes/kafka-consumer/migration.ts.hbs +17 -0
  143. package/dist/templates/recipes/oauth2-client-credentials/README.md.hbs +40 -0
  144. package/dist/templates/recipes/oauth2-client-credentials/client.spec.ts.hbs +234 -0
  145. package/dist/templates/recipes/oauth2-client-credentials/client.ts.hbs +210 -0
  146. package/dist/templates/recipes/oauth2-client-credentials/index.ts.hbs +2 -0
  147. package/dist/templates/recipes/oauth2-client-credentials/module.ts.hbs +58 -0
  148. package/dist/templates/recipes/oauth2-token-introspection/README.md.hbs +158 -0
  149. package/dist/templates/recipes/oauth2-token-introspection/client.spec.ts.hbs +350 -0
  150. package/dist/templates/recipes/oauth2-token-introspection/client.ts.hbs +241 -0
  151. package/dist/templates/recipes/oauth2-token-introspection/http-client.spec.ts.hbs +411 -0
  152. package/dist/templates/recipes/oauth2-token-introspection/http-client.ts.hbs +343 -0
  153. package/dist/templates/recipes/oauth2-token-introspection/index.ts.hbs +3 -0
  154. package/dist/templates/recipes/oauth2-token-introspection/module.ts.hbs +58 -0
  155. package/dist/templates/recipes/oidc-bff-session/README.md.hbs +96 -0
  156. package/dist/templates/recipes/oidc-bff-session/client.test.ts.hbs +663 -0
  157. package/dist/templates/recipes/oidc-bff-session/client.ts.hbs +635 -0
  158. package/dist/templates/recipes/oidc-bff-session/index.ts.hbs +3 -0
  159. package/dist/templates/recipes/oidc-bff-session/store.integration.test.ts.hbs +480 -0
  160. package/dist/templates/recipes/oidc-bff-session/store.test.ts.hbs +87 -0
  161. package/dist/templates/recipes/oidc-bff-session/store.ts.hbs +549 -0
  162. package/dist/templates/recipes/oidc-bff-session/valkey.test.ts.hbs +158 -0
  163. package/dist/templates/recipes/oidc-bff-session/valkey.ts.hbs +148 -0
  164. package/dist/templates/recipes/oidc-resource-server/README.md.hbs +74 -0
  165. package/dist/templates/recipes/oidc-resource-server/index.ts.hbs +2 -0
  166. package/dist/templates/recipes/oidc-resource-server/module.ts.hbs +51 -0
  167. package/dist/templates/recipes/oidc-resource-server/verifier.spec.ts.hbs +186 -0
  168. package/dist/templates/recipes/oidc-resource-server/verifier.ts.hbs +440 -0
  169. package/dist/templates/recipes/platform-parc-bound-authorization/README.md.hbs +92 -0
  170. package/dist/templates/recipes/platform-parc-bound-authorization/client.ts.hbs +142 -0
  171. package/dist/templates/recipes/platform-service-access-request-context/docs.md.hbs +61 -0
  172. package/dist/templates/recipes/platform-service-access-request-context/env.example.hbs +7 -0
  173. package/dist/templates/recipes/platform-service-access-request-context/index.ts.hbs +7 -0
  174. package/dist/templates/recipes/platform-service-access-request-context/request-context-headers.ts.hbs +61 -0
  175. package/dist/templates/recipes/platform-service-access-request-context/request-context-introspection.parser.ts.hbs +132 -0
  176. package/dist/templates/recipes/platform-service-access-request-context/request-context-introspection.types.ts.hbs +40 -0
  177. package/dist/templates/recipes/platform-service-access-request-context/service-access-request-context.client.ts.hbs +45 -0
  178. package/dist/templates/recipes/platform-service-access-request-context/service-access-request-context.config.ts.hbs +142 -0
  179. package/dist/templates/recipes/platform-service-access-request-context/service-access-request-context.guard.ts.hbs +77 -0
  180. package/dist/templates/recipes/platform-service-access-request-context/service-access-request-context.module.ts.hbs +17 -0
  181. package/dist/templates/repository/repository.hbs +43 -5
  182. package/dist/templates/resolver/graphql-input.hbs +23 -6
  183. package/dist/templates/resolver/resolver.hbs +4 -0
  184. package/dist/templates/service/domain-service.hbs +2 -2
  185. package/dist/templates/test/controller.spec.hbs +5 -1
  186. package/dist/templates/test/prisma-repository.spec.hbs +192 -0
  187. package/dist/templates/test/repository.spec.hbs +41 -2
  188. package/dist/templates/test/usecase.spec.hbs +24 -5
  189. package/dist/templates/usecase/application-usecase.hbs +17 -0
  190. package/dist/templates/usecase/create-usecase.hbs +34 -3
  191. package/dist/templates/usecase/update-usecase.hbs +15 -1
  192. package/dist/utils/config.utils.d.ts +2 -0
  193. package/dist/utils/config.utils.js +14 -2
  194. package/dist/utils/config.utils.js.map +1 -1
  195. package/dist/utils/dependency.utils.d.ts +18 -2
  196. package/dist/utils/dependency.utils.js +144 -15
  197. package/dist/utils/dependency.utils.js.map +1 -1
  198. package/dist/utils/field.utils.d.ts +6 -0
  199. package/dist/utils/field.utils.js +78 -24
  200. package/dist/utils/field.utils.js.map +1 -1
  201. package/dist/utils/field.utils.spec.d.ts +1 -0
  202. package/dist/utils/field.utils.spec.js +38 -0
  203. package/dist/utils/field.utils.spec.js.map +1 -0
  204. package/dist/utils/file.utils.d.ts +39 -3
  205. package/dist/utils/file.utils.js +150 -13
  206. package/dist/utils/file.utils.js.map +1 -1
  207. package/dist/utils/naming.utils.js +5 -4
  208. package/dist/utils/naming.utils.js.map +1 -1
  209. package/dist/utils/static-recipe.utils.d.ts +4 -0
  210. package/dist/utils/static-recipe.utils.js +148 -0
  211. package/dist/utils/static-recipe.utils.js.map +1 -0
  212. package/dist/utils/template-engine.utils.js +83 -68
  213. package/dist/utils/template-engine.utils.js.map +1 -1
  214. package/package.json +20 -11
@@ -44,9 +44,18 @@ const generate_entity_1 = require("./generate-entity");
44
44
  const file_utils_1 = require("../utils/file.utils");
45
45
  const naming_utils_1 = require("../utils/naming.utils");
46
46
  const dependency_utils_1 = require("../utils/dependency.utils");
47
+ const config_utils_1 = require("../utils/config.utils");
48
+ const migration_1 = require("./migration");
47
49
  async function generateAll(entityName, options) {
48
50
  console.log(chalk_1.default.blue(`\n🚀 Generating complete scaffolding for: ${entityName}`));
49
- const orm = options.orm || 'typeorm';
51
+ const basePath = options.path || process.cwd();
52
+ const config = await (0, config_utils_1.loadConfig)(basePath);
53
+ const orm = options.orm || config.orm || 'typeorm';
54
+ const dryRun = !!options.dryRun;
55
+ if (dryRun) {
56
+ (0, file_utils_1.resetDryRunFiles)();
57
+ console.log(chalk_1.default.yellow(' Dry run: no files, directories, or dependencies will be written.'));
58
+ }
50
59
  // Check if we need to install dependencies
51
60
  const requiredDeps = ['@nestjs/cqrs', 'class-validator', 'class-transformer', '@nestjs/swagger'];
52
61
  if (orm === 'prisma') {
@@ -55,91 +64,116 @@ async function generateAll(entityName, options) {
55
64
  else {
56
65
  requiredDeps.push('typeorm', '@nestjs/typeorm');
57
66
  }
58
- if (options.installDeps) {
67
+ if (options.installDeps && !dryRun) {
59
68
  await (0, dependency_utils_1.installDependencies)(options.path || process.cwd(), requiredDeps);
60
69
  }
70
+ else if (options.installDeps && dryRun) {
71
+ console.log(chalk_1.default.yellow(` Dry run: would install dependencies: ${requiredDeps.join(', ')}`));
72
+ }
61
73
  const moduleName = options.module || entityName;
62
- const basePath = options.path || process.cwd();
63
74
  const modulePath = (0, file_utils_1.getModulePath)(basePath, moduleName);
64
75
  const fieldsString = options.fields || '';
65
76
  // Check if module exists, create if not
66
77
  const moduleFilePath = path.join(modulePath, `${(0, naming_utils_1.toKebabCase)(moduleName)}.module.ts`);
67
78
  if (!(await (0, file_utils_1.fileExists)(moduleFilePath))) {
68
79
  console.log(chalk_1.default.yellow(` Module ${moduleName} doesn't exist. Creating...`));
69
- await (0, generate_module_1.generateModule)(moduleName, options);
80
+ await (0, generate_module_1.generateModule)(moduleName, { ...options, dryRun });
70
81
  }
71
82
  // Prepare template data with fields
72
- const templateData = (0, file_utils_1.prepareTemplateData)(entityName, moduleName, fieldsString);
83
+ const templateData = await (0, file_utils_1.prepareConfiguredTemplateData)(entityName, moduleName, {
84
+ basePath,
85
+ fieldsString,
86
+ orm,
87
+ features: {
88
+ ...config.features,
89
+ delete: options.delete === false ? false : config.features.delete,
90
+ },
91
+ });
73
92
  // Generate entity with all related files
74
- await (0, generate_entity_1.generateEntity)(entityName, { ...options, module: moduleName, fields: fieldsString, orm, _fromGenerateAll: true });
93
+ await (0, generate_entity_1.generateEntity)(entityName, {
94
+ ...options,
95
+ module: moduleName,
96
+ fields: fieldsString,
97
+ orm,
98
+ dryRun,
99
+ _fromGenerateAll: true,
100
+ });
75
101
  // Generate PrismaService if using Prisma
76
102
  if (orm === 'prisma') {
77
- await generatePrismaService(basePath);
103
+ await generatePrismaService(basePath, dryRun);
78
104
  }
79
105
  // Generate CRUD commands
80
106
  console.log(chalk_1.default.cyan(' Generating commands...'));
81
- await generateCommand('create', entityName, modulePath, templateData);
82
- await generateCommand('update', entityName, modulePath, templateData);
83
- await generateCommand('delete', entityName, modulePath, templateData);
107
+ await generateCommand('create', entityName, modulePath, templateData, dryRun);
108
+ await generateCommand('update', entityName, modulePath, templateData, dryRun);
109
+ if (templateData.deleteEnabled) {
110
+ await generateCommand('delete', entityName, modulePath, templateData, dryRun);
111
+ }
84
112
  // Generate use cases
85
113
  console.log(chalk_1.default.cyan(' Generating use cases...'));
86
- await generateUseCase('create', entityName, modulePath, templateData);
87
- await generateUseCase('update', entityName, modulePath, templateData);
88
- await generateUseCase('delete', entityName, modulePath, templateData);
114
+ await generateUseCase('create', entityName, modulePath, templateData, dryRun);
115
+ await generateUseCase('update', entityName, modulePath, templateData, dryRun);
116
+ if (templateData.deleteEnabled) {
117
+ await generateUseCase('delete', entityName, modulePath, templateData, dryRun);
118
+ }
89
119
  // Generate queries
90
120
  console.log(chalk_1.default.cyan(' Generating queries...'));
91
- await generateQueryHandler('get-by-id', entityName, modulePath, templateData);
92
- await generateQueryHandler('get-all', entityName, modulePath, templateData);
121
+ await generateQueryHandler('get-by-id', entityName, modulePath, templateData, dryRun);
122
+ await generateQueryHandler('get-all', entityName, modulePath, templateData, dryRun);
93
123
  // Generate DTOs
94
124
  console.log(chalk_1.default.cyan(' Generating DTOs...'));
95
- await generateDto('create', entityName, modulePath, templateData);
96
- await generateDto('update', entityName, modulePath, templateData);
97
- await generateDto('response', entityName, modulePath, templateData);
98
- await generatePaginationDtos(modulePath);
125
+ await generateDto('create', entityName, modulePath, templateData, dryRun);
126
+ await generateDto('update', entityName, modulePath, templateData, dryRun);
127
+ await generateDto('response', entityName, modulePath, templateData, dryRun);
128
+ await generatePaginationDtos(modulePath, templateData, dryRun);
99
129
  // Generate controller
100
130
  console.log(chalk_1.default.cyan(' Generating controller...'));
101
131
  const controllerTemplatePath = path.join(__dirname, '../templates/controller/controller.hbs');
102
132
  const controllerOutputPath = path.join(modulePath, 'application/controllers', `${(0, naming_utils_1.toKebabCase)(entityName)}.controller.ts`);
103
- await (0, file_utils_1.generateFromTemplate)(controllerTemplatePath, controllerOutputPath, templateData);
133
+ await (0, file_utils_1.generateFromTemplate)(controllerTemplatePath, controllerOutputPath, templateData, dryRun);
104
134
  // Generate migration file or Prisma schema snippet
105
135
  if (orm === 'prisma') {
106
136
  console.log(chalk_1.default.cyan(' Generating Prisma schema snippet...'));
107
- await generatePrismaSchemaSnippet(entityName, basePath, templateData);
137
+ await generatePrismaSchemaSnippet(entityName, basePath, templateData, dryRun);
108
138
  }
109
139
  else {
110
140
  console.log(chalk_1.default.cyan(' Generating migration...'));
111
- await generateMigration(entityName, basePath, templateData);
141
+ await generateMigration(entityName, basePath, templateData, dryRun);
112
142
  }
113
143
  // Generate barrel exports
114
144
  console.log(chalk_1.default.cyan(' Generating barrel exports...'));
115
- await generateBarrelExports(entityName, modulePath, orm);
145
+ await generateBarrelExports(entityName, modulePath, orm, dryRun, templateData.deleteEnabled);
116
146
  // Generate tests if requested
117
147
  if (options.withTests) {
118
148
  console.log(chalk_1.default.cyan(' Generating tests...'));
119
- await generateTests(entityName, modulePath, templateData);
149
+ await generateTests(entityName, modulePath, templateData, dryRun);
120
150
  }
121
151
  // Generate GraphQL files if requested
122
152
  if (options.withGraphql) {
123
153
  console.log(chalk_1.default.cyan(' Generating GraphQL resolvers and types...'));
124
- await generateGraphQL(entityName, modulePath, templateData);
154
+ await generateGraphQL(entityName, modulePath, templateData, dryRun);
155
+ }
156
+ if (dryRun) {
157
+ printDryRunSummary(basePath);
158
+ return;
125
159
  }
126
160
  console.log(chalk_1.default.green(`\n✅ Complete scaffolding generated successfully!`));
127
161
  console.log(chalk_1.default.cyan(`\n📁 Generated structure:`));
128
162
  console.log(` ${chalk_1.default.white('Module:')} ${modulePath}`);
129
163
  console.log(` ${chalk_1.default.white('Entity:')} ${entityName}`);
130
164
  console.log(` ${chalk_1.default.white('ORM:')} ${orm === 'prisma' ? 'Prisma' : 'TypeORM'}`);
131
- console.log(` ${chalk_1.default.white('Commands:')} Create, Update, Delete`);
165
+ console.log(` ${chalk_1.default.white('Commands:')} Create, Update${templateData.deleteEnabled ? ', Delete' : ''}`);
132
166
  console.log(` ${chalk_1.default.white('Queries:')} GetById, GetAll (paginated)`);
133
- console.log(` ${chalk_1.default.white('Use Cases:')} Create, Update, Delete`);
167
+ console.log(` ${chalk_1.default.white('Use Cases:')} Create, Update${templateData.deleteEnabled ? ', Delete' : ''}`);
134
168
  console.log(` ${chalk_1.default.white('DTOs:')} Create, Update, Response, Pagination`);
135
- console.log(` ${chalk_1.default.white('Controller:')} Full CRUD REST endpoints`);
169
+ console.log(` ${chalk_1.default.white('Controller:')} ${templateData.deleteEnabled ? 'Full CRUD' : 'Create, read, and update'} REST endpoints`);
136
170
  console.log(` ${chalk_1.default.white('Repository:')} With pagination support`);
137
171
  console.log(` ${chalk_1.default.white('Mapper:')} Domain ↔ ${orm === 'prisma' ? 'Prisma' : 'ORM'} ↔ Response`);
138
172
  if (options.withGraphql) {
139
173
  console.log(` ${chalk_1.default.white('GraphQL:')} Resolver, Types, Inputs`);
140
174
  }
141
175
  if (templateData.hasFields) {
142
- console.log(chalk_1.default.green(`\n✨ Fields generated: ${templateData.fields?.map(f => f.name).join(', ')}`));
176
+ console.log(chalk_1.default.green(`\n✨ Fields generated: ${templateData.fields?.map((f) => f.name).join(', ')}`));
143
177
  }
144
178
  console.log(chalk_1.default.yellow(`\n📋 Next steps:`));
145
179
  console.log(` 1. ${templateData.hasFields ? 'Review' : 'Add properties to'} your entity and DTOs`);
@@ -152,24 +186,39 @@ async function generateAll(entityName, options) {
152
186
  console.log(` 2. Run the migration: ${chalk_1.default.cyan('npm run migration:run')}`);
153
187
  }
154
188
  console.log(` ${orm === 'prisma' ? '5' : '3'}. Import ${(0, naming_utils_1.toPascalCase)(moduleName)}Module in your app.module.ts`);
155
- console.log(` ${orm === 'prisma' ? '6' : '4'}. Start your server and test the API at ${chalk_1.default.cyan(`/${(0, naming_utils_1.toKebabCase)(entityName)}s`)}`);
189
+ console.log(` ${orm === 'prisma' ? '6' : '4'}. Start your server and test the API at ${chalk_1.default.cyan(`/${templateData.entityNamePluralKebab}`)}`);
190
+ }
191
+ function printDryRunSummary(basePath) {
192
+ const changes = (0, file_utils_1.getDryRunFiles)();
193
+ console.log(chalk_1.default.cyan(`\n🧪 Dry run complete. Planned file changes (${changes.length}):`));
194
+ if (!changes.length) {
195
+ console.log(chalk_1.default.gray(' No file changes planned.'));
196
+ return;
197
+ }
198
+ for (const change of changes) {
199
+ const relativePath = path.relative(basePath, change.filePath);
200
+ console.log(` ${change.action.padEnd(6)} ${relativePath}`);
201
+ }
156
202
  }
157
- async function generateCommand(action, entityName, modulePath, templateData) {
203
+ async function generateCommand(action, entityName, modulePath, templateData, dryRun = false) {
158
204
  const templatePath = path.join(__dirname, `../templates/command/${action}-command.hbs`);
159
205
  const outputPath = path.join(modulePath, 'application/commands', `${action}-${(0, naming_utils_1.toKebabCase)(entityName)}.command.ts`);
160
- await (0, file_utils_1.generateFromTemplate)(templatePath, outputPath, templateData);
206
+ await (0, file_utils_1.generateFromTemplate)(templatePath, outputPath, templateData, dryRun);
161
207
  }
162
- async function generateUseCase(action, entityName, modulePath, templateData) {
208
+ async function generateUseCase(action, entityName, modulePath, templateData, dryRun = false) {
163
209
  const templatePath = path.join(__dirname, `../templates/usecase/${action}-usecase.hbs`);
164
210
  const outputPath = path.join(modulePath, 'application/domain/usecases', `${action}-${(0, naming_utils_1.toKebabCase)(entityName)}.use-case.ts`);
165
- await (0, file_utils_1.generateFromTemplate)(templatePath, outputPath, templateData);
211
+ await (0, file_utils_1.generateFromTemplate)(templatePath, outputPath, templateData, dryRun);
166
212
  }
167
- async function generateQueryHandler(type, entityName, modulePath, templateData) {
213
+ async function generateQueryHandler(type, entityName, modulePath, templateData, dryRun = false) {
214
+ const fileName = type === 'get-all'
215
+ ? `get-all-${templateData.entityNamePluralKebab}.query.ts`
216
+ : `get-${(0, naming_utils_1.toKebabCase)(entityName)}-by-id.query.ts`;
168
217
  const templatePath = path.join(__dirname, `../templates/query/${type}.query.hbs`);
169
- const outputPath = path.join(modulePath, 'application/queries', `${type}-${(0, naming_utils_1.toKebabCase)(entityName)}${type === 'get-all' ? 's' : ''}.query.ts`);
170
- await (0, file_utils_1.generateFromTemplate)(templatePath, outputPath, templateData);
218
+ const outputPath = path.join(modulePath, 'application/queries', fileName);
219
+ await (0, file_utils_1.generateFromTemplate)(templatePath, outputPath, templateData, dryRun);
171
220
  }
172
- async function generateDto(type, entityName, modulePath, templateData) {
221
+ async function generateDto(type, entityName, modulePath, templateData, dryRun = false) {
173
222
  const templateMap = {
174
223
  create: 'create-dto.hbs',
175
224
  update: 'update-dto.hbs',
@@ -187,34 +236,42 @@ async function generateDto(type, entityName, modulePath, templateData) {
187
236
  };
188
237
  const templatePath = path.join(__dirname, `../templates/dto/${templateMap[type]}`);
189
238
  const outputPath = path.join(modulePath, `application/dto/${outputDirMap[type]}`, fileNameMap[type]);
190
- await (0, file_utils_1.generateFromTemplate)(templatePath, outputPath, templateData);
239
+ await (0, file_utils_1.generateFromTemplate)(templatePath, outputPath, templateData, dryRun);
191
240
  }
192
- async function generatePaginationDtos(modulePath) {
241
+ async function generatePaginationDtos(modulePath, templateData, dryRun = false) {
193
242
  // Generate pagination query DTO
194
243
  const paginationQueryTemplatePath = path.join(__dirname, '../templates/dto/pagination-query.dto.hbs');
195
244
  const paginationQueryOutputPath = path.join(modulePath, 'application/dto/requests', 'pagination.query.dto.ts');
196
245
  if (!(await (0, file_utils_1.fileExists)(paginationQueryOutputPath))) {
197
- await (0, file_utils_1.generateFromTemplate)(paginationQueryTemplatePath, paginationQueryOutputPath, (0, file_utils_1.prepareTemplateData)('Pagination', 'shared'));
246
+ await (0, file_utils_1.generateFromTemplate)(paginationQueryTemplatePath, paginationQueryOutputPath, templateData, dryRun);
198
247
  }
199
248
  // Generate paginated response DTO
200
249
  const paginatedResponseTemplatePath = path.join(__dirname, '../templates/dto/paginated-response.dto.hbs');
201
250
  const paginatedResponseOutputPath = path.join(modulePath, 'application/dto/responses', 'paginated.response.dto.ts');
202
251
  if (!(await (0, file_utils_1.fileExists)(paginatedResponseOutputPath))) {
203
- await (0, file_utils_1.generateFromTemplate)(paginatedResponseTemplatePath, paginatedResponseOutputPath, (0, file_utils_1.prepareTemplateData)('Paginated', 'shared'));
252
+ await (0, file_utils_1.generateFromTemplate)(paginatedResponseTemplatePath, paginatedResponseOutputPath, templateData, dryRun);
204
253
  }
205
254
  }
206
- async function generateMigration(entityName, basePath, templateData) {
255
+ async function generateMigration(entityName, basePath, templateData, dryRun = false) {
207
256
  const timestamp = Date.now();
208
257
  const tableName = templateData.tableName;
209
258
  const migrationName = `create_${tableName}_table`;
210
259
  const fileName = `${timestamp}-${migrationName}.ts`;
211
- const fieldsColumns = templateData.migrationColumns || ` // Add your custom columns here
260
+ const fieldsColumns = templateData.migrationColumns ||
261
+ ` // Add your custom columns here
212
262
  // Example:
213
263
  // {
214
264
  // name: "name",
215
265
  // type: "varchar",
216
266
  // isNullable: false,
217
267
  // },`;
268
+ const softDeleteColumn = templateData.softDelete
269
+ ? ` {
270
+ name: "deleted_at",
271
+ type: "timestamp",
272
+ isNullable: true,
273
+ },`
274
+ : '';
218
275
  const content = `import { MigrationInterface, QueryRunner, Table } from "typeorm";
219
276
 
220
277
  export class Create${(0, naming_utils_1.toPascalCase)(entityName)}Table${timestamp} implements MigrationInterface {
@@ -246,11 +303,7 @@ ${fieldsColumns}
246
303
  type: "timestamp",
247
304
  default: "CURRENT_TIMESTAMP",
248
305
  },
249
- {
250
- name: "deleted_at",
251
- type: "timestamp",
252
- isNullable: true,
253
- },
306
+ ${softDeleteColumn}
254
307
  ],
255
308
  }),
256
309
  true,
@@ -262,163 +315,172 @@ ${fieldsColumns}
262
315
  }
263
316
  }
264
317
  `;
265
- const migrationPath = path.join(basePath, 'src/migrations', fileName);
266
- await (0, file_utils_1.writeFile)(migrationPath, content);
318
+ const config = await (0, config_utils_1.loadConfig)(basePath);
319
+ const migrationsDir = (0, migration_1.resolveMigrationOutputPath)(basePath, config.paths.migrations, 'src/migrations');
320
+ const migrationPath = path.join(migrationsDir, fileName);
321
+ await (0, file_utils_1.writeGeneratedFile)(migrationPath, content, dryRun);
267
322
  console.log(chalk_1.default.green(` ✓ Migration: ${fileName}`));
268
323
  }
269
- async function generateBarrelExports(entityName, modulePath, orm = 'typeorm') {
324
+ async function generateBarrelExports(entityName, modulePath, orm = 'typeorm', dryRun = false, deleteEnabled = true) {
270
325
  const entityNameKebab = (0, naming_utils_1.toKebabCase)(entityName);
271
326
  const entityNamePascal = (0, naming_utils_1.toPascalCase)(entityName);
327
+ const entityNamePluralKebab = (0, naming_utils_1.toKebabCase)((0, naming_utils_1.toPlural)(entityName));
328
+ const entityNamePluralPascal = (0, naming_utils_1.toPlural)((0, naming_utils_1.toPascalCase)(entityName));
272
329
  const isPrisma = orm === 'prisma';
273
330
  // Commands index
274
331
  const commandsIndexPath = path.join(modulePath, 'application/commands/index.ts');
275
- const commandsIndexContent = `export * from './create-${entityNameKebab}.command';
276
- export * from './update-${entityNameKebab}.command';
277
- export * from './delete-${entityNameKebab}.command';
278
-
279
- import { Create${entityNamePascal}Handler } from './create-${entityNameKebab}.command';
280
- import { Update${entityNamePascal}Handler } from './update-${entityNameKebab}.command';
281
- import { Delete${entityNamePascal}Handler } from './delete-${entityNameKebab}.command';
282
-
283
- export const CommandHandlers = [
284
- Create${entityNamePascal}Handler,
285
- Update${entityNamePascal}Handler,
286
- Delete${entityNamePascal}Handler,
287
- ];
288
- `;
289
- await (0, file_utils_1.writeFile)(commandsIndexPath, commandsIndexContent);
332
+ await (0, file_utils_1.updateBarrelFile)(commandsIndexPath, {
333
+ exports: [
334
+ `export * from './create-${entityNameKebab}.command';`,
335
+ `export * from './update-${entityNameKebab}.command';`,
336
+ ...(deleteEnabled ? [`export * from './delete-${entityNameKebab}.command';`] : []),
337
+ ],
338
+ imports: [
339
+ `import { Create${entityNamePascal}Handler } from './create-${entityNameKebab}.command';`,
340
+ `import { Update${entityNamePascal}Handler } from './update-${entityNameKebab}.command';`,
341
+ ...(deleteEnabled
342
+ ? [`import { Delete${entityNamePascal}Handler } from './delete-${entityNameKebab}.command';`]
343
+ : []),
344
+ ],
345
+ arrayName: 'CommandHandlers',
346
+ arrayItems: [
347
+ `Create${entityNamePascal}Handler`,
348
+ `Update${entityNamePascal}Handler`,
349
+ ...(deleteEnabled ? [`Delete${entityNamePascal}Handler`] : []),
350
+ ],
351
+ dryRun,
352
+ });
290
353
  // Queries index
291
354
  const queriesIndexPath = path.join(modulePath, 'application/queries/index.ts');
292
- const entityNamePluralPascal = (0, naming_utils_1.toPascalCase)(entityName) + 's';
293
- const queriesIndexContent = `export * from './get-${entityNameKebab}-by-id.query';
294
- export * from './get-all-${entityNameKebab}s.query';
295
-
296
- import { Get${entityNamePascal}ByIdHandler } from './get-${entityNameKebab}-by-id.query';
297
- import { GetAll${entityNamePluralPascal}Handler } from './get-all-${entityNameKebab}s.query';
298
-
299
- export const Queries = [
300
- Get${entityNamePascal}ByIdHandler,
301
- GetAll${entityNamePluralPascal}Handler,
302
- ];
303
- `;
304
- await (0, file_utils_1.writeFile)(queriesIndexPath, queriesIndexContent);
355
+ await (0, file_utils_1.updateBarrelFile)(queriesIndexPath, {
356
+ exports: [
357
+ `export * from './get-${entityNameKebab}-by-id.query';`,
358
+ `export * from './get-all-${entityNamePluralKebab}.query';`,
359
+ ],
360
+ imports: [
361
+ `import { Get${entityNamePascal}ByIdHandler } from './get-${entityNameKebab}-by-id.query';`,
362
+ `import { GetAll${entityNamePluralPascal}Handler } from './get-all-${entityNamePluralKebab}.query';`,
363
+ ],
364
+ arrayName: 'Queries',
365
+ arrayItems: [`Get${entityNamePascal}ByIdHandler`, `GetAll${entityNamePluralPascal}Handler`],
366
+ dryRun,
367
+ });
305
368
  // Use cases index
306
369
  const useCasesIndexPath = path.join(modulePath, 'application/domain/usecases/index.ts');
307
- const useCasesIndexContent = `export * from './create-${entityNameKebab}.use-case';
308
- export * from './update-${entityNameKebab}.use-case';
309
- export * from './delete-${entityNameKebab}.use-case';
310
-
311
- import { Create${entityNamePascal}UseCase } from './create-${entityNameKebab}.use-case';
312
- import { Update${entityNamePascal}UseCase } from './update-${entityNameKebab}.use-case';
313
- import { Delete${entityNamePascal}UseCase } from './delete-${entityNameKebab}.use-case';
314
-
315
- export const UseCases = [
316
- Create${entityNamePascal}UseCase,
317
- Update${entityNamePascal}UseCase,
318
- Delete${entityNamePascal}UseCase,
319
- ];
320
- `;
321
- await (0, file_utils_1.writeFile)(useCasesIndexPath, useCasesIndexContent);
370
+ await (0, file_utils_1.updateBarrelFile)(useCasesIndexPath, {
371
+ exports: [
372
+ `export * from './create-${entityNameKebab}.use-case';`,
373
+ `export * from './update-${entityNameKebab}.use-case';`,
374
+ ...(deleteEnabled ? [`export * from './delete-${entityNameKebab}.use-case';`] : []),
375
+ ],
376
+ imports: [
377
+ `import { Create${entityNamePascal}UseCase } from './create-${entityNameKebab}.use-case';`,
378
+ `import { Update${entityNamePascal}UseCase } from './update-${entityNameKebab}.use-case';`,
379
+ ...(deleteEnabled
380
+ ? [`import { Delete${entityNamePascal}UseCase } from './delete-${entityNameKebab}.use-case';`]
381
+ : []),
382
+ ],
383
+ arrayName: 'UseCases',
384
+ arrayItems: [
385
+ `Create${entityNamePascal}UseCase`,
386
+ `Update${entityNamePascal}UseCase`,
387
+ ...(deleteEnabled ? [`Delete${entityNamePascal}UseCase`] : []),
388
+ ],
389
+ dryRun,
390
+ });
322
391
  // DTOs index
323
392
  const dtosIndexPath = path.join(modulePath, 'application/dto/index.ts');
324
- const dtosIndexContent = `export * from './requests';
325
- export * from './responses';
326
- `;
327
- await (0, file_utils_1.writeFile)(dtosIndexPath, dtosIndexContent);
393
+ await (0, file_utils_1.updateBarrelFile)(dtosIndexPath, {
394
+ exports: [`export * from './requests';`, `export * from './responses';`],
395
+ dryRun,
396
+ });
328
397
  // Requests index
329
398
  const requestsIndexPath = path.join(modulePath, 'application/dto/requests/index.ts');
330
- const requestsIndexContent = `export * from './create-${entityNameKebab}.dto';
331
- export * from './update-${entityNameKebab}.dto';
332
- export * from './pagination.query.dto';
333
- `;
334
- await (0, file_utils_1.writeFile)(requestsIndexPath, requestsIndexContent);
399
+ await (0, file_utils_1.updateBarrelFile)(requestsIndexPath, {
400
+ exports: [
401
+ `export * from './create-${entityNameKebab}.dto';`,
402
+ `export * from './update-${entityNameKebab}.dto';`,
403
+ `export * from './pagination.query.dto';`,
404
+ ],
405
+ dryRun,
406
+ });
335
407
  // Responses index
336
408
  const responsesIndexPath = path.join(modulePath, 'application/dto/responses/index.ts');
337
- const responsesIndexContent = `export * from './${entityNameKebab}.response.dto';
338
- export * from './paginated.response.dto';
339
- `;
340
- await (0, file_utils_1.writeFile)(responsesIndexPath, responsesIndexContent);
409
+ await (0, file_utils_1.updateBarrelFile)(responsesIndexPath, {
410
+ exports: [
411
+ `export * from './${entityNameKebab}.response.dto';`,
412
+ `export * from './paginated.response.dto';`,
413
+ ],
414
+ dryRun,
415
+ });
341
416
  // Controllers index
342
417
  const controllersIndexPath = path.join(modulePath, 'application/controllers/index.ts');
343
- const controllersIndexContent = `export * from './${entityNameKebab}.controller';
344
-
345
- import { ${entityNamePascal}Controller } from './${entityNameKebab}.controller';
346
-
347
- export const Controllers = [${entityNamePascal}Controller];
348
- `;
349
- await (0, file_utils_1.writeFile)(controllersIndexPath, controllersIndexContent);
418
+ await (0, file_utils_1.updateBarrelFile)(controllersIndexPath, {
419
+ exports: [`export * from './${entityNameKebab}.controller';`],
420
+ imports: [`import { ${entityNamePascal}Controller } from './${entityNameKebab}.controller';`],
421
+ arrayName: 'Controllers',
422
+ arrayItems: [`${entityNamePascal}Controller`],
423
+ dryRun,
424
+ });
350
425
  // Entities index
351
426
  const entitiesIndexPath = path.join(modulePath, 'application/domain/entities/index.ts');
352
- const entitiesIndexContent = `export * from './${entityNameKebab}.entity';
353
- `;
354
- await (0, file_utils_1.writeFile)(entitiesIndexPath, entitiesIndexContent);
427
+ await (0, file_utils_1.updateBarrelFile)(entitiesIndexPath, {
428
+ exports: [`export * from './${entityNameKebab}.entity';`],
429
+ dryRun,
430
+ });
355
431
  // Repositories index
356
432
  const repositoriesIndexPath = path.join(modulePath, 'infrastructure/repositories/index.ts');
357
- const repositoriesIndexContent = `export * from './${entityNameKebab}.repository';
358
-
359
- import { ${entityNamePascal}Repository } from './${entityNameKebab}.repository';
360
-
361
- export const Repositories = [${entityNamePascal}Repository];
362
- `;
363
- await (0, file_utils_1.writeFile)(repositoriesIndexPath, repositoriesIndexContent);
433
+ await (0, file_utils_1.updateBarrelFile)(repositoriesIndexPath, {
434
+ exports: [`export * from './${entityNameKebab}.repository';`],
435
+ imports: [`import { ${entityNamePascal}Repository } from './${entityNameKebab}.repository';`],
436
+ arrayName: 'Repositories',
437
+ arrayItems: [`${entityNamePascal}Repository`],
438
+ dryRun,
439
+ });
364
440
  // Mappers index
365
441
  const mappersIndexPath = path.join(modulePath, 'infrastructure/mappers/index.ts');
366
- const mappersIndexContent = `export * from './${entityNameKebab}.mapper';
367
-
368
- import { ${entityNamePascal}Mapper } from './${entityNameKebab}.mapper';
369
-
370
- export const Mappers = [${entityNamePascal}Mapper];
371
- `;
372
- await (0, file_utils_1.writeFile)(mappersIndexPath, mappersIndexContent);
442
+ await (0, file_utils_1.updateBarrelFile)(mappersIndexPath, {
443
+ exports: [`export * from './${entityNameKebab}.mapper';`],
444
+ imports: [`import { ${entityNamePascal}Mapper } from './${entityNameKebab}.mapper';`],
445
+ arrayName: 'Mappers',
446
+ arrayItems: [`${entityNamePascal}Mapper`],
447
+ dryRun,
448
+ });
373
449
  // ORM entities index (TypeORM only)
374
450
  if (!isPrisma) {
375
451
  const ormEntitiesIndexPath = path.join(modulePath, 'infrastructure/orm-entities/index.ts');
376
- const ormEntitiesIndexContent = `export * from './${entityNameKebab}.orm-entity';
377
-
378
- import { ${entityNamePascal}OrmEntity } from './${entityNameKebab}.orm-entity';
379
-
380
- export const OrmEntities = [${entityNamePascal}OrmEntity];
381
- `;
382
- await (0, file_utils_1.writeFile)(ormEntitiesIndexPath, ormEntitiesIndexContent);
452
+ await (0, file_utils_1.updateBarrelFile)(ormEntitiesIndexPath, {
453
+ exports: [`export * from './${entityNameKebab}.orm-entity';`],
454
+ imports: [`import { ${entityNamePascal}OrmEntity } from './${entityNameKebab}.orm-entity';`],
455
+ arrayName: 'OrmEntities',
456
+ arrayItems: [`${entityNamePascal}OrmEntity`],
457
+ dryRun,
458
+ });
383
459
  }
384
- // Services index (empty for now)
385
- const servicesIndexPath = path.join(modulePath, 'application/domain/services/index.ts');
386
- const servicesIndexContent = `// Export your domain services here
387
- // import { YourService } from './your.service';
388
- // export const Services = [YourService];
389
-
390
- export const Services: any[] = [];
391
- `;
392
- await (0, file_utils_1.writeFile)(servicesIndexPath, servicesIndexContent);
393
- // Events index (empty for now)
394
- const eventsIndexPath = path.join(modulePath, 'application/domain/events/index.ts');
395
- const eventsIndexContent = `// Export your domain events here
396
- // export * from './your-event.event';
397
- `;
398
- await (0, file_utils_1.writeFile)(eventsIndexPath, eventsIndexContent);
399
460
  }
400
- async function generateTests(entityName, modulePath, templateData) {
461
+ async function generateTests(entityName, modulePath, templateData, dryRun = false) {
401
462
  const entityNameKebab = (0, naming_utils_1.toKebabCase)(entityName);
402
463
  // Repository test
403
- const repoTestTemplatePath = path.join(__dirname, '../templates/test/repository.spec.hbs');
464
+ const repoTestTemplatePath = templateData.isPrisma
465
+ ? path.join(__dirname, '../templates/test/prisma-repository.spec.hbs')
466
+ : path.join(__dirname, '../templates/test/repository.spec.hbs');
404
467
  const repoTestOutputPath = path.join(modulePath, 'infrastructure/repositories', `${entityNameKebab}.repository.spec.ts`);
405
- await (0, file_utils_1.generateFromTemplate)(repoTestTemplatePath, repoTestOutputPath, templateData);
468
+ await (0, file_utils_1.generateFromTemplate)(repoTestTemplatePath, repoTestOutputPath, templateData, dryRun);
406
469
  console.log(chalk_1.default.green(` ✓ Repository test`));
407
470
  // Use case tests
408
471
  const useCaseTestTemplatePath = path.join(__dirname, '../templates/test/usecase.spec.hbs');
409
472
  const useCaseTestOutputPath = path.join(modulePath, 'application/domain/usecases', `${entityNameKebab}.use-case.spec.ts`);
410
- await (0, file_utils_1.generateFromTemplate)(useCaseTestTemplatePath, useCaseTestOutputPath, templateData);
473
+ await (0, file_utils_1.generateFromTemplate)(useCaseTestTemplatePath, useCaseTestOutputPath, templateData, dryRun);
411
474
  console.log(chalk_1.default.green(` ✓ Use case tests`));
412
475
  // Controller test
413
476
  const controllerTestTemplatePath = path.join(__dirname, '../templates/test/controller.spec.hbs');
414
477
  const controllerTestOutputPath = path.join(modulePath, 'application/controllers', `${entityNameKebab}.controller.spec.ts`);
415
- await (0, file_utils_1.generateFromTemplate)(controllerTestTemplatePath, controllerTestOutputPath, templateData);
478
+ await (0, file_utils_1.generateFromTemplate)(controllerTestTemplatePath, controllerTestOutputPath, templateData, dryRun);
416
479
  console.log(chalk_1.default.green(` ✓ Controller test`));
417
480
  }
418
- async function generateGraphQL(entityName, modulePath, templateData) {
481
+ async function generateGraphQL(entityName, modulePath, templateData, dryRun = false) {
419
482
  const entityNameKebab = (0, naming_utils_1.toKebabCase)(entityName);
420
483
  const entityNamePascal = (0, naming_utils_1.toPascalCase)(entityName);
421
- const entityNamePluralKebab = (0, naming_utils_1.toKebabCase)(templateData.entityNamePlural);
422
484
  // Create GraphQL directories
423
485
  const graphqlPath = path.join(modulePath, 'application/graphql');
424
486
  const typesPath = path.join(graphqlPath, 'types');
@@ -427,35 +489,35 @@ async function generateGraphQL(entityName, modulePath, templateData) {
427
489
  // Generate resolver
428
490
  const resolverTemplatePath = path.join(__dirname, '../templates/resolver/resolver.hbs');
429
491
  const resolverOutputPath = path.join(graphqlPath, `${entityNameKebab}.resolver.ts`);
430
- await (0, file_utils_1.generateFromTemplate)(resolverTemplatePath, resolverOutputPath, templateData);
492
+ await (0, file_utils_1.generateFromTemplate)(resolverTemplatePath, resolverOutputPath, templateData, dryRun);
431
493
  console.log(chalk_1.default.green(` ✓ Resolver`));
432
494
  // Generate GraphQL type
433
495
  const typeTemplatePath = path.join(__dirname, '../templates/resolver/graphql-type.hbs');
434
496
  const typeOutputPath = path.join(typesPath, `${entityNameKebab}.type.ts`);
435
- await (0, file_utils_1.generateFromTemplate)(typeTemplatePath, typeOutputPath, templateData);
497
+ await (0, file_utils_1.generateFromTemplate)(typeTemplatePath, typeOutputPath, templateData, dryRun);
436
498
  console.log(chalk_1.default.green(` ✓ GraphQL Type`));
437
499
  // Generate GraphQL inputs
438
500
  const inputTemplatePath = path.join(__dirname, '../templates/resolver/graphql-input.hbs');
439
501
  const inputOutputPath = path.join(inputsPath, `${entityNameKebab}.input.ts`);
440
- await (0, file_utils_1.generateFromTemplate)(inputTemplatePath, inputOutputPath, templateData);
502
+ await (0, file_utils_1.generateFromTemplate)(inputTemplatePath, inputOutputPath, templateData, dryRun);
441
503
  console.log(chalk_1.default.green(` ✓ GraphQL Inputs`));
442
504
  // Generate pagination args (if not exists)
443
505
  const paginationArgsPath = path.join(argsPath, 'pagination.args.ts');
444
506
  if (!(await (0, file_utils_1.fileExists)(paginationArgsPath))) {
445
507
  const paginationArgsTemplatePath = path.join(__dirname, '../templates/resolver/pagination-args.hbs');
446
- await (0, file_utils_1.generateFromTemplate)(paginationArgsTemplatePath, paginationArgsPath, templateData);
508
+ await (0, file_utils_1.generateFromTemplate)(paginationArgsTemplatePath, paginationArgsPath, templateData, dryRun);
447
509
  console.log(chalk_1.default.green(` ✓ Pagination Args`));
448
510
  }
449
511
  // Generate barrel exports
450
512
  const typesIndexContent = `export * from "./${entityNameKebab}.type";
451
513
  `;
452
- await (0, file_utils_1.writeFile)(path.join(typesPath, 'index.ts'), typesIndexContent);
514
+ await (0, file_utils_1.writeGeneratedFile)(path.join(typesPath, 'index.ts'), typesIndexContent, dryRun);
453
515
  const inputsIndexContent = `export * from "./${entityNameKebab}.input";
454
516
  `;
455
- await (0, file_utils_1.writeFile)(path.join(inputsPath, 'index.ts'), inputsIndexContent);
517
+ await (0, file_utils_1.writeGeneratedFile)(path.join(inputsPath, 'index.ts'), inputsIndexContent, dryRun);
456
518
  const argsIndexContent = `export * from "./pagination.args";
457
519
  `;
458
- await (0, file_utils_1.writeFile)(path.join(argsPath, 'index.ts'), argsIndexContent);
520
+ await (0, file_utils_1.writeGeneratedFile)(path.join(argsPath, 'index.ts'), argsIndexContent, dryRun);
459
521
  const graphqlIndexContent = `export * from "./${entityNameKebab}.resolver";
460
522
  export * from "./types";
461
523
  export * from "./inputs";
@@ -465,9 +527,9 @@ import { ${entityNamePascal}Resolver } from "./${entityNameKebab}.resolver";
465
527
 
466
528
  export const Resolvers = [${entityNamePascal}Resolver];
467
529
  `;
468
- await (0, file_utils_1.writeFile)(path.join(graphqlPath, 'index.ts'), graphqlIndexContent);
530
+ await (0, file_utils_1.writeGeneratedFile)(path.join(graphqlPath, 'index.ts'), graphqlIndexContent, dryRun);
469
531
  }
470
- async function generatePrismaService(basePath) {
532
+ async function generatePrismaService(basePath, dryRun = false) {
471
533
  const prismaServicePath = path.join(basePath, 'src/prisma/prisma.service.ts');
472
534
  if (await (0, file_utils_1.fileExists)(prismaServicePath)) {
473
535
  console.log(chalk_1.default.yellow(` PrismaService already exists. Skipping...`));
@@ -525,7 +587,7 @@ export class PrismaService extends PrismaClient implements OnModuleInit, OnModul
525
587
  }
526
588
  }
527
589
  `;
528
- await (0, file_utils_1.writeFile)(prismaServicePath, content);
590
+ await (0, file_utils_1.writeGeneratedFile)(prismaServicePath, content, dryRun);
529
591
  console.log(chalk_1.default.green(` ✓ PrismaService`));
530
592
  // Also generate prisma.module.ts
531
593
  const prismaModulePath = path.join(basePath, 'src/prisma/prisma.module.ts');
@@ -540,7 +602,7 @@ import { PrismaService } from "./prisma.service";
540
602
  })
541
603
  export class PrismaModule {}
542
604
  `;
543
- await (0, file_utils_1.writeFile)(prismaModulePath, moduleContent);
605
+ await (0, file_utils_1.writeGeneratedFile)(prismaModulePath, moduleContent, dryRun);
544
606
  console.log(chalk_1.default.green(` ✓ PrismaModule`));
545
607
  }
546
608
  // Generate index.ts
@@ -549,10 +611,10 @@ export class PrismaModule {}
549
611
  const indexContent = `export * from "./prisma.service";
550
612
  export * from "./prisma.module";
551
613
  `;
552
- await (0, file_utils_1.writeFile)(indexPath, indexContent);
614
+ await (0, file_utils_1.writeGeneratedFile)(indexPath, indexContent, dryRun);
553
615
  }
554
616
  }
555
- async function generatePrismaSchemaSnippet(entityName, basePath, templateData) {
617
+ async function generatePrismaSchemaSnippet(entityName, basePath, templateData, dryRun = false) {
556
618
  const tableName = templateData.tableName;
557
619
  const entityNamePascal = (0, naming_utils_1.toPascalCase)(entityName);
558
620
  // Generate fields for Prisma schema
@@ -585,7 +647,7 @@ ${fieldsContent}
585
647
  is_active Boolean @default(true)
586
648
  created_at DateTime @default(now())
587
649
  updated_at DateTime @updatedAt
588
- deleted_at DateTime?
650
+ ${templateData.softDelete ? ' deleted_at DateTime?' : ''}
589
651
 
590
652
  @@map("${tableName}")
591
653
  }
@@ -597,7 +659,7 @@ ${fieldsContent}
597
659
  // =============================================================
598
660
  `;
599
661
  const snippetPath = path.join(basePath, `prisma/snippets/${(0, naming_utils_1.toKebabCase)(entityName)}.prisma`);
600
- await (0, file_utils_1.writeFile)(snippetPath, content);
662
+ await (0, file_utils_1.writeGeneratedFile)(snippetPath, content, dryRun);
601
663
  console.log(chalk_1.default.green(` ✓ Prisma schema snippet: prisma/snippets/${(0, naming_utils_1.toKebabCase)(entityName)}.prisma`));
602
664
  }
603
665
  //# sourceMappingURL=generate-all.js.map