@specverse/engines 5.0.2 → 5.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.
- package/dist/ai/commands/fill.d.ts.map +1 -1
- package/dist/ai/commands/fill.js +16 -7
- package/dist/ai/commands/fill.js.map +1 -1
- package/dist/ai/commands/template.d.ts.map +1 -1
- package/dist/ai/commands/template.js +17 -8
- package/dist/ai/commands/template.js.map +1 -1
- package/dist/bundles/deriveCatalog.d.ts +18 -0
- package/dist/bundles/deriveCatalog.d.ts.map +1 -0
- package/dist/bundles/deriveCatalog.js +263 -0
- package/dist/bundles/deriveCatalog.js.map +1 -0
- package/dist/bundles/index.d.ts +15 -0
- package/dist/bundles/index.d.ts.map +1 -0
- package/dist/bundles/index.js +15 -0
- package/dist/bundles/index.js.map +1 -0
- package/dist/bundles/types.d.ts +53 -0
- package/dist/bundles/types.d.ts.map +1 -0
- package/dist/bundles/types.js +22 -0
- package/dist/bundles/types.js.map +1 -0
- package/dist/bundles/validate.d.ts +55 -0
- package/dist/bundles/validate.d.ts.map +1 -0
- package/dist/bundles/validate.js +471 -0
- package/dist/bundles/validate.js.map +1 -0
- package/dist/inference/quint-transpiler.js +2 -2
- package/dist/inference/quint-transpiler.js.map +1 -1
- package/dist/libs/instance-factories/applications/templates/react/runtime-package-json-generator.js +1 -1
- package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +43 -0
- package/dist/libs/instance-factories/tools/templates/mcp/mcp-server-generator.js +11 -4
- package/libs/instance-factories/applications/templates/react/runtime-package-json-generator.ts +1 -1
- package/libs/instance-factories/cli/templates/commander/command-generator.ts +43 -0
- package/libs/instance-factories/tools/templates/mcp/mcp-server-generator.ts +10 -3
- package/package.json +9 -5
- package/assets/examples/09-api/ai-spec.yaml +0 -194
- package/assets/examples/09-api/converted.yaml +0 -95
- package/assets/examples/09-api/diagram-architecture.mmd +0 -10
- package/assets/examples/09-api/diagram-er.mmd +0 -10
- package/assets/examples/09-api/documentation.html +0 -104
- package/assets/examples/09-api/documentation.md +0 -95
- package/assets/examples/09-api/inferred-spec.yaml +0 -420
- package/assets/examples/09-api/openapi.json +0 -61
- package/assets/examples/10-api/README.md +0 -216
- package/assets/examples/10-api/ai-spec.yaml +0 -194
- package/assets/examples/10-api/converted.yaml +0 -96
- package/assets/examples/10-api/diagram-architecture.mmd +0 -10
- package/assets/examples/10-api/diagram-er.mmd +0 -10
- package/assets/examples/10-api/documentation.html +0 -104
- package/assets/examples/10-api/documentation.md +0 -95
- package/assets/examples/10-api/inferred-spec.yaml +0 -7
- package/assets/examples/10-api/metadata.yaml +0 -89
- package/assets/examples/10-api/openapi.json +0 -61
- package/assets/examples/10-api/package-integration-test.js +0 -177
- package/assets/examples/10-api/usage-example.js +0 -323
- package/assets/examples/10-api/usage-example.ts +0 -363
- package/assets/examples/10-api/workflow-test.js +0 -113
- package/assets/examples/validate-examples-with-expected-failures.cjs +0 -328
- package/assets/examples/validate-examples.cjs +0 -225
- package/assets/prompts/MOVED.md +0 -35
- package/assets/prompts/SUMMARY-v8-PROMOTION.md +0 -445
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SpecVerse JavaScript API Usage Examples
|
|
3
|
-
*
|
|
4
|
-
* Simple examples showing how to use SpecVerse from JavaScript
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { SpecVerseParser } from '../../dist/index.js';
|
|
8
|
-
import { readFileSync, writeFileSync } from 'fs';
|
|
9
|
-
import * as yaml from 'js-yaml';
|
|
10
|
-
|
|
11
|
-
// ============================================
|
|
12
|
-
// BASIC USAGE EXAMPLE
|
|
13
|
-
// ============================================
|
|
14
|
-
|
|
15
|
-
// 1. Parse a SpecVerse file
|
|
16
|
-
function parseSpec(filePath) {
|
|
17
|
-
// Load the schema (in real usage, this would be from node_modules/@specverse/lang/schema/)
|
|
18
|
-
const schema = JSON.parse(readFileSync('../../schema/SPECVERSE-SCHEMA.json', 'utf8'));
|
|
19
|
-
|
|
20
|
-
// Create parser
|
|
21
|
-
const parser = new SpecVerseParser(schema);
|
|
22
|
-
|
|
23
|
-
// Parse the file
|
|
24
|
-
const content = readFileSync(filePath, 'utf8');
|
|
25
|
-
const result = parser.parseContent(content, filePath);
|
|
26
|
-
|
|
27
|
-
if (result.errors.length > 0) {
|
|
28
|
-
console.error('Errors:', result.errors);
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
console.log('✅ Parsed successfully');
|
|
33
|
-
return result.ast;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// 2. Validate a specification
|
|
37
|
-
function validateSpec(filePath) {
|
|
38
|
-
const schema = JSON.parse(readFileSync('../../schema/SPECVERSE-SCHEMA.json', 'utf8'));
|
|
39
|
-
const parser = new SpecVerseParser(schema);
|
|
40
|
-
|
|
41
|
-
const content = readFileSync(filePath, 'utf8');
|
|
42
|
-
const result = parser.parseContent(content, filePath);
|
|
43
|
-
|
|
44
|
-
return result.errors.length === 0;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// 3. Convert .specly to .yaml
|
|
48
|
-
function speclyToYaml(inputPath, outputPath) {
|
|
49
|
-
const schema = JSON.parse(readFileSync('../../schema/SPECVERSE-SCHEMA.json', 'utf8'));
|
|
50
|
-
const parser = new SpecVerseParser(schema);
|
|
51
|
-
|
|
52
|
-
const content = readFileSync(inputPath, 'utf8');
|
|
53
|
-
const result = parser.processToYaml(content);
|
|
54
|
-
|
|
55
|
-
if (result.errors.length === 0) {
|
|
56
|
-
writeFileSync(outputPath, result.yaml);
|
|
57
|
-
console.log('✅ Converted to YAML');
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
console.error('❌ Conversion failed:', result.errors);
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// 4. Extract information from AST
|
|
66
|
-
function analyzeSpec(ast) {
|
|
67
|
-
if (!ast) return null;
|
|
68
|
-
|
|
69
|
-
// Count different elements
|
|
70
|
-
const stats = {
|
|
71
|
-
components: ast.components.length,
|
|
72
|
-
models: 0,
|
|
73
|
-
controllers: 0,
|
|
74
|
-
services: 0,
|
|
75
|
-
events: 0,
|
|
76
|
-
views: 0
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
// Iterate through components
|
|
80
|
-
ast.components.forEach(component => {
|
|
81
|
-
stats.models += component.models?.length || 0;
|
|
82
|
-
stats.controllers += component.controllers?.length || 0;
|
|
83
|
-
stats.services += component.services?.length || 0;
|
|
84
|
-
stats.events += component.events?.length || 0;
|
|
85
|
-
stats.views += component.views?.length || 0;
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
return stats;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// 5. Example: Generate a simple report
|
|
92
|
-
function generateReport(filePath) {
|
|
93
|
-
const ast = parseSpec(filePath);
|
|
94
|
-
if (!ast) return;
|
|
95
|
-
|
|
96
|
-
const stats = analyzeSpec(ast);
|
|
97
|
-
|
|
98
|
-
const report = {
|
|
99
|
-
file: filePath,
|
|
100
|
-
timestamp: new Date().toISOString(),
|
|
101
|
-
statistics: stats,
|
|
102
|
-
components: ast.components.map(c => ({
|
|
103
|
-
name: c.name,
|
|
104
|
-
version: c.version,
|
|
105
|
-
modelCount: c.models?.length || 0,
|
|
106
|
-
exports: c.exports
|
|
107
|
-
}))
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
console.log('\n📊 Specification Report:');
|
|
111
|
-
console.log(JSON.stringify(report, null, 2));
|
|
112
|
-
|
|
113
|
-
return report;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// ============================================
|
|
117
|
-
// USING THE INFERENCE ENGINE
|
|
118
|
-
// ============================================
|
|
119
|
-
|
|
120
|
-
import { LogicalInferenceEngine } from '../../dist/index.js';
|
|
121
|
-
|
|
122
|
-
async function runInference(filePath) {
|
|
123
|
-
// Parse the file first
|
|
124
|
-
const ast = parseSpec(filePath);
|
|
125
|
-
if (!ast) return;
|
|
126
|
-
|
|
127
|
-
// Configure inference
|
|
128
|
-
const config = {
|
|
129
|
-
logical: {
|
|
130
|
-
generateControllers: true,
|
|
131
|
-
generateServices: true,
|
|
132
|
-
generateEvents: true,
|
|
133
|
-
generateViews: true,
|
|
134
|
-
generateTypes: true
|
|
135
|
-
},
|
|
136
|
-
rules: {
|
|
137
|
-
logicalRulesPath: '../../dist/inference-engine/rules/logical',
|
|
138
|
-
deploymentRulesPath: '../../dist/inference-engine/rules/deployment'
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
// Create and run inference engine
|
|
143
|
-
const engine = new LogicalInferenceEngine(config);
|
|
144
|
-
|
|
145
|
-
// Extract models from AST
|
|
146
|
-
const models = ast.components.flatMap(c => c.models);
|
|
147
|
-
|
|
148
|
-
// Load rules first
|
|
149
|
-
console.log('📋 Loading inference rules...');
|
|
150
|
-
const rulesValidation = await engine.loadRules();
|
|
151
|
-
|
|
152
|
-
if (!rulesValidation.valid) {
|
|
153
|
-
console.error('❌ Failed to load inference rules:', rulesValidation.errors.map(e => e.message));
|
|
154
|
-
return null;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Run inference
|
|
158
|
-
const componentName = 'GeneratedComponent';
|
|
159
|
-
const result = await engine.inferLogicalSpecification(models, componentName);
|
|
160
|
-
|
|
161
|
-
console.log('✅ Inference complete:');
|
|
162
|
-
console.log(' Validation:', result.validation.valid ? '✅' : '❌');
|
|
163
|
-
console.log(' Controllers:', result.statistics.controllersGenerated);
|
|
164
|
-
console.log(' Services:', result.statistics.servicesGenerated);
|
|
165
|
-
console.log(' Events:', result.statistics.eventsGenerated);
|
|
166
|
-
console.log(' Views:', result.statistics.viewsGenerated);
|
|
167
|
-
|
|
168
|
-
if (!result.validation.valid) {
|
|
169
|
-
console.error(' Errors:', result.validation.errors.map(e => e.message));
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Save the inferred specification
|
|
173
|
-
const output = yaml.dump(result.specification, {
|
|
174
|
-
indent: 2,
|
|
175
|
-
lineWidth: 120
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
writeFileSync('inferred-spec.yaml', output);
|
|
179
|
-
console.log('💾 Saved to inferred-spec.yaml');
|
|
180
|
-
|
|
181
|
-
return result;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// ============================================
|
|
185
|
-
// USING GENERATORS
|
|
186
|
-
// ============================================
|
|
187
|
-
|
|
188
|
-
import {
|
|
189
|
-
AIViewGenerator,
|
|
190
|
-
UMLGenerator,
|
|
191
|
-
DocumentationGenerator
|
|
192
|
-
} from '../../dist/index.js';
|
|
193
|
-
|
|
194
|
-
function generateAIView(ast) {
|
|
195
|
-
try {
|
|
196
|
-
const generator = new AIViewGenerator();
|
|
197
|
-
const aiSpec = generator.generate(ast);
|
|
198
|
-
|
|
199
|
-
// Save as YAML
|
|
200
|
-
const output = yaml.dump(aiSpec, { indent: 2 });
|
|
201
|
-
writeFileSync('ai-spec.yaml', output);
|
|
202
|
-
|
|
203
|
-
console.log('✅ AI specification generated');
|
|
204
|
-
return aiSpec;
|
|
205
|
-
} catch (error) {
|
|
206
|
-
console.warn('⚠️ AI view generation failed:', error.message);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
function generateDiagrams(ast) {
|
|
211
|
-
try {
|
|
212
|
-
const generator = new UMLGenerator();
|
|
213
|
-
|
|
214
|
-
// Generate ER diagram
|
|
215
|
-
const erDiagram = generator.generate(ast, {
|
|
216
|
-
type: 'er',
|
|
217
|
-
includeAttributes: true,
|
|
218
|
-
includeRelationships: true
|
|
219
|
-
});
|
|
220
|
-
if (erDiagram) {
|
|
221
|
-
writeFileSync('diagram-er.mmd', erDiagram);
|
|
222
|
-
console.log('✅ ER diagram generated');
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Generate architecture diagram
|
|
226
|
-
const archDiagram = generator.generate(ast, {
|
|
227
|
-
type: 'architecture',
|
|
228
|
-
includeControllers: true,
|
|
229
|
-
includeServices: true,
|
|
230
|
-
includeEvents: true
|
|
231
|
-
});
|
|
232
|
-
if (archDiagram) {
|
|
233
|
-
writeFileSync('diagram-architecture.mmd', archDiagram);
|
|
234
|
-
console.log('✅ Architecture diagram generated');
|
|
235
|
-
}
|
|
236
|
-
} catch (error) {
|
|
237
|
-
console.warn('⚠️ Diagram generation failed:', error.message);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
function generateDocs(ast) {
|
|
242
|
-
try {
|
|
243
|
-
const generator = new DocumentationGenerator();
|
|
244
|
-
|
|
245
|
-
// Generate markdown
|
|
246
|
-
const markdown = generator.generate(ast, {
|
|
247
|
-
format: 'markdown',
|
|
248
|
-
includeTableOfContents: true,
|
|
249
|
-
includeExamples: true,
|
|
250
|
-
includeDiagrams: false
|
|
251
|
-
});
|
|
252
|
-
writeFileSync('documentation.md', markdown);
|
|
253
|
-
|
|
254
|
-
// Generate HTML
|
|
255
|
-
const html = generator.generate(ast, {
|
|
256
|
-
format: 'html',
|
|
257
|
-
includeTableOfContents: true,
|
|
258
|
-
includeExamples: true
|
|
259
|
-
});
|
|
260
|
-
writeFileSync('documentation.html', html);
|
|
261
|
-
|
|
262
|
-
// Generate OpenAPI
|
|
263
|
-
const openapi = generator.generate(ast, {
|
|
264
|
-
format: 'openapi',
|
|
265
|
-
baseUrl: 'https://api.example.com'
|
|
266
|
-
});
|
|
267
|
-
writeFileSync('openapi.json', openapi);
|
|
268
|
-
|
|
269
|
-
console.log('✅ Documentation generated (Markdown, HTML, OpenAPI)');
|
|
270
|
-
return markdown;
|
|
271
|
-
} catch (error) {
|
|
272
|
-
console.warn('⚠️ Documentation generation failed:', error.message);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// ============================================
|
|
277
|
-
// MAIN EXAMPLE
|
|
278
|
-
// ============================================
|
|
279
|
-
|
|
280
|
-
async function main() {
|
|
281
|
-
const specFile = '../01-fundamentals/01-01-basic-model.specly';
|
|
282
|
-
|
|
283
|
-
// Basic operations
|
|
284
|
-
console.log('1️⃣ Parsing...');
|
|
285
|
-
const ast = parseSpec(specFile);
|
|
286
|
-
|
|
287
|
-
if (ast) {
|
|
288
|
-
console.log('2️⃣ Analyzing...');
|
|
289
|
-
const stats = analyzeSpec(ast);
|
|
290
|
-
console.log(' Stats:', stats);
|
|
291
|
-
|
|
292
|
-
console.log('3️⃣ Running inference...');
|
|
293
|
-
await runInference(specFile);
|
|
294
|
-
|
|
295
|
-
console.log('4️⃣ Generating outputs...');
|
|
296
|
-
generateAIView(ast);
|
|
297
|
-
generateDiagrams(ast);
|
|
298
|
-
generateDocs(ast);
|
|
299
|
-
|
|
300
|
-
console.log('5️⃣ Converting to YAML...');
|
|
301
|
-
speclyToYaml(specFile, 'converted.yaml');
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
console.log('\n✨ Done!');
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// Run if executed directly
|
|
308
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
309
|
-
main().catch(console.error);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
// Export functions for use in other modules
|
|
313
|
-
export {
|
|
314
|
-
parseSpec,
|
|
315
|
-
validateSpec,
|
|
316
|
-
speclyToYaml,
|
|
317
|
-
analyzeSpec,
|
|
318
|
-
generateReport,
|
|
319
|
-
runInference,
|
|
320
|
-
generateAIView,
|
|
321
|
-
generateDiagrams,
|
|
322
|
-
generateDocs
|
|
323
|
-
};
|
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SpecVerse TypeScript/JavaScript API Usage Examples
|
|
3
|
-
*
|
|
4
|
-
* This file demonstrates how to use SpecVerse functionality programmatically
|
|
5
|
-
* instead of through the CLI.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
// Parser and AST
|
|
10
|
-
SpecVerseParser,
|
|
11
|
-
ParseResult,
|
|
12
|
-
SpecVerseAST,
|
|
13
|
-
|
|
14
|
-
// Inference Engine
|
|
15
|
-
LogicalInferenceEngine,
|
|
16
|
-
InferenceEngineConfig,
|
|
17
|
-
|
|
18
|
-
// Generators
|
|
19
|
-
AIViewGenerator,
|
|
20
|
-
UMLGenerator,
|
|
21
|
-
DocumentationGenerator,
|
|
22
|
-
UnifiedDiagramGenerator,
|
|
23
|
-
|
|
24
|
-
// Types
|
|
25
|
-
ModelSpec,
|
|
26
|
-
ControllerSpec,
|
|
27
|
-
ServiceSpec,
|
|
28
|
-
EventSpec,
|
|
29
|
-
ViewSpec
|
|
30
|
-
} from '@specverse/lang';
|
|
31
|
-
|
|
32
|
-
import { readFileSync, writeFileSync } from 'fs';
|
|
33
|
-
import * as yaml from 'js-yaml';
|
|
34
|
-
|
|
35
|
-
// ============================================
|
|
36
|
-
// 1. PARSING SPECVERSE FILES
|
|
37
|
-
// ============================================
|
|
38
|
-
|
|
39
|
-
async function parseSpecification(filePath: string): Promise<SpecVerseAST | undefined> {
|
|
40
|
-
// Load the schema (in real usage, this would be from node_modules/@specverse/lang/schema/)
|
|
41
|
-
const schema = JSON.parse(readFileSync('node_modules/@specverse/lang/schema/SPECVERSE-SCHEMA.json', 'utf8'));
|
|
42
|
-
|
|
43
|
-
// Create parser instance
|
|
44
|
-
const parser = new SpecVerseParser(schema);
|
|
45
|
-
|
|
46
|
-
// Read and parse the file
|
|
47
|
-
const content = readFileSync(filePath, 'utf8');
|
|
48
|
-
const result: ParseResult = parser.parseContent(content, filePath);
|
|
49
|
-
|
|
50
|
-
// Check for errors
|
|
51
|
-
if (result.errors.length > 0) {
|
|
52
|
-
console.error('Parse errors:', result.errors);
|
|
53
|
-
return undefined;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Handle warnings if any
|
|
57
|
-
if (result.warnings && result.warnings.length > 0) {
|
|
58
|
-
console.warn('Parse warnings:', result.warnings);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
console.log('✅ Successfully parsed:', filePath);
|
|
62
|
-
return result.ast;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// ============================================
|
|
66
|
-
// 2. USING THE INFERENCE ENGINE
|
|
67
|
-
// ============================================
|
|
68
|
-
|
|
69
|
-
async function runInference(ast: SpecVerseAST): Promise<any> {
|
|
70
|
-
// Configure inference options
|
|
71
|
-
const config: Partial<InferenceEngineConfig> = {
|
|
72
|
-
logical: {
|
|
73
|
-
generateControllers: true,
|
|
74
|
-
generateServices: true,
|
|
75
|
-
generateEvents: true,
|
|
76
|
-
generateViews: true,
|
|
77
|
-
generateTypes: true,
|
|
78
|
-
},
|
|
79
|
-
rules: {
|
|
80
|
-
logicalRulesPath: 'node_modules/@specverse/lang/dist/inference-engine/rules/logical',
|
|
81
|
-
deploymentRulesPath: 'node_modules/@specverse/lang/dist/inference-engine/rules/deployment'
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// Create inference engine instance
|
|
86
|
-
const inferenceEngine = new LogicalInferenceEngine(config);
|
|
87
|
-
|
|
88
|
-
// Extract models from AST
|
|
89
|
-
const models = ast.components.flatMap(c => c.models);
|
|
90
|
-
|
|
91
|
-
// Load rules first
|
|
92
|
-
console.log('📋 Loading inference rules...');
|
|
93
|
-
const rulesValidation = await inferenceEngine.loadRules();
|
|
94
|
-
|
|
95
|
-
if (!rulesValidation.valid) {
|
|
96
|
-
console.error('❌ Failed to load inference rules:', rulesValidation.errors.map(e => e.message));
|
|
97
|
-
return undefined;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Run inference on models
|
|
101
|
-
const componentName = 'GeneratedComponent';
|
|
102
|
-
const inferenceResult = await inferenceEngine.inferLogicalSpecification(models, componentName);
|
|
103
|
-
|
|
104
|
-
console.log('📊 Inference Results:');
|
|
105
|
-
console.log(' Validation:', inferenceResult.validation.valid ? '✅' : '❌');
|
|
106
|
-
console.log(' Models processed:', inferenceResult.statistics.modelsProcessed);
|
|
107
|
-
console.log(' Controllers generated:', inferenceResult.statistics.controllersGenerated);
|
|
108
|
-
console.log(' Services generated:', inferenceResult.statistics.servicesGenerated);
|
|
109
|
-
console.log(' Events generated:', inferenceResult.statistics.eventsGenerated);
|
|
110
|
-
console.log(' Views generated:', inferenceResult.statistics.viewsGenerated);
|
|
111
|
-
|
|
112
|
-
if (!inferenceResult.validation.valid) {
|
|
113
|
-
console.error(' Errors:', inferenceResult.validation.errors.map(e => e.message));
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return inferenceResult;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// ============================================
|
|
120
|
-
// 3. GENERATING AI-OPTIMIZED SPECIFICATIONS
|
|
121
|
-
// ============================================
|
|
122
|
-
|
|
123
|
-
async function generateAIView(ast: SpecVerseAST): Promise<void> {
|
|
124
|
-
const generator = new AIViewGenerator();
|
|
125
|
-
|
|
126
|
-
// Generate AI-optimized specification
|
|
127
|
-
const aiSpec = generator.generate(ast);
|
|
128
|
-
|
|
129
|
-
// Convert to YAML for readability
|
|
130
|
-
const yamlOutput = yaml.dump(aiSpec, {
|
|
131
|
-
indent: 2,
|
|
132
|
-
lineWidth: 120,
|
|
133
|
-
noRefs: true
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
writeFileSync('output/ai-optimized.yaml', yamlOutput);
|
|
137
|
-
console.log('✅ AI-optimized specification generated');
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// ============================================
|
|
141
|
-
// 4. GENERATING UML DIAGRAMS
|
|
142
|
-
// ============================================
|
|
143
|
-
|
|
144
|
-
async function generateUMLDiagrams(ast: SpecVerseAST): Promise<void> {
|
|
145
|
-
try {
|
|
146
|
-
const generator = new UMLGenerator();
|
|
147
|
-
|
|
148
|
-
// Generate different types of diagrams with proper options
|
|
149
|
-
const diagramTypes = [
|
|
150
|
-
{ type: 'er' as const, includeAttributes: true, includeRelationships: true },
|
|
151
|
-
{ type: 'sequence' as const, includeEvents: true },
|
|
152
|
-
{ type: 'architecture' as const, includeControllers: true, includeServices: true, includeEvents: true },
|
|
153
|
-
{ type: 'lifecycle' as const }
|
|
154
|
-
];
|
|
155
|
-
|
|
156
|
-
// Generate and save diagrams
|
|
157
|
-
for (const options of diagramTypes) {
|
|
158
|
-
const content = generator.generate(ast, options);
|
|
159
|
-
if (content) {
|
|
160
|
-
writeFileSync(`output/diagram-${options.type}.mmd`, content);
|
|
161
|
-
console.log(`✅ Generated ${options.type} diagram`);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
} catch (error) {
|
|
165
|
-
console.warn('⚠️ UML diagram generation failed:', error instanceof Error ? error.message : String(error));
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// ============================================
|
|
170
|
-
// 5. GENERATING DOCUMENTATION
|
|
171
|
-
// ============================================
|
|
172
|
-
|
|
173
|
-
async function generateDocumentation(ast: SpecVerseAST): Promise<void> {
|
|
174
|
-
try {
|
|
175
|
-
const generator = new DocumentationGenerator();
|
|
176
|
-
|
|
177
|
-
// Generate markdown documentation
|
|
178
|
-
const markdown = generator.generate(ast, {
|
|
179
|
-
format: 'markdown',
|
|
180
|
-
includeTableOfContents: true,
|
|
181
|
-
includeExamples: true,
|
|
182
|
-
includeDiagrams: false
|
|
183
|
-
});
|
|
184
|
-
writeFileSync('output/documentation.md', markdown);
|
|
185
|
-
|
|
186
|
-
// Generate HTML documentation
|
|
187
|
-
const html = generator.generate(ast, {
|
|
188
|
-
format: 'html',
|
|
189
|
-
includeTableOfContents: true,
|
|
190
|
-
includeExamples: true
|
|
191
|
-
});
|
|
192
|
-
writeFileSync('output/documentation.html', html);
|
|
193
|
-
|
|
194
|
-
// Generate OpenAPI specification
|
|
195
|
-
const openapi = generator.generate(ast, {
|
|
196
|
-
format: 'openapi',
|
|
197
|
-
baseUrl: 'https://api.example.com'
|
|
198
|
-
});
|
|
199
|
-
writeFileSync('output/openapi.json', openapi);
|
|
200
|
-
|
|
201
|
-
console.log('✅ Documentation generated (Markdown, HTML, OpenAPI)');
|
|
202
|
-
} catch (error) {
|
|
203
|
-
console.warn('⚠️ Documentation generation failed:', error instanceof Error ? error.message : String(error));
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// ============================================
|
|
208
|
-
// 6. WORKING WITH MERMAID DIAGRAMS (V3.1)
|
|
209
|
-
// ============================================
|
|
210
|
-
|
|
211
|
-
async function generateMermaidDiagrams(filePath: string): Promise<void> {
|
|
212
|
-
const generator = new UnifiedDiagramGenerator();
|
|
213
|
-
|
|
214
|
-
// Generate all diagram types
|
|
215
|
-
const outputDir = 'output/diagrams';
|
|
216
|
-
await generator.generateFromFile(filePath, outputDir);
|
|
217
|
-
|
|
218
|
-
console.log('✅ Mermaid diagrams generated in:', outputDir);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// ============================================
|
|
222
|
-
// 7. CUSTOM PROCESSING EXAMPLE
|
|
223
|
-
// ============================================
|
|
224
|
-
|
|
225
|
-
async function customProcessing(ast: SpecVerseAST): Promise<void> {
|
|
226
|
-
// Extract all models
|
|
227
|
-
const allModels: ModelSpec[] = ast.components.flatMap(c => c.models);
|
|
228
|
-
|
|
229
|
-
// Extract all controllers
|
|
230
|
-
const allControllers: ControllerSpec[] = ast.components.flatMap(c => c.controllers);
|
|
231
|
-
|
|
232
|
-
// Extract all events
|
|
233
|
-
const allEvents: EventSpec[] = ast.components.flatMap(c => c.events);
|
|
234
|
-
|
|
235
|
-
// Custom analysis
|
|
236
|
-
console.log('\n📊 Custom Analysis:');
|
|
237
|
-
console.log('Total models:', allModels.length);
|
|
238
|
-
console.log('Models with lifecycles:', allModels.filter(m => m.lifecycle).length);
|
|
239
|
-
console.log('Total endpoints:', allControllers.flatMap(c => c.actions).length);
|
|
240
|
-
console.log('Total events:', allEvents.length);
|
|
241
|
-
|
|
242
|
-
// Generate custom output
|
|
243
|
-
const customOutput = {
|
|
244
|
-
summary: {
|
|
245
|
-
modelCount: allModels.length,
|
|
246
|
-
controllerCount: allControllers.length,
|
|
247
|
-
eventCount: allEvents.length,
|
|
248
|
-
},
|
|
249
|
-
models: allModels.map(m => ({
|
|
250
|
-
name: m.name,
|
|
251
|
-
attributeCount: Object.keys(m.attributes || {}).length,
|
|
252
|
-
hasLifecycle: !!m.lifecycle,
|
|
253
|
-
relationshipCount: m.relationships?.length || 0
|
|
254
|
-
})),
|
|
255
|
-
controllers: allControllers.map(c => ({
|
|
256
|
-
name: c.name,
|
|
257
|
-
actionCount: c.actions.length,
|
|
258
|
-
model: c.model
|
|
259
|
-
}))
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
writeFileSync('output/custom-analysis.json', JSON.stringify(customOutput, null, 2));
|
|
263
|
-
console.log('✅ Custom analysis saved');
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// ============================================
|
|
267
|
-
// 8. VALIDATION ONLY
|
|
268
|
-
// ============================================
|
|
269
|
-
|
|
270
|
-
function validateSpecification(filePath: string): boolean {
|
|
271
|
-
const schema = JSON.parse(readFileSync('node_modules/@specverse/lang/schema/SPECVERSE-SCHEMA.json', 'utf8'));
|
|
272
|
-
const parser = new SpecVerseParser(schema);
|
|
273
|
-
|
|
274
|
-
const content = readFileSync(filePath, 'utf8');
|
|
275
|
-
const result = parser.parseContent(content, filePath);
|
|
276
|
-
|
|
277
|
-
if (result.errors.length === 0) {
|
|
278
|
-
console.log('✅ Specification is valid');
|
|
279
|
-
return true;
|
|
280
|
-
} else {
|
|
281
|
-
console.error('❌ Validation errors:');
|
|
282
|
-
result.errors.forEach(error => console.error(' -', error));
|
|
283
|
-
return false;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// ============================================
|
|
288
|
-
// 9. PROCESSING SPECLY TO YAML
|
|
289
|
-
// ============================================
|
|
290
|
-
|
|
291
|
-
function processSpeclyToYaml(speclyPath: string, outputPath: string): void {
|
|
292
|
-
const schema = JSON.parse(readFileSync('node_modules/@specverse/lang/schema/SPECVERSE-SCHEMA.json', 'utf8'));
|
|
293
|
-
const parser = new SpecVerseParser(schema);
|
|
294
|
-
|
|
295
|
-
const content = readFileSync(speclyPath, 'utf8');
|
|
296
|
-
const result = parser.processToYaml(content);
|
|
297
|
-
|
|
298
|
-
if (result.errors.length > 0) {
|
|
299
|
-
console.error('❌ Processing errors:', result.errors);
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
writeFileSync(outputPath, result.yaml);
|
|
304
|
-
console.log('✅ Processed to YAML:', outputPath);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// ============================================
|
|
308
|
-
// MAIN EXAMPLE USAGE
|
|
309
|
-
// ============================================
|
|
310
|
-
|
|
311
|
-
async function main() {
|
|
312
|
-
try {
|
|
313
|
-
const specFile = 'examples/01-fundamentals/01-01-basic-model.specly';
|
|
314
|
-
|
|
315
|
-
// 1. Parse the specification
|
|
316
|
-
const ast = await parseSpecification(specFile);
|
|
317
|
-
if (!ast) {
|
|
318
|
-
console.error('Failed to parse specification');
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// 2. Run inference to generate complete architecture
|
|
323
|
-
const inferenceResult = await runInference(ast);
|
|
324
|
-
|
|
325
|
-
// 3. Generate various outputs
|
|
326
|
-
await generateAIView(ast);
|
|
327
|
-
await generateUMLDiagrams(ast);
|
|
328
|
-
await generateDocumentation(ast);
|
|
329
|
-
await generateMermaidDiagrams(specFile);
|
|
330
|
-
|
|
331
|
-
// 4. Custom processing
|
|
332
|
-
await customProcessing(ast);
|
|
333
|
-
|
|
334
|
-
// 5. Process .specly to .yaml
|
|
335
|
-
processSpeclyToYaml(specFile, 'output/processed.yaml');
|
|
336
|
-
|
|
337
|
-
console.log('\n✨ All operations completed successfully!');
|
|
338
|
-
|
|
339
|
-
} catch (error) {
|
|
340
|
-
console.error('Error:', error);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// Run if this file is executed directly
|
|
345
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
346
|
-
main();
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// ============================================
|
|
350
|
-
// EXPORTS FOR USE IN OTHER MODULES
|
|
351
|
-
// ============================================
|
|
352
|
-
|
|
353
|
-
export {
|
|
354
|
-
parseSpecification,
|
|
355
|
-
runInference,
|
|
356
|
-
generateAIView,
|
|
357
|
-
generateUMLDiagrams,
|
|
358
|
-
generateDocumentation,
|
|
359
|
-
generateMermaidDiagrams,
|
|
360
|
-
customProcessing,
|
|
361
|
-
validateSpecification,
|
|
362
|
-
processSpeclyToYaml
|
|
363
|
-
};
|