nestjs-ddd-cli 2.2.0 → 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 +26 -3
  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,655 @@
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.setupHealthProbesAdvanced = setupHealthProbesAdvanced;
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 setupHealthProbesAdvanced(basePath, options = {}) {
45
+ console.log(chalk_1.default.bold.blue('\n🏥 Setting up Advanced Health Probes\n'));
46
+ const moduleName = options.module || 'shared';
47
+ const pascalName = (0, naming_utils_1.toPascalCase)(moduleName);
48
+ const kebabName = (0, naming_utils_1.toKebabCase)(moduleName);
49
+ const dependencies = options.dependencies || ['database', 'redis', 'external-api'];
50
+ const includeKubernetes = options.includeKubernetes !== false;
51
+ const baseDir = path.join(basePath, 'src', kebabName, 'infrastructure', 'health');
52
+ fs.mkdirSync(baseDir, { recursive: true });
53
+ // Health indicator registry
54
+ const healthRegistryContent = `import { Injectable, Logger } from '@nestjs/common';
55
+ import { HealthIndicator, HealthIndicatorResult, HealthCheckError } from '@nestjs/terminus';
56
+
57
+ export type HealthStatus = 'healthy' | 'degraded' | 'unhealthy';
58
+
59
+ export interface DependencyHealth {
60
+ name: string;
61
+ status: HealthStatus;
62
+ responseTimeMs?: number;
63
+ message?: string;
64
+ lastCheck: Date;
65
+ consecutiveFailures: number;
66
+ }
67
+
68
+ export interface HealthCheckConfig {
69
+ name: string;
70
+ critical: boolean;
71
+ timeout: number;
72
+ interval: number;
73
+ healthyThreshold: number;
74
+ unhealthyThreshold: number;
75
+ }
76
+
77
+ /**
78
+ * Custom health indicator with circuit breaker pattern
79
+ */
80
+ @Injectable()
81
+ export class DependencyHealthIndicator extends HealthIndicator {
82
+ private readonly logger = new Logger(DependencyHealthIndicator.name);
83
+ private readonly healthStates: Map<string, DependencyHealth> = new Map();
84
+ private readonly configs: Map<string, HealthCheckConfig> = new Map();
85
+
86
+ /**
87
+ * Register a dependency health check
88
+ */
89
+ registerDependency(config: HealthCheckConfig): void {
90
+ this.configs.set(config.name, config);
91
+ this.healthStates.set(config.name, {
92
+ name: config.name,
93
+ status: 'healthy',
94
+ lastCheck: new Date(),
95
+ consecutiveFailures: 0,
96
+ });
97
+ }
98
+
99
+ /**
100
+ * Check a dependency's health
101
+ */
102
+ async checkDependency(
103
+ name: string,
104
+ checkFn: () => Promise<boolean>,
105
+ ): Promise<HealthIndicatorResult> {
106
+ const config = this.configs.get(name);
107
+ const state = this.healthStates.get(name);
108
+
109
+ if (!config || !state) {
110
+ throw new HealthCheckError(
111
+ \`Dependency \${name} not registered\`,
112
+ this.getStatus(name, false),
113
+ );
114
+ }
115
+
116
+ const startTime = Date.now();
117
+
118
+ try {
119
+ // Add timeout to health check
120
+ const result = await Promise.race([
121
+ checkFn(),
122
+ new Promise<boolean>((_, reject) =>
123
+ setTimeout(() => reject(new Error('Health check timeout')), config.timeout),
124
+ ),
125
+ ]);
126
+
127
+ const responseTime = Date.now() - startTime;
128
+
129
+ if (result) {
130
+ state.consecutiveFailures = 0;
131
+ state.status = 'healthy';
132
+ state.responseTimeMs = responseTime;
133
+ state.message = undefined;
134
+ state.lastCheck = new Date();
135
+
136
+ return this.getStatus(name, true, { responseTimeMs: responseTime });
137
+ } else {
138
+ throw new Error('Health check returned false');
139
+ }
140
+ } catch (error) {
141
+ state.consecutiveFailures++;
142
+ state.lastCheck = new Date();
143
+ state.message = error instanceof Error ? error.message : 'Unknown error';
144
+ state.responseTimeMs = Date.now() - startTime;
145
+
146
+ // Determine status based on consecutive failures
147
+ if (state.consecutiveFailures >= config.unhealthyThreshold) {
148
+ state.status = 'unhealthy';
149
+ } else if (state.consecutiveFailures >= Math.ceil(config.unhealthyThreshold / 2)) {
150
+ state.status = 'degraded';
151
+ }
152
+
153
+ this.logger.warn(
154
+ \`Health check failed for \${name}: \${state.message} (failures: \${state.consecutiveFailures})\`,
155
+ );
156
+
157
+ if (config.critical && state.status === 'unhealthy') {
158
+ throw new HealthCheckError(
159
+ \`Critical dependency \${name} is unhealthy\`,
160
+ this.getStatus(name, false, { error: state.message }),
161
+ );
162
+ }
163
+
164
+ return this.getStatus(name, state.status !== 'unhealthy', {
165
+ status: state.status,
166
+ error: state.message,
167
+ consecutiveFailures: state.consecutiveFailures,
168
+ });
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Get all dependency health states
174
+ */
175
+ getAllHealthStates(): DependencyHealth[] {
176
+ return Array.from(this.healthStates.values());
177
+ }
178
+
179
+ /**
180
+ * Get overall health status
181
+ */
182
+ getOverallStatus(): HealthStatus {
183
+ const states = this.getAllHealthStates();
184
+
185
+ if (states.some((s) => s.status === 'unhealthy')) {
186
+ return 'unhealthy';
187
+ }
188
+ if (states.some((s) => s.status === 'degraded')) {
189
+ return 'degraded';
190
+ }
191
+ return 'healthy';
192
+ }
193
+ }
194
+
195
+ /**
196
+ * Database health indicator
197
+ */
198
+ @Injectable()
199
+ export class DatabaseHealthIndicator extends HealthIndicator {
200
+ async check(key: string, pingFn: () => Promise<boolean>): Promise<HealthIndicatorResult> {
201
+ try {
202
+ const isHealthy = await pingFn();
203
+ return this.getStatus(key, isHealthy);
204
+ } catch (error) {
205
+ throw new HealthCheckError(
206
+ \`Database \${key} health check failed\`,
207
+ this.getStatus(key, false, { error: error instanceof Error ? error.message : 'Unknown' }),
208
+ );
209
+ }
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Memory health indicator
215
+ */
216
+ @Injectable()
217
+ export class MemoryHealthIndicator extends HealthIndicator {
218
+ check(
219
+ key: string,
220
+ options: { heapUsedThreshold: number; rssThreshold: number },
221
+ ): HealthIndicatorResult {
222
+ const memUsage = process.memoryUsage();
223
+ const heapUsedMB = memUsage.heapUsed / 1024 / 1024;
224
+ const rssMB = memUsage.rss / 1024 / 1024;
225
+
226
+ const isHealthy = heapUsedMB < options.heapUsedThreshold && rssMB < options.rssThreshold;
227
+
228
+ return this.getStatus(key, isHealthy, {
229
+ heapUsedMB: Math.round(heapUsedMB),
230
+ rssMB: Math.round(rssMB),
231
+ heapTotalMB: Math.round(memUsage.heapTotal / 1024 / 1024),
232
+ });
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Disk health indicator
238
+ */
239
+ @Injectable()
240
+ export class DiskHealthIndicator extends HealthIndicator {
241
+ async check(
242
+ key: string,
243
+ options: { path: string; thresholdPercent: number },
244
+ ): Promise<HealthIndicatorResult> {
245
+ // This is a placeholder - in production, use a library like 'diskusage'
246
+ // or call df command
247
+ return this.getStatus(key, true, {
248
+ path: options.path,
249
+ threshold: options.thresholdPercent,
250
+ });
251
+ }
252
+ }
253
+ `;
254
+ fs.writeFileSync(path.join(baseDir, 'health-indicators.ts'), healthRegistryContent);
255
+ // Health controller with Kubernetes probes
256
+ const healthControllerContent = `import { Controller, Get, HttpCode, HttpStatus, Res } from '@nestjs/common';
257
+ import { Response } from 'express';
258
+ import {
259
+ HealthCheck,
260
+ HealthCheckService,
261
+ HealthCheckResult,
262
+ } from '@nestjs/terminus';
263
+ import {
264
+ DependencyHealthIndicator,
265
+ DatabaseHealthIndicator,
266
+ MemoryHealthIndicator,
267
+ HealthStatus,
268
+ } from './health-indicators';
269
+
270
+ interface ProbeResponse {
271
+ status: HealthStatus;
272
+ timestamp: string;
273
+ uptime: number;
274
+ checks?: Record<string, any>;
275
+ }
276
+
277
+ /**
278
+ * Health check controller with Kubernetes probe support
279
+ */
280
+ @Controller('health')
281
+ export class HealthController {
282
+ private startTime: Date;
283
+ private ready: boolean = false;
284
+
285
+ constructor(
286
+ private readonly health: HealthCheckService,
287
+ private readonly dependencyHealth: DependencyHealthIndicator,
288
+ private readonly dbHealth: DatabaseHealthIndicator,
289
+ private readonly memoryHealth: MemoryHealthIndicator,
290
+ ) {
291
+ this.startTime = new Date();
292
+ }
293
+
294
+ /**
295
+ * Liveness probe - Is the application running?
296
+ * Returns 200 if the process is alive, regardless of dependency health
297
+ */
298
+ @Get('live')
299
+ @HttpCode(HttpStatus.OK)
300
+ async liveness(@Res() res: Response): Promise<void> {
301
+ const response: ProbeResponse = {
302
+ status: 'healthy',
303
+ timestamp: new Date().toISOString(),
304
+ uptime: this.getUptimeSeconds(),
305
+ };
306
+
307
+ res.status(HttpStatus.OK).json(response);
308
+ }
309
+
310
+ /**
311
+ * Readiness probe - Is the application ready to receive traffic?
312
+ * Returns 200 only if all critical dependencies are healthy
313
+ */
314
+ @Get('ready')
315
+ async readiness(@Res() res: Response): Promise<void> {
316
+ const checks = this.dependencyHealth.getAllHealthStates();
317
+ const overallStatus = this.dependencyHealth.getOverallStatus();
318
+
319
+ const response: ProbeResponse = {
320
+ status: overallStatus,
321
+ timestamp: new Date().toISOString(),
322
+ uptime: this.getUptimeSeconds(),
323
+ checks: checks.reduce((acc, check) => {
324
+ acc[check.name] = {
325
+ status: check.status,
326
+ responseTimeMs: check.responseTimeMs,
327
+ lastCheck: check.lastCheck,
328
+ };
329
+ return acc;
330
+ }, {} as Record<string, any>),
331
+ };
332
+
333
+ const httpStatus = overallStatus === 'unhealthy'
334
+ ? HttpStatus.SERVICE_UNAVAILABLE
335
+ : HttpStatus.OK;
336
+
337
+ res.status(httpStatus).json(response);
338
+ }
339
+
340
+ /**
341
+ * Startup probe - Has the application finished initialization?
342
+ * Kubernetes uses this to know when to start liveness/readiness checks
343
+ */
344
+ @Get('startup')
345
+ async startup(@Res() res: Response): Promise<void> {
346
+ const response: ProbeResponse = {
347
+ status: this.ready ? 'healthy' : 'unhealthy',
348
+ timestamp: new Date().toISOString(),
349
+ uptime: this.getUptimeSeconds(),
350
+ };
351
+
352
+ const httpStatus = this.ready
353
+ ? HttpStatus.OK
354
+ : HttpStatus.SERVICE_UNAVAILABLE;
355
+
356
+ res.status(httpStatus).json(response);
357
+ }
358
+
359
+ /**
360
+ * Mark application as ready (call after initialization)
361
+ */
362
+ markReady(): void {
363
+ this.ready = true;
364
+ }
365
+
366
+ /**
367
+ * Mark application as not ready (e.g., during graceful shutdown)
368
+ */
369
+ markNotReady(): void {
370
+ this.ready = false;
371
+ }
372
+
373
+ /**
374
+ * Detailed health check with all indicators
375
+ */
376
+ @Get()
377
+ @HealthCheck()
378
+ async check(): Promise<HealthCheckResult> {
379
+ return this.health.check([
380
+ // Memory check
381
+ () => this.memoryHealth.check('memory', {
382
+ heapUsedThreshold: 500, // MB
383
+ rssThreshold: 1000, // MB
384
+ }),
385
+ // Add more checks here
386
+ ]);
387
+ }
388
+
389
+ /**
390
+ * Deep health check - checks all dependencies
391
+ */
392
+ @Get('deep')
393
+ async deepCheck(@Res() res: Response): Promise<void> {
394
+ const startTime = Date.now();
395
+ const checks = this.dependencyHealth.getAllHealthStates();
396
+ const overallStatus = this.dependencyHealth.getOverallStatus();
397
+
398
+ const response = {
399
+ status: overallStatus,
400
+ timestamp: new Date().toISOString(),
401
+ uptime: this.getUptimeSeconds(),
402
+ checkDurationMs: Date.now() - startTime,
403
+ dependencies: checks.map((check) => ({
404
+ name: check.name,
405
+ status: check.status,
406
+ responseTimeMs: check.responseTimeMs,
407
+ message: check.message,
408
+ lastCheck: check.lastCheck,
409
+ consecutiveFailures: check.consecutiveFailures,
410
+ })),
411
+ system: {
412
+ memory: process.memoryUsage(),
413
+ cpu: process.cpuUsage(),
414
+ nodeVersion: process.version,
415
+ pid: process.pid,
416
+ },
417
+ };
418
+
419
+ const httpStatus = overallStatus === 'unhealthy'
420
+ ? HttpStatus.SERVICE_UNAVAILABLE
421
+ : HttpStatus.OK;
422
+
423
+ res.status(httpStatus).json(response);
424
+ }
425
+
426
+ private getUptimeSeconds(): number {
427
+ return Math.floor((Date.now() - this.startTime.getTime()) / 1000);
428
+ }
429
+ }
430
+ `;
431
+ fs.writeFileSync(path.join(baseDir, 'health.controller.ts'), healthControllerContent);
432
+ // Graceful shutdown handler
433
+ const gracefulShutdownContent = `import { Injectable, Logger, OnModuleDestroy, OnApplicationShutdown } from '@nestjs/common';
434
+ import { HealthController } from './health.controller';
435
+
436
+ interface ShutdownHook {
437
+ name: string;
438
+ priority: number;
439
+ handler: () => Promise<void>;
440
+ }
441
+
442
+ /**
443
+ * Graceful shutdown manager for Kubernetes
444
+ */
445
+ @Injectable()
446
+ export class GracefulShutdownService implements OnModuleDestroy, OnApplicationShutdown {
447
+ private readonly logger = new Logger(GracefulShutdownService.name);
448
+ private readonly hooks: ShutdownHook[] = [];
449
+ private isShuttingDown: boolean = false;
450
+ private readonly shutdownTimeout: number;
451
+ private readonly preShutdownWait: number;
452
+
453
+ constructor(private readonly healthController: HealthController) {
454
+ this.shutdownTimeout = parseInt(process.env.SHUTDOWN_TIMEOUT_MS || '30000', 10);
455
+ this.preShutdownWait = parseInt(process.env.PRE_SHUTDOWN_WAIT_MS || '5000', 10);
456
+
457
+ // Handle process signals
458
+ process.on('SIGTERM', () => this.handleSignal('SIGTERM'));
459
+ process.on('SIGINT', () => this.handleSignal('SIGINT'));
460
+ }
461
+
462
+ /**
463
+ * Register a shutdown hook
464
+ */
465
+ registerHook(name: string, handler: () => Promise<void>, priority: number = 10): void {
466
+ this.hooks.push({ name, handler, priority });
467
+ this.hooks.sort((a, b) => a.priority - b.priority);
468
+ }
469
+
470
+ /**
471
+ * Handle shutdown signal
472
+ */
473
+ private async handleSignal(signal: string): Promise<void> {
474
+ if (this.isShuttingDown) {
475
+ this.logger.warn(\`Already shutting down, ignoring \${signal}\`);
476
+ return;
477
+ }
478
+
479
+ this.isShuttingDown = true;
480
+ this.logger.log(\`Received \${signal}, starting graceful shutdown...\`);
481
+
482
+ // Mark as not ready immediately
483
+ this.healthController.markNotReady();
484
+
485
+ // Wait for in-flight requests to complete
486
+ this.logger.log(\`Waiting \${this.preShutdownWait}ms for in-flight requests...\`);
487
+ await this.sleep(this.preShutdownWait);
488
+
489
+ // Run shutdown hooks with timeout
490
+ await this.runHooksWithTimeout();
491
+
492
+ this.logger.log('Graceful shutdown complete');
493
+ process.exit(0);
494
+ }
495
+
496
+ /**
497
+ * Run all hooks with overall timeout
498
+ */
499
+ private async runHooksWithTimeout(): Promise<void> {
500
+ const timeoutPromise = new Promise<void>((_, reject) => {
501
+ setTimeout(() => reject(new Error('Shutdown timeout exceeded')), this.shutdownTimeout);
502
+ });
503
+
504
+ try {
505
+ await Promise.race([this.runHooks(), timeoutPromise]);
506
+ } catch (error) {
507
+ this.logger.error(\`Shutdown error: \${error}\`);
508
+ }
509
+ }
510
+
511
+ /**
512
+ * Run all registered hooks
513
+ */
514
+ private async runHooks(): Promise<void> {
515
+ for (const hook of this.hooks) {
516
+ try {
517
+ this.logger.log(\`Running shutdown hook: \${hook.name}\`);
518
+ await hook.handler();
519
+ this.logger.log(\`Completed shutdown hook: \${hook.name}\`);
520
+ } catch (error) {
521
+ this.logger.error(\`Shutdown hook \${hook.name} failed: \${error}\`);
522
+ }
523
+ }
524
+ }
525
+
526
+ /**
527
+ * NestJS lifecycle hook
528
+ */
529
+ async onModuleDestroy(): Promise<void> {
530
+ this.logger.log('Module destroying...');
531
+ }
532
+
533
+ /**
534
+ * NestJS lifecycle hook
535
+ */
536
+ async onApplicationShutdown(signal?: string): Promise<void> {
537
+ this.logger.log(\`Application shutdown: \${signal}\`);
538
+ }
539
+
540
+ private sleep(ms: number): Promise<void> {
541
+ return new Promise((resolve) => setTimeout(resolve, ms));
542
+ }
543
+ }
544
+ `;
545
+ fs.writeFileSync(path.join(baseDir, 'graceful-shutdown.service.ts'), gracefulShutdownContent);
546
+ // Kubernetes configuration examples
547
+ if (includeKubernetes) {
548
+ const k8sConfigContent = `# Kubernetes Health Probe Configuration
549
+ # Add these to your deployment spec
550
+
551
+ # Example deployment.yaml probes configuration:
552
+ #
553
+ # spec:
554
+ # containers:
555
+ # - name: ${kebabName}
556
+ # livenessProbe:
557
+ # httpGet:
558
+ # path: /health/live
559
+ # port: 3000
560
+ # initialDelaySeconds: 10
561
+ # periodSeconds: 10
562
+ # timeoutSeconds: 5
563
+ # failureThreshold: 3
564
+ #
565
+ # readinessProbe:
566
+ # httpGet:
567
+ # path: /health/ready
568
+ # port: 3000
569
+ # initialDelaySeconds: 5
570
+ # periodSeconds: 5
571
+ # timeoutSeconds: 3
572
+ # failureThreshold: 3
573
+ #
574
+ # startupProbe:
575
+ # httpGet:
576
+ # path: /health/startup
577
+ # port: 3000
578
+ # initialDelaySeconds: 0
579
+ # periodSeconds: 5
580
+ # timeoutSeconds: 3
581
+ # failureThreshold: 30 # 30 * 5s = 150s max startup time
582
+ #
583
+ # Environment variables for graceful shutdown:
584
+ # - name: SHUTDOWN_TIMEOUT_MS
585
+ # value: "30000"
586
+ # - name: PRE_SHUTDOWN_WAIT_MS
587
+ # value: "5000"
588
+ #
589
+ # Lifecycle hooks for graceful shutdown:
590
+ # lifecycle:
591
+ # preStop:
592
+ # exec:
593
+ # command: ["sh", "-c", "sleep 5"] # Allow time for service mesh to drain
594
+ #
595
+ # Pod disruption budget (optional):
596
+ # apiVersion: policy/v1
597
+ # kind: PodDisruptionBudget
598
+ # metadata:
599
+ # name: ${kebabName}-pdb
600
+ # spec:
601
+ # minAvailable: 1
602
+ # selector:
603
+ # matchLabels:
604
+ # app: ${kebabName}
605
+ `;
606
+ fs.writeFileSync(path.join(baseDir, 'k8s-probes.yaml'), k8sConfigContent);
607
+ }
608
+ // Health module
609
+ const healthModuleContent = `import { Module } from '@nestjs/common';
610
+ import { TerminusModule } from '@nestjs/terminus';
611
+ import { HealthController } from './health.controller';
612
+ import {
613
+ DependencyHealthIndicator,
614
+ DatabaseHealthIndicator,
615
+ MemoryHealthIndicator,
616
+ DiskHealthIndicator,
617
+ } from './health-indicators';
618
+ import { GracefulShutdownService } from './graceful-shutdown.service';
619
+
620
+ @Module({
621
+ imports: [TerminusModule],
622
+ controllers: [HealthController],
623
+ providers: [
624
+ DependencyHealthIndicator,
625
+ DatabaseHealthIndicator,
626
+ MemoryHealthIndicator,
627
+ DiskHealthIndicator,
628
+ GracefulShutdownService,
629
+ ],
630
+ exports: [
631
+ DependencyHealthIndicator,
632
+ GracefulShutdownService,
633
+ ],
634
+ })
635
+ export class ${pascalName}HealthModule {}
636
+ `;
637
+ fs.writeFileSync(path.join(baseDir, 'health.module.ts'), healthModuleContent);
638
+ console.log(chalk_1.default.green(` ✓ Created health indicators`));
639
+ console.log(chalk_1.default.green(` ✓ Created health controller`));
640
+ console.log(chalk_1.default.green(` ✓ Created graceful shutdown service`));
641
+ console.log(chalk_1.default.green(` ✓ Created health module`));
642
+ if (includeKubernetes) {
643
+ console.log(chalk_1.default.green(` ✓ Created Kubernetes configuration`));
644
+ }
645
+ console.log(chalk_1.default.bold.green(`\n✅ Advanced health probes setup complete for ${pascalName}`));
646
+ console.log(chalk_1.default.cyan(`Generated files in: ${baseDir}`));
647
+ console.log(chalk_1.default.gray(' - health-indicators.ts (Custom health indicators)'));
648
+ console.log(chalk_1.default.gray(' - health.controller.ts (K8s probe endpoints)'));
649
+ console.log(chalk_1.default.gray(' - graceful-shutdown.service.ts (Graceful shutdown)'));
650
+ console.log(chalk_1.default.gray(' - health.module.ts (Health module)'));
651
+ if (includeKubernetes) {
652
+ console.log(chalk_1.default.gray(' - k8s-probes.yaml (Kubernetes configuration)'));
653
+ }
654
+ }
655
+ //# sourceMappingURL=health-probes-advanced.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-probes-advanced.js","sourceRoot":"","sources":["../../src/commands/health-probes-advanced.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Internationalization (i18n) & Localization Engine Generator
3
+ * Generates comprehensive i18n infrastructure
4
+ */
5
+ export interface I18nOptions {
6
+ path?: string;
7
+ defaultLocale?: string;
8
+ supportedLocales?: string[];
9
+ }
10
+ export declare function setupI18n(basePath: string, options?: I18nOptions): Promise<void>;