@evolith/smart-cli 0.0.3-beta → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/README.es.md +51 -15
  2. package/README.md +51 -15
  3. package/dist/app.module.js +2 -0
  4. package/dist/app.module.js.map +1 -1
  5. package/dist/application/ports/webhook-notifier.port.d.ts +4 -0
  6. package/dist/application/ports/webhook-notifier.port.js +3 -0
  7. package/dist/application/ports/webhook-notifier.port.js.map +1 -0
  8. package/dist/application/services/index.d.ts +1 -0
  9. package/dist/application/services/index.js +28 -2
  10. package/dist/application/services/index.js.map +1 -1
  11. package/dist/application/services/initialize-project.spec.d.ts +1 -0
  12. package/dist/application/services/initialize-project.spec.js +211 -0
  13. package/dist/application/services/initialize-project.spec.js.map +1 -0
  14. package/dist/application/use-cases/evaluate-gate.use-case.d.ts +20 -0
  15. package/dist/application/use-cases/evaluate-gate.use-case.js +72 -0
  16. package/dist/application/use-cases/evaluate-gate.use-case.js.map +1 -0
  17. package/dist/application/use-cases/validate-satellite.use-case.d.ts +1 -0
  18. package/dist/application/use-cases/validate-satellite.use-case.js +7 -3
  19. package/dist/application/use-cases/validate-satellite.use-case.js.map +1 -1
  20. package/dist/commands/adr/adr.command.d.ts +2 -0
  21. package/dist/commands/adr/adr.command.js +36 -14
  22. package/dist/commands/adr/adr.command.js.map +1 -1
  23. package/dist/commands/architecture/scaffold.command.d.ts +1 -0
  24. package/dist/commands/architecture/scaffold.command.js +23 -1
  25. package/dist/commands/architecture/scaffold.command.js.map +1 -1
  26. package/dist/commands/gate/gate.command.d.ts +23 -0
  27. package/dist/commands/gate/gate.command.js +210 -0
  28. package/dist/commands/gate/gate.command.js.map +1 -0
  29. package/dist/commands/sdlc/gate-status.command.d.ts +3 -1
  30. package/dist/commands/sdlc/gate-status.command.js +78 -3
  31. package/dist/commands/sdlc/gate-status.command.js.map +1 -1
  32. package/dist/commands/sdlc/gate-status.command.spec.d.ts +1 -0
  33. package/dist/commands/sdlc/gate-status.command.spec.js +302 -0
  34. package/dist/commands/sdlc/gate-status.command.spec.js.map +1 -0
  35. package/dist/commands/sdlc/generate-domain.command.d.ts +2 -0
  36. package/dist/commands/sdlc/generate-domain.command.js +123 -12
  37. package/dist/commands/sdlc/generate-domain.command.js.map +1 -1
  38. package/dist/commands/sdlc/generate-domain.command.spec.js +103 -29
  39. package/dist/commands/sdlc/generate-domain.command.spec.js.map +1 -1
  40. package/dist/commands/sdlc/handoff.command.js +2 -2
  41. package/dist/commands/sdlc/handoff.command.js.map +1 -1
  42. package/dist/commands/sdlc/sdlc.command.js +40 -6
  43. package/dist/commands/sdlc/sdlc.command.js.map +1 -1
  44. package/dist/commands/sdlc/sdlc.command.spec.js +48 -14
  45. package/dist/commands/sdlc/sdlc.command.spec.js.map +1 -1
  46. package/dist/commands/validate/validate.command.d.ts +2 -0
  47. package/dist/commands/validate/validate.command.js +16 -2
  48. package/dist/commands/validate/validate.command.js.map +1 -1
  49. package/dist/core/abstractions/interfaces.d.ts +1 -0
  50. package/dist/core/abstractions/interfaces.js.map +1 -1
  51. package/dist/core/abstractions/providers/config-parser.provider.spec.d.ts +1 -0
  52. package/dist/core/abstractions/providers/config-parser.provider.spec.js +18 -0
  53. package/dist/core/abstractions/providers/config-parser.provider.spec.js.map +1 -0
  54. package/dist/core/abstractions/providers/mock-filesystem.provider.d.ts +1 -0
  55. package/dist/core/abstractions/providers/mock-filesystem.provider.js +4 -0
  56. package/dist/core/abstractions/providers/mock-filesystem.provider.js.map +1 -1
  57. package/dist/core/abstractions/providers/mock-filesystem.provider.spec.d.ts +1 -0
  58. package/dist/core/abstractions/providers/mock-filesystem.provider.spec.js +56 -0
  59. package/dist/core/abstractions/providers/mock-filesystem.provider.spec.js.map +1 -0
  60. package/dist/core/abstractions/providers/node-filesystem.provider.d.ts +1 -0
  61. package/dist/core/abstractions/providers/node-filesystem.provider.js +4 -0
  62. package/dist/core/abstractions/providers/node-filesystem.provider.js.map +1 -1
  63. package/dist/core/architecture/nx-workspace.strategy.d.ts +3 -0
  64. package/dist/core/architecture/nx-workspace.strategy.js +35 -6
  65. package/dist/core/architecture/nx-workspace.strategy.js.map +1 -1
  66. package/dist/core/architecture/nx-workspace.strategy.spec.d.ts +1 -0
  67. package/dist/core/architecture/nx-workspace.strategy.spec.js +187 -0
  68. package/dist/core/architecture/nx-workspace.strategy.spec.js.map +1 -0
  69. package/dist/core/architecture/workspace-manager.strategy.d.ts +1 -0
  70. package/dist/core/generators/hexagonal-scaffolder.d.ts +6 -0
  71. package/dist/core/generators/hexagonal-scaffolder.js +260 -0
  72. package/dist/core/generators/hexagonal-scaffolder.js.map +1 -0
  73. package/dist/core/generators/hexagonal-scaffolder.spec.d.ts +1 -0
  74. package/dist/core/generators/hexagonal-scaffolder.spec.js +164 -0
  75. package/dist/core/generators/hexagonal-scaffolder.spec.js.map +1 -0
  76. package/dist/core/generators/mermaid-class-parser.d.ts +38 -0
  77. package/dist/core/generators/mermaid-class-parser.js +183 -0
  78. package/dist/core/generators/mermaid-class-parser.js.map +1 -0
  79. package/dist/core/generators/mermaid-class-parser.spec.d.ts +1 -0
  80. package/dist/core/generators/mermaid-class-parser.spec.js +148 -0
  81. package/dist/core/generators/mermaid-class-parser.spec.js.map +1 -0
  82. package/dist/core/mcp/server.d.ts +3 -1
  83. package/dist/core/mcp/server.js +82 -108
  84. package/dist/core/mcp/server.js.map +1 -1
  85. package/dist/core/mcp/server.spec.js +20 -4
  86. package/dist/core/mcp/server.spec.js.map +1 -1
  87. package/dist/core/mcp/tools/gate.d.ts +1 -0
  88. package/dist/core/mcp/tools/gate.js +68 -0
  89. package/dist/core/mcp/tools/gate.js.map +1 -0
  90. package/dist/core/metrics/dora-calculator.d.ts +18 -0
  91. package/dist/core/metrics/dora-calculator.js +146 -0
  92. package/dist/core/metrics/dora-calculator.js.map +1 -0
  93. package/dist/core/metrics/dora-calculator.spec.d.ts +1 -0
  94. package/dist/core/metrics/dora-calculator.spec.js +164 -0
  95. package/dist/core/metrics/dora-calculator.spec.js.map +1 -0
  96. package/dist/core/metrics/git-log-reader.d.ts +14 -0
  97. package/dist/core/metrics/git-log-reader.js +39 -0
  98. package/dist/core/metrics/git-log-reader.js.map +1 -0
  99. package/dist/core/metrics/git-log-reader.spec.d.ts +1 -0
  100. package/dist/core/metrics/git-log-reader.spec.js +108 -0
  101. package/dist/core/metrics/git-log-reader.spec.js.map +1 -0
  102. package/dist/core/observability/command-watcher.spec.d.ts +1 -0
  103. package/dist/core/observability/command-watcher.spec.js +123 -0
  104. package/dist/core/observability/command-watcher.spec.js.map +1 -0
  105. package/dist/core/observability/index.d.ts +1 -0
  106. package/dist/core/observability/index.js +3 -1
  107. package/dist/core/observability/index.js.map +1 -1
  108. package/dist/core/observability/tool-usage-telemetry.service.d.ts +46 -0
  109. package/dist/core/observability/tool-usage-telemetry.service.js +181 -0
  110. package/dist/core/observability/tool-usage-telemetry.service.js.map +1 -0
  111. package/dist/core/services/command-history.service.d.ts +1 -0
  112. package/dist/core/services/command-history.service.js +4 -0
  113. package/dist/core/services/command-history.service.js.map +1 -1
  114. package/dist/core/services/command-history.service.spec.js +217 -126
  115. package/dist/core/services/command-history.service.spec.js.map +1 -1
  116. package/dist/core/upgrade/satellite-upgrade.service.spec.js +204 -144
  117. package/dist/core/upgrade/satellite-upgrade.service.spec.js.map +1 -1
  118. package/dist/core/validators/deep-architecture-analyzer.spec.js +27 -57
  119. package/dist/core/validators/deep-architecture-analyzer.spec.js.map +1 -1
  120. package/dist/core/validators/evaluators/evaluator.interface.d.ts +14 -0
  121. package/dist/core/validators/evaluators/evaluator.interface.js +3 -0
  122. package/dist/core/validators/evaluators/evaluator.interface.js.map +1 -0
  123. package/dist/core/validators/evaluators/native-evaluator.d.ts +31 -0
  124. package/dist/core/validators/evaluators/native-evaluator.js +461 -0
  125. package/dist/core/validators/evaluators/native-evaluator.js.map +1 -0
  126. package/dist/core/validators/evaluators/opa-evaluator.d.ts +20 -0
  127. package/dist/core/validators/evaluators/opa-evaluator.js +249 -0
  128. package/dist/core/validators/evaluators/opa-evaluator.js.map +1 -0
  129. package/dist/core/validators/phase-gate-validator.service.d.ts +4 -0
  130. package/dist/core/validators/phase-gate-validator.service.js +74 -9
  131. package/dist/core/validators/phase-gate-validator.service.js.map +1 -1
  132. package/dist/core/validators/rule-evaluation-engine.d.ts +34 -0
  133. package/dist/core/validators/rule-evaluation-engine.js +187 -0
  134. package/dist/core/validators/rule-evaluation-engine.js.map +1 -0
  135. package/dist/core/validators/rule-evaluation-engine.spec.d.ts +1 -0
  136. package/dist/core/validators/rule-evaluation-engine.spec.js +243 -0
  137. package/dist/core/validators/rule-evaluation-engine.spec.js.map +1 -0
  138. package/dist/core/validators/ruleset-validator.service.d.ts +2 -0
  139. package/dist/core/validators/ruleset-validator.service.js +29 -4
  140. package/dist/core/validators/ruleset-validator.service.js.map +1 -1
  141. package/dist/domain/gate-evidence.d.ts +59 -0
  142. package/dist/domain/gate-evidence.js +38 -0
  143. package/dist/domain/gate-evidence.js.map +1 -0
  144. package/dist/domain/services/adr.service.d.ts +2 -2
  145. package/dist/domain/services/adr.service.js +12 -8
  146. package/dist/domain/services/adr.service.js.map +1 -1
  147. package/dist/infrastructure/adapters/webhook.adapter.d.ts +5 -0
  148. package/dist/infrastructure/adapters/webhook.adapter.js +19 -0
  149. package/dist/infrastructure/adapters/webhook.adapter.js.map +1 -0
  150. package/dist/infrastructure/cli/command-executor.spec.d.ts +1 -0
  151. package/dist/infrastructure/cli/command-executor.spec.js +149 -0
  152. package/dist/infrastructure/cli/command-executor.spec.js.map +1 -0
  153. package/dist/infrastructure/cli/providers/providers.spec.d.ts +1 -0
  154. package/dist/infrastructure/cli/providers/providers.spec.js +251 -0
  155. package/dist/infrastructure/cli/providers/providers.spec.js.map +1 -0
  156. package/package.json +23 -5
@@ -0,0 +1,260 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.scaffoldHexagonal = scaffoldHexagonal;
37
+ const path = __importStar(require("path"));
38
+ const fs = __importStar(require("fs-extra"));
39
+ function indent(n, s) {
40
+ const pad = ' '.repeat(n);
41
+ return s
42
+ .split('\n')
43
+ .map(l => (l.trim() ? pad + l : l))
44
+ .join('\n');
45
+ }
46
+ function renderParams(params) {
47
+ return params.map(p => `${p.name}: ${p.type}`).join(', ');
48
+ }
49
+ function renderMethodStub(m, isAsync = false) {
50
+ const sig = `${m.name}(${renderParams(m.params)}): ${isAsync ? `Promise<${m.returnType}>` : m.returnType}`;
51
+ return [
52
+ `${m.visibility === 'public' ? '' : m.visibility + ' '}${isAsync ? 'async ' : ''}${sig} {`,
53
+ ` throw new Error('Not implemented: ${m.name}');`,
54
+ `}`,
55
+ ].join('\n');
56
+ }
57
+ function renderConstructorParam(p) {
58
+ const access = p.visibility === 'public' ? 'public readonly ' : 'private ';
59
+ return `${access}${p.name}: ${p.type}`;
60
+ }
61
+ function generateEntity(cls) {
62
+ const ctorParams = cls.properties.map(renderConstructorParam).join(',\n ');
63
+ const methods = cls.methods
64
+ .map(m => indent(1, renderMethodStub(m)))
65
+ .join('\n\n');
66
+ return [
67
+ `/**`,
68
+ ` * ${cls.name} — Domain Entity`,
69
+ ` * Generated by: evolith sdlc generate`,
70
+ ` * Stereotype: ${cls.stereotype}`,
71
+ ` */`,
72
+ `export class ${cls.name} {`,
73
+ ctorParams
74
+ ? ` constructor(\n ${ctorParams},\n ) {}`
75
+ : ` constructor() {}`,
76
+ methods ? `\n${methods}` : '',
77
+ `}`,
78
+ ``,
79
+ ].filter(l => l !== undefined).join('\n');
80
+ }
81
+ function generateValueObject(cls) {
82
+ const ctorParams = cls.properties.map(renderConstructorParam).join(',\n ');
83
+ const methods = cls.methods
84
+ .filter(m => m.name !== 'validate')
85
+ .map(m => indent(1, renderMethodStub(m)))
86
+ .join('\n\n');
87
+ return [
88
+ `/**`,
89
+ ` * ${cls.name} — Value Object`,
90
+ ` * Generated by: evolith sdlc generate`,
91
+ ` */`,
92
+ `export class ${cls.name} {`,
93
+ ctorParams
94
+ ? ` constructor(\n ${ctorParams},\n ) {\n this.validate();\n }`
95
+ : ` constructor() {\n this.validate();\n }`,
96
+ ``,
97
+ ` private validate(): void {`,
98
+ ` // TODO: add validation rules for ${cls.name}`,
99
+ ` }`,
100
+ methods ? `\n${methods}` : '',
101
+ `}`,
102
+ ``,
103
+ ].join('\n');
104
+ }
105
+ function generateAggregate(cls) {
106
+ const ctorParams = cls.properties.map(renderConstructorParam).join(',\n ');
107
+ const methods = cls.methods
108
+ .map(m => indent(1, renderMethodStub(m)))
109
+ .join('\n\n');
110
+ return [
111
+ `/**`,
112
+ ` * ${cls.name} — Aggregate Root`,
113
+ ` * Generated by: evolith sdlc generate`,
114
+ ` */`,
115
+ `export class ${cls.name} {`,
116
+ ` private readonly _domainEvents: unknown[] = [];`,
117
+ ``,
118
+ ctorParams
119
+ ? ` constructor(\n ${ctorParams},\n ) {}`
120
+ : ` constructor() {}`,
121
+ ``,
122
+ ` get domainEvents(): unknown[] {`,
123
+ ` return [...this._domainEvents];`,
124
+ ` }`,
125
+ ``,
126
+ ` protected addDomainEvent(event: unknown): void {`,
127
+ ` this._domainEvents.push(event);`,
128
+ ` }`,
129
+ methods ? `\n${methods}` : '',
130
+ `}`,
131
+ ``,
132
+ ].join('\n');
133
+ }
134
+ function generateRepositoryInterface(cls, entityName) {
135
+ const methodSigs = cls.methods.map(m => {
136
+ const sig = `${m.name}(${renderParams(m.params)}): Promise<${m.returnType === 'void' ? 'void' : m.returnType}>`;
137
+ return ` ${sig};`;
138
+ });
139
+ const hasFindById = cls.methods.some(m => m.name === 'findById');
140
+ const hasSave = cls.methods.some(m => m.name === 'save');
141
+ if (!hasFindById)
142
+ methodSigs.unshift(` findById(id: string): Promise<${entityName} | null>;`);
143
+ if (!hasSave)
144
+ methodSigs.push(` save(entity: ${entityName}): Promise<void>;`);
145
+ return [
146
+ `/**`,
147
+ ` * I${cls.name} — Repository Interface`,
148
+ ` * Generated by: evolith sdlc generate`,
149
+ ` */`,
150
+ `import type { ${entityName} } from '../entities/${entityName}';`,
151
+ ``,
152
+ `export interface I${cls.name} {`,
153
+ ...methodSigs,
154
+ `}`,
155
+ ``,
156
+ ].join('\n');
157
+ }
158
+ function generateRepositoryImpl(cls, entityName) {
159
+ const methods = [
160
+ ` async findById(id: string): Promise<${entityName} | null> {`,
161
+ ` // TODO: implement persistence`,
162
+ ` throw new Error('Not implemented: findById');`,
163
+ ` }`,
164
+ ``,
165
+ ` async save(entity: ${entityName}): Promise<void> {`,
166
+ ` // TODO: implement persistence`,
167
+ ` throw new Error('Not implemented: save');`,
168
+ ` }`,
169
+ ];
170
+ cls.methods.forEach(m => {
171
+ if (m.name === 'findById' || m.name === 'save')
172
+ return;
173
+ methods.push('');
174
+ methods.push(` async ${m.name}(${renderParams(m.params)}): Promise<${m.returnType === 'void' ? 'void' : m.returnType}> {`);
175
+ methods.push(` throw new Error('Not implemented: ${m.name}');`);
176
+ methods.push(` }`);
177
+ });
178
+ return [
179
+ `/**`,
180
+ ` * ${cls.name} — Repository Implementation (stub)`,
181
+ ` * Generated by: evolith sdlc generate`,
182
+ ` * Replace with real persistence logic (TypeORM, Prisma, etc.)`,
183
+ ` */`,
184
+ `import type { ${entityName} } from '../../domain/entities/${entityName}';`,
185
+ `import type { I${cls.name} } from '../../domain/repositories/I${cls.name}';`,
186
+ ``,
187
+ `export class ${cls.name} implements I${cls.name} {`,
188
+ ...methods,
189
+ `}`,
190
+ ``,
191
+ ].join('\n');
192
+ }
193
+ function generateService(cls) {
194
+ const methods = cls.methods
195
+ .map(m => indent(1, renderMethodStub(m, true)))
196
+ .join('\n\n');
197
+ return [
198
+ `/**`,
199
+ ` * ${cls.name} — Domain Service`,
200
+ ` * Generated by: evolith sdlc generate`,
201
+ ` */`,
202
+ `export class ${cls.name} {`,
203
+ methods || ` // TODO: implement domain service methods`,
204
+ `}`,
205
+ ``,
206
+ ].join('\n');
207
+ }
208
+ function resolveEntityNameForRepo(cls, diagram) {
209
+ const rel = diagram.relationships.find(r => r.from === cls.name || r.to === cls.name);
210
+ if (rel) {
211
+ const other = rel.from === cls.name ? rel.to : rel.from;
212
+ const otherCls = diagram.classes.find(c => c.name === other);
213
+ if (otherCls && (otherCls.stereotype === 'Entity' || otherCls.stereotype === 'Aggregate')) {
214
+ return otherCls.name;
215
+ }
216
+ }
217
+ return cls.name.replace(/Repository$/i, '') || cls.name;
218
+ }
219
+ async function scaffoldHexagonal(diagram, targetDir, dryRun = false) {
220
+ const created = [];
221
+ const skipped = [];
222
+ async function write(relPath, content) {
223
+ const abs = path.join(targetDir, relPath);
224
+ if (await fs.pathExists(abs)) {
225
+ skipped.push(relPath);
226
+ return;
227
+ }
228
+ if (!dryRun) {
229
+ await fs.ensureDir(path.dirname(abs));
230
+ await fs.writeFile(abs, content, 'utf-8');
231
+ }
232
+ created.push(relPath);
233
+ }
234
+ for (const cls of diagram.classes) {
235
+ switch (cls.stereotype) {
236
+ case 'Entity':
237
+ await write(`src/domain/entities/${cls.name}.ts`, generateEntity(cls));
238
+ break;
239
+ case 'Aggregate':
240
+ await write(`src/domain/entities/${cls.name}.ts`, generateAggregate(cls));
241
+ break;
242
+ case 'ValueObject':
243
+ await write(`src/domain/value-objects/${cls.name}.ts`, generateValueObject(cls));
244
+ break;
245
+ case 'Repository': {
246
+ const entityName = resolveEntityNameForRepo(cls, diagram);
247
+ await write(`src/domain/repositories/I${cls.name}.ts`, generateRepositoryInterface(cls, entityName));
248
+ await write(`src/infrastructure/persistence/${cls.name}.ts`, generateRepositoryImpl(cls, entityName));
249
+ break;
250
+ }
251
+ case 'Service':
252
+ await write(`src/domain/services/${cls.name}.ts`, generateService(cls));
253
+ break;
254
+ default:
255
+ await write(`src/domain/entities/${cls.name}.ts`, generateEntity(cls));
256
+ }
257
+ }
258
+ return { created, skipped };
259
+ }
260
+ //# sourceMappingURL=hexagonal-scaffolder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hexagonal-scaffolder.js","sourceRoot":"","sources":["../../../src/core/generators/hexagonal-scaffolder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,164 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const os = __importStar(require("os"));
37
+ const path = __importStar(require("path"));
38
+ const fs = __importStar(require("fs-extra"));
39
+ const hexagonal_scaffolder_1 = require("./hexagonal-scaffolder");
40
+ const mermaid_class_parser_1 = require("./mermaid-class-parser");
41
+ const DIAGRAM_SRC = `
42
+ classDiagram
43
+ class User {
44
+ <<Entity>>
45
+ +String id
46
+ +String name
47
+ +validate() void
48
+ }
49
+
50
+ class Email {
51
+ <<Value Object>>
52
+ +String value
53
+ +isValid() bool
54
+ }
55
+
56
+ class Order {
57
+ <<Aggregate>>
58
+ +String orderId
59
+ }
60
+
61
+ class UserRepository {
62
+ <<Repository>>
63
+ +findById(id String) User
64
+ +save(user User) void
65
+ }
66
+
67
+ class EmailService {
68
+ <<Service>>
69
+ +sendConfirmation(email String) void
70
+ }
71
+
72
+ UserRepository --> User
73
+ `;
74
+ describe('scaffoldHexagonal', () => {
75
+ let tmpDir;
76
+ let diagram;
77
+ beforeAll(async () => {
78
+ tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'evolith-scaffold-test-'));
79
+ diagram = (0, mermaid_class_parser_1.parseClassDiagram)(DIAGRAM_SRC);
80
+ });
81
+ afterAll(async () => {
82
+ await fs.remove(tmpDir);
83
+ });
84
+ it('parses diagram to 5 classes', () => {
85
+ expect(diagram.classes).toHaveLength(5);
86
+ });
87
+ describe('dryRun mode', () => {
88
+ it('returns created list without writing files', async () => {
89
+ const result = await (0, hexagonal_scaffolder_1.scaffoldHexagonal)(diagram, tmpDir, true);
90
+ expect(result.created.length).toBeGreaterThan(0);
91
+ expect(result.skipped).toHaveLength(0);
92
+ const exists = await fs.pathExists(path.join(tmpDir, 'src'));
93
+ expect(exists).toBe(false);
94
+ });
95
+ });
96
+ describe('real write mode', () => {
97
+ let result;
98
+ beforeAll(async () => {
99
+ result = await (0, hexagonal_scaffolder_1.scaffoldHexagonal)(diagram, tmpDir);
100
+ });
101
+ it('creates Entity file', async () => {
102
+ const p = path.join(tmpDir, 'src/domain/entities/User.ts');
103
+ await expect(fs.pathExists(p)).resolves.toBe(true);
104
+ });
105
+ it('creates ValueObject file', async () => {
106
+ const p = path.join(tmpDir, 'src/domain/value-objects/Email.ts');
107
+ await expect(fs.pathExists(p)).resolves.toBe(true);
108
+ });
109
+ it('creates Aggregate file', async () => {
110
+ const p = path.join(tmpDir, 'src/domain/entities/Order.ts');
111
+ await expect(fs.pathExists(p)).resolves.toBe(true);
112
+ });
113
+ it('creates Repository interface', async () => {
114
+ const p = path.join(tmpDir, 'src/domain/repositories/IUserRepository.ts');
115
+ await expect(fs.pathExists(p)).resolves.toBe(true);
116
+ });
117
+ it('creates Repository implementation', async () => {
118
+ const p = path.join(tmpDir, 'src/infrastructure/persistence/UserRepository.ts');
119
+ await expect(fs.pathExists(p)).resolves.toBe(true);
120
+ });
121
+ it('creates Service file', async () => {
122
+ const p = path.join(tmpDir, 'src/domain/services/EmailService.ts');
123
+ await expect(fs.pathExists(p)).resolves.toBe(true);
124
+ });
125
+ it('reports all files as created', () => {
126
+ expect(result.created).toHaveLength(6);
127
+ expect(result.skipped).toHaveLength(0);
128
+ });
129
+ it('Entity file contains class declaration and constructor', async () => {
130
+ const content = await fs.readFile(path.join(tmpDir, 'src/domain/entities/User.ts'), 'utf-8');
131
+ expect(content).toContain('export class User');
132
+ expect(content).toContain('constructor(');
133
+ expect(content).toContain('id: string');
134
+ });
135
+ it('ValueObject file contains validate() method', async () => {
136
+ const content = await fs.readFile(path.join(tmpDir, 'src/domain/value-objects/Email.ts'), 'utf-8');
137
+ expect(content).toContain('export class Email');
138
+ expect(content).toContain('private validate()');
139
+ expect(content).toContain('this.validate()');
140
+ });
141
+ it('Aggregate file contains domainEvents', async () => {
142
+ const content = await fs.readFile(path.join(tmpDir, 'src/domain/entities/Order.ts'), 'utf-8');
143
+ expect(content).toContain('domainEvents');
144
+ expect(content).toContain('addDomainEvent');
145
+ });
146
+ it('Repository interface imports entity and has findById/save', async () => {
147
+ const content = await fs.readFile(path.join(tmpDir, 'src/domain/repositories/IUserRepository.ts'), 'utf-8');
148
+ expect(content).toContain('import type { User }');
149
+ expect(content).toContain('findById');
150
+ expect(content).toContain('save');
151
+ });
152
+ it('Repository impl implements the interface', async () => {
153
+ const content = await fs.readFile(path.join(tmpDir, 'src/infrastructure/persistence/UserRepository.ts'), 'utf-8');
154
+ expect(content).toContain('implements IUserRepository');
155
+ expect(content).toContain('Not implemented');
156
+ });
157
+ it('skips existing files on second run', async () => {
158
+ const result2 = await (0, hexagonal_scaffolder_1.scaffoldHexagonal)(diagram, tmpDir);
159
+ expect(result2.created).toHaveLength(0);
160
+ expect(result2.skipped).toHaveLength(6);
161
+ });
162
+ });
163
+ });
164
+ //# sourceMappingURL=hexagonal-scaffolder.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hexagonal-scaffolder.spec.js","sourceRoot":"","sources":["../../../src/core/generators/hexagonal-scaffolder.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ export type Stereotype = 'Entity' | 'ValueObject' | 'Aggregate' | 'Repository' | 'Service' | 'unknown';
2
+ export type Visibility = 'public' | 'private' | 'protected' | 'package';
3
+ export interface PropertyDef {
4
+ visibility: Visibility;
5
+ type: string;
6
+ name: string;
7
+ }
8
+ export interface MethodDef {
9
+ visibility: Visibility;
10
+ name: string;
11
+ params: ParamDef[];
12
+ returnType: string;
13
+ }
14
+ export interface ParamDef {
15
+ name: string;
16
+ type: string;
17
+ }
18
+ export interface ClassDef {
19
+ name: string;
20
+ stereotype: Stereotype;
21
+ properties: PropertyDef[];
22
+ methods: MethodDef[];
23
+ }
24
+ export interface RelationshipDef {
25
+ from: string;
26
+ to: string;
27
+ arrow: string;
28
+ label?: string;
29
+ fromCard?: string;
30
+ toCard?: string;
31
+ }
32
+ export interface ClassDiagram {
33
+ classes: ClassDef[];
34
+ relationships: RelationshipDef[];
35
+ }
36
+ export declare function extractMermaidBlocks(markdown: string): string[];
37
+ export declare function parseClassDiagram(block: string): ClassDiagram | null;
38
+ export declare function parseDddModel(markdown: string): ClassDiagram | null;
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractMermaidBlocks = extractMermaidBlocks;
4
+ exports.parseClassDiagram = parseClassDiagram;
5
+ exports.parseDddModel = parseDddModel;
6
+ const VISIBILITY_MAP = {
7
+ '+': 'public',
8
+ '-': 'private',
9
+ '#': 'protected',
10
+ '~': 'package',
11
+ };
12
+ function parseVisibility(prefix) {
13
+ return VISIBILITY_MAP[prefix] ?? 'public';
14
+ }
15
+ function normaliseStereotype(raw) {
16
+ const s = raw.replace(/\s+/g, '').toLowerCase();
17
+ if (s === 'entity')
18
+ return 'Entity';
19
+ if (s === 'valueobject' || s === 'vo')
20
+ return 'ValueObject';
21
+ if (s === 'aggregate' || s === 'aggregateroot')
22
+ return 'Aggregate';
23
+ if (s === 'repository')
24
+ return 'Repository';
25
+ if (s === 'service' || s === 'domainservice')
26
+ return 'Service';
27
+ return 'unknown';
28
+ }
29
+ function toCamelCase(s) {
30
+ return s.charAt(0).toLowerCase() + s.slice(1);
31
+ }
32
+ function mapMermaidType(t) {
33
+ const map = {
34
+ String: 'string',
35
+ string: 'string',
36
+ Int: 'number',
37
+ int: 'number',
38
+ Integer: 'number',
39
+ Long: 'number',
40
+ Float: 'number',
41
+ Double: 'number',
42
+ number: 'number',
43
+ Boolean: 'boolean',
44
+ boolean: 'boolean',
45
+ Bool: 'boolean',
46
+ bool: 'boolean',
47
+ Void: 'void',
48
+ void: 'void',
49
+ Date: 'Date',
50
+ List: 'Array<unknown>',
51
+ Object: 'Record<string, unknown>',
52
+ };
53
+ return map[t] ?? t;
54
+ }
55
+ const METHOD_RE = /^([+\-#~]?)\s*(\w+)\s*\(([^)]*)\)\s*(\w+)?\s*$/;
56
+ const PROP_RE = /^([+\-#~]?)\s*(\w+)\s+(\w+)\s*$/;
57
+ function parseMember(line) {
58
+ const trimmed = line.trim();
59
+ if (!trimmed || trimmed.startsWith('<<'))
60
+ return null;
61
+ const mM = METHOD_RE.exec(trimmed);
62
+ if (mM) {
63
+ const [, visChar, name, rawParams, ret] = mM;
64
+ return {
65
+ visibility: parseVisibility(visChar),
66
+ name,
67
+ params: parseParams(rawParams),
68
+ returnType: mapMermaidType(ret ?? 'void'),
69
+ };
70
+ }
71
+ const mP = PROP_RE.exec(trimmed);
72
+ if (mP) {
73
+ const [, visChar, typePart, namePart] = mP;
74
+ return {
75
+ visibility: parseVisibility(visChar),
76
+ type: mapMermaidType(typePart),
77
+ name: toCamelCase(namePart),
78
+ };
79
+ }
80
+ return null;
81
+ }
82
+ function parseParams(raw) {
83
+ if (!raw.trim())
84
+ return [];
85
+ return raw.split(',').map(p => {
86
+ const parts = p.trim().split(/\s+/);
87
+ if (parts.length >= 2) {
88
+ return { type: mapMermaidType(parts[1]), name: parts[0] };
89
+ }
90
+ return { type: mapMermaidType(parts[0]), name: toCamelCase(parts[0]) };
91
+ });
92
+ }
93
+ function isMethod(m) {
94
+ return 'params' in m;
95
+ }
96
+ const REL_RE = /^(\w+)\s*(?:"([^"]*)")?\s*(-->|\.\.>|--\|>|\.\.\|>|o--|o\.\.|\*--|<-->|--)\s*(?:"([^"]*)")?\s*(\w+)(?:\s*:\s*(.+))?$/;
97
+ function parseRelationship(line) {
98
+ const m = REL_RE.exec(line.trim());
99
+ if (!m)
100
+ return null;
101
+ const [, from, fromCard, arrow, toCard, to, label] = m;
102
+ return {
103
+ from, to, arrow,
104
+ ...(fromCard ? { fromCard } : {}),
105
+ ...(toCard ? { toCard } : {}),
106
+ ...(label ? { label: label.trim() } : {}),
107
+ };
108
+ }
109
+ function extractMermaidBlocks(markdown) {
110
+ const blocks = [];
111
+ const re = /```mermaid\s*\n([\s\S]*?)```/g;
112
+ let m;
113
+ while ((m = re.exec(markdown)) !== null) {
114
+ blocks.push(m[1]);
115
+ }
116
+ return blocks;
117
+ }
118
+ function parseClassDiagram(block) {
119
+ const lines = block.split('\n').map(l => l.trim()).filter(Boolean);
120
+ if (!lines.some(l => l.toLowerCase().startsWith('classdiagram'))) {
121
+ return null;
122
+ }
123
+ const classes = [];
124
+ const relationships = [];
125
+ let i = 0;
126
+ while (i < lines.length) {
127
+ const line = lines[i];
128
+ const classOpen = /^class\s+(\w+)\s*\{/.exec(line);
129
+ if (classOpen) {
130
+ const cls = {
131
+ name: classOpen[1],
132
+ stereotype: 'unknown',
133
+ properties: [],
134
+ methods: [],
135
+ };
136
+ i++;
137
+ while (i < lines.length && lines[i] !== '}') {
138
+ const inner = lines[i].trim();
139
+ const stereoMatch = /^<<([^>]+)>>$/.exec(inner);
140
+ if (stereoMatch) {
141
+ cls.stereotype = normaliseStereotype(stereoMatch[1]);
142
+ }
143
+ else {
144
+ const member = parseMember(inner);
145
+ if (member) {
146
+ if (isMethod(member))
147
+ cls.methods.push(member);
148
+ else
149
+ cls.properties.push(member);
150
+ }
151
+ }
152
+ i++;
153
+ }
154
+ classes.push(cls);
155
+ i++;
156
+ continue;
157
+ }
158
+ const classNoBody = /^class\s+(\w+)\s*$/.exec(line);
159
+ if (classNoBody) {
160
+ classes.push({ name: classNoBody[1], stereotype: 'unknown', properties: [], methods: [] });
161
+ i++;
162
+ continue;
163
+ }
164
+ const rel = parseRelationship(line);
165
+ if (rel) {
166
+ relationships.push(rel);
167
+ i++;
168
+ continue;
169
+ }
170
+ i++;
171
+ }
172
+ return { classes, relationships };
173
+ }
174
+ function parseDddModel(markdown) {
175
+ const blocks = extractMermaidBlocks(markdown);
176
+ for (const block of blocks) {
177
+ const diagram = parseClassDiagram(block);
178
+ if (diagram)
179
+ return diagram;
180
+ }
181
+ return null;
182
+ }
183
+ //# sourceMappingURL=mermaid-class-parser.js.map