nestjs-ddd-cli 2.2.1 → 3.2.1

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 (254) 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 +485 -32
  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 +82 -24
  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-orchestrator.d.ts +14 -0
  71. package/dist/commands/generate-orchestrator.js +887 -0
  72. package/dist/commands/generate-orchestrator.js.map +1 -0
  73. package/dist/commands/generate-repository.d.ts +14 -0
  74. package/dist/commands/generate-repository.js +1019 -0
  75. package/dist/commands/generate-repository.js.map +1 -0
  76. package/dist/commands/generate-shared.d.ts +4 -0
  77. package/dist/commands/generate-shared.js +388 -0
  78. package/dist/commands/generate-shared.js.map +1 -0
  79. package/dist/commands/generate-value-object.d.ts +32 -0
  80. package/dist/commands/generate-value-object.js +700 -0
  81. package/dist/commands/generate-value-object.js.map +1 -0
  82. package/dist/commands/graphql-subscriptions.d.ts +6 -0
  83. package/dist/commands/graphql-subscriptions.js +607 -0
  84. package/dist/commands/graphql-subscriptions.js.map +1 -0
  85. package/dist/commands/graphql-types.d.ts +5 -0
  86. package/dist/commands/graphql-types.js +423 -0
  87. package/dist/commands/graphql-types.js.map +1 -0
  88. package/dist/commands/health-probes-advanced.d.ts +6 -0
  89. package/dist/commands/health-probes-advanced.js +655 -0
  90. package/dist/commands/health-probes-advanced.js.map +1 -0
  91. package/dist/commands/i18n-setup.d.ts +10 -0
  92. package/dist/commands/i18n-setup.js +677 -0
  93. package/dist/commands/i18n-setup.js.map +1 -0
  94. package/dist/commands/init-config.d.ts +6 -0
  95. package/dist/commands/init-config.js +370 -0
  96. package/dist/commands/init-config.js.map +1 -0
  97. package/dist/commands/init-project.js +56 -6
  98. package/dist/commands/init-project.js.map +1 -1
  99. package/dist/commands/interactive-scaffold.d.ts +5 -0
  100. package/dist/commands/interactive-scaffold.js +271 -0
  101. package/dist/commands/interactive-scaffold.js.map +1 -0
  102. package/dist/commands/metrics-prometheus.d.ts +6 -0
  103. package/dist/commands/metrics-prometheus.js +681 -0
  104. package/dist/commands/metrics-prometheus.js.map +1 -0
  105. package/dist/commands/migration-engine.d.ts +6 -0
  106. package/dist/commands/migration-engine.js +446 -0
  107. package/dist/commands/migration-engine.js.map +1 -0
  108. package/dist/commands/migration.d.ts +12 -0
  109. package/dist/commands/migration.js +484 -0
  110. package/dist/commands/migration.js.map +1 -0
  111. package/dist/commands/monorepo.d.ts +8 -0
  112. package/dist/commands/monorepo.js +483 -0
  113. package/dist/commands/monorepo.js.map +1 -0
  114. package/dist/commands/multi-database.d.ts +5 -0
  115. package/dist/commands/multi-database.js +439 -0
  116. package/dist/commands/multi-database.js.map +1 -0
  117. package/dist/commands/observability-tracing.d.ts +10 -0
  118. package/dist/commands/observability-tracing.js +740 -0
  119. package/dist/commands/observability-tracing.js.map +1 -0
  120. package/dist/commands/openapi-export.d.ts +8 -0
  121. package/dist/commands/openapi-export.js +359 -0
  122. package/dist/commands/openapi-export.js.map +1 -0
  123. package/dist/commands/perf-analyzer.d.ts +8 -0
  124. package/dist/commands/perf-analyzer.js +423 -0
  125. package/dist/commands/perf-analyzer.js.map +1 -0
  126. package/dist/commands/rate-limiting.d.ts +10 -0
  127. package/dist/commands/rate-limiting.js +953 -0
  128. package/dist/commands/rate-limiting.js.map +1 -0
  129. package/dist/commands/recipe-plugin.d.ts +56 -0
  130. package/dist/commands/recipe-plugin.js +315 -0
  131. package/dist/commands/recipe-plugin.js.map +1 -0
  132. package/dist/commands/recipe.d.ts +6 -0
  133. package/dist/commands/recipe.js +3941 -0
  134. package/dist/commands/recipe.js.map +1 -0
  135. package/dist/commands/recipes/elasticsearch.recipe.d.ts +1 -0
  136. package/dist/commands/recipes/elasticsearch.recipe.js +761 -0
  137. package/dist/commands/recipes/elasticsearch.recipe.js.map +1 -0
  138. package/dist/commands/recipes/event-sourcing.recipe.d.ts +1 -0
  139. package/dist/commands/recipes/event-sourcing.recipe.js +889 -0
  140. package/dist/commands/recipes/event-sourcing.recipe.js.map +1 -0
  141. package/dist/commands/recipes/index.d.ts +7 -0
  142. package/dist/commands/recipes/index.js +24 -0
  143. package/dist/commands/recipes/index.js.map +1 -0
  144. package/dist/commands/recipes/message-queue.recipe.d.ts +1 -0
  145. package/dist/commands/recipes/message-queue.recipe.js +706 -0
  146. package/dist/commands/recipes/message-queue.recipe.js.map +1 -0
  147. package/dist/commands/recipes/middleware.recipe.d.ts +1 -0
  148. package/dist/commands/recipes/middleware.recipe.js +383 -0
  149. package/dist/commands/recipes/middleware.recipe.js.map +1 -0
  150. package/dist/commands/recipes/multi-tenancy.recipe.d.ts +1 -0
  151. package/dist/commands/recipes/multi-tenancy.recipe.js +520 -0
  152. package/dist/commands/recipes/multi-tenancy.recipe.js.map +1 -0
  153. package/dist/commands/recipes/oauth2.recipe.d.ts +1 -0
  154. package/dist/commands/recipes/oauth2.recipe.js +472 -0
  155. package/dist/commands/recipes/oauth2.recipe.js.map +1 -0
  156. package/dist/commands/recipes/websocket.recipe.d.ts +1 -0
  157. package/dist/commands/recipes/websocket.recipe.js +453 -0
  158. package/dist/commands/recipes/websocket.recipe.js.map +1 -0
  159. package/dist/commands/resilience-patterns.d.ts +13 -0
  160. package/dist/commands/resilience-patterns.js +1029 -0
  161. package/dist/commands/resilience-patterns.js.map +1 -0
  162. package/dist/commands/security-patterns.d.ts +11 -0
  163. package/dist/commands/security-patterns.js +2233 -0
  164. package/dist/commands/security-patterns.js.map +1 -0
  165. package/dist/commands/template-debug.d.ts +27 -0
  166. package/dist/commands/template-debug.js +388 -0
  167. package/dist/commands/template-debug.js.map +1 -0
  168. package/dist/commands/test-factory-full.d.ts +9 -0
  169. package/dist/commands/test-factory-full.js +1570 -0
  170. package/dist/commands/test-factory-full.js.map +1 -0
  171. package/dist/commands/test-scaffold.d.ts +7 -0
  172. package/dist/commands/test-scaffold.js +621 -0
  173. package/dist/commands/test-scaffold.js.map +1 -0
  174. package/dist/index.js +1088 -0
  175. package/dist/index.js.map +1 -1
  176. package/dist/templates/ai-context/CLAUDE.md.hbs +158 -0
  177. package/dist/templates/ai-context/conventions.md.hbs +154 -0
  178. package/dist/templates/command/create-command.hbs +6 -14
  179. package/dist/templates/command/delete-command.hbs +19 -0
  180. package/dist/templates/command/update-command.hbs +24 -0
  181. package/dist/templates/controller/controller.hbs +64 -17
  182. package/dist/templates/dto/create-dto.hbs +29 -5
  183. package/dist/templates/dto/filter-dto.hbs +52 -0
  184. package/dist/templates/dto/filter-query.dto.hbs +148 -0
  185. package/dist/templates/dto/paginated-response.dto.hbs +29 -0
  186. package/dist/templates/dto/pagination-query.dto.hbs +30 -0
  187. package/dist/templates/dto/response-dto.hbs +38 -0
  188. package/dist/templates/dto/update-dto.hbs +11 -0
  189. package/dist/templates/entity/entity.hbs +32 -1
  190. package/dist/templates/event/domain-event.hbs +33 -7
  191. package/dist/templates/event/event-handler.hbs +40 -0
  192. package/dist/templates/exception/base-exceptions.hbs +69 -0
  193. package/dist/templates/exception/entity-not-found.exception.hbs +7 -0
  194. package/dist/templates/mapper/mapper.hbs +49 -24
  195. package/dist/templates/module/module.hbs +34 -10
  196. package/dist/templates/orm-entity/orm-entity.hbs +63 -12
  197. package/dist/templates/prisma/prisma-mapper.hbs +71 -0
  198. package/dist/templates/prisma/prisma-repository.hbs +114 -0
  199. package/dist/templates/prisma/prisma-schema.hbs +20 -0
  200. package/dist/templates/prisma/prisma-service.hbs +51 -0
  201. package/dist/templates/query/get-all.query.hbs +50 -0
  202. package/dist/templates/query/get-by-id.query.hbs +31 -0
  203. package/dist/templates/repository/repository.hbs +55 -13
  204. package/dist/templates/resolver/graphql-input.hbs +54 -0
  205. package/dist/templates/resolver/graphql-type.hbs +58 -0
  206. package/dist/templates/resolver/pagination-args.hbs +33 -0
  207. package/dist/templates/resolver/resolver.hbs +62 -0
  208. package/dist/templates/shared/prisma-query-builder.util.hbs +189 -0
  209. package/dist/templates/shared/query-builder.util.hbs +218 -0
  210. package/dist/templates/test/controller.spec.hbs +124 -0
  211. package/dist/templates/test/repository.spec.hbs +158 -0
  212. package/dist/templates/test/usecase.spec.hbs +116 -0
  213. package/dist/templates/usecase/create-usecase.hbs +19 -7
  214. package/dist/templates/usecase/delete-usecase.hbs +17 -0
  215. package/dist/templates/usecase/update-usecase.hbs +31 -0
  216. package/dist/utils/config.utils.d.ts +45 -0
  217. package/dist/utils/config.utils.js +211 -0
  218. package/dist/utils/config.utils.js.map +1 -0
  219. package/dist/utils/error.utils.d.ts +145 -0
  220. package/dist/utils/error.utils.js +422 -0
  221. package/dist/utils/error.utils.js.map +1 -0
  222. package/dist/utils/field.utils.d.ts +54 -0
  223. package/dist/utils/field.utils.js +389 -0
  224. package/dist/utils/field.utils.js.map +1 -0
  225. package/dist/utils/file.utils.d.ts +19 -8
  226. package/dist/utils/file.utils.js +135 -4
  227. package/dist/utils/file.utils.js.map +1 -1
  228. package/dist/utils/idempotency.utils.d.ts +123 -0
  229. package/dist/utils/idempotency.utils.js +444 -0
  230. package/dist/utils/idempotency.utils.js.map +1 -0
  231. package/dist/utils/naming.utils.js +24 -5
  232. package/dist/utils/naming.utils.js.map +1 -1
  233. package/dist/utils/performance.utils.d.ts +37 -0
  234. package/dist/utils/performance.utils.js +158 -0
  235. package/dist/utils/performance.utils.js.map +1 -0
  236. package/dist/utils/relation.utils.d.ts +92 -0
  237. package/dist/utils/relation.utils.js +388 -0
  238. package/dist/utils/relation.utils.js.map +1 -0
  239. package/dist/utils/rollback.utils.d.ts +49 -0
  240. package/dist/utils/rollback.utils.js +306 -0
  241. package/dist/utils/rollback.utils.js.map +1 -0
  242. package/dist/utils/schema.utils.d.ts +123 -0
  243. package/dist/utils/schema.utils.js +419 -0
  244. package/dist/utils/schema.utils.js.map +1 -0
  245. package/dist/utils/security.utils.d.ts +57 -0
  246. package/dist/utils/security.utils.js +315 -0
  247. package/dist/utils/security.utils.js.map +1 -0
  248. package/dist/utils/template-engine.utils.d.ts +80 -0
  249. package/dist/utils/template-engine.utils.js +463 -0
  250. package/dist/utils/template-engine.utils.js.map +1 -0
  251. package/dist/utils/validation-registry.utils.d.ts +160 -0
  252. package/dist/utils/validation-registry.utils.js +526 -0
  253. package/dist/utils/validation-registry.utils.js.map +1 -0
  254. package/package.json +3 -1
@@ -0,0 +1,621 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.setupDatabaseSeeding = setupDatabaseSeeding;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const chalk_1 = __importDefault(require("chalk"));
43
+ const naming_utils_1 = require("../utils/naming.utils");
44
+ async function setupDatabaseSeeding(basePath, options = {}) {
45
+ console.log(chalk_1.default.bold.blue('\n🌱 Setting up Database Seeding Infrastructure\n'));
46
+ const moduleName = options.module || 'shared';
47
+ const pascalName = (0, naming_utils_1.toPascalCase)(moduleName);
48
+ const camelName = (0, naming_utils_1.toCamelCase)(moduleName);
49
+ const kebabName = (0, naming_utils_1.toKebabCase)(moduleName);
50
+ const orm = options.orm || 'typeorm';
51
+ const entities = options.entities || [moduleName];
52
+ const baseDir = path.join(basePath, 'src', kebabName, 'infrastructure', 'seeding');
53
+ fs.mkdirSync(baseDir, { recursive: true });
54
+ // Seed runner
55
+ const seedRunnerContent = `import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
56
+ ${orm === 'typeorm' ? "import { DataSource, EntityManager } from 'typeorm';" : ''}
57
+ ${orm === 'prisma' ? "import { PrismaService } from '../prisma/prisma.service';" : ''}
58
+
59
+ interface SeedConfig {
60
+ name: string;
61
+ priority: number;
62
+ environments: string[];
63
+ dependencies?: string[];
64
+ }
65
+
66
+ interface SeederClass {
67
+ config: SeedConfig;
68
+ run(context: SeedContext): Promise<void>;
69
+ shouldRun?(context: SeedContext): Promise<boolean>;
70
+ rollback?(context: SeedContext): Promise<void>;
71
+ }
72
+
73
+ export interface SeedContext {
74
+ environment: string;
75
+ ${orm === 'typeorm' ? 'entityManager: EntityManager;' : ''}
76
+ ${orm === 'prisma' ? 'prisma: PrismaService;' : ''}
77
+ logger: Logger;
78
+ data: Map<string, any>;
79
+ }
80
+
81
+ /**
82
+ * Database seeding runner with dependency resolution and environment support
83
+ */
84
+ @Injectable()
85
+ export class SeedRunner implements OnModuleInit {
86
+ private readonly logger = new Logger(SeedRunner.name);
87
+ private readonly seeders: SeederClass[] = [];
88
+ private readonly executedSeeders: Set<string> = new Set();
89
+
90
+ constructor(
91
+ ${orm === 'typeorm' ? 'private readonly dataSource: DataSource,' : ''}
92
+ ${orm === 'prisma' ? 'private readonly prisma: PrismaService,' : ''}
93
+ ) {}
94
+
95
+ async onModuleInit(): Promise<void> {
96
+ const shouldSeed = process.env.RUN_SEEDS === 'true';
97
+ if (shouldSeed) {
98
+ await this.runAll();
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Register a seeder
104
+ */
105
+ register(seeder: SeederClass): void {
106
+ this.seeders.push(seeder);
107
+ this.sortSeeders();
108
+ }
109
+
110
+ /**
111
+ * Sort seeders by priority and dependencies
112
+ */
113
+ private sortSeeders(): void {
114
+ this.seeders.sort((a, b) => {
115
+ // Check dependencies first
116
+ if (a.config.dependencies?.includes(b.config.name)) {
117
+ return 1;
118
+ }
119
+ if (b.config.dependencies?.includes(a.config.name)) {
120
+ return -1;
121
+ }
122
+ // Then sort by priority
123
+ return a.config.priority - b.config.priority;
124
+ });
125
+ }
126
+
127
+ /**
128
+ * Run all registered seeders
129
+ */
130
+ async runAll(environment?: string): Promise<void> {
131
+ const env = environment || process.env.NODE_ENV || 'development';
132
+ this.logger.log(\`Running seeders for environment: \${env}\`);
133
+
134
+ const context = await this.createContext(env);
135
+
136
+ for (const seeder of this.seeders) {
137
+ await this.runSeeder(seeder, context);
138
+ }
139
+
140
+ this.logger.log('All seeders completed');
141
+ }
142
+
143
+ /**
144
+ * Run a specific seeder
145
+ */
146
+ async runSeeder(seeder: SeederClass, context: SeedContext): Promise<void> {
147
+ const { config } = seeder;
148
+
149
+ // Check if already executed
150
+ if (this.executedSeeders.has(config.name)) {
151
+ return;
152
+ }
153
+
154
+ // Check environment
155
+ if (!config.environments.includes(context.environment) && !config.environments.includes('*')) {
156
+ this.logger.debug(\`Skipping \${config.name} - not for \${context.environment}\`);
157
+ return;
158
+ }
159
+
160
+ // Run dependencies first
161
+ if (config.dependencies) {
162
+ for (const depName of config.dependencies) {
163
+ const depSeeder = this.seeders.find((s) => s.config.name === depName);
164
+ if (depSeeder && !this.executedSeeders.has(depName)) {
165
+ await this.runSeeder(depSeeder, context);
166
+ }
167
+ }
168
+ }
169
+
170
+ // Check if should run
171
+ if (seeder.shouldRun) {
172
+ const should = await seeder.shouldRun(context);
173
+ if (!should) {
174
+ this.logger.debug(\`Skipping \${config.name} - shouldRun returned false\`);
175
+ return;
176
+ }
177
+ }
178
+
179
+ // Run the seeder
180
+ try {
181
+ this.logger.log(\`Running seeder: \${config.name}\`);
182
+ await seeder.run(context);
183
+ this.executedSeeders.add(config.name);
184
+ this.logger.log(\`Completed seeder: \${config.name}\`);
185
+ } catch (error) {
186
+ this.logger.error(\`Seeder \${config.name} failed: \${error}\`);
187
+ throw error;
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Rollback all seeders
193
+ */
194
+ async rollbackAll(environment?: string): Promise<void> {
195
+ const env = environment || process.env.NODE_ENV || 'development';
196
+ this.logger.log(\`Rolling back seeders for environment: \${env}\`);
197
+
198
+ const context = await this.createContext(env);
199
+
200
+ // Rollback in reverse order
201
+ const reversedSeeders = [...this.seeders].reverse();
202
+
203
+ for (const seeder of reversedSeeders) {
204
+ if (seeder.rollback && this.executedSeeders.has(seeder.config.name)) {
205
+ try {
206
+ this.logger.log(\`Rolling back seeder: \${seeder.config.name}\`);
207
+ await seeder.rollback(context);
208
+ this.executedSeeders.delete(seeder.config.name);
209
+ } catch (error) {
210
+ this.logger.error(\`Rollback failed for \${seeder.config.name}: \${error}\`);
211
+ }
212
+ }
213
+ }
214
+ }
215
+
216
+ /**
217
+ * Create seed context
218
+ */
219
+ private async createContext(environment: string): Promise<SeedContext> {
220
+ return {
221
+ environment,
222
+ ${orm === 'typeorm' ? 'entityManager: this.dataSource.manager,' : ''}
223
+ ${orm === 'prisma' ? 'prisma: this.prisma,' : ''}
224
+ logger: this.logger,
225
+ data: new Map(),
226
+ };
227
+ }
228
+
229
+ /**
230
+ * Reset execution state
231
+ */
232
+ reset(): void {
233
+ this.executedSeeders.clear();
234
+ }
235
+ }
236
+ `;
237
+ fs.writeFileSync(path.join(baseDir, 'seed-runner.ts'), seedRunnerContent);
238
+ // Fixture factory
239
+ const fixtureFactoryContent = `import { faker } from '@faker-js/faker';
240
+
241
+ type FactoryFunction<T> = (overrides?: Partial<T>) => T;
242
+ type AsyncFactoryFunction<T> = (overrides?: Partial<T>) => Promise<T>;
243
+
244
+ interface FactoryDefinition<T> {
245
+ default: () => T;
246
+ states?: Record<string, Partial<T> | ((base: T) => Partial<T>)>;
247
+ }
248
+
249
+ /**
250
+ * Type-safe fixture factory for generating test and seed data
251
+ */
252
+ export class FixtureFactory {
253
+ private static factories: Map<string, FactoryDefinition<any>> = new Map();
254
+ private static sequences: Map<string, number> = new Map();
255
+
256
+ /**
257
+ * Define a factory for an entity
258
+ */
259
+ static define<T>(name: string, definition: FactoryDefinition<T>): void {
260
+ this.factories.set(name, definition);
261
+ }
262
+
263
+ /**
264
+ * Create a single instance
265
+ */
266
+ static create<T>(name: string, overrides?: Partial<T>, state?: string): T {
267
+ const factory = this.factories.get(name);
268
+ if (!factory) {
269
+ throw new Error(\`Factory "\${name}" not defined\`);
270
+ }
271
+
272
+ let instance = factory.default();
273
+
274
+ // Apply state if specified
275
+ if (state && factory.states?.[state]) {
276
+ const stateValue = factory.states[state];
277
+ const stateOverrides = typeof stateValue === 'function'
278
+ ? stateValue(instance)
279
+ : stateValue;
280
+ instance = { ...instance, ...stateOverrides };
281
+ }
282
+
283
+ // Apply overrides
284
+ if (overrides) {
285
+ instance = { ...instance, ...overrides };
286
+ }
287
+
288
+ return instance;
289
+ }
290
+
291
+ /**
292
+ * Create multiple instances
293
+ */
294
+ static createMany<T>(name: string, count: number, overrides?: Partial<T>, state?: string): T[] {
295
+ return Array.from({ length: count }, () => this.create<T>(name, overrides, state));
296
+ }
297
+
298
+ /**
299
+ * Get next value in a sequence
300
+ */
301
+ static sequence(name: string): number {
302
+ const current = this.sequences.get(name) || 0;
303
+ const next = current + 1;
304
+ this.sequences.set(name, next);
305
+ return next;
306
+ }
307
+
308
+ /**
309
+ * Reset all sequences
310
+ */
311
+ static resetSequences(): void {
312
+ this.sequences.clear();
313
+ }
314
+
315
+ /**
316
+ * Reset specific sequence
317
+ */
318
+ static resetSequence(name: string): void {
319
+ this.sequences.delete(name);
320
+ }
321
+ }
322
+
323
+ // ===============================
324
+ // Example Factory Definitions
325
+ // ===============================
326
+
327
+ ${entities.map(entity => {
328
+ const pascal = (0, naming_utils_1.toPascalCase)(entity);
329
+ const camel = (0, naming_utils_1.toCamelCase)(entity);
330
+ return `
331
+ /**
332
+ * ${pascal} factory definition
333
+ */
334
+ FixtureFactory.define<{
335
+ id: string;
336
+ name: string;
337
+ email: string;
338
+ createdAt: Date;
339
+ updatedAt: Date;
340
+ isActive: boolean;
341
+ }>('${camel}', {
342
+ default: () => ({
343
+ id: faker.string.uuid(),
344
+ name: faker.person.fullName(),
345
+ email: faker.internet.email(),
346
+ createdAt: faker.date.past(),
347
+ updatedAt: faker.date.recent(),
348
+ isActive: true,
349
+ }),
350
+ states: {
351
+ inactive: { isActive: false },
352
+ recent: (base) => ({
353
+ createdAt: faker.date.recent({ days: 7 }),
354
+ updatedAt: new Date(),
355
+ }),
356
+ },
357
+ });`;
358
+ }).join('\n')}
359
+
360
+ // ===============================
361
+ // Builder Pattern Factory
362
+ // ===============================
363
+
364
+ /**
365
+ * Fluent builder for creating test fixtures
366
+ */
367
+ export class FixtureBuilder<T> {
368
+ private overrides: Partial<T> = {};
369
+ private state?: string;
370
+ private traits: string[] = [];
371
+
372
+ constructor(private readonly factoryName: string) {}
373
+
374
+ /**
375
+ * Set specific field value
376
+ */
377
+ with<K extends keyof T>(key: K, value: T[K]): this {
378
+ this.overrides[key] = value;
379
+ return this;
380
+ }
381
+
382
+ /**
383
+ * Apply a predefined state
384
+ */
385
+ withState(state: string): this {
386
+ this.state = state;
387
+ return this;
388
+ }
389
+
390
+ /**
391
+ * Apply multiple overrides
392
+ */
393
+ withOverrides(overrides: Partial<T>): this {
394
+ this.overrides = { ...this.overrides, ...overrides };
395
+ return this;
396
+ }
397
+
398
+ /**
399
+ * Build single instance
400
+ */
401
+ build(): T {
402
+ return FixtureFactory.create<T>(this.factoryName, this.overrides, this.state);
403
+ }
404
+
405
+ /**
406
+ * Build multiple instances
407
+ */
408
+ buildMany(count: number): T[] {
409
+ return Array.from({ length: count }, () => this.build());
410
+ }
411
+ }
412
+
413
+ /**
414
+ * Create a builder for a factory
415
+ */
416
+ export function fixture<T>(name: string): FixtureBuilder<T> {
417
+ return new FixtureBuilder<T>(name);
418
+ }
419
+
420
+ // ===============================
421
+ // Seed Data Helpers
422
+ // ===============================
423
+
424
+ /**
425
+ * Generate realistic seed data for common scenarios
426
+ */
427
+ export const SeedDataGenerators = {
428
+ /**
429
+ * Generate users with various roles
430
+ */
431
+ users(count: number, roleDistribution: Record<string, number> = { user: 0.8, admin: 0.15, superadmin: 0.05 }) {
432
+ const users: any[] = [];
433
+ const roles = Object.entries(roleDistribution);
434
+
435
+ for (let i = 0; i < count; i++) {
436
+ const rand = Math.random();
437
+ let cumulative = 0;
438
+ let selectedRole = roles[0][0];
439
+
440
+ for (const [role, probability] of roles) {
441
+ cumulative += probability;
442
+ if (rand <= cumulative) {
443
+ selectedRole = role;
444
+ break;
445
+ }
446
+ }
447
+
448
+ users.push({
449
+ id: faker.string.uuid(),
450
+ email: faker.internet.email(),
451
+ name: faker.person.fullName(),
452
+ role: selectedRole,
453
+ createdAt: faker.date.past({ years: 2 }),
454
+ });
455
+ }
456
+
457
+ return users;
458
+ },
459
+
460
+ /**
461
+ * Generate time-series data
462
+ */
463
+ timeSeries(
464
+ startDate: Date,
465
+ endDate: Date,
466
+ intervalMs: number,
467
+ valueGenerator: () => number,
468
+ ) {
469
+ const data: { timestamp: Date; value: number }[] = [];
470
+ let current = new Date(startDate);
471
+
472
+ while (current <= endDate) {
473
+ data.push({
474
+ timestamp: new Date(current),
475
+ value: valueGenerator(),
476
+ });
477
+ current = new Date(current.getTime() + intervalMs);
478
+ }
479
+
480
+ return data;
481
+ },
482
+
483
+ /**
484
+ * Generate hierarchical data (e.g., categories, org structure)
485
+ */
486
+ hierarchy<T extends { id: string; parentId: string | null }>(
487
+ depth: number,
488
+ childrenPerNode: number,
489
+ nodeGenerator: (level: number, parentId: string | null) => Omit<T, 'id' | 'parentId'>,
490
+ ): T[] {
491
+ const nodes: T[] = [];
492
+
493
+ function generateLevel(level: number, parentId: string | null): void {
494
+ if (level >= depth) return;
495
+
496
+ const count = level === 0 ? Math.ceil(childrenPerNode / 2) : childrenPerNode;
497
+
498
+ for (let i = 0; i < count; i++) {
499
+ const id = faker.string.uuid();
500
+ const node = {
501
+ id,
502
+ parentId,
503
+ ...nodeGenerator(level, parentId),
504
+ } as T;
505
+
506
+ nodes.push(node);
507
+ generateLevel(level + 1, id);
508
+ }
509
+ }
510
+
511
+ generateLevel(0, null);
512
+ return nodes;
513
+ },
514
+ };
515
+ `;
516
+ fs.writeFileSync(path.join(baseDir, 'fixture-factory.ts'), fixtureFactoryContent);
517
+ // Example seeder
518
+ const exampleSeederContent = `import { Injectable } from '@nestjs/common';
519
+ import { SeedRunner, SeedContext } from './seed-runner';
520
+ import { FixtureFactory, SeedDataGenerators } from './fixture-factory';
521
+
522
+ /**
523
+ * Example seeder for ${pascalName}
524
+ */
525
+ @Injectable()
526
+ export class ${pascalName}Seeder {
527
+ static readonly config = {
528
+ name: '${camelName}Seeder',
529
+ priority: 10,
530
+ environments: ['development', 'test', 'staging'],
531
+ dependencies: [], // Add dependencies here
532
+ };
533
+
534
+ constructor(private readonly seedRunner: SeedRunner) {
535
+ this.seedRunner.register(this);
536
+ }
537
+
538
+ /**
539
+ * Check if seeder should run
540
+ */
541
+ async shouldRun(context: SeedContext): Promise<boolean> {
542
+ // Example: Check if data already exists
543
+ // const count = await context.entityManager.count(${pascalName}Entity);
544
+ // return count === 0;
545
+ return true;
546
+ }
547
+
548
+ /**
549
+ * Run the seeder
550
+ */
551
+ async run(context: SeedContext): Promise<void> {
552
+ context.logger.log('Seeding ${pascalName} data...');
553
+
554
+ // Generate seed data
555
+ const items = FixtureFactory.createMany('${camelName}', 50);
556
+
557
+ // Insert data
558
+ // await context.entityManager.save(${pascalName}Entity, items);
559
+
560
+ // Store reference for dependent seeders
561
+ context.data.set('${camelName}Ids', items.map(i => i.id));
562
+
563
+ context.logger.log(\`Seeded \${items.length} ${camelName} records\`);
564
+ }
565
+
566
+ /**
567
+ * Rollback the seeder
568
+ */
569
+ async rollback(context: SeedContext): Promise<void> {
570
+ context.logger.log('Rolling back ${pascalName} data...');
571
+
572
+ // Delete seeded data
573
+ // await context.entityManager.delete(${pascalName}Entity, {});
574
+
575
+ context.data.delete('${camelName}Ids');
576
+ }
577
+ }
578
+
579
+ /**
580
+ * Reference data seeder (static/lookup data)
581
+ */
582
+ @Injectable()
583
+ export class ReferenceDataSeeder {
584
+ static readonly config = {
585
+ name: 'referenceDataSeeder',
586
+ priority: 1, // Run first
587
+ environments: ['*'], // All environments
588
+ };
589
+
590
+ constructor(private readonly seedRunner: SeedRunner) {
591
+ this.seedRunner.register(this);
592
+ }
593
+
594
+ async run(context: SeedContext): Promise<void> {
595
+ context.logger.log('Seeding reference data...');
596
+
597
+ // Example: Seed status types, categories, etc.
598
+ const statuses = [
599
+ { code: 'ACTIVE', name: 'Active', order: 1 },
600
+ { code: 'INACTIVE', name: 'Inactive', order: 2 },
601
+ { code: 'PENDING', name: 'Pending', order: 3 },
602
+ { code: 'ARCHIVED', name: 'Archived', order: 4 },
603
+ ];
604
+
605
+ // await context.entityManager.upsert(StatusEntity, statuses, ['code']);
606
+
607
+ context.data.set('statuses', statuses);
608
+ }
609
+ }
610
+ `;
611
+ fs.writeFileSync(path.join(baseDir, `${kebabName}.seeder.ts`), exampleSeederContent);
612
+ console.log(chalk_1.default.green(` ✓ Created seed runner`));
613
+ console.log(chalk_1.default.green(` ✓ Created fixture factory`));
614
+ console.log(chalk_1.default.green(` ✓ Created ${kebabName}.seeder.ts`));
615
+ console.log(chalk_1.default.bold.green(`\n✅ Database seeding setup complete for ${pascalName}`));
616
+ console.log(chalk_1.default.cyan(`Generated files in: ${baseDir}`));
617
+ console.log(chalk_1.default.gray(' - seed-runner.ts (Seeder orchestration)'));
618
+ console.log(chalk_1.default.gray(' - fixture-factory.ts (Test data generation)'));
619
+ console.log(chalk_1.default.gray(` - ${kebabName}.seeder.ts (Example seeder)`));
620
+ }
621
+ //# sourceMappingURL=database-seeding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-seeding.js","sourceRoot":"","sources":["../../src/commands/database-seeding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface DbOptimizationOptions {
2
+ module?: string;
3
+ orm?: 'typeorm' | 'prisma' | 'mikro-orm';
4
+ includeDataLoader?: boolean;
5
+ includeQueryAnalyzer?: boolean;
6
+ }
7
+ export declare function setupDbOptimization(basePath: string, options?: DbOptimizationOptions): Promise<void>;