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,315 @@
1
+ "use strict";
2
+ /**
3
+ * Security utilities for the CLI
4
+ * Implements OWASP-recommended practices for input validation and path safety
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.validateSafePath = validateSafePath;
41
+ exports.sanitizeEntityName = sanitizeEntityName;
42
+ exports.validateFieldName = validateFieldName;
43
+ exports.sanitizeShellInput = sanitizeShellInput;
44
+ exports.validateNumericInput = validateNumericInput;
45
+ exports.sanitizeHtmlOutput = sanitizeHtmlOutput;
46
+ exports.maskSensitiveData = maskSensitiveData;
47
+ exports.validateUrl = validateUrl;
48
+ exports.createRateLimitKey = createRateLimitKey;
49
+ exports.safeJsonParse = safeJsonParse;
50
+ const path = __importStar(require("path"));
51
+ /**
52
+ * Validates that a path does not escape the base directory
53
+ * Prevents path traversal attacks (OWASP A01:2021)
54
+ */
55
+ function validateSafePath(basePath, targetPath) {
56
+ const resolvedBase = path.resolve(basePath);
57
+ const resolvedTarget = path.resolve(basePath, targetPath);
58
+ if (!resolvedTarget.startsWith(resolvedBase + path.sep) && resolvedTarget !== resolvedBase) {
59
+ throw new Error(`Security: Path traversal detected in "${targetPath}"`);
60
+ }
61
+ return resolvedTarget;
62
+ }
63
+ /**
64
+ * Sanitizes entity/module names for safe file system operations
65
+ * Prevents directory traversal and special character injection
66
+ */
67
+ function sanitizeEntityName(name) {
68
+ if (!name || typeof name !== 'string') {
69
+ throw new Error('Security: Entity name must be a non-empty string');
70
+ }
71
+ // Remove any path separators, dots (for traversal), and special characters
72
+ const sanitized = name
73
+ .replace(/\.{2,}/g, '') // Remove consecutive dots (path traversal)
74
+ .replace(/[\/\\]/g, '') // Remove path separators
75
+ .replace(/[<>:"|?*\x00-\x1f]/g, '') // Remove invalid filename chars
76
+ .replace(/^[\s.-]+|[\s.-]+$/g, '') // Trim leading/trailing dots, spaces, hyphens
77
+ .trim();
78
+ if (sanitized.length === 0) {
79
+ throw new Error(`Security: Invalid entity name after sanitization: "${name}"`);
80
+ }
81
+ if (sanitized.length > 100) {
82
+ throw new Error(`Security: Entity name exceeds maximum length (100): "${name}"`);
83
+ }
84
+ // Block common injection patterns
85
+ const dangerousPatterns = [
86
+ /^(con|prn|aux|nul|com[0-9]|lpt[0-9])$/i, // Windows reserved names
87
+ /[\x00-\x1f]/g, // Control characters
88
+ /__proto__|constructor|prototype/i, // Prototype pollution
89
+ ];
90
+ for (const pattern of dangerousPatterns) {
91
+ if (pattern.test(sanitized)) {
92
+ throw new Error(`Security: Entity name contains dangerous pattern: "${name}"`);
93
+ }
94
+ }
95
+ return sanitized;
96
+ }
97
+ /**
98
+ * Validates that field names are safe for use in SQL/ORM queries
99
+ * Only allows alphanumeric characters and underscores, starting with letter
100
+ */
101
+ function validateFieldName(fieldName, allowedFields) {
102
+ if (!fieldName || typeof fieldName !== 'string') {
103
+ throw new Error('Security: Field name must be a non-empty string');
104
+ }
105
+ // If allowed fields list provided, strict whitelist validation
106
+ if (allowedFields && allowedFields.length > 0) {
107
+ if (!allowedFields.includes(fieldName)) {
108
+ throw new Error(`Security: Field "${fieldName}" not in allowed list: ${allowedFields.join(', ')}`);
109
+ }
110
+ return fieldName;
111
+ }
112
+ // Pattern: must start with letter or underscore, followed by alphanumeric/underscore
113
+ const SAFE_FIELD_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
114
+ if (!SAFE_FIELD_REGEX.test(fieldName)) {
115
+ throw new Error(`Security: Invalid field name format: "${fieldName}"`);
116
+ }
117
+ if (fieldName.length > 64) {
118
+ throw new Error(`Security: Field name exceeds maximum length (64): "${fieldName}"`);
119
+ }
120
+ // Block SQL keywords as field names
121
+ const SQL_KEYWORDS = [
122
+ 'SELECT',
123
+ 'INSERT',
124
+ 'UPDATE',
125
+ 'DELETE',
126
+ 'DROP',
127
+ 'CREATE',
128
+ 'ALTER',
129
+ 'TRUNCATE',
130
+ 'GRANT',
131
+ 'REVOKE',
132
+ 'UNION',
133
+ 'WHERE',
134
+ 'FROM',
135
+ 'JOIN',
136
+ 'OR',
137
+ 'AND',
138
+ 'NOT',
139
+ 'NULL',
140
+ 'TRUE',
141
+ 'FALSE',
142
+ 'EXEC',
143
+ 'EXECUTE',
144
+ 'XP_',
145
+ 'SP_',
146
+ ];
147
+ if (SQL_KEYWORDS.includes(fieldName.toUpperCase())) {
148
+ throw new Error(`Security: Field name "${fieldName}" is a reserved SQL keyword`);
149
+ }
150
+ return fieldName;
151
+ }
152
+ /**
153
+ * Sanitizes input for use in shell commands
154
+ * Implements whitelist approach - only allows safe characters
155
+ */
156
+ function sanitizeShellInput(input) {
157
+ if (!input || typeof input !== 'string') {
158
+ throw new Error('Security: Shell input must be a non-empty string');
159
+ }
160
+ // Strict whitelist: only alphanumeric, hyphen, underscore, dot, forward slash
161
+ // (for paths within allowed directories)
162
+ const SAFE_SHELL_REGEX = /^[a-zA-Z0-9_\-./]+$/;
163
+ if (!SAFE_SHELL_REGEX.test(input)) {
164
+ // Instead of throwing, sanitize by removing unsafe characters
165
+ const sanitized = input.replace(/[^a-zA-Z0-9_\-./]/g, '');
166
+ if (sanitized.length === 0) {
167
+ throw new Error('Security: Shell input contains only disallowed characters');
168
+ }
169
+ return sanitized;
170
+ }
171
+ // Block command injection patterns
172
+ if (/\.\./g.test(input)) {
173
+ throw new Error('Security: Shell input contains path traversal');
174
+ }
175
+ return input;
176
+ }
177
+ /**
178
+ * Validates numeric input is within safe bounds
179
+ */
180
+ function validateNumericInput(value, options = {}) {
181
+ const { min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER, allowNegative = true, allowZero = true } = options;
182
+ if (typeof value !== 'number' || isNaN(value) || !isFinite(value)) {
183
+ throw new Error(`Security: Invalid numeric value: ${value}`);
184
+ }
185
+ if (!allowNegative && value < 0) {
186
+ throw new Error(`Security: Negative values not allowed: ${value}`);
187
+ }
188
+ if (!allowZero && value === 0) {
189
+ throw new Error('Security: Zero value not allowed');
190
+ }
191
+ if (value < min || value > max) {
192
+ throw new Error(`Security: Value ${value} out of range [${min}, ${max}]`);
193
+ }
194
+ return value;
195
+ }
196
+ /**
197
+ * Sanitizes string for safe HTML output
198
+ * Prevents XSS attacks (OWASP A03:2021)
199
+ */
200
+ function sanitizeHtmlOutput(input) {
201
+ if (!input || typeof input !== 'string') {
202
+ return '';
203
+ }
204
+ const htmlEntities = {
205
+ '&': '&amp;',
206
+ '<': '&lt;',
207
+ '>': '&gt;',
208
+ '"': '&quot;',
209
+ "'": '&#x27;',
210
+ '/': '&#x2F;',
211
+ '`': '&#x60;',
212
+ '=': '&#x3D;',
213
+ };
214
+ return input.replace(/[&<>"'/`=]/g, (char) => htmlEntities[char] || char);
215
+ }
216
+ /**
217
+ * Masks sensitive data in strings (API keys, passwords, etc.)
218
+ * For safe logging
219
+ */
220
+ function maskSensitiveData(input) {
221
+ if (!input || typeof input !== 'string') {
222
+ return '[EMPTY]';
223
+ }
224
+ if (input.length <= 8) {
225
+ return '****';
226
+ }
227
+ // Show first 4 and last 4 characters
228
+ return `${input.substring(0, 4)}${'*'.repeat(Math.min(input.length - 8, 20))}${input.substring(input.length - 4)}`;
229
+ }
230
+ /**
231
+ * Validates URL is safe and uses allowed protocols
232
+ */
233
+ function validateUrl(url, allowedProtocols = ['https:', 'http:']) {
234
+ if (!url || typeof url !== 'string') {
235
+ throw new Error('Security: URL must be a non-empty string');
236
+ }
237
+ let parsed;
238
+ try {
239
+ parsed = new URL(url);
240
+ }
241
+ catch {
242
+ throw new Error(`Security: Invalid URL format: ${url}`);
243
+ }
244
+ if (!allowedProtocols.includes(parsed.protocol)) {
245
+ throw new Error(`Security: URL protocol "${parsed.protocol}" not allowed. Allowed: ${allowedProtocols.join(', ')}`);
246
+ }
247
+ // Block localhost and internal IPs in production
248
+ const hostname = parsed.hostname.toLowerCase();
249
+ const blockedHostPatterns = [
250
+ /^localhost$/i,
251
+ /^127\./,
252
+ /^10\./,
253
+ /^172\.(1[6-9]|2[0-9]|3[01])\./,
254
+ /^192\.168\./,
255
+ /^0\.0\.0\.0$/,
256
+ /^\[::1\]$/,
257
+ /^metadata\.google\.internal$/,
258
+ /^169\.254\./,
259
+ ];
260
+ if (process.env.NODE_ENV === 'production') {
261
+ for (const pattern of blockedHostPatterns) {
262
+ if (pattern.test(hostname)) {
263
+ throw new Error(`Security: URL hostname "${hostname}" blocked in production`);
264
+ }
265
+ }
266
+ }
267
+ return url;
268
+ }
269
+ /**
270
+ * Creates a rate limit key from request data
271
+ * Sanitizes to prevent key injection
272
+ */
273
+ function createRateLimitKey(prefix, identifier) {
274
+ const sanitizedPrefix = prefix.replace(/[^a-zA-Z0-9_-]/g, '');
275
+ const sanitizedIdentifier = identifier.replace(/[^a-zA-Z0-9_\-@.]/g, '').substring(0, 128);
276
+ return `${sanitizedPrefix}:${sanitizedIdentifier}`;
277
+ }
278
+ /**
279
+ * Validates JSON input for safe parsing
280
+ * Prevents prototype pollution
281
+ */
282
+ function safeJsonParse(input) {
283
+ if (!input || typeof input !== 'string') {
284
+ throw new Error('Security: JSON input must be a non-empty string');
285
+ }
286
+ // Check for potential prototype pollution patterns before parsing
287
+ if (/__proto__|constructor|prototype/.test(input)) {
288
+ throw new Error('Security: JSON contains prototype pollution attempt');
289
+ }
290
+ try {
291
+ const parsed = JSON.parse(input);
292
+ // Deep check for prototype pollution
293
+ function checkObject(obj, depth = 0) {
294
+ if (depth > 10)
295
+ return; // Limit recursion depth
296
+ if (obj && typeof obj === 'object') {
297
+ for (const key of Object.keys(obj)) {
298
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
299
+ throw new Error('Security: JSON object contains prototype pollution key');
300
+ }
301
+ checkObject(obj[key], depth + 1);
302
+ }
303
+ }
304
+ }
305
+ checkObject(parsed);
306
+ return parsed;
307
+ }
308
+ catch (error) {
309
+ if (error instanceof Error && error.message.includes('Security:')) {
310
+ throw error;
311
+ }
312
+ throw new Error(`Security: Invalid JSON: ${error.message}`);
313
+ }
314
+ }
315
+ //# sourceMappingURL=security.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.utils.js","sourceRoot":"","sources":["../../src/utils/security.utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Config-Driven Template System
3
+ * Provides template inheritance, hooks, and per-module overrides
4
+ */
5
+ import Handlebars from 'handlebars';
6
+ export interface TemplateConfig {
7
+ extends?: string;
8
+ overrides?: Record<string, string>;
9
+ hooks?: {
10
+ preGenerate?: string;
11
+ postGenerate?: string;
12
+ preCompile?: string;
13
+ postCompile?: string;
14
+ };
15
+ helpers?: Record<string, string>;
16
+ partials?: Record<string, string>;
17
+ }
18
+ export interface GenerationContext {
19
+ entityName: string;
20
+ moduleName: string;
21
+ fields: any[];
22
+ relations?: any[];
23
+ config: Record<string, any>;
24
+ options: Record<string, any>;
25
+ meta: {
26
+ timestamp: Date;
27
+ version: string;
28
+ generator: string;
29
+ };
30
+ }
31
+ export interface GenerationHook {
32
+ (context: GenerationContext): Promise<GenerationContext> | GenerationContext;
33
+ }
34
+ export interface TemplateRegistry {
35
+ templates: Map<string, CompiledTemplate>;
36
+ partials: Map<string, Handlebars.TemplateDelegate>;
37
+ helpers: Map<string, Handlebars.HelperDelegate>;
38
+ hooks: {
39
+ preGenerate: GenerationHook[];
40
+ postGenerate: GenerationHook[];
41
+ };
42
+ }
43
+ export interface CompiledTemplate {
44
+ name: string;
45
+ source: string;
46
+ compiled: Handlebars.TemplateDelegate;
47
+ config?: TemplateConfig;
48
+ }
49
+ /**
50
+ * Create a new template registry
51
+ */
52
+ export declare function createTemplateRegistry(): TemplateRegistry;
53
+ /**
54
+ * Load template from file with optional config
55
+ */
56
+ export declare function loadTemplate(registry: TemplateRegistry, templatePath: string, name?: string): CompiledTemplate;
57
+ /**
58
+ * Load all templates from a directory
59
+ */
60
+ export declare function loadTemplatesFromDirectory(registry: TemplateRegistry, dirPath: string): void;
61
+ /**
62
+ * Register a partial template
63
+ */
64
+ export declare function registerPartial(registry: TemplateRegistry, name: string, source: string): void;
65
+ /**
66
+ * Register a custom helper
67
+ */
68
+ export declare function registerHelper(registry: TemplateRegistry, name: string, helper: Handlebars.HelperDelegate): void;
69
+ /**
70
+ * Register a generation hook
71
+ */
72
+ export declare function registerHook(registry: TemplateRegistry, phase: 'preGenerate' | 'postGenerate', hook: GenerationHook): void;
73
+ /**
74
+ * Render a template with context
75
+ */
76
+ export declare function renderTemplate(registry: TemplateRegistry, templateName: string, context: GenerationContext): Promise<string>;
77
+ /**
78
+ * Create per-module template overrides
79
+ */
80
+ export declare function createModuleTemplateConfig(moduleName: string, overrides: Record<string, string>): TemplateConfig;