@specverse/engines 4.1.5 → 4.1.6

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 (120) hide show
  1. package/dist/libs/instance-factories/applications/templates/generic/backend-env-generator.js +22 -0
  2. package/dist/libs/instance-factories/applications/templates/generic/backend-package-json-generator.js +66 -0
  3. package/dist/libs/instance-factories/applications/templates/generic/backend-tsconfig-generator.js +54 -0
  4. package/dist/libs/instance-factories/applications/templates/generic/main-generator.js +290 -0
  5. package/dist/libs/instance-factories/applications/templates/react/_view-components-source.js +530 -0
  6. package/dist/libs/instance-factories/applications/templates/react/api-client-generator.js +437 -0
  7. package/dist/libs/instance-factories/applications/templates/react/api-types-generator.js +146 -0
  8. package/dist/libs/instance-factories/applications/templates/react/app-tsx-generator.js +73 -0
  9. package/dist/libs/instance-factories/applications/templates/react/env-example-generator.js +18 -0
  10. package/dist/libs/instance-factories/applications/templates/react/field-helpers-generator.js +99 -0
  11. package/dist/libs/instance-factories/applications/templates/react/gitignore-generator.js +35 -0
  12. package/dist/libs/instance-factories/applications/templates/react/index-css-generator.js +9 -0
  13. package/dist/libs/instance-factories/applications/templates/react/index-html-generator.js +23 -0
  14. package/dist/libs/instance-factories/applications/templates/react/main-tsx-generator.js +29 -0
  15. package/dist/libs/instance-factories/applications/templates/react/package-json-generator.js +49 -0
  16. package/dist/libs/instance-factories/applications/templates/react/pattern-adapter-generator.js +156 -0
  17. package/dist/libs/instance-factories/applications/templates/react/react-pattern-adapter.js +935 -0
  18. package/dist/libs/instance-factories/applications/templates/react/relationship-field-generator.js +143 -0
  19. package/dist/libs/instance-factories/applications/templates/react/runtime-app-tsx-generator.js +101 -0
  20. package/dist/libs/instance-factories/applications/templates/react/runtime-package-json-generator.js +50 -0
  21. package/dist/libs/instance-factories/applications/templates/react/tailwind-adapter-generator.js +646 -0
  22. package/dist/libs/instance-factories/applications/templates/react/tailwind-adapter-wrapper-generator.js +65 -0
  23. package/dist/libs/instance-factories/applications/templates/react/tsconfig-generator.js +28 -0
  24. package/dist/libs/instance-factories/applications/templates/react/use-api-hooks-generator.js +132 -0
  25. package/dist/libs/instance-factories/applications/templates/react/view-dashboard-generator.js +143 -0
  26. package/dist/libs/instance-factories/applications/templates/react/view-detail-generator.js +143 -0
  27. package/dist/libs/instance-factories/applications/templates/react/view-form-generator.js +355 -0
  28. package/dist/libs/instance-factories/applications/templates/react/view-list-generator.js +91 -0
  29. package/dist/libs/instance-factories/applications/templates/react/view-router-generator.js +79 -0
  30. package/dist/libs/instance-factories/applications/templates/react/vite-config-generator.js +42 -0
  31. package/dist/libs/instance-factories/cli/templates/commander/cli-bin-wrapper-generator.js +11 -0
  32. package/dist/libs/instance-factories/cli/templates/commander/cli-entry-generator.js +111 -0
  33. package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +928 -0
  34. package/dist/libs/instance-factories/communication/templates/eventemitter/bus-generator.js +83 -0
  35. package/dist/libs/instance-factories/communication/templates/eventemitter/publisher-generator.js +91 -0
  36. package/dist/libs/instance-factories/communication/templates/eventemitter/subscriber-generator.js +86 -0
  37. package/dist/libs/instance-factories/controllers/templates/fastify/meta-routes-generator.js +93 -0
  38. package/dist/libs/instance-factories/controllers/templates/fastify/routes-generator.js +280 -0
  39. package/dist/libs/instance-factories/controllers/templates/fastify/server-generator.js +125 -0
  40. package/dist/libs/instance-factories/infrastructure/templates/docker-k8s/infrastructure-generator.js +25 -0
  41. package/dist/libs/instance-factories/orms/templates/prisma/schema-generator.js +371 -0
  42. package/dist/libs/instance-factories/orms/templates/prisma/services-generator.js +266 -0
  43. package/dist/libs/instance-factories/scaffolding/templates/generic/env-example-generator.js +51 -0
  44. package/dist/libs/instance-factories/scaffolding/templates/generic/env-generator.js +61 -0
  45. package/dist/libs/instance-factories/scaffolding/templates/generic/gitignore-generator.js +59 -0
  46. package/dist/libs/instance-factories/scaffolding/templates/generic/package-json-generator.js +126 -0
  47. package/dist/libs/instance-factories/scaffolding/templates/generic/readme-generator.js +159 -0
  48. package/dist/libs/instance-factories/scaffolding/templates/generic/tsconfig-generator.js +56 -0
  49. package/dist/libs/instance-factories/scaffolding/templates/generic/tsconfig-react-generator.js +37 -0
  50. package/dist/libs/instance-factories/sdks/templates/python/sdk-generator.js +29 -0
  51. package/dist/libs/instance-factories/sdks/templates/typescript/sdk-generator.js +28 -0
  52. package/dist/libs/instance-factories/services/templates/memory/generate-interpreter.js +14 -0
  53. package/dist/libs/instance-factories/services/templates/memory/step-conventions-memory.js +415 -0
  54. package/dist/libs/instance-factories/services/templates/prisma/behavior-generator.js +177 -0
  55. package/dist/libs/instance-factories/services/templates/prisma/controller-generator.js +413 -0
  56. package/dist/libs/instance-factories/services/templates/prisma/service-generator.js +243 -0
  57. package/dist/libs/instance-factories/services/templates/prisma/step-conventions.js +264 -0
  58. package/dist/libs/instance-factories/services/templates/shared-patterns.js +24 -0
  59. package/dist/libs/instance-factories/shared/path-resolver.js +59 -0
  60. package/dist/libs/instance-factories/storage/templates/mongodb/config-generator.js +13 -0
  61. package/dist/libs/instance-factories/storage/templates/mongodb/docker-generator.js +16 -0
  62. package/dist/libs/instance-factories/storage/templates/postgresql/config-generator.js +45 -0
  63. package/dist/libs/instance-factories/storage/templates/postgresql/docker-generator.js +46 -0
  64. package/dist/libs/instance-factories/storage/templates/redis/config-generator.js +14 -0
  65. package/dist/libs/instance-factories/storage/templates/redis/docker-generator.js +16 -0
  66. package/dist/libs/instance-factories/test-generation.js +145 -0
  67. package/dist/libs/instance-factories/testing/templates/vitest/tests-generator.js +30 -0
  68. package/dist/libs/instance-factories/tools/templates/mcp/mcp-server-generator.js +149 -0
  69. package/dist/libs/instance-factories/tools/templates/mcp/static/src/controllers/MCPServerController.js +232 -0
  70. package/dist/libs/instance-factories/tools/templates/mcp/static/src/events/EventEmitter.js +49 -0
  71. package/dist/libs/instance-factories/tools/templates/mcp/static/src/index.js +18 -0
  72. package/dist/libs/instance-factories/tools/templates/mcp/static/src/interfaces/ResourceProvider.js +0 -0
  73. package/dist/libs/instance-factories/tools/templates/mcp/static/src/models/LibrarySuggestion.js +97 -0
  74. package/dist/libs/instance-factories/tools/templates/mcp/static/src/models/SpecVerseResource.js +64 -0
  75. package/dist/libs/instance-factories/tools/templates/mcp/static/src/server/mcp-server.js +182 -0
  76. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/CLIProxyService.js +1210 -0
  77. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/EmbeddedResourcesAdapter.js +172 -0
  78. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/EntityModuleService.js +240 -0
  79. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/HybridResourcesProvider.js +147 -0
  80. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/LibraryToolsService.js +281 -0
  81. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/OrchestratorBridge.js +409 -0
  82. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/OrchestratorToolsService.js +414 -0
  83. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/PromptToolsService.js +467 -0
  84. package/dist/libs/instance-factories/tools/templates/mcp/static/src/services/ResourcesProviderService.js +135 -0
  85. package/dist/libs/instance-factories/tools/templates/mcp/static/src/types/index.js +0 -0
  86. package/dist/libs/instance-factories/tools/templates/vscode/static/extension.js +965 -0
  87. package/dist/libs/instance-factories/tools/templates/vscode/vscode-extension-generator.js +238 -0
  88. package/dist/libs/instance-factories/validation/templates/zod/validation-generator.js +25 -0
  89. package/dist/libs/instance-factories/views/index.js +48 -0
  90. package/dist/libs/instance-factories/views/templates/react/adapters/antd-adapter.js +742 -0
  91. package/dist/libs/instance-factories/views/templates/react/adapters/mui-adapter.js +824 -0
  92. package/dist/libs/instance-factories/views/templates/react/adapters/shadcn-adapter.js +719 -0
  93. package/dist/libs/instance-factories/views/templates/react/app-generator.js +45 -0
  94. package/dist/libs/instance-factories/views/templates/react/components-generator.js +779 -0
  95. package/dist/libs/instance-factories/views/templates/react/forms-generator.js +285 -0
  96. package/dist/libs/instance-factories/views/templates/react/frontend-package-json-generator.js +46 -0
  97. package/dist/libs/instance-factories/views/templates/react/hooks-generator.js +111 -0
  98. package/dist/libs/instance-factories/views/templates/react/index-css-generator.js +9 -0
  99. package/dist/libs/instance-factories/views/templates/react/index-html-generator.js +23 -0
  100. package/dist/libs/instance-factories/views/templates/react/main-tsx-generator.js +21 -0
  101. package/dist/libs/instance-factories/views/templates/react/react-component-generator.js +299 -0
  102. package/dist/libs/instance-factories/views/templates/react/router-generator.js +136 -0
  103. package/dist/libs/instance-factories/views/templates/react/router-generic-generator.js +107 -0
  104. package/dist/libs/instance-factories/views/templates/react/shared-utils-generator.js +179 -0
  105. package/dist/libs/instance-factories/views/templates/react/spec-json-generator.js +7 -0
  106. package/dist/libs/instance-factories/views/templates/react/types-generator.js +56 -0
  107. package/dist/libs/instance-factories/views/templates/react/views-metadata-generator.js +27 -0
  108. package/dist/libs/instance-factories/views/templates/react/vite-config-generator.js +29 -0
  109. package/dist/libs/instance-factories/views/templates/runtime/runtime-view-renderer.js +261 -0
  110. package/dist/libs/instance-factories/views/templates/shared/adapter-types.js +34 -0
  111. package/dist/libs/instance-factories/views/templates/shared/atomic-components-registry.js +800 -0
  112. package/dist/libs/instance-factories/views/templates/shared/base-generator.js +305 -0
  113. package/dist/libs/instance-factories/views/templates/shared/component-metadata.js +517 -0
  114. package/dist/libs/instance-factories/views/templates/shared/composite-pattern-types.js +0 -0
  115. package/dist/libs/instance-factories/views/templates/shared/composite-patterns.js +445 -0
  116. package/dist/libs/instance-factories/views/templates/shared/index.js +80 -0
  117. package/dist/libs/instance-factories/views/templates/shared/pattern-validator.js +210 -0
  118. package/dist/libs/instance-factories/views/templates/shared/property-mapper.js +492 -0
  119. package/dist/libs/instance-factories/views/templates/shared/syntax-mapper.js +321 -0
  120. package/package.json +3 -2
@@ -0,0 +1,264 @@
1
+ function toVar(name) {
2
+ return name.charAt(0).toLowerCase() + name.slice(1);
3
+ }
4
+ function toMethod(words) {
5
+ return words.trim().replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/^\w/, (c) => c.toLowerCase());
6
+ }
7
+ const STEP_CONVENTIONS = [
8
+ // --- Validation ---
9
+ {
10
+ name: "validate",
11
+ pattern: /^validate\s+(.+)/i,
12
+ generateCall: (m, ctx) => ` // Step ${ctx.stepNum}: Validate ${m[1]}
13
+ const validationResult = this.validate(params, { operation: '${ctx.operationName}' });
14
+ if (!validationResult.valid) {
15
+ throw new Error(\`Validation failed: \${validationResult.errors.join(', ')}\`);
16
+ }`
17
+ },
18
+ // --- Check / Guard ---
19
+ {
20
+ name: "check",
21
+ pattern: /^check\s+(.+)/i,
22
+ generateCall: (m, ctx) => {
23
+ const condition = m[1];
24
+ const methodName = toMethod("check " + condition);
25
+ return ` // Step ${ctx.stepNum}: Check ${condition}
26
+ const checkResult = await this.${methodName}(params);
27
+ if (!checkResult) {
28
+ throw new Error('Check failed: ${condition}');
29
+ }`;
30
+ },
31
+ generateMethod: (m, ctx) => {
32
+ const condition = m[1];
33
+ const methodName = toMethod("check " + condition);
34
+ return `
35
+ private async ${methodName}(params: any): Promise<boolean> {
36
+ // TODO: Implement check \u2014 ${condition}
37
+ const ${toVar(ctx.prismaModel)} = await this.prisma.${toVar(ctx.prismaModel)}.findUnique({ where: { id: params.id } });
38
+ if (!${toVar(ctx.prismaModel)}) return false;
39
+ return true;
40
+ }`;
41
+ }
42
+ },
43
+ // --- Find / Lookup ---
44
+ {
45
+ name: "find",
46
+ pattern: /^find\s+(\w+)\s+by\s+(\w+)/i,
47
+ generateCall: (m, ctx) => {
48
+ const model = m[1];
49
+ const field = m[2];
50
+ return ` // Step ${ctx.stepNum}: Find ${model} by ${field}
51
+ const ${toVar(model)} = await this.prisma.${toVar(model)}.findUnique({ where: { ${field}: params.${field} } });
52
+ if (!${toVar(model)}) {
53
+ throw new Error('${model} not found by ${field}');
54
+ }`;
55
+ }
56
+ },
57
+ // --- Create ---
58
+ {
59
+ name: "create",
60
+ pattern: /^create\s+(\w+)(?:\s+record)?/i,
61
+ generateCall: (m, ctx) => {
62
+ const model = m[1];
63
+ return ` // Step ${ctx.stepNum}: Create ${model}
64
+ const ${toVar(model)} = await this.prisma.${toVar(model)}.create({ data: params });`;
65
+ }
66
+ },
67
+ // --- Update field ---
68
+ {
69
+ name: "update-field",
70
+ pattern: /^update\s+(\w+)\s+(\w+)\s+to\s+(.+)/i,
71
+ generateCall: (m, ctx) => {
72
+ const model = m[1];
73
+ const field = m[2];
74
+ const value = m[3].trim().replace(/"/g, "'");
75
+ const isString = /^[a-z]/.test(value) && !value.includes(".");
76
+ const val = isString ? `'${value}'` : value;
77
+ return ` // Step ${ctx.stepNum}: Update ${model} ${field} to ${value}
78
+ await this.prisma.${toVar(model)}.update({
79
+ where: { id: params.id },
80
+ data: { ${field}: ${val} },
81
+ });`;
82
+ }
83
+ },
84
+ // --- Generic update ---
85
+ {
86
+ name: "update",
87
+ pattern: /^update\s+(\w+)(?:\s+(.+))?/i,
88
+ generateCall: (m, ctx) => {
89
+ const model = m[1];
90
+ return ` // Step ${ctx.stepNum}: Update ${model}
91
+ await this.prisma.${toVar(model)}.update({
92
+ where: { id: params.id },
93
+ data: params,
94
+ });`;
95
+ }
96
+ },
97
+ // --- Delete ---
98
+ {
99
+ name: "delete",
100
+ pattern: /^delete\s+(\w+)/i,
101
+ generateCall: (m, ctx) => {
102
+ const model = m[1];
103
+ return ` // Step ${ctx.stepNum}: Delete ${model}
104
+ await this.prisma.${toVar(model)}.delete({ where: { id: params.id } });`;
105
+ }
106
+ },
107
+ // --- Transition / Evolve ---
108
+ {
109
+ name: "transition",
110
+ pattern: /^transition\s+(\w+)\s+to\s+(\w+)/i,
111
+ generateCall: (m, ctx) => {
112
+ const model = m[1];
113
+ const state = m[2];
114
+ return ` // Step ${ctx.stepNum}: Transition ${model} to ${state}
115
+ const current = await this.prisma.${toVar(model)}.findUniqueOrThrow({ where: { id: params.id } });
116
+ // Lifecycle validation would check valid transition here
117
+ await this.prisma.${toVar(model)}.update({
118
+ where: { id: params.id },
119
+ data: { status: '${state}' },
120
+ });`;
121
+ }
122
+ },
123
+ // --- Set field ---
124
+ {
125
+ name: "set",
126
+ pattern: /^set\s+(\w+)\s+to\s+(.+)/i,
127
+ generateCall: (m, ctx) => {
128
+ const field = m[1];
129
+ const value = m[2].trim();
130
+ const isCurrentTime = /current time|now|timestamp/i.test(value);
131
+ const val = isCurrentTime ? "new Date()" : `'${value}'`;
132
+ return ` // Step ${ctx.stepNum}: Set ${field} to ${value}
133
+ await this.prisma.${toVar(ctx.prismaModel)}.update({
134
+ where: { id: params.id },
135
+ data: { ${field}: ${val} },
136
+ });`;
137
+ }
138
+ },
139
+ // --- Increment ---
140
+ {
141
+ name: "increment",
142
+ pattern: /^increment\s+(\w+)\s+by\s+(\w+)/i,
143
+ generateCall: (m, ctx) => {
144
+ const field = m[1];
145
+ const amount = m[2];
146
+ const amountVal = /^\d+$/.test(amount) ? amount : `params.${amount}`;
147
+ return ` // Step ${ctx.stepNum}: Increment ${field} by ${amount}
148
+ await this.prisma.${toVar(ctx.prismaModel)}.update({
149
+ where: { id: params.id },
150
+ data: { ${field}: { increment: ${amountVal} } },
151
+ });`;
152
+ }
153
+ },
154
+ // --- Decrement ---
155
+ {
156
+ name: "decrement",
157
+ pattern: /^decrement\s+(\w+)\s+by\s+(\w+)/i,
158
+ generateCall: (m, ctx) => {
159
+ const field = m[1];
160
+ const amount = m[2];
161
+ const amountVal = /^\d+$/.test(amount) ? amount : `params.${amount}`;
162
+ return ` // Step ${ctx.stepNum}: Decrement ${field} by ${amount}
163
+ const current${field} = await this.prisma.${toVar(ctx.prismaModel)}.findUniqueOrThrow({ where: { id: params.id } });
164
+ if ((current${field}.${field} || 0) < ${amountVal}) {
165
+ throw new Error('Cannot decrement ${field} below zero');
166
+ }
167
+ await this.prisma.${toVar(ctx.prismaModel)}.update({
168
+ where: { id: params.id },
169
+ data: { ${field}: { decrement: ${amountVal} } },
170
+ });`;
171
+ }
172
+ },
173
+ // --- Calculate ---
174
+ {
175
+ name: "calculate",
176
+ pattern: /^calculate\s+(.+)/i,
177
+ generateCall: (m, ctx) => {
178
+ const metric = m[1];
179
+ const methodName = toMethod("calculate " + metric);
180
+ return ` // Step ${ctx.stepNum}: Calculate ${metric}
181
+ const ${toVar(metric.replace(/\s+/g, ""))} = await this.${methodName}(params);`;
182
+ },
183
+ generateMethod: (m, ctx) => {
184
+ const metric = m[1];
185
+ const methodName = toMethod("calculate " + metric);
186
+ return `
187
+ private async ${methodName}(params: any): Promise<number> {
188
+ // TODO: Implement calculation \u2014 ${metric}
189
+ return 0;
190
+ }`;
191
+ }
192
+ },
193
+ // --- Send event ---
194
+ {
195
+ name: "send-event",
196
+ pattern: /^(?:send|emit|publish)\s+(\w+)\s+event/i,
197
+ generateCall: (m, ctx) => {
198
+ const event = m[1];
199
+ return ` // Step ${ctx.stepNum}: Emit ${event} event
200
+ this.emit('${event}', { ${toVar(ctx.prismaModel)}Id: params.id, operation: '${ctx.operationName}', timestamp: new Date().toISOString() });`;
201
+ }
202
+ },
203
+ // --- Send notification ---
204
+ {
205
+ name: "send-notification",
206
+ pattern: /^send\s+(\w+)\s+notification/i,
207
+ generateCall: (m, ctx) => {
208
+ const type = m[1];
209
+ return ` // Step ${ctx.stepNum}: Send ${type} notification
210
+ this.emit('${type}Notification', { ${toVar(ctx.prismaModel)}Id: params.id, operation: '${ctx.operationName}' });`;
211
+ }
212
+ },
213
+ // --- Call service ---
214
+ {
215
+ name: "call-service",
216
+ pattern: /^call\s+(\w+)\.(\w+)/i,
217
+ generateCall: (m, ctx) => {
218
+ const service = m[1];
219
+ const method = m[2];
220
+ return ` // Step ${ctx.stepNum}: Call ${service}.${method}
221
+ await this.${toVar(service)}.${method}(params);`;
222
+ }
223
+ },
224
+ // --- Return ---
225
+ {
226
+ name: "return",
227
+ pattern: /^return\s+(.+)/i,
228
+ generateCall: (m, ctx) => {
229
+ const value = m[1].trim();
230
+ const isModel = /^(updated|created|the)\s+/i.test(value) || value === ctx.modelName;
231
+ if (isModel) {
232
+ return ` // Step ${ctx.stepNum}: Return result
233
+ return ${toVar(ctx.prismaModel)};`;
234
+ }
235
+ return ` // Step ${ctx.stepNum}: Return ${value}
236
+ return ${value};`;
237
+ }
238
+ }
239
+ ];
240
+ function matchStep(step, ctx) {
241
+ for (const convention of STEP_CONVENTIONS) {
242
+ const match = step.match(convention.pattern);
243
+ if (match) {
244
+ return {
245
+ call: convention.generateCall(match, ctx),
246
+ helperMethod: convention.generateMethod?.(match, ctx)
247
+ };
248
+ }
249
+ }
250
+ const methodName = toMethod(step);
251
+ return {
252
+ call: ` // Step ${ctx.stepNum}: ${step}
253
+ await this.${methodName}(params);`,
254
+ helperMethod: `
255
+ private async ${methodName}(params: any): Promise<void> {
256
+ // TODO: Implement \u2014 ${step}
257
+ throw new Error('Not implemented: ${methodName}');
258
+ }`
259
+ };
260
+ }
261
+ export {
262
+ STEP_CONVENTIONS,
263
+ matchStep
264
+ };
@@ -0,0 +1,24 @@
1
+ const CONVENTION_PATTERNS = [
2
+ { name: "validate", pattern: /^validate\s+(.+)/i, description: "Validate input data" },
3
+ { name: "check-no-existing", pattern: /^check\s+(?:no\s+existing|.*has\s+no\s+existing)\s+(\w+)\s+for\s+(\w+)\s+in\s+(\w+)/i, description: "Check no duplicate entity exists for a pair" },
4
+ { name: "check", pattern: /^check\s+(.+)/i, description: "Check a condition" },
5
+ { name: "find", pattern: /^find\s+(\w+)\s+by\s+(\w+)/i, description: "Find entity by field" },
6
+ { name: "find-all-for", pattern: /^find\s+(?:all\s+)?(\w+?)s?\s+(?:for|of|belonging\s+to)\s+(\w+)/i, description: "Cross-model query via foreign key" },
7
+ { name: "count-per", pattern: /^count\s+(\w+?)s?\s+(?:per|by|for\s+each)\s+(\w+)/i, description: "Group-by aggregation count" },
8
+ { name: "create", pattern: /^create\s+(\w+)(?:\s+record)?/i, description: "Create a new entity" },
9
+ { name: "update-field", pattern: /^update\s+(\w+)\s+(\w+)\s+to\s+(.+)/i, description: "Update specific field to value" },
10
+ { name: "update", pattern: /^update\s+(\w+)$/i, description: "Update entity with params" },
11
+ { name: "delete", pattern: /^delete\s+(\w+)/i, description: "Delete an entity" },
12
+ { name: "transition", pattern: /^transition\s+(\w+)\s+to\s+(\w+)/i, description: "Lifecycle state transition" },
13
+ { name: "set", pattern: /^set\s+(\w+)\s+to\s+(.+)/i, description: "Set a field value" },
14
+ { name: "increment", pattern: /^increment\s+(\w+)\s+by\s+(\w+)/i, description: "Increment numeric field" },
15
+ { name: "decrement", pattern: /^decrement\s+(\w+)\s+by\s+(\w+)/i, description: "Decrement numeric field" },
16
+ { name: "calculate", pattern: /^calculate\s+(.+)/i, description: "Calculate metric or aggregation" },
17
+ { name: "send-event", pattern: /^(?:send|emit|publish)\s+(\w+)\s+event/i, description: "Publish domain event" },
18
+ { name: "send-notification", pattern: /^send\s+(\w+)\s+notification/i, description: "Send notification event" },
19
+ { name: "call-service", pattern: /^call\s+(\w+)\.(\w+)/i, description: "Delegate to another service" },
20
+ { name: "return", pattern: /^return\s+(.+)/i, description: "Return a value" }
21
+ ];
22
+ export {
23
+ CONVENTION_PATTERNS
24
+ };
@@ -0,0 +1,59 @@
1
+ function resolvePath(relativePath, target, config = {}) {
2
+ const {
3
+ outputStructure = "monorepo",
4
+ backendDir = "backend",
5
+ frontendDir = "frontend",
6
+ baseDir = "."
7
+ } = config;
8
+ if (outputStructure === "standalone") {
9
+ return baseDir === "." ? relativePath : `${baseDir}/${relativePath}`;
10
+ }
11
+ const prefix = target === "backend" ? backendDir : target === "frontend" ? frontendDir : "shared";
12
+ return `${prefix}/${relativePath}`;
13
+ }
14
+ function resolveImportPath(from, to, importPath, config = {}) {
15
+ const { outputStructure = "monorepo" } = config;
16
+ if (outputStructure === "standalone") {
17
+ if (from === "frontend" && to === "backend") {
18
+ throw new Error("Frontend cannot directly import from backend in standalone mode. Use API calls.");
19
+ }
20
+ return importPath;
21
+ }
22
+ if (from === to) {
23
+ return importPath;
24
+ }
25
+ if (from === "frontend" && to === "shared") {
26
+ return `../../shared/${importPath}`;
27
+ }
28
+ if (from === "backend" && to === "shared") {
29
+ return `../../shared/${importPath}`;
30
+ }
31
+ return importPath;
32
+ }
33
+ function getApiBaseUrl(config) {
34
+ const { outputStructure = "monorepo", apiBaseUrl } = config;
35
+ if (apiBaseUrl) {
36
+ return apiBaseUrl;
37
+ }
38
+ if (outputStructure === "standalone") {
39
+ return "${VITE_API_BASE_URL}";
40
+ }
41
+ const port = config.serverPort || 3e3;
42
+ return `http://localhost:${port}`;
43
+ }
44
+ function getPathConfig(context) {
45
+ return {
46
+ outputStructure: context.configuration?.outputStructure || "monorepo",
47
+ backendDir: context.configuration?.backendDir || "backend",
48
+ frontendDir: context.configuration?.frontendDir || "frontend",
49
+ baseDir: context.configuration?.baseDir || ".",
50
+ apiBaseUrl: context.configuration?.apiBaseUrl,
51
+ serverPort: context.configuration?.environments?.development?.server?.port || context.manifest?.configuration?.environments?.development?.server?.port
52
+ };
53
+ }
54
+ export {
55
+ getApiBaseUrl,
56
+ getPathConfig,
57
+ resolveImportPath,
58
+ resolvePath
59
+ };
@@ -0,0 +1,13 @@
1
+ function generateMongoDBConfig(context) {
2
+ const { instance } = context;
3
+ const instanceName = instance?.name || "mongodb";
4
+ return `// MongoDB configuration for ${instanceName}
5
+ // TODO: Implement full MongoDB config generator
6
+ export const mongoConfig = {
7
+ url: process.env.MONGO_URL || 'mongodb://localhost:27017/${instanceName}'
8
+ };
9
+ `;
10
+ }
11
+ export {
12
+ generateMongoDBConfig as default
13
+ };
@@ -0,0 +1,16 @@
1
+ function generateMongoDBDocker(context) {
2
+ const { instance } = context;
3
+ const instanceName = instance?.name || "mongodb";
4
+ return `# MongoDB Docker Compose for ${instanceName}
5
+ # TODO: Implement full MongoDB docker generator
6
+ version: '3.8'
7
+ services:
8
+ ${instanceName}:
9
+ image: mongo:6
10
+ ports:
11
+ - "27017:27017"
12
+ `;
13
+ }
14
+ export {
15
+ generateMongoDBDocker as default
16
+ };
@@ -0,0 +1,45 @@
1
+ function generatePostgreSQLConfig(context) {
2
+ const { instance, implType } = context;
3
+ const config = implType.configuration || {};
4
+ const instanceName = instance?.name || "default";
5
+ return `/**
6
+ * PostgreSQL Database Configuration
7
+ * Instance: ${instanceName}
8
+ * Generated from SpecVerse specification
9
+ */
10
+
11
+ import { Pool, PoolConfig } from 'pg';
12
+
13
+ export const ${instanceName}Config: PoolConfig = {
14
+ host: process.env.${instanceName.toUpperCase()}_DB_HOST || ${JSON.stringify(config.host || "localhost")},
15
+ port: parseInt(process.env.${instanceName.toUpperCase()}_DB_PORT || '${config.port || 5432}'),
16
+ database: process.env.${instanceName.toUpperCase()}_DB_NAME || ${JSON.stringify(config.database || "app")},
17
+ user: process.env.${instanceName.toUpperCase()}_DB_USER,
18
+ password: process.env.${instanceName.toUpperCase()}_DB_PASSWORD,
19
+
20
+ // Connection pool settings
21
+ min: ${config.pool?.min || 2},
22
+ max: ${config.pool?.max || 10},
23
+ idleTimeoutMillis: ${config.pool?.idleTimeoutMillis || 3e4},
24
+ connectionTimeoutMillis: ${config.pool?.connectionTimeoutMillis || 2e3},
25
+
26
+ // Performance settings
27
+ statement_timeout: 30000,
28
+ query_timeout: 30000,
29
+ };
30
+
31
+ // Create connection pool
32
+ export const ${instanceName}Pool = new Pool(${instanceName}Config);
33
+
34
+ // Handle pool errors
35
+ ${instanceName}Pool.on('error', (err) => {
36
+ console.error('Unexpected error on idle PostgreSQL client (${instanceName})', err);
37
+ process.exit(-1);
38
+ });
39
+
40
+ export default ${instanceName}Pool;
41
+ `;
42
+ }
43
+ export {
44
+ generatePostgreSQLConfig as default
45
+ };
@@ -0,0 +1,46 @@
1
+ function generatePostgreSQLDocker(context) {
2
+ const { instance, implType } = context;
3
+ const config = implType.configuration || {};
4
+ const instanceName = instance?.name || "postgres";
5
+ return `# PostgreSQL Docker Compose Configuration
6
+ # Instance: ${instanceName}
7
+ # Generated from SpecVerse specification
8
+
9
+ version: '3.8'
10
+
11
+ services:
12
+ ${instanceName}:
13
+ image: postgres:15-alpine
14
+ container_name: ${instanceName}
15
+ restart: unless-stopped
16
+
17
+ ports:
18
+ - "\${${instanceName.toUpperCase()}_DB_PORT:-${config.port || 5432}}:5432"
19
+
20
+ environment:
21
+ POSTGRES_DB: \${${instanceName.toUpperCase()}_DB_NAME:-app}
22
+ POSTGRES_USER: \${${instanceName.toUpperCase()}_DB_USER:-postgres}
23
+ POSTGRES_PASSWORD: \${${instanceName.toUpperCase()}_DB_PASSWORD}
24
+
25
+ # Performance settings
26
+ POSTGRES_MAX_CONNECTIONS: ${config.settings?.max_connections || 100}
27
+ POSTGRES_SHARED_BUFFERS: ${config.settings?.shared_buffers || "256MB"}
28
+
29
+ volumes:
30
+ - ${instanceName}_data:/var/lib/postgresql/data
31
+ - ./init-scripts:/docker-entrypoint-initdb.d
32
+
33
+ healthcheck:
34
+ test: ["CMD-SHELL", "pg_isready -U \${${instanceName.toUpperCase()}_DB_USER:-postgres}"]
35
+ interval: 10s
36
+ timeout: 5s
37
+ retries: 5
38
+
39
+ volumes:
40
+ ${instanceName}_data:
41
+ driver: local
42
+ `;
43
+ }
44
+ export {
45
+ generatePostgreSQLDocker as default
46
+ };
@@ -0,0 +1,14 @@
1
+ function generateRedisConfig(context) {
2
+ const { instance } = context;
3
+ const instanceName = instance?.name || "redis";
4
+ return `// Redis configuration for ${instanceName}
5
+ // TODO: Implement full Redis config generator
6
+ export const redisConfig = {
7
+ host: process.env.REDIS_HOST || 'localhost',
8
+ port: parseInt(process.env.REDIS_PORT || '6379')
9
+ };
10
+ `;
11
+ }
12
+ export {
13
+ generateRedisConfig as default
14
+ };
@@ -0,0 +1,16 @@
1
+ function generateRedisDocker(context) {
2
+ const { instance } = context;
3
+ const instanceName = instance?.name || "redis";
4
+ return `# Redis Docker Compose for ${instanceName}
5
+ # TODO: Implement full Redis docker generator
6
+ version: '3.8'
7
+ services:
8
+ ${instanceName}:
9
+ image: redis:7-alpine
10
+ ports:
11
+ - "6379:6379"
12
+ `;
13
+ }
14
+ export {
15
+ generateRedisDocker as default
16
+ };
@@ -0,0 +1,145 @@
1
+ import { createDefaultLibrary, createResolver, createCodeGenerator, loadManifest } from "@specverse/engines/realize";
2
+ import { UnifiedSpecVerseParser } from "@specverse/engine-parser";
3
+ import { readFileSync } from "fs";
4
+ import { resolve } from "path";
5
+ async function testV33Generation() {
6
+ console.log("\u{1F9EA} Testing v3.3 Implementation Types System\n");
7
+ try {
8
+ console.log("\u{1F4DA} Step 1: Loading Implementation Type Library...");
9
+ const library = await createDefaultLibrary(process.cwd());
10
+ const allTypes = library.find({});
11
+ console.log(` \u2705 Library loaded with ${allTypes.length} implementation types`);
12
+ allTypes.forEach((type) => {
13
+ console.log(` - ${type.name} v${type.version} (${type.type})`);
14
+ });
15
+ console.log();
16
+ console.log("\u{1F4C4} Step 2: Loading v3.3 Manifest...");
17
+ const manifestPath = resolve(process.cwd(), "examples/v33-test/fastify-prisma-manifest.yaml");
18
+ const manifest = loadManifest(manifestPath);
19
+ console.log(` \u2705 Manifest loaded: ${manifest.name}`);
20
+ console.log(` - Version: ${manifest.version}`);
21
+ console.log(` - Implementation Types: ${manifest.implementationTypes?.length || 0}`);
22
+ console.log(` - Capability Mappings: ${Object.keys(manifest.capabilityMappings || {}).length}`);
23
+ console.log();
24
+ console.log("\u{1F50D} Step 3: Creating Capability Resolver...");
25
+ const resolver = createResolver(library, manifest);
26
+ console.log(` \u2705 Resolver created`);
27
+ console.log();
28
+ console.log("\u{1F4DD} Step 4: Parsing Test Spec...");
29
+ const specPath = resolve(process.cwd(), "examples/01-fundamentals/01-01-basic-model.specly");
30
+ const specContent = readFileSync(specPath, "utf8");
31
+ const schemaPath = resolve(process.cwd(), "schema/SPECVERSE-SCHEMA.json");
32
+ const schema = JSON.parse(readFileSync(schemaPath, "utf8"));
33
+ const parser = new UnifiedSpecVerseParser(schema);
34
+ const parseResult = parser.parse(specContent, "specly");
35
+ if (parseResult.errors && parseResult.errors.length > 0) {
36
+ console.error(" \u274C Parse errors:");
37
+ parseResult.errors.forEach((err) => {
38
+ console.error(` - ${err.message}`);
39
+ });
40
+ return;
41
+ }
42
+ console.log(` \u2705 Spec parsed successfully`);
43
+ console.log(` - Component: ${parseResult.ast?.components ? Object.keys(parseResult.ast.components)[0] : "unknown"}`);
44
+ console.log(` - Models: ${parseResult.ast?.components?.[Object.keys(parseResult.ast.components)[0]]?.models?.length || 0}`);
45
+ console.log(` - Controllers: ${parseResult.ast?.components?.[Object.keys(parseResult.ast.components)[0]]?.controllers?.length || 0}`);
46
+ const deployment = {
47
+ environment: "development",
48
+ instances: {
49
+ "apiServer": {
50
+ name: "Test API Server",
51
+ type: "api-server",
52
+ advertises: ["api.rest", "api.rest.crud"],
53
+ uses: ["storage.database"]
54
+ },
55
+ "database": {
56
+ name: "Test Database",
57
+ type: "storage",
58
+ advertises: ["storage.database", "storage.prisma"],
59
+ uses: []
60
+ }
61
+ }
62
+ };
63
+ console.log(` - Mocked deployment for testing`);
64
+ console.log(` - Instances: ${Object.keys(deployment.instances || {}).length}`);
65
+ console.log();
66
+ console.log("\u{1F517} Step 5: Testing Capability Resolution...");
67
+ const apiInstance = deployment.instances?.["apiServer"];
68
+ if (!apiInstance) {
69
+ console.error(" \u274C No api-server instance found");
70
+ return;
71
+ }
72
+ console.log(` Testing instance: ${apiInstance.name}`);
73
+ console.log(` Advertises: ${apiInstance.advertises?.join(", ")}`);
74
+ const resolved = resolver.resolveForInstance(apiInstance);
75
+ console.log(` \u2705 Resolved ${resolved.length} implementation type(s)`);
76
+ resolved.forEach((impl2) => {
77
+ console.log(` - ${impl2.implementationType.name}`);
78
+ console.log(` Capability: ${impl2.capability}`);
79
+ console.log(` Templates: ${Object.keys(impl2.implementationType.codeTemplates).join(", ")}`);
80
+ });
81
+ console.log();
82
+ console.log("\u2699\uFE0F Step 6: Testing Code Generation...");
83
+ const codeGen = createCodeGenerator({ outputDir: "/tmp/v33-test" });
84
+ const componentName = Object.keys(parseResult.ast?.components || {})[0];
85
+ const component = parseResult.ast?.components?.[componentName];
86
+ const model = component?.models?.[0];
87
+ const controller = component?.controllers?.[0] || {
88
+ name: `${model?.name}Controller`,
89
+ path: `/api/${model?.name?.toLowerCase()}`,
90
+ model: model?.name,
91
+ endpoints: [
92
+ { operation: "create", method: "POST", path: "/" },
93
+ { operation: "retrieve", method: "GET", path: "/:id" },
94
+ { operation: "update", method: "PUT", path: "/:id" },
95
+ { operation: "delete", method: "DELETE", path: "/:id" },
96
+ { operation: "list", method: "GET", path: "/" }
97
+ ]
98
+ };
99
+ if (!model) {
100
+ console.error(" \u274C No model found in spec");
101
+ return;
102
+ }
103
+ console.log(` Generating code for model: ${model.name}`);
104
+ const impl = resolved[0];
105
+ const templates = ["routes", "services", "schema"];
106
+ for (const templateName of templates) {
107
+ try {
108
+ console.log(` Testing ${templateName} template...`);
109
+ const output = await codeGen.generateFromTemplate(
110
+ impl,
111
+ templateName,
112
+ {
113
+ spec: parseResult.ast,
114
+ model,
115
+ controller,
116
+ models: [model]
117
+ },
118
+ { outputDir: "/tmp/v33-test" }
119
+ );
120
+ console.log(` \u2705 ${templateName}: ${output.filePath}`);
121
+ console.log(` Code length: ${output.code.length} characters`);
122
+ console.log(` First 100 chars: ${output.code.substring(0, 100)}...`);
123
+ } catch (error) {
124
+ console.error(` \u274C ${templateName} failed: ${error instanceof Error ? error.message : String(error)}`);
125
+ }
126
+ }
127
+ console.log();
128
+ console.log("\u2705 All tests completed!");
129
+ console.log("\n\u{1F4CA} Summary:");
130
+ console.log(` - Library: \u2705 Loaded`);
131
+ console.log(` - Manifest: \u2705 Loaded`);
132
+ console.log(` - Spec: \u2705 Parsed`);
133
+ console.log(` - Resolution: \u2705 Working`);
134
+ console.log(` - Generation: \u2705 Working`);
135
+ console.log("\n\u{1F389} v3.3 Implementation Types System is operational!");
136
+ } catch (error) {
137
+ console.error("\n\u274C Test failed:", error instanceof Error ? error.message : String(error));
138
+ if (error instanceof Error && error.stack) {
139
+ console.error("\nStack trace:");
140
+ console.error(error.stack);
141
+ }
142
+ process.exit(1);
143
+ }
144
+ }
145
+ testV33Generation();
@@ -0,0 +1,30 @@
1
+ import { generateTests } from "../../../../../scripts/generate-tests.js";
2
+ function generateTestSuite(context) {
3
+ const { spec, implType, outputDir } = context;
4
+ if (!spec) {
5
+ throw new Error("Specification is required in template context");
6
+ }
7
+ const config = implType.configuration || {};
8
+ const options = {
9
+ testFramework: config.testFramework || "vitest",
10
+ generateUnitTests: config.generateUnitTests !== false,
11
+ generateIntegrationTests: config.generateIntegrationTests !== false,
12
+ generateE2ETests: config.generateE2ETests !== false,
13
+ generateFixtures: config.generateFixtures !== false,
14
+ generateMocks: config.generateMocks !== false
15
+ };
16
+ const result = generateTests(spec, outputDir || "./tests", options);
17
+ return JSON.stringify({
18
+ message: "Test suite generated successfully",
19
+ unitTests: result.unitTests,
20
+ integrationTests: result.integrationTests,
21
+ e2eTests: result.e2eTests,
22
+ fixtureCount: result.fixtureCount,
23
+ mockCount: result.mockCount,
24
+ outputDir: result.outputDir,
25
+ files: result.files
26
+ }, null, 2);
27
+ }
28
+ export {
29
+ generateTestSuite as default
30
+ };