@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,22 @@
1
+ function generateBackendEnv(context) {
2
+ const { spec, manifest } = context;
3
+ const projectName = (spec.metadata?.component || "app").toLowerCase().replace(/\s+/g, "-");
4
+ const dbName = `spv_${projectName}_dev`;
5
+ const dbUser = process.env.USER || "postgres";
6
+ const port = manifest?.configuration?.environments?.development?.server?.port || 3e3;
7
+ return `# Backend Environment Configuration
8
+ # Database
9
+ DATABASE_URL="postgresql://${dbUser}:@localhost:5432/${dbName}"
10
+
11
+ # API Configuration
12
+ PORT=${port}
13
+ HOST=0.0.0.0
14
+ NODE_ENV=development
15
+
16
+ # CORS
17
+ CORS_ORIGINS="http://localhost:5173"
18
+ `;
19
+ }
20
+ export {
21
+ generateBackendEnv as default
22
+ };
@@ -0,0 +1,66 @@
1
+ function generateBackendPackageJson(context) {
2
+ const { spec } = context;
3
+ const appName = (spec.metadata?.component || "app").toLowerCase().replace(/\s+/g, "-");
4
+ const pkg = {
5
+ name: `${appName}-backend`,
6
+ version: spec.metadata?.version || "1.0.0",
7
+ description: `Backend API for ${spec.metadata?.component || "application"}`,
8
+ type: "module",
9
+ bin: {
10
+ [appName]: "./bin/cli.mjs"
11
+ },
12
+ scripts: {
13
+ // Development
14
+ "dev": "tsx watch src/main.ts",
15
+ "dev:debug": "tsx watch --inspect src/main.ts",
16
+ // Build
17
+ "build": "tsc",
18
+ "build:watch": "tsc --watch",
19
+ // Production
20
+ "start": "node dist/main.js",
21
+ // Database
22
+ "db:setup": "prisma generate && prisma db push",
23
+ "db:generate": "prisma generate",
24
+ "db:push": "prisma db push",
25
+ "db:migrate": "prisma migrate dev",
26
+ "db:studio": "prisma studio",
27
+ "db:seed": "tsx prisma/seed.ts",
28
+ // Testing
29
+ "test": "vitest run --passWithNoTests",
30
+ "test:watch": "vitest watch",
31
+ "test:coverage": "vitest --coverage",
32
+ // Linting
33
+ "lint": "eslint src --ext .ts",
34
+ "lint:fix": "eslint src --ext .ts --fix",
35
+ // Type checking
36
+ "typecheck": "tsc --noEmit"
37
+ },
38
+ dependencies: {
39
+ "@prisma/client": "^5.7.0",
40
+ "fastify": "^4.25.0",
41
+ "@fastify/cors": "^8.4.0",
42
+ "@fastify/helmet": "^11.1.1",
43
+ "@fastify/rate-limit": "^9.1.0",
44
+ "zod": "^3.22.0",
45
+ "dotenv": "^16.3.0"
46
+ },
47
+ devDependencies: {
48
+ "typescript": "^5.3.0",
49
+ "@types/node": "^20.10.0",
50
+ "tsx": "^4.7.0",
51
+ "prisma": "^5.7.0",
52
+ "vitest": "^1.0.0",
53
+ "@vitest/coverage-v8": "^1.0.0",
54
+ "eslint": "^8.55.0",
55
+ "@typescript-eslint/eslint-plugin": "^6.15.0",
56
+ "@typescript-eslint/parser": "^6.15.0"
57
+ },
58
+ engines: {
59
+ node: ">=18.0.0"
60
+ }
61
+ };
62
+ return JSON.stringify(pkg, null, 2);
63
+ }
64
+ export {
65
+ generateBackendPackageJson as default
66
+ };
@@ -0,0 +1,54 @@
1
+ function generateBackendTsConfig(context) {
2
+ const config = {
3
+ compilerOptions: {
4
+ // Target and Module
5
+ target: "ES2022",
6
+ module: "ESNext",
7
+ lib: ["ES2022"],
8
+ moduleResolution: "node",
9
+ // Output
10
+ outDir: "./dist",
11
+ rootDir: "./src",
12
+ // Strict Type Checking
13
+ strict: true,
14
+ noImplicitAny: true,
15
+ strictNullChecks: true,
16
+ strictFunctionTypes: true,
17
+ strictBindCallApply: true,
18
+ strictPropertyInitialization: true,
19
+ noImplicitThis: true,
20
+ alwaysStrict: true,
21
+ // Additional Checks
22
+ noUnusedLocals: true,
23
+ noUnusedParameters: true,
24
+ noImplicitReturns: true,
25
+ noFallthroughCasesInSwitch: true,
26
+ noUncheckedIndexedAccess: true,
27
+ // Module Resolution
28
+ esModuleInterop: true,
29
+ allowSyntheticDefaultImports: true,
30
+ resolveJsonModule: true,
31
+ isolatedModules: true,
32
+ // Source Maps
33
+ sourceMap: true,
34
+ declaration: true,
35
+ declarationMap: true,
36
+ // Skip lib check for faster builds
37
+ skipLibCheck: true,
38
+ // Emit
39
+ removeComments: false,
40
+ importHelpers: true,
41
+ // Experimental
42
+ experimentalDecorators: true,
43
+ emitDecoratorMetadata: true,
44
+ // Types
45
+ types: ["node"]
46
+ },
47
+ include: ["src/**/*"],
48
+ exclude: ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
49
+ };
50
+ return JSON.stringify(config, null, 2);
51
+ }
52
+ export {
53
+ generateBackendTsConfig as default
54
+ };
@@ -0,0 +1,290 @@
1
+ function generateMain(context) {
2
+ const { spec, manifest } = context;
3
+ let framework = "fastify";
4
+ if (manifest.capabilityMappings) {
5
+ const apiMapping = manifest.capabilityMappings.find(
6
+ (m) => m.capability === "api.rest"
7
+ );
8
+ if (apiMapping?.instanceFactory) {
9
+ const factoryName = apiMapping.instanceFactory.toLowerCase();
10
+ if (factoryName.includes("fastify")) framework = "fastify";
11
+ else if (factoryName.includes("express")) framework = "express";
12
+ else if (factoryName.includes("nestjs")) framework = "nestjs";
13
+ }
14
+ }
15
+ switch (framework) {
16
+ case "fastify":
17
+ return generateFastifyMain(spec);
18
+ case "express":
19
+ return generateExpressMain(spec);
20
+ case "nestjs":
21
+ return generateNestJSMain(spec);
22
+ default:
23
+ throw new Error(`Unsupported framework: ${framework}`);
24
+ }
25
+ }
26
+ function generateFastifyMain(spec) {
27
+ const controllers = spec.controllers || [];
28
+ const services = spec.services || [];
29
+ const routeImports = controllers.map(
30
+ (ctrl) => `import ${ctrl.name.replace("Controller", "")}Routes from './routes/${ctrl.name}.js';`
31
+ ).join("\n");
32
+ const metaRoutesImport = ``;
33
+ const serviceImports = services.map(
34
+ (svc) => `import { ${svc.name} } from './services/${svc.name}.js';`
35
+ ).join("\n");
36
+ const controllerImports = controllers.map(
37
+ (ctrl) => `import { ${ctrl.name} } from './controllers/${ctrl.name}.js';`
38
+ ).join("\n");
39
+ const serviceInstantiations = services.map(
40
+ (svc) => ` const ${svc.name.charAt(0).toLowerCase() + svc.name.slice(1)} = new ${svc.name}(prisma);`
41
+ ).join("\n");
42
+ const controllerInstantiations = controllers.map(
43
+ (ctrl) => ` const ${ctrl.name.charAt(0).toLowerCase() + ctrl.name.slice(1)} = new ${ctrl.name}();`
44
+ ).join("\n");
45
+ const serviceMap = services.map(
46
+ (svc) => ` ${svc.name}: ${svc.name.charAt(0).toLowerCase() + svc.name.slice(1)}`
47
+ ).join(",\n");
48
+ const controllerMap = controllers.map(
49
+ (ctrl) => ` ${ctrl.name}: ${ctrl.name.charAt(0).toLowerCase() + ctrl.name.slice(1)}`
50
+ ).join(",\n");
51
+ const routeRegistrations = controllers.map((ctrl) => {
52
+ let prefix = ctrl.basePath;
53
+ if (!prefix) {
54
+ const modelName = ctrl.model || ctrl.name.replace("Controller", "");
55
+ const pluralModel = modelName.toLowerCase() + "s";
56
+ prefix = `/api/${pluralModel}`;
57
+ }
58
+ return ` await app.register(${ctrl.name.replace("Controller", "")}Routes, {
59
+ prefix: '${prefix}',
60
+ controllers: {
61
+ ${ctrl.name}: ${ctrl.name.charAt(0).toLowerCase() + ctrl.name.slice(1)}
62
+ },
63
+ services: services
64
+ });`;
65
+ }).join("\n");
66
+ const specJson = JSON.stringify(spec, null, 2).replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$");
67
+ return `import Fastify from 'fastify';
68
+ import cors from '@fastify/cors';
69
+ import { PrismaClient } from '@prisma/client';
70
+ ${routeImports}
71
+ ${metaRoutesImport}
72
+ ${serviceImports}
73
+ ${controllerImports}
74
+
75
+ // Embedded specification for /api/spec endpoint
76
+ const spec = ${specJson};
77
+
78
+ const app = Fastify({
79
+ logger: {
80
+ level: process.env.LOG_LEVEL || 'info'
81
+ }
82
+ });
83
+
84
+ const prisma = new PrismaClient();
85
+
86
+ async function start() {
87
+ try {
88
+ // Initialize services and controllers
89
+ ${serviceInstantiations}
90
+ ${controllerInstantiations}
91
+ ${controllers.length > 0 ? `
92
+ const services = {
93
+ ${serviceMap}
94
+ };` : ""}
95
+
96
+ // Register plugins
97
+ await app.register(cors, {
98
+ origin: true,
99
+ credentials: true
100
+ });
101
+
102
+ // Spec endpoint \u2014 serves the specification for the runtime frontend
103
+ app.get('/api/spec', async () => spec);
104
+
105
+ // Runtime info endpoint \u2014 models and controllers for DevShell
106
+ app.get('/api/runtime/info', async () => ({
107
+ controllers: [${controllers.map((c) => `'${c.name}'`).join(", ")}],
108
+ models: [${controllers.map((c) => `'${c.model || c.name.replace("Controller", "")}'`).join(", ")}],
109
+ events: [],
110
+ services: []
111
+ }));
112
+
113
+ // Register routes
114
+ // MetaRoutes disabled for now - enable when meta-routes generator is integrated
115
+ // await app.register(MetaRoutes, {
116
+ // prefix: '/api'
117
+ // });
118
+ ${routeRegistrations}
119
+
120
+ const preferredPort = process.env.PORT ? parseInt(process.env.PORT) : 3000;
121
+ const host = process.env.HOST || '0.0.0.0';
122
+
123
+ // Try to start server with automatic port fallback
124
+ let port = preferredPort;
125
+ let started = false;
126
+ const maxAttempts = 10;
127
+
128
+ for (let i = 0; i < maxAttempts && !started; i++) {
129
+ port = preferredPort + i;
130
+ try {
131
+ await app.listen({ port, host });
132
+ started = true;
133
+
134
+ if (i > 0) {
135
+ console.log(\`\u26A0\uFE0F Port \${preferredPort} was in use, using \${port} instead\`);
136
+ }
137
+ console.log(\`\u{1F680} Server running on http://\${host}:\${port}\`);
138
+ console.log(\`\u{1F4DA} Environment: \${process.env.NODE_ENV || 'development'}\`);
139
+ } catch (err: any) {
140
+ if (err.code === 'EADDRINUSE' && i < maxAttempts - 1) {
141
+ // Port in use, try next port
142
+ continue;
143
+ } else {
144
+ // Different error or ran out of attempts
145
+ throw err;
146
+ }
147
+ }
148
+ }
149
+
150
+ if (!started) {
151
+ throw new Error(\`Could not find available port in range \${preferredPort}-\${preferredPort + maxAttempts - 1}\`);
152
+ }
153
+ } catch (err) {
154
+ app.log.error(err);
155
+ await prisma.$disconnect();
156
+ process.exit(1);
157
+ }
158
+ }
159
+
160
+ // Handle graceful shutdown
161
+ process.on('SIGINT', async () => {
162
+ console.log('\\n\u{1F44B} Shutting down gracefully...');
163
+ await app.close();
164
+ await prisma.$disconnect();
165
+ process.exit(0);
166
+ });
167
+
168
+ process.on('SIGTERM', async () => {
169
+ console.log('\\n\u{1F44B} Shutting down gracefully...');
170
+ await app.close();
171
+ await prisma.$disconnect();
172
+ process.exit(0);
173
+ });
174
+
175
+ start();
176
+ `;
177
+ }
178
+ function generateExpressMain(spec) {
179
+ const controllers = spec.controllers || [];
180
+ const routeImports = controllers.map(
181
+ (ctrl) => `import ${ctrl.name.replace("Controller", "")}Router from './routes/${ctrl.name}.js';`
182
+ ).join("\n");
183
+ const routeRegistrations = controllers.map(
184
+ (ctrl) => `app.use('${ctrl.basePath || "/api"}', ${ctrl.name.replace("Controller", "")}Router);`
185
+ ).join("\n");
186
+ return `import express from 'express';
187
+ import cors from 'cors';
188
+ ${routeImports}
189
+
190
+ const app = express();
191
+
192
+ // Middleware
193
+ app.use(cors());
194
+ app.use(express.json());
195
+
196
+ // Routes
197
+ ${routeRegistrations}
198
+
199
+ async function start() {
200
+ const preferredPort = process.env.PORT ? parseInt(process.env.PORT) : 3000;
201
+ const host = process.env.HOST || '0.0.0.0';
202
+ const maxAttempts = 10;
203
+
204
+ // Try to start server with automatic port fallback
205
+ for (let i = 0; i < maxAttempts; i++) {
206
+ const port = preferredPort + i;
207
+ try {
208
+ await new Promise((resolve, reject) => {
209
+ const server = app.listen(port, host, () => {
210
+ if (i > 0) {
211
+ console.log(\`\u26A0\uFE0F Port \${preferredPort} was in use, using \${port} instead\`);
212
+ }
213
+ console.log(\`\u{1F680} Server running on http://\${host}:\${port}\`);
214
+ console.log(\`\u{1F4DA} Environment: \${process.env.NODE_ENV || 'development'}\`);
215
+ resolve(server);
216
+ }).on('error', (err: any) => {
217
+ if (err.code === 'EADDRINUSE' && i < maxAttempts - 1) {
218
+ resolve(null); // Try next port
219
+ } else {
220
+ reject(err);
221
+ }
222
+ });
223
+ });
224
+ break; // Successfully started
225
+ } catch (err) {
226
+ if (i === maxAttempts - 1) {
227
+ console.error(\`Could not find available port in range \${preferredPort}-\${preferredPort + maxAttempts - 1}\`);
228
+ process.exit(1);
229
+ }
230
+ }
231
+ }
232
+ }
233
+
234
+ start();
235
+
236
+ export default app;
237
+ `;
238
+ }
239
+ function generateNestJSMain(spec) {
240
+ return `import { NestFactory } from '@nestjs/core';
241
+ import { AppModule } from './app.module.js';
242
+
243
+ async function bootstrap() {
244
+ const app = await NestFactory.create(AppModule, {
245
+ logger: ['log', 'error', 'warn', 'debug', 'verbose']
246
+ });
247
+
248
+ app.enableCors({
249
+ origin: true,
250
+ credentials: true
251
+ });
252
+
253
+ const preferredPort = process.env.PORT ? parseInt(process.env.PORT) : 3000;
254
+ const host = process.env.HOST || '0.0.0.0';
255
+ const maxAttempts = 10;
256
+
257
+ // Try to start server with automatic port fallback
258
+ let started = false;
259
+ for (let i = 0; i < maxAttempts && !started; i++) {
260
+ const port = preferredPort + i;
261
+ try {
262
+ await app.listen(port, host);
263
+ started = true;
264
+
265
+ if (i > 0) {
266
+ console.log(\`\u26A0\uFE0F Port \${preferredPort} was in use, using \${port} instead\`);
267
+ }
268
+ console.log(\`\u{1F680} Server running on http://\${host}:\${port}\`);
269
+ console.log(\`\u{1F4DA} Environment: \${process.env.NODE_ENV || 'development'}\`);
270
+ } catch (err: any) {
271
+ if (err.code === 'EADDRINUSE' && i < maxAttempts - 1) {
272
+ // Port in use, try next port
273
+ continue;
274
+ } else {
275
+ throw err;
276
+ }
277
+ }
278
+ }
279
+
280
+ if (!started) {
281
+ throw new Error(\`Could not find available port in range \${preferredPort}-\${preferredPort + maxAttempts - 1}\`);
282
+ }
283
+ }
284
+
285
+ bootstrap();
286
+ `;
287
+ }
288
+ export {
289
+ generateMain as default
290
+ };