nestjs-ddd-cli 2.2.1 → 3.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/README.md +247 -408
  2. package/ddd.schema.json +111 -0
  3. package/dist/commands/aggregate-validator.d.ts +9 -0
  4. package/dist/commands/aggregate-validator.js +953 -0
  5. package/dist/commands/aggregate-validator.js.map +1 -0
  6. package/dist/commands/ai-assist.d.ts +8 -0
  7. package/dist/commands/ai-assist.js +337 -0
  8. package/dist/commands/ai-assist.js.map +1 -0
  9. package/dist/commands/api-contracts.d.ts +9 -0
  10. package/dist/commands/api-contracts.js +1368 -0
  11. package/dist/commands/api-contracts.js.map +1 -0
  12. package/dist/commands/api-docs.d.ts +8 -0
  13. package/dist/commands/api-docs.js +408 -0
  14. package/dist/commands/api-docs.js.map +1 -0
  15. package/dist/commands/api-versioning.d.ts +11 -0
  16. package/dist/commands/api-versioning.js +643 -0
  17. package/dist/commands/api-versioning.js.map +1 -0
  18. package/dist/commands/audit-logging.d.ts +9 -0
  19. package/dist/commands/audit-logging.js +1129 -0
  20. package/dist/commands/audit-logging.js.map +1 -0
  21. package/dist/commands/batch-generate.d.ts +10 -0
  22. package/dist/commands/batch-generate.js +405 -0
  23. package/dist/commands/batch-generate.js.map +1 -0
  24. package/dist/commands/caching-strategies.d.ts +9 -0
  25. package/dist/commands/caching-strategies.js +874 -0
  26. package/dist/commands/caching-strategies.js.map +1 -0
  27. package/dist/commands/code-analyzer.d.ts +42 -0
  28. package/dist/commands/code-analyzer.js +474 -0
  29. package/dist/commands/code-analyzer.js.map +1 -0
  30. package/dist/commands/database-seeding.d.ts +6 -0
  31. package/dist/commands/database-seeding.js +621 -0
  32. package/dist/commands/database-seeding.js.map +1 -0
  33. package/dist/commands/db-optimization.d.ts +7 -0
  34. package/dist/commands/db-optimization.js +687 -0
  35. package/dist/commands/db-optimization.js.map +1 -0
  36. package/dist/commands/dependency-graph.d.ts +6 -0
  37. package/dist/commands/dependency-graph.js +329 -0
  38. package/dist/commands/dependency-graph.js.map +1 -0
  39. package/dist/commands/doctor-enhanced.d.ts +22 -0
  40. package/dist/commands/doctor-enhanced.js +543 -0
  41. package/dist/commands/doctor-enhanced.js.map +1 -0
  42. package/dist/commands/doctor.d.ts +4 -0
  43. package/dist/commands/doctor.js +151 -0
  44. package/dist/commands/doctor.js.map +1 -0
  45. package/dist/commands/env-manager.d.ts +6 -0
  46. package/dist/commands/env-manager.js +419 -0
  47. package/dist/commands/env-manager.js.map +1 -0
  48. package/dist/commands/event-sourcing-full.d.ts +10 -0
  49. package/dist/commands/event-sourcing-full.js +1107 -0
  50. package/dist/commands/event-sourcing-full.js.map +1 -0
  51. package/dist/commands/feature-flags.d.ts +9 -0
  52. package/dist/commands/feature-flags.js +824 -0
  53. package/dist/commands/feature-flags.js.map +1 -0
  54. package/dist/commands/filter-dsl.d.ts +10 -0
  55. package/dist/commands/filter-dsl.js +1407 -0
  56. package/dist/commands/filter-dsl.js.map +1 -0
  57. package/dist/commands/generate-all.js +525 -36
  58. package/dist/commands/generate-all.js.map +1 -1
  59. package/dist/commands/generate-deployment.d.ts +8 -0
  60. package/dist/commands/generate-deployment.js +746 -0
  61. package/dist/commands/generate-deployment.js.map +1 -0
  62. package/dist/commands/generate-domain-service.d.ts +14 -0
  63. package/dist/commands/generate-domain-service.js +796 -0
  64. package/dist/commands/generate-domain-service.js.map +1 -0
  65. package/dist/commands/generate-entity.js +87 -25
  66. package/dist/commands/generate-entity.js.map +1 -1
  67. package/dist/commands/generate-from-schema.d.ts +56 -0
  68. package/dist/commands/generate-from-schema.js +222 -0
  69. package/dist/commands/generate-from-schema.js.map +1 -0
  70. package/dist/commands/generate-module.js +37 -29
  71. package/dist/commands/generate-module.js.map +1 -1
  72. package/dist/commands/generate-orchestrator.d.ts +14 -0
  73. package/dist/commands/generate-orchestrator.js +887 -0
  74. package/dist/commands/generate-orchestrator.js.map +1 -0
  75. package/dist/commands/generate-repository.d.ts +14 -0
  76. package/dist/commands/generate-repository.js +1019 -0
  77. package/dist/commands/generate-repository.js.map +1 -0
  78. package/dist/commands/generate-shared.d.ts +4 -0
  79. package/dist/commands/generate-shared.js +388 -0
  80. package/dist/commands/generate-shared.js.map +1 -0
  81. package/dist/commands/generate-value-object.d.ts +32 -0
  82. package/dist/commands/generate-value-object.js +700 -0
  83. package/dist/commands/generate-value-object.js.map +1 -0
  84. package/dist/commands/graphql-subscriptions.d.ts +6 -0
  85. package/dist/commands/graphql-subscriptions.js +607 -0
  86. package/dist/commands/graphql-subscriptions.js.map +1 -0
  87. package/dist/commands/graphql-types.d.ts +5 -0
  88. package/dist/commands/graphql-types.js +423 -0
  89. package/dist/commands/graphql-types.js.map +1 -0
  90. package/dist/commands/health-probes-advanced.d.ts +6 -0
  91. package/dist/commands/health-probes-advanced.js +655 -0
  92. package/dist/commands/health-probes-advanced.js.map +1 -0
  93. package/dist/commands/i18n-setup.d.ts +10 -0
  94. package/dist/commands/i18n-setup.js +677 -0
  95. package/dist/commands/i18n-setup.js.map +1 -0
  96. package/dist/commands/init-config.d.ts +6 -0
  97. package/dist/commands/init-config.js +370 -0
  98. package/dist/commands/init-config.js.map +1 -0
  99. package/dist/commands/init-project.js +56 -6
  100. package/dist/commands/init-project.js.map +1 -1
  101. package/dist/commands/interactive-scaffold.d.ts +5 -0
  102. package/dist/commands/interactive-scaffold.js +271 -0
  103. package/dist/commands/interactive-scaffold.js.map +1 -0
  104. package/dist/commands/metrics-prometheus.d.ts +6 -0
  105. package/dist/commands/metrics-prometheus.js +681 -0
  106. package/dist/commands/metrics-prometheus.js.map +1 -0
  107. package/dist/commands/migration-engine.d.ts +6 -0
  108. package/dist/commands/migration-engine.js +446 -0
  109. package/dist/commands/migration-engine.js.map +1 -0
  110. package/dist/commands/migration.d.ts +12 -0
  111. package/dist/commands/migration.js +484 -0
  112. package/dist/commands/migration.js.map +1 -0
  113. package/dist/commands/monorepo.d.ts +8 -0
  114. package/dist/commands/monorepo.js +483 -0
  115. package/dist/commands/monorepo.js.map +1 -0
  116. package/dist/commands/multi-database.d.ts +5 -0
  117. package/dist/commands/multi-database.js +439 -0
  118. package/dist/commands/multi-database.js.map +1 -0
  119. package/dist/commands/observability-tracing.d.ts +10 -0
  120. package/dist/commands/observability-tracing.js +740 -0
  121. package/dist/commands/observability-tracing.js.map +1 -0
  122. package/dist/commands/openapi-export.d.ts +8 -0
  123. package/dist/commands/openapi-export.js +359 -0
  124. package/dist/commands/openapi-export.js.map +1 -0
  125. package/dist/commands/perf-analyzer.d.ts +8 -0
  126. package/dist/commands/perf-analyzer.js +423 -0
  127. package/dist/commands/perf-analyzer.js.map +1 -0
  128. package/dist/commands/rate-limiting.d.ts +10 -0
  129. package/dist/commands/rate-limiting.js +953 -0
  130. package/dist/commands/rate-limiting.js.map +1 -0
  131. package/dist/commands/recipe-plugin.d.ts +56 -0
  132. package/dist/commands/recipe-plugin.js +315 -0
  133. package/dist/commands/recipe-plugin.js.map +1 -0
  134. package/dist/commands/recipe.d.ts +6 -0
  135. package/dist/commands/recipe.js +3988 -0
  136. package/dist/commands/recipe.js.map +1 -0
  137. package/dist/commands/recipes/elasticsearch.recipe.d.ts +1 -0
  138. package/dist/commands/recipes/elasticsearch.recipe.js +761 -0
  139. package/dist/commands/recipes/elasticsearch.recipe.js.map +1 -0
  140. package/dist/commands/recipes/event-sourcing.recipe.d.ts +1 -0
  141. package/dist/commands/recipes/event-sourcing.recipe.js +889 -0
  142. package/dist/commands/recipes/event-sourcing.recipe.js.map +1 -0
  143. package/dist/commands/recipes/index.d.ts +8 -0
  144. package/dist/commands/recipes/index.js +25 -0
  145. package/dist/commands/recipes/index.js.map +1 -0
  146. package/dist/commands/recipes/joi-env.recipe.d.ts +1 -0
  147. package/dist/commands/recipes/joi-env.recipe.js +301 -0
  148. package/dist/commands/recipes/joi-env.recipe.js.map +1 -0
  149. package/dist/commands/recipes/message-queue.recipe.d.ts +1 -0
  150. package/dist/commands/recipes/message-queue.recipe.js +706 -0
  151. package/dist/commands/recipes/message-queue.recipe.js.map +1 -0
  152. package/dist/commands/recipes/middleware.recipe.d.ts +1 -0
  153. package/dist/commands/recipes/middleware.recipe.js +383 -0
  154. package/dist/commands/recipes/middleware.recipe.js.map +1 -0
  155. package/dist/commands/recipes/multi-tenancy.recipe.d.ts +1 -0
  156. package/dist/commands/recipes/multi-tenancy.recipe.js +520 -0
  157. package/dist/commands/recipes/multi-tenancy.recipe.js.map +1 -0
  158. package/dist/commands/recipes/oauth2.recipe.d.ts +1 -0
  159. package/dist/commands/recipes/oauth2.recipe.js +472 -0
  160. package/dist/commands/recipes/oauth2.recipe.js.map +1 -0
  161. package/dist/commands/recipes/websocket.recipe.d.ts +1 -0
  162. package/dist/commands/recipes/websocket.recipe.js +453 -0
  163. package/dist/commands/recipes/websocket.recipe.js.map +1 -0
  164. package/dist/commands/resilience-patterns.d.ts +13 -0
  165. package/dist/commands/resilience-patterns.js +1029 -0
  166. package/dist/commands/resilience-patterns.js.map +1 -0
  167. package/dist/commands/security-patterns.d.ts +11 -0
  168. package/dist/commands/security-patterns.js +2233 -0
  169. package/dist/commands/security-patterns.js.map +1 -0
  170. package/dist/commands/template-debug.d.ts +27 -0
  171. package/dist/commands/template-debug.js +388 -0
  172. package/dist/commands/template-debug.js.map +1 -0
  173. package/dist/commands/test-factory-full.d.ts +9 -0
  174. package/dist/commands/test-factory-full.js +1570 -0
  175. package/dist/commands/test-factory-full.js.map +1 -0
  176. package/dist/commands/test-scaffold.d.ts +7 -0
  177. package/dist/commands/test-scaffold.js +621 -0
  178. package/dist/commands/test-scaffold.js.map +1 -0
  179. package/dist/index.js +1092 -1
  180. package/dist/index.js.map +1 -1
  181. package/dist/templates/ai-context/CLAUDE.md.hbs +173 -0
  182. package/dist/templates/ai-context/conventions.md.hbs +161 -0
  183. package/dist/templates/command/create-command.hbs +6 -14
  184. package/dist/templates/command/delete-command.hbs +19 -0
  185. package/dist/templates/command/update-command.hbs +24 -0
  186. package/dist/templates/controller/controller.hbs +64 -17
  187. package/dist/templates/dto/create-dto.hbs +29 -5
  188. package/dist/templates/dto/filter-dto.hbs +52 -0
  189. package/dist/templates/dto/filter-query.dto.hbs +148 -0
  190. package/dist/templates/dto/paginated-response.dto.hbs +29 -0
  191. package/dist/templates/dto/pagination-query.dto.hbs +30 -0
  192. package/dist/templates/dto/response-dto.hbs +38 -0
  193. package/dist/templates/dto/update-dto.hbs +11 -0
  194. package/dist/templates/entity/entity.hbs +32 -1
  195. package/dist/templates/event/domain-event.hbs +33 -7
  196. package/dist/templates/event/event-handler.hbs +40 -0
  197. package/dist/templates/exception/base-exceptions.hbs +69 -0
  198. package/dist/templates/exception/entity-not-found.exception.hbs +7 -0
  199. package/dist/templates/mapper/mapper.hbs +49 -24
  200. package/dist/templates/module/module.hbs +34 -10
  201. package/dist/templates/orm-entity/orm-entity.hbs +63 -12
  202. package/dist/templates/prisma/prisma-mapper.hbs +71 -0
  203. package/dist/templates/prisma/prisma-repository.hbs +114 -0
  204. package/dist/templates/prisma/prisma-schema.hbs +20 -0
  205. package/dist/templates/prisma/prisma-service.hbs +51 -0
  206. package/dist/templates/query/get-all.query.hbs +50 -0
  207. package/dist/templates/query/get-by-id.query.hbs +31 -0
  208. package/dist/templates/repository/repository.hbs +56 -14
  209. package/dist/templates/resolver/graphql-input.hbs +54 -0
  210. package/dist/templates/resolver/graphql-type.hbs +58 -0
  211. package/dist/templates/resolver/pagination-args.hbs +33 -0
  212. package/dist/templates/resolver/resolver.hbs +62 -0
  213. package/dist/templates/shared/prisma-query-builder.util.hbs +189 -0
  214. package/dist/templates/shared/query-builder.util.hbs +218 -0
  215. package/dist/templates/test/controller.spec.hbs +124 -0
  216. package/dist/templates/test/repository.spec.hbs +158 -0
  217. package/dist/templates/test/usecase.spec.hbs +116 -0
  218. package/dist/templates/usecase/create-usecase.hbs +20 -8
  219. package/dist/templates/usecase/delete-usecase.hbs +17 -0
  220. package/dist/templates/usecase/update-usecase.hbs +31 -0
  221. package/dist/utils/config.utils.d.ts +45 -0
  222. package/dist/utils/config.utils.js +211 -0
  223. package/dist/utils/config.utils.js.map +1 -0
  224. package/dist/utils/dependency.utils.d.ts +2 -0
  225. package/dist/utils/dependency.utils.js +44 -3
  226. package/dist/utils/dependency.utils.js.map +1 -1
  227. package/dist/utils/error.utils.d.ts +145 -0
  228. package/dist/utils/error.utils.js +422 -0
  229. package/dist/utils/error.utils.js.map +1 -0
  230. package/dist/utils/field.utils.d.ts +54 -0
  231. package/dist/utils/field.utils.js +401 -0
  232. package/dist/utils/field.utils.js.map +1 -0
  233. package/dist/utils/file.utils.d.ts +33 -8
  234. package/dist/utils/file.utils.js +237 -5
  235. package/dist/utils/file.utils.js.map +1 -1
  236. package/dist/utils/idempotency.utils.d.ts +123 -0
  237. package/dist/utils/idempotency.utils.js +444 -0
  238. package/dist/utils/idempotency.utils.js.map +1 -0
  239. package/dist/utils/naming.utils.js +24 -5
  240. package/dist/utils/naming.utils.js.map +1 -1
  241. package/dist/utils/performance.utils.d.ts +37 -0
  242. package/dist/utils/performance.utils.js +158 -0
  243. package/dist/utils/performance.utils.js.map +1 -0
  244. package/dist/utils/relation.utils.d.ts +92 -0
  245. package/dist/utils/relation.utils.js +388 -0
  246. package/dist/utils/relation.utils.js.map +1 -0
  247. package/dist/utils/rollback.utils.d.ts +49 -0
  248. package/dist/utils/rollback.utils.js +306 -0
  249. package/dist/utils/rollback.utils.js.map +1 -0
  250. package/dist/utils/schema.utils.d.ts +123 -0
  251. package/dist/utils/schema.utils.js +419 -0
  252. package/dist/utils/schema.utils.js.map +1 -0
  253. package/dist/utils/security.utils.d.ts +57 -0
  254. package/dist/utils/security.utils.js +315 -0
  255. package/dist/utils/security.utils.js.map +1 -0
  256. package/dist/utils/template-engine.utils.d.ts +80 -0
  257. package/dist/utils/template-engine.utils.js +478 -0
  258. package/dist/utils/template-engine.utils.js.map +1 -0
  259. package/dist/utils/validation-registry.utils.d.ts +160 -0
  260. package/dist/utils/validation-registry.utils.js +526 -0
  261. package/dist/utils/validation-registry.utils.js.map +1 -0
  262. package/package.json +12 -8
@@ -43,12 +43,51 @@ exports.writeFile = writeFile;
43
43
  exports.readTemplate = readTemplate;
44
44
  exports.compileTemplate = compileTemplate;
45
45
  exports.generateFromTemplate = generateFromTemplate;
46
+ exports.resetDryRunFiles = resetDryRunFiles;
47
+ exports.getDryRunFiles = getDryRunFiles;
48
+ exports.addDryRunFile = addDryRunFile;
49
+ exports.writeGeneratedFile = writeGeneratedFile;
50
+ exports.updateBarrelFile = updateBarrelFile;
46
51
  exports.getModulePath = getModulePath;
47
52
  const fs = __importStar(require("fs-extra"));
48
53
  const path = __importStar(require("path"));
49
54
  const handlebars_1 = __importDefault(require("handlebars"));
50
55
  const naming_utils_1 = require("./naming.utils");
51
- function prepareTemplateData(entityName, moduleName) {
56
+ const field_utils_1 = require("./field.utils");
57
+ // Register Handlebars helpers
58
+ handlebars_1.default.registerHelper('eq', function (a, b) {
59
+ return a === b;
60
+ });
61
+ handlebars_1.default.registerHelper('lowercase', function (str) {
62
+ return typeof str === 'string' ? str.toLowerCase() : str;
63
+ });
64
+ handlebars_1.default.registerHelper('uppercase', function (str) {
65
+ return typeof str === 'string' ? str.toUpperCase() : str;
66
+ });
67
+ handlebars_1.default.registerHelper('pascalCase', function (str) {
68
+ return typeof str === 'string' ? (0, naming_utils_1.toPascalCase)(str) : str;
69
+ });
70
+ handlebars_1.default.registerHelper('camelCase', function (str) {
71
+ return typeof str === 'string' ? (0, naming_utils_1.toCamelCase)(str) : str;
72
+ });
73
+ handlebars_1.default.registerHelper('kebabCase', function (str) {
74
+ return typeof str === 'string' ? (0, naming_utils_1.toKebabCase)(str) : str;
75
+ });
76
+ function prepareTemplateData(entityName, moduleName, fieldsString) {
77
+ const parsedFields = fieldsString ? (0, field_utils_1.parseFields)(fieldsString) : null;
78
+ const fieldsTemplateData = parsedFields?.fields.length
79
+ ? (0, field_utils_1.generateFieldsTemplateData)(parsedFields.fields)
80
+ : null;
81
+ // Check for relations and generate imports
82
+ const relationFields = parsedFields?.fields.filter((f) => f.isRelation) || [];
83
+ const hasRelations = relationFields.length > 0;
84
+ // Generate unique relation imports
85
+ const relationTargets = [...new Set(relationFields.map((f) => f.relationTarget).filter(Boolean))];
86
+ const relationImports = relationTargets.length > 0
87
+ ? relationTargets
88
+ .map((target) => `import { ${target}OrmEntity } from "./${(0, naming_utils_1.toKebabCase)(target)}.orm-entity";`)
89
+ .join('\n')
90
+ : '';
52
91
  return {
53
92
  entityName,
54
93
  entityNamePascal: (0, naming_utils_1.toPascalCase)(entityName),
@@ -56,17 +95,78 @@ function prepareTemplateData(entityName, moduleName) {
56
95
  entityNameKebab: (0, naming_utils_1.toKebabCase)(entityName),
57
96
  entityNameSnake: (0, naming_utils_1.toSnakeCase)(entityName),
58
97
  entityNamePlural: (0, naming_utils_1.toPlural)((0, naming_utils_1.toPascalCase)(entityName)),
98
+ entityNamePluralPascal: (0, naming_utils_1.toPlural)((0, naming_utils_1.toPascalCase)(entityName)),
99
+ entityNamePluralCamel: (0, naming_utils_1.toCamelCase)((0, naming_utils_1.toPlural)(entityName)),
59
100
  entityNamePluralKebab: (0, naming_utils_1.toKebabCase)((0, naming_utils_1.toPlural)(entityName)),
60
101
  tableName: (0, naming_utils_1.toTableName)(entityName),
61
- moduleName,
102
+ moduleName: (0, naming_utils_1.toPascalCase)(moduleName),
62
103
  moduleNameKebab: (0, naming_utils_1.toKebabCase)(moduleName),
104
+ moduleNamePascal: (0, naming_utils_1.toPascalCase)(moduleName),
105
+ // Field-aware properties
106
+ fields: parsedFields?.fields || [],
107
+ hasFields: (parsedFields?.fields.length || 0) > 0,
108
+ entityProperties: fieldsTemplateData?.entityProperties || '',
109
+ entityPropsInterface: fieldsTemplateData?.entityPropsInterface || '',
110
+ dtoProperties: fieldsTemplateData?.dtoProperties || '',
111
+ ormColumns: fieldsTemplateData?.ormColumns || '',
112
+ migrationColumns: fieldsTemplateData?.migrationColumns || '',
113
+ responseProperties: fieldsTemplateData?.responseProperties || '',
114
+ // Relation properties
115
+ hasRelations,
116
+ relationImports,
63
117
  };
64
118
  }
119
+ /**
120
+ * Validate that a path is safe and within allowed bounds
121
+ * Prevents path traversal attacks (OWASP A01:2021)
122
+ */
123
+ function validatePath(targetPath, basePath) {
124
+ if (!targetPath || typeof targetPath !== 'string') {
125
+ throw new Error('Path must be a non-empty string');
126
+ }
127
+ // Check for null bytes (can bypass security checks)
128
+ if (targetPath.includes('\0')) {
129
+ throw new Error('Path contains null byte');
130
+ }
131
+ // Check for path traversal patterns
132
+ const normalizedPath = path.normalize(targetPath);
133
+ if (normalizedPath.includes('..')) {
134
+ // After normalization, if .. still exists, it's going above root
135
+ const resolvedPath = path.resolve(targetPath);
136
+ const cwdPath = basePath || process.cwd();
137
+ if (!resolvedPath.startsWith(cwdPath)) {
138
+ throw new Error('Path traversal detected: path escapes base directory');
139
+ }
140
+ }
141
+ // Block access to sensitive system directories
142
+ const blockedPatterns = [
143
+ /^\/etc\//i,
144
+ /^\/proc\//i,
145
+ /^\/sys\//i,
146
+ /^\/dev\//i,
147
+ /^\/root\//i,
148
+ /^C:\\Windows/i,
149
+ /^C:\\Program Files/i,
150
+ /\.env$/i,
151
+ /\.git\//i,
152
+ /\.ssh\//i,
153
+ /id_rsa/i,
154
+ /\.pem$/i,
155
+ /\.key$/i,
156
+ ];
157
+ for (const pattern of blockedPatterns) {
158
+ if (pattern.test(normalizedPath)) {
159
+ throw new Error(`Access to path is blocked: ${normalizedPath}`);
160
+ }
161
+ }
162
+ }
65
163
  async function ensureDir(dirPath) {
164
+ validatePath(dirPath);
66
165
  await fs.ensureDir(dirPath);
67
166
  }
68
167
  async function fileExists(filePath) {
69
168
  try {
169
+ validatePath(filePath);
70
170
  await fs.access(filePath);
71
171
  return true;
72
172
  }
@@ -75,20 +175,152 @@ async function fileExists(filePath) {
75
175
  }
76
176
  }
77
177
  async function writeFile(filePath, content) {
178
+ validatePath(filePath);
179
+ // Validate content size (prevent DoS via huge files)
180
+ validateContentSize(content);
78
181
  await ensureDir(path.dirname(filePath));
79
182
  await fs.writeFile(filePath, content, 'utf-8');
80
183
  }
184
+ function validateContentSize(content) {
185
+ const maxContentSize = 10 * 1024 * 1024; // 10MB max
186
+ if (content && content.length > maxContentSize) {
187
+ throw new Error(`Content exceeds maximum size of ${maxContentSize} bytes`);
188
+ }
189
+ }
81
190
  async function readTemplate(templatePath) {
191
+ validatePath(templatePath);
192
+ // Get file stats to check size before reading
193
+ try {
194
+ const stats = await fs.stat(templatePath);
195
+ const maxTemplateSize = 1024 * 1024; // 1MB max for templates
196
+ if (stats.size > maxTemplateSize) {
197
+ throw new Error(`Template file exceeds maximum size of ${maxTemplateSize} bytes`);
198
+ }
199
+ }
200
+ catch (error) {
201
+ if (error.code === 'ENOENT') {
202
+ throw new Error(`Template file not found: ${templatePath}`);
203
+ }
204
+ throw error;
205
+ }
82
206
  return fs.readFile(templatePath, 'utf-8');
83
207
  }
84
208
  function compileTemplate(template, data) {
85
- const compiledTemplate = handlebars_1.default.compile(template);
209
+ const compiledTemplate = handlebars_1.default.compile(template, { noEscape: true });
86
210
  return compiledTemplate(data);
87
211
  }
88
- async function generateFromTemplate(templatePath, outputPath, data) {
212
+ async function generateFromTemplate(templatePath, outputPath, data, dryRun = false) {
89
213
  const template = await readTemplate(templatePath);
90
214
  const content = compileTemplate(template, data);
91
- await writeFile(outputPath, content);
215
+ await writeGeneratedFile(outputPath, content, dryRun);
216
+ return outputPath;
217
+ }
218
+ let dryRunFiles = [];
219
+ function resetDryRunFiles() {
220
+ dryRunFiles = [];
221
+ }
222
+ function getDryRunFiles() {
223
+ return [...dryRunFiles];
224
+ }
225
+ function addDryRunFile(filePath, action = 'create') {
226
+ if (dryRunFiles.some((change) => change.filePath === filePath)) {
227
+ return;
228
+ }
229
+ dryRunFiles.push({ filePath, action });
230
+ }
231
+ async function writeGeneratedFile(filePath, content, dryRun = false) {
232
+ validatePath(filePath);
233
+ validateContentSize(content);
234
+ if (dryRun) {
235
+ addDryRunFile(filePath, (await fileExists(filePath)) ? 'update' : 'create');
236
+ return;
237
+ }
238
+ await writeFile(filePath, content);
239
+ }
240
+ async function updateBarrelFile(filePath, update) {
241
+ validatePath(filePath);
242
+ let content = '';
243
+ if (await fileExists(filePath)) {
244
+ content = await fs.readFile(filePath, 'utf-8');
245
+ }
246
+ const originalContent = content;
247
+ content = appendUniqueLines(content, update.exports || [], update.arrayName);
248
+ content = appendUniqueLines(content, update.imports || [], update.arrayName);
249
+ if (update.arrayName && update.arrayItems?.length) {
250
+ content = mergeExportedArray(content, update.arrayName, update.arrayItems);
251
+ }
252
+ content = normalizeFileContent(content);
253
+ if (content !== normalizeFileContent(originalContent)) {
254
+ await writeGeneratedFile(filePath, content, !!update.dryRun);
255
+ }
256
+ }
257
+ function appendUniqueLines(content, lines, beforeArrayName) {
258
+ const existingLines = new Set(content
259
+ .split(/\r?\n/)
260
+ .map((line) => line.trim())
261
+ .filter(Boolean));
262
+ const missingLines = lines
263
+ .map((line) => line.trim())
264
+ .filter((line) => line.length > 0 && !existingLines.has(line));
265
+ if (!missingLines.length) {
266
+ return content;
267
+ }
268
+ const insertion = `${missingLines.join('\n')}\n`;
269
+ if (beforeArrayName) {
270
+ const arrayPattern = new RegExp(`export const ${escapeRegExp(beforeArrayName)}(:[^=]+)?\\s*=\\s*\\[`);
271
+ const arrayMatch = arrayPattern.exec(content);
272
+ if (arrayMatch?.index !== undefined) {
273
+ const beforeArray = content.slice(0, arrayMatch.index).trimEnd();
274
+ const afterArray = content.slice(arrayMatch.index);
275
+ const prefix = beforeArray.length > 0 ? `${beforeArray}\n` : '';
276
+ return `${prefix}${insertion}${afterArray}`;
277
+ }
278
+ }
279
+ const trimmedContent = content.trimEnd();
280
+ const prefix = trimmedContent.length > 0 ? `${trimmedContent}\n` : '';
281
+ return `${prefix}${insertion}`;
282
+ }
283
+ function mergeExportedArray(content, arrayName, arrayItems) {
284
+ const uniqueItems = [...new Set(arrayItems.map((item) => item.trim()).filter(Boolean))];
285
+ const escapedArrayName = escapeRegExp(arrayName);
286
+ const arrayPattern = new RegExp(`export const ${escapedArrayName}(:[^=]+)?\\s*=\\s*\\[([\\s\\S]*?)\\];`);
287
+ const match = arrayPattern.exec(content);
288
+ if (!match) {
289
+ const arrayContent = uniqueItems.map((item) => ` ${item},`).join('\n');
290
+ return appendUniqueLines(content, [`export const ${arrayName} = [\n${arrayContent}\n];`]);
291
+ }
292
+ const typeAnnotation = match[1] || '';
293
+ const body = match[2] || '';
294
+ const missingItems = uniqueItems.filter((item) => !hasArrayItem(body, item));
295
+ if (!missingItems.length) {
296
+ return content;
297
+ }
298
+ const nextBody = appendArrayItems(body, missingItems);
299
+ const nextArray = `export const ${arrayName}${typeAnnotation} = [${nextBody}];`;
300
+ return content.replace(match[0], nextArray);
301
+ }
302
+ function hasArrayItem(body, item) {
303
+ return new RegExp(`(^|[^A-Za-z0-9_$])${escapeRegExp(item)}([^A-Za-z0-9_$]|$)`).test(body);
304
+ }
305
+ function appendArrayItems(body, missingItems) {
306
+ const linesToAdd = missingItems.map((item) => ` ${item},`).join('\n');
307
+ const trimmedBody = body.trim();
308
+ if (!trimmedBody) {
309
+ return `\n${linesToAdd}\n`;
310
+ }
311
+ if (!body.includes('\n')) {
312
+ return `\n ${trimmedBody.replace(/,\s*$/, '')},\n${linesToAdd}\n`;
313
+ }
314
+ const bodyWithTrailingComma = /,\s*$/.test(body.trimEnd())
315
+ ? body.trimEnd()
316
+ : `${body.trimEnd()},`;
317
+ return `${bodyWithTrailingComma}\n${linesToAdd}\n`;
318
+ }
319
+ function normalizeFileContent(content) {
320
+ return content.trimEnd() ? `${content.trimEnd()}\n` : '';
321
+ }
322
+ function escapeRegExp(str) {
323
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
92
324
  }
93
325
  function getModulePath(basePath, moduleName) {
94
326
  return path.join(basePath, 'src', 'modules', (0, naming_utils_1.toKebabCase)(moduleName));
@@ -1 +1 @@
1
- {"version":3,"file":"file.utils.js","sourceRoot":"","sources":["../../src/utils/file.utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,kDAaC;AAED,8BAEC;AAED,gCAOC;AAED,8BAGC;AAED,oCAEC;AAED,0CAGC;AAED,oDAQC;AAED,sCAEC;AA9ED,6CAA+B;AAC/B,2CAA6B;AAC7B,4DAAoC;AACpC,iDAA4G;AAqB5G,SAAgB,mBAAmB,CAAC,UAAkB,EAAE,UAAkB;IACxE,OAAO;QACL,UAAU;QACV,gBAAgB,EAAE,IAAA,2BAAY,EAAC,UAAU,CAAC;QAC1C,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QACxC,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QACxC,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QACxC,gBAAgB,EAAE,IAAA,uBAAQ,EAAC,IAAA,2BAAY,EAAC,UAAU,CAAC,CAAC;QACpD,qBAAqB,EAAE,IAAA,0BAAW,EAAC,IAAA,uBAAQ,EAAC,UAAU,CAAC,CAAC;QACxD,SAAS,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QAClC,UAAU;QACV,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;KACzC,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAE,OAAe;IAC/D,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxC,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAEM,KAAK,UAAU,YAAY,CAAC,YAAoB;IACrD,OAAO,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,SAAgB,eAAe,CAAC,QAAgB,EAAE,IAAkB;IAClE,MAAM,gBAAgB,GAAG,oBAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtD,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAEM,KAAK,UAAU,oBAAoB,CACxC,YAAoB,EACpB,UAAkB,EAClB,IAAkB;IAElB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,aAAa,CAAC,QAAgB,EAAE,UAAkB;IAChE,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC,CAAC,CAAC;AACxE,CAAC"}
1
+ {"version":3,"file":"file.utils.js","sourceRoot":"","sources":["../../src/utils/file.utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Idempotency & Consistency System
3
+ * Tracks generated files and ensures safe re-generation
4
+ */
5
+ export interface GenerationManifest {
6
+ version: string;
7
+ generatedAt: string;
8
+ lastModified: string;
9
+ generator: string;
10
+ entities: EntityManifest[];
11
+ files: FileManifest[];
12
+ checksums: Record<string, string>;
13
+ }
14
+ export interface EntityManifest {
15
+ name: string;
16
+ module: string;
17
+ fields: string[];
18
+ relations: string[];
19
+ generatedFiles: string[];
20
+ hash: string;
21
+ generatedAt: string;
22
+ }
23
+ export interface FileManifest {
24
+ path: string;
25
+ type: 'entity' | 'dto' | 'service' | 'controller' | 'repository' | 'module' | 'test' | 'other';
26
+ entity?: string;
27
+ module?: string;
28
+ hash: string;
29
+ generatedAt: string;
30
+ modifiedAt?: string;
31
+ isModified: boolean;
32
+ mergeStrategy: MergeStrategy;
33
+ }
34
+ export type MergeStrategy = 'overwrite' | 'skip' | 'merge' | 'backup' | 'prompt';
35
+ export interface GenerationPlan {
36
+ create: FileOperation[];
37
+ update: FileOperation[];
38
+ skip: FileOperation[];
39
+ conflict: FileOperation[];
40
+ }
41
+ export interface FileOperation {
42
+ path: string;
43
+ action: 'create' | 'update' | 'skip' | 'conflict' | 'backup';
44
+ reason?: string;
45
+ content?: string;
46
+ existingHash?: string;
47
+ newHash?: string;
48
+ }
49
+ /**
50
+ * Load or create generation manifest
51
+ */
52
+ export declare function loadManifest(basePath: string): GenerationManifest;
53
+ /**
54
+ * Create an empty manifest
55
+ */
56
+ export declare function createEmptyManifest(): GenerationManifest;
57
+ /**
58
+ * Save manifest to disk
59
+ */
60
+ export declare function saveManifest(basePath: string, manifest: GenerationManifest): void;
61
+ /**
62
+ * Calculate file hash
63
+ */
64
+ export declare function calculateHash(content: string): string;
65
+ /**
66
+ * Check if a file has been manually modified
67
+ */
68
+ export declare function isFileModified(filePath: string, manifest: GenerationManifest): boolean;
69
+ /**
70
+ * Plan generation operations with conflict detection
71
+ */
72
+ export declare function planGeneration(basePath: string, filesToGenerate: Array<{
73
+ path: string;
74
+ content: string;
75
+ type: FileManifest['type'];
76
+ }>, manifest: GenerationManifest, options?: {
77
+ mergeStrategy?: MergeStrategy;
78
+ force?: boolean;
79
+ }): GenerationPlan;
80
+ /**
81
+ * Execute a generation plan
82
+ */
83
+ export declare function executePlan(basePath: string, plan: GenerationPlan, manifest: GenerationManifest): {
84
+ success: boolean;
85
+ created: number;
86
+ updated: number;
87
+ skipped: number;
88
+ errors: string[];
89
+ };
90
+ /**
91
+ * Backup a file before overwriting
92
+ */
93
+ export declare function backupFile(basePath: string, filePath: string): string;
94
+ /**
95
+ * Restore a file from backup
96
+ */
97
+ export declare function restoreFile(basePath: string, filePath: string, backupTimestamp?: string): boolean;
98
+ /**
99
+ * Register an entity in the manifest
100
+ */
101
+ export declare function registerEntity(manifest: GenerationManifest, entity: {
102
+ name: string;
103
+ module: string;
104
+ fields: string[];
105
+ relations: string[];
106
+ generatedFiles: string[];
107
+ }): void;
108
+ /**
109
+ * Check if an entity was previously generated
110
+ */
111
+ export declare function wasEntityGenerated(manifest: GenerationManifest, entityName: string, moduleName: string): boolean;
112
+ /**
113
+ * Get entity manifest
114
+ */
115
+ export declare function getEntityManifest(manifest: GenerationManifest, entityName: string, moduleName: string): EntityManifest | undefined;
116
+ /**
117
+ * Clean up old backups (keep last N)
118
+ */
119
+ export declare function cleanupBackups(basePath: string, keepLast?: number): number;
120
+ /**
121
+ * Generate a summary of what will change
122
+ */
123
+ export declare function summarizePlan(plan: GenerationPlan): string;