ezpm2gui 1.1.0 → 1.2.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/server/config/project-configs.json +236 -0
- package/dist/server/index.js +30 -5
- package/dist/server/logs/deployment.log +12 -0
- package/dist/server/routes/deployApplication.js +174 -27
- package/dist/server/routes/logStreaming.js +174 -0
- package/dist/server/routes/remoteConnections.d.ts +3 -0
- package/dist/server/routes/remoteConnections.js +634 -0
- package/dist/server/services/ProjectSetupService.d.ts +72 -0
- package/dist/server/services/ProjectSetupService.js +327 -0
- package/dist/server/utils/dialog.d.ts +1 -0
- package/dist/server/utils/dialog.js +16 -0
- package/dist/server/utils/encryption.d.ts +12 -0
- package/dist/server/utils/encryption.js +72 -0
- package/dist/server/utils/remote-connection.d.ts +152 -0
- package/dist/server/utils/remote-connection.js +590 -0
- package/dist/server/utils/upload.d.ts +3 -0
- package/dist/server/utils/upload.js +39 -0
- package/package.json +65 -63
- package/src/client/build/asset-manifest.json +3 -3
- package/src/client/build/favicon.ico +2 -0
- package/src/client/build/index.html +1 -1
- package/src/client/build/logo192.svg +7 -0
- package/src/client/build/logo512.svg +7 -0
- package/src/client/build/manifest.json +5 -6
- package/src/client/build/static/js/{main.1d7f99ff.js → main.31323a04.js} +13 -13
- package/src/client/build/static/js/main.31323a04.js.map +1 -0
- package/src/client/build/static/js/main.1d7f99ff.js.map +0 -1
- /package/src/client/build/static/js/{main.1d7f99ff.js.LICENSE.txt → main.31323a04.js.LICENSE.txt} +0 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
{
|
|
2
|
+
"projectTypes": {
|
|
3
|
+
"node": {
|
|
4
|
+
"name": "Node.js",
|
|
5
|
+
"detection": {
|
|
6
|
+
"files": ["package.json"],
|
|
7
|
+
"extensions": [".js", ".ts", ".jsx", ".tsx"]
|
|
8
|
+
},
|
|
9
|
+
"setup": {
|
|
10
|
+
"steps": [
|
|
11
|
+
{
|
|
12
|
+
"name": "Check Node.js version",
|
|
13
|
+
"command": "node --version",
|
|
14
|
+
"description": "Verifying Node.js installation",
|
|
15
|
+
"required": true
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Install dependencies",
|
|
19
|
+
"command": "npm install",
|
|
20
|
+
"description": "Installing project dependencies",
|
|
21
|
+
"required": true,
|
|
22
|
+
"workingDirectory": "project"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "Build project (if build script exists)",
|
|
26
|
+
"command": "npm run build",
|
|
27
|
+
"description": "Building the project",
|
|
28
|
+
"required": false,
|
|
29
|
+
"conditional": "build_script_exists",
|
|
30
|
+
"workingDirectory": "project"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "Run tests (if test script exists)",
|
|
34
|
+
"command": "npm test",
|
|
35
|
+
"description": "Running tests",
|
|
36
|
+
"required": false,
|
|
37
|
+
"conditional": "test_script_exists",
|
|
38
|
+
"workingDirectory": "project"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"environment": {
|
|
42
|
+
"NODE_ENV": "production"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"validation": {
|
|
46
|
+
"checks": [
|
|
47
|
+
{
|
|
48
|
+
"name": "package.json exists",
|
|
49
|
+
"file": "package.json"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "node_modules exists after install",
|
|
53
|
+
"directory": "node_modules"
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
"defaultConfig": {
|
|
58
|
+
"interpreter": "node",
|
|
59
|
+
"execMode": "fork",
|
|
60
|
+
"supportsCluster": true,
|
|
61
|
+
"startScript": "npm start"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"python": {
|
|
65
|
+
"name": "Python",
|
|
66
|
+
"detection": {
|
|
67
|
+
"files": ["requirements.txt", "pyproject.toml", "setup.py", "Pipfile"],
|
|
68
|
+
"extensions": [".py"]
|
|
69
|
+
},
|
|
70
|
+
"setup": {
|
|
71
|
+
"steps": [
|
|
72
|
+
{
|
|
73
|
+
"name": "Check Python version",
|
|
74
|
+
"command": "python --version",
|
|
75
|
+
"description": "Verifying Python installation",
|
|
76
|
+
"required": true
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "Create virtual environment",
|
|
80
|
+
"command": "python -m venv venv",
|
|
81
|
+
"description": "Creating Python virtual environment",
|
|
82
|
+
"required": true,
|
|
83
|
+
"workingDirectory": "project"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "Activate virtual environment (Windows)",
|
|
87
|
+
"command": ".\\venv\\Scripts\\Activate.ps1",
|
|
88
|
+
"description": "Activating virtual environment",
|
|
89
|
+
"required": true,
|
|
90
|
+
"platform": "win32",
|
|
91
|
+
"workingDirectory": "project"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"name": "Activate virtual environment (Unix)",
|
|
95
|
+
"command": "source venv/bin/activate",
|
|
96
|
+
"description": "Activating virtual environment",
|
|
97
|
+
"required": true,
|
|
98
|
+
"platform": "unix",
|
|
99
|
+
"workingDirectory": "project"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "Upgrade pip",
|
|
103
|
+
"command": "python -m pip install --upgrade pip",
|
|
104
|
+
"description": "Upgrading pip",
|
|
105
|
+
"required": true,
|
|
106
|
+
"workingDirectory": "project",
|
|
107
|
+
"useVenv": true
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"name": "Install requirements",
|
|
111
|
+
"command": "pip install -r requirements.txt",
|
|
112
|
+
"description": "Installing Python dependencies",
|
|
113
|
+
"required": true,
|
|
114
|
+
"conditional": "requirements_exists",
|
|
115
|
+
"workingDirectory": "project",
|
|
116
|
+
"useVenv": true
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"name": "Install from pyproject.toml",
|
|
120
|
+
"command": "pip install -e .",
|
|
121
|
+
"description": "Installing from pyproject.toml",
|
|
122
|
+
"required": true,
|
|
123
|
+
"conditional": "pyproject_exists",
|
|
124
|
+
"workingDirectory": "project",
|
|
125
|
+
"useVenv": true
|
|
126
|
+
}
|
|
127
|
+
],
|
|
128
|
+
"environment": {
|
|
129
|
+
"PYTHONPATH": ".",
|
|
130
|
+
"PYTHON_UNBUFFERED": "1"
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
"validation": {
|
|
134
|
+
"checks": [
|
|
135
|
+
{
|
|
136
|
+
"name": "Virtual environment created",
|
|
137
|
+
"directory": "venv"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"name": "Requirements file exists",
|
|
141
|
+
"file": "requirements.txt",
|
|
142
|
+
"optional": true
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
"defaultConfig": {
|
|
147
|
+
"interpreter": "python",
|
|
148
|
+
"execMode": "fork",
|
|
149
|
+
"supportsCluster": false,
|
|
150
|
+
"interpreterPath": "venv/Scripts/python.exe"
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"dotnet": {
|
|
154
|
+
"name": ".NET",
|
|
155
|
+
"detection": {
|
|
156
|
+
"files": ["*.csproj", "*.fsproj", "*.vbproj", "*.sln"],
|
|
157
|
+
"extensions": [".cs", ".fs", ".vb"]
|
|
158
|
+
},
|
|
159
|
+
"setup": {
|
|
160
|
+
"steps": [
|
|
161
|
+
{
|
|
162
|
+
"name": "Check .NET version",
|
|
163
|
+
"command": "dotnet --version",
|
|
164
|
+
"description": "Verifying .NET installation",
|
|
165
|
+
"required": true
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"name": "Restore packages",
|
|
169
|
+
"command": "dotnet restore",
|
|
170
|
+
"description": "Restoring NuGet packages",
|
|
171
|
+
"required": true,
|
|
172
|
+
"workingDirectory": "project"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"name": "Build project",
|
|
176
|
+
"command": "dotnet build --configuration Release",
|
|
177
|
+
"description": "Building .NET project",
|
|
178
|
+
"required": true,
|
|
179
|
+
"workingDirectory": "project"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"name": "Publish project",
|
|
183
|
+
"command": "dotnet publish --configuration Release --output ./publish",
|
|
184
|
+
"description": "Publishing .NET project",
|
|
185
|
+
"required": true,
|
|
186
|
+
"workingDirectory": "project"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"name": "Run tests",
|
|
190
|
+
"command": "dotnet test",
|
|
191
|
+
"description": "Running .NET tests",
|
|
192
|
+
"required": false,
|
|
193
|
+
"conditional": "test_project_exists",
|
|
194
|
+
"workingDirectory": "project"
|
|
195
|
+
}
|
|
196
|
+
],
|
|
197
|
+
"environment": {
|
|
198
|
+
"DOTNET_ENVIRONMENT": "Production",
|
|
199
|
+
"ASPNETCORE_ENVIRONMENT": "Production"
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
"validation": {
|
|
203
|
+
"checks": [
|
|
204
|
+
{
|
|
205
|
+
"name": "Project file exists",
|
|
206
|
+
"pattern": "*.csproj"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"name": "Publish directory exists",
|
|
210
|
+
"directory": "publish"
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
},
|
|
214
|
+
"defaultConfig": {
|
|
215
|
+
"interpreter": "dotnet",
|
|
216
|
+
"execMode": "fork",
|
|
217
|
+
"supportsCluster": false,
|
|
218
|
+
"startCommand": "dotnet run"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
"global": {
|
|
223
|
+
"timeouts": {
|
|
224
|
+
"setup": 300000,
|
|
225
|
+
"validation": 30000
|
|
226
|
+
},
|
|
227
|
+
"retries": {
|
|
228
|
+
"setup": 2,
|
|
229
|
+
"validation": 1
|
|
230
|
+
},
|
|
231
|
+
"logging": {
|
|
232
|
+
"level": "info",
|
|
233
|
+
"file": "deployment.log"
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
package/dist/server/index.js
CHANGED
|
@@ -9,13 +9,13 @@ const http_1 = __importDefault(require("http"));
|
|
|
9
9
|
const socket_io_1 = require("socket.io");
|
|
10
10
|
const pm2_1 = __importDefault(require("pm2"));
|
|
11
11
|
const os_1 = __importDefault(require("os"));
|
|
12
|
-
// Import routes
|
|
13
|
-
const clusterManagement_1 = __importDefault(require("./routes/clusterManagement"));
|
|
14
12
|
const processConfig_1 = __importDefault(require("./routes/processConfig"));
|
|
15
13
|
const deployApplication_1 = __importDefault(require("./routes/deployApplication"));
|
|
16
14
|
const modules_1 = __importDefault(require("./routes/modules"));
|
|
15
|
+
const remoteConnections_1 = __importDefault(require("./routes/remoteConnections"));
|
|
17
16
|
const logStreaming_1 = require("./routes/logStreaming");
|
|
18
17
|
const pm2_connection_1 = require("./utils/pm2-connection");
|
|
18
|
+
const remote_connection_1 = require("./utils/remote-connection");
|
|
19
19
|
/**
|
|
20
20
|
* Create and configure the express server
|
|
21
21
|
*/
|
|
@@ -41,11 +41,11 @@ function createServer() {
|
|
|
41
41
|
else {
|
|
42
42
|
console.error('Static files directory not found at:', staticPath);
|
|
43
43
|
}
|
|
44
|
-
// Register routes
|
|
45
|
-
app.use('/api/cluster', clusterManagement_1.default);
|
|
44
|
+
// Register routes app.use('/api/cluster', clusterManagementRoutes);
|
|
46
45
|
app.use('/api/config', processConfig_1.default);
|
|
47
46
|
app.use('/api/deploy', deployApplication_1.default);
|
|
48
47
|
app.use('/api/modules', modules_1.default);
|
|
48
|
+
app.use('/api/remote', remoteConnections_1.default);
|
|
49
49
|
// Setup log streaming with Socket.IO
|
|
50
50
|
(0, logStreaming_1.setupLogStreaming)(io); // PM2 API endpoints
|
|
51
51
|
app.get('/api/processes', async (req, res) => {
|
|
@@ -90,7 +90,7 @@ function createServer() {
|
|
|
90
90
|
pm2_1.default.restart(id, cb);
|
|
91
91
|
break;
|
|
92
92
|
case 'delete':
|
|
93
|
-
pm2_1.default.
|
|
93
|
+
pm2_1.default.delete(id, cb);
|
|
94
94
|
break;
|
|
95
95
|
default:
|
|
96
96
|
cb(new Error('Invalid action'));
|
|
@@ -236,4 +236,29 @@ if (require.main === module) {
|
|
|
236
236
|
server.listen(PORT, () => {
|
|
237
237
|
console.log(`Server running on http://${HOST}:${PORT}`);
|
|
238
238
|
});
|
|
239
|
+
// Handle shutdown gracefully
|
|
240
|
+
process.on('SIGINT', async () => {
|
|
241
|
+
console.log('\nGracefully shutting down...');
|
|
242
|
+
try {
|
|
243
|
+
await (0, pm2_connection_1.disconnectFromPM2)();
|
|
244
|
+
await remote_connection_1.remoteConnectionManager.closeAllConnections();
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
console.error('Error during shutdown:', error);
|
|
248
|
+
}
|
|
249
|
+
server.close();
|
|
250
|
+
process.exit(0);
|
|
251
|
+
});
|
|
252
|
+
process.on('SIGTERM', async () => {
|
|
253
|
+
console.log('\nGracefully shutting down...');
|
|
254
|
+
try {
|
|
255
|
+
await (0, pm2_connection_1.disconnectFromPM2)();
|
|
256
|
+
await remote_connection_1.remoteConnectionManager.closeAllConnections();
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
console.error('Error during shutdown:', error);
|
|
260
|
+
}
|
|
261
|
+
server.close();
|
|
262
|
+
process.exit(0);
|
|
263
|
+
});
|
|
239
264
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[2025-05-25T18:02:41.395Z] Starting setup for python project at: D:\Projects\FaceDetection
|
|
2
|
+
[2025-05-25T18:02:41.396Z] Executing step: Check Python version
|
|
3
|
+
[2025-05-25T18:02:41.954Z] Step "Check Python version" completed with exit code: 0
|
|
4
|
+
[2025-05-25T18:02:41.955Z] Executing step: Create virtual environment
|
|
5
|
+
[2025-05-25T18:03:20.998Z] Step "Create virtual environment" completed with exit code: 0
|
|
6
|
+
[2025-05-25T18:03:20.999Z] Executing step: Activate virtual environment (Windows)
|
|
7
|
+
[2025-05-25T18:03:21.176Z] Step "Activate virtual environment (Windows)" completed with exit code: 0
|
|
8
|
+
[2025-05-25T18:03:21.176Z] Executing step: Upgrade pip
|
|
9
|
+
[2025-05-25T18:03:48.644Z] Step "Upgrade pip" completed with exit code: 0
|
|
10
|
+
[2025-05-25T18:03:48.645Z] Executing step: Install requirements
|
|
11
|
+
[2025-05-25T18:04:56.318Z] Step "Install requirements" completed with exit code: 0
|
|
12
|
+
[2025-05-25T18:04:56.322Z] Setup completed. Success: true
|
|
@@ -7,10 +7,11 @@ const express_1 = require("express");
|
|
|
7
7
|
const pm2_1 = __importDefault(require("pm2"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const ProjectSetupService_1 = require("../services/ProjectSetupService");
|
|
10
11
|
const router = (0, express_1.Router)();
|
|
11
12
|
// Deploy a new application
|
|
12
|
-
router.post('/', (req, res) => {
|
|
13
|
-
const { name, script, cwd, instances, exec_mode, autorestart, watch, max_memory_restart, env } = req.body;
|
|
13
|
+
router.post('/', async (req, res) => {
|
|
14
|
+
const { name, script, cwd, instances, exec_mode, autorestart, watch, max_memory_restart, env, appType, autoSetup = true } = req.body;
|
|
14
15
|
// Validate required fields
|
|
15
16
|
if (!name || !script) {
|
|
16
17
|
return res.status(400).json({ error: 'Name and script path are required' });
|
|
@@ -19,37 +20,103 @@ router.post('/', (req, res) => {
|
|
|
19
20
|
if (!fs_1.default.existsSync(script)) {
|
|
20
21
|
return res.status(400).json({ error: `Script file not found: ${script}` });
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
pm2_1.default.connect((err) => {
|
|
35
|
-
if (err) {
|
|
36
|
-
console.error(err);
|
|
37
|
-
return res.status(500).json({ error: 'Failed to connect to PM2' });
|
|
23
|
+
try {
|
|
24
|
+
const projectPath = cwd || path_1.default.dirname(script);
|
|
25
|
+
let setupResult = null;
|
|
26
|
+
let finalEnv = env || {};
|
|
27
|
+
let interpreterPath = '';
|
|
28
|
+
// Auto-detect project type if not provided
|
|
29
|
+
let detectedType = appType;
|
|
30
|
+
if (!detectedType) {
|
|
31
|
+
detectedType = ProjectSetupService_1.projectSetupService.detectProjectType(projectPath);
|
|
32
|
+
if (detectedType) {
|
|
33
|
+
console.log(`Auto-detected project type: ${detectedType}`);
|
|
34
|
+
}
|
|
38
35
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
// Run project setup if auto-setup is enabled and project type is detected
|
|
37
|
+
if (autoSetup && detectedType && ['node', 'python', 'dotnet'].includes(detectedType)) {
|
|
38
|
+
console.log(`Running setup for ${detectedType} project...`);
|
|
39
|
+
try {
|
|
40
|
+
setupResult = await ProjectSetupService_1.projectSetupService.setupProject(projectPath, detectedType);
|
|
41
|
+
if (!setupResult.success) {
|
|
42
|
+
return res.status(500).json({
|
|
43
|
+
error: 'Project setup failed',
|
|
44
|
+
details: setupResult.errors,
|
|
45
|
+
warnings: setupResult.warnings,
|
|
46
|
+
steps: setupResult.steps
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
// Merge environment variables from setup
|
|
50
|
+
finalEnv = { ...setupResult.environment, ...finalEnv };
|
|
51
|
+
// Set interpreter path for Python projects
|
|
52
|
+
if (setupResult.interpreterPath) {
|
|
53
|
+
interpreterPath = setupResult.interpreterPath;
|
|
54
|
+
}
|
|
55
|
+
console.log('Project setup completed successfully');
|
|
56
|
+
}
|
|
57
|
+
catch (setupError) {
|
|
58
|
+
console.error('Setup error:', setupError);
|
|
43
59
|
return res.status(500).json({
|
|
44
|
-
error:
|
|
60
|
+
error: 'Project setup failed',
|
|
61
|
+
details: setupError instanceof Error ? setupError.message : 'Unknown setup error'
|
|
45
62
|
});
|
|
46
63
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
64
|
+
}
|
|
65
|
+
// Create deployment configuration
|
|
66
|
+
const appConfig = {
|
|
67
|
+
name,
|
|
68
|
+
script,
|
|
69
|
+
cwd: projectPath,
|
|
70
|
+
instances: parseInt(instances) || 1,
|
|
71
|
+
exec_mode: exec_mode || 'fork',
|
|
72
|
+
autorestart: autorestart !== undefined ? autorestart : true,
|
|
73
|
+
watch: watch || false,
|
|
74
|
+
max_memory_restart: max_memory_restart || '150M',
|
|
75
|
+
env: finalEnv
|
|
76
|
+
};
|
|
77
|
+
// Set interpreter for Python projects
|
|
78
|
+
if (detectedType === 'python' && interpreterPath) {
|
|
79
|
+
appConfig.interpreter = interpreterPath;
|
|
80
|
+
}
|
|
81
|
+
else if (detectedType === 'dotnet') {
|
|
82
|
+
appConfig.interpreter = 'dotnet';
|
|
83
|
+
// For .NET projects, update script to point to the published DLL if available
|
|
84
|
+
const publishedDll = path_1.default.join(projectPath, 'publish', `${path_1.default.basename(projectPath)}.dll`);
|
|
85
|
+
if (fs_1.default.existsSync(publishedDll)) {
|
|
86
|
+
appConfig.script = publishedDll;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
pm2_1.default.connect((err) => {
|
|
90
|
+
if (err) {
|
|
91
|
+
console.error(err);
|
|
92
|
+
return res.status(500).json({ error: 'Failed to connect to PM2' });
|
|
93
|
+
}
|
|
94
|
+
pm2_1.default.start(appConfig, (err) => {
|
|
95
|
+
pm2_1.default.disconnect();
|
|
96
|
+
if (err) {
|
|
97
|
+
console.error('PM2 start error:', err);
|
|
98
|
+
return res.status(500).json({
|
|
99
|
+
error: `Failed to deploy application: ${err.message || 'Unknown error'}`
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
res.json({
|
|
103
|
+
success: true,
|
|
104
|
+
message: `Application ${name} deployed successfully`,
|
|
105
|
+
setupResult: setupResult ? {
|
|
106
|
+
steps: setupResult.steps,
|
|
107
|
+
warnings: setupResult.warnings
|
|
108
|
+
} : null
|
|
109
|
+
});
|
|
50
110
|
});
|
|
51
111
|
});
|
|
52
|
-
}
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
console.error('Deployment error:', error);
|
|
115
|
+
return res.status(500).json({
|
|
116
|
+
error: 'Deployment failed',
|
|
117
|
+
details: error instanceof Error ? error.message : 'Unknown error'
|
|
118
|
+
});
|
|
119
|
+
}
|
|
53
120
|
});
|
|
54
121
|
// Generate ecosystem.config.js file
|
|
55
122
|
router.post('/generate-ecosystem', (req, res) => {
|
|
@@ -160,4 +227,84 @@ router.get('/generate-ecosystem-preview', (req, res) => {
|
|
|
160
227
|
}
|
|
161
228
|
});
|
|
162
229
|
});
|
|
230
|
+
// Detect project type
|
|
231
|
+
router.post('/detect-project', (req, res) => {
|
|
232
|
+
const { projectPath } = req.body;
|
|
233
|
+
if (!projectPath) {
|
|
234
|
+
return res.status(400).json({ error: 'Project path is required' });
|
|
235
|
+
}
|
|
236
|
+
if (!fs_1.default.existsSync(projectPath)) {
|
|
237
|
+
return res.status(400).json({ error: 'Project path does not exist' });
|
|
238
|
+
}
|
|
239
|
+
try {
|
|
240
|
+
const projectType = ProjectSetupService_1.projectSetupService.detectProjectType(projectPath);
|
|
241
|
+
const config = projectType ? ProjectSetupService_1.projectSetupService.getProjectConfig(projectType) : null;
|
|
242
|
+
res.json({
|
|
243
|
+
success: true,
|
|
244
|
+
projectType,
|
|
245
|
+
config: config ? {
|
|
246
|
+
name: config.name,
|
|
247
|
+
defaultConfig: config.defaultConfig,
|
|
248
|
+
setupSteps: config.setup.steps.length
|
|
249
|
+
} : null
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
res.status(500).json({
|
|
254
|
+
error: 'Failed to detect project type',
|
|
255
|
+
details: error instanceof Error ? error.message : 'Unknown error'
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
// Setup project (without deployment)
|
|
260
|
+
router.post('/setup-project', async (req, res) => {
|
|
261
|
+
const { projectPath, projectType } = req.body;
|
|
262
|
+
if (!projectPath || !projectType) {
|
|
263
|
+
return res.status(400).json({ error: 'Project path and type are required' });
|
|
264
|
+
}
|
|
265
|
+
if (!fs_1.default.existsSync(projectPath)) {
|
|
266
|
+
return res.status(400).json({ error: 'Project path does not exist' });
|
|
267
|
+
}
|
|
268
|
+
try {
|
|
269
|
+
const setupResult = await ProjectSetupService_1.projectSetupService.setupProject(projectPath, projectType);
|
|
270
|
+
res.json({
|
|
271
|
+
success: setupResult.success,
|
|
272
|
+
steps: setupResult.steps,
|
|
273
|
+
errors: setupResult.errors,
|
|
274
|
+
warnings: setupResult.warnings,
|
|
275
|
+
environment: setupResult.environment,
|
|
276
|
+
interpreterPath: setupResult.interpreterPath
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
res.status(500).json({
|
|
281
|
+
error: 'Project setup failed',
|
|
282
|
+
details: error instanceof Error ? error.message : 'Unknown error'
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
// Get supported project types
|
|
287
|
+
router.get('/project-types', (req, res) => {
|
|
288
|
+
try {
|
|
289
|
+
const types = ProjectSetupService_1.projectSetupService.getSupportedProjectTypes();
|
|
290
|
+
const typeConfigs = types.map(type => {
|
|
291
|
+
const config = ProjectSetupService_1.projectSetupService.getProjectConfig(type);
|
|
292
|
+
return {
|
|
293
|
+
type,
|
|
294
|
+
name: config === null || config === void 0 ? void 0 : config.name,
|
|
295
|
+
defaultConfig: config === null || config === void 0 ? void 0 : config.defaultConfig
|
|
296
|
+
};
|
|
297
|
+
});
|
|
298
|
+
res.json({
|
|
299
|
+
success: true,
|
|
300
|
+
types: typeConfigs
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
res.status(500).json({
|
|
305
|
+
error: 'Failed to get project types',
|
|
306
|
+
details: error instanceof Error ? error.message : 'Unknown error'
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
});
|
|
163
310
|
exports.default = router;
|