ezpm2gui 1.0.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/README.md +202 -14
- package/bin/ezpm2gui.js +40 -44
- package/bin/ezpm2gui.ts +51 -0
- package/bin/generate-ecosystem.js +24 -22
- package/bin/generate-ecosystem.ts +56 -0
- package/dist/server/config/project-configs.json +236 -0
- package/dist/server/index.js +64 -19
- package/dist/server/logs/deployment.log +12 -0
- package/dist/server/routes/clusterManagement.d.ts +3 -0
- package/dist/server/routes/clusterManagement.js +152 -0
- package/dist/server/routes/deployApplication.d.ts +3 -0
- package/dist/server/routes/deployApplication.js +310 -0
- package/dist/server/routes/logStreaming.d.ts +5 -0
- package/dist/server/routes/logStreaming.js +276 -0
- package/dist/server/routes/modules.d.ts +3 -0
- package/dist/server/routes/modules.js +106 -0
- package/dist/server/routes/processConfig.d.ts +3 -0
- package/dist/server/routes/processConfig.js +118 -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/pm2-connection.d.ts +16 -0
- package/dist/server/utils/pm2-connection.js +141 -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 -49
- package/src/client/build/asset-manifest.json +6 -6
- 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/css/main.672b8f26.css +2 -0
- package/src/client/build/static/css/main.672b8f26.css.map +1 -0
- package/src/client/build/static/js/main.31323a04.js +156 -0
- package/src/client/build/static/js/{main.dde30e92.js.LICENSE.txt → main.31323a04.js.LICENSE.txt} +19 -0
- package/src/client/build/static/js/main.31323a04.js.map +1 -0
- package/ .npmignore +0 -39
- package/install.bat +0 -22
- package/install.sh +0 -23
- package/src/client/build/static/css/main.c1cbda3a.css +0 -2
- package/src/client/build/static/css/main.c1cbda3a.css.map +0 -1
- package/src/client/build/static/js/main.dde30e92.js +0 -3
- package/src/client/build/static/js/main.dde30e92.js.map +0 -1
- package/src/client/package-lock.json +0 -16192
- package/src/client/package.json +0 -39
- package/src/client/public/index.html +0 -20
- package/src/client/public/manifest.json +0 -25
- package/src/index.ts +0 -24
- package/src/server/index.ts +0 -240
- package/tsconfig.json +0 -18
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const express_1 = require("express");
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const router = (0, express_1.Router)();
|
|
6
|
+
// List installed modules
|
|
7
|
+
router.get('/', (req, res) => {
|
|
8
|
+
const pm2Command = (0, child_process_1.spawn)('pm2', ['module:list']);
|
|
9
|
+
let output = '';
|
|
10
|
+
let errorOutput = '';
|
|
11
|
+
pm2Command.stdout.on('data', (data) => {
|
|
12
|
+
output += data.toString();
|
|
13
|
+
});
|
|
14
|
+
pm2Command.stderr.on('data', (data) => {
|
|
15
|
+
errorOutput += data.toString();
|
|
16
|
+
});
|
|
17
|
+
pm2Command.on('close', (code) => {
|
|
18
|
+
if (code !== 0) {
|
|
19
|
+
return res.status(500).json({
|
|
20
|
+
error: 'Failed to list PM2 modules',
|
|
21
|
+
details: errorOutput
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
// Parse the output to get module information
|
|
25
|
+
try {
|
|
26
|
+
const moduleLines = output.split('\n').filter(line => line.includes('│') && !line.includes('Module') && line.trim() !== '');
|
|
27
|
+
const modules = moduleLines.map(line => {
|
|
28
|
+
const parts = line.split('│').map(part => part.trim()).filter(Boolean);
|
|
29
|
+
if (parts.length >= 3) {
|
|
30
|
+
return {
|
|
31
|
+
name: parts[0],
|
|
32
|
+
version: parts[1],
|
|
33
|
+
status: parts[2]
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}).filter(Boolean);
|
|
38
|
+
res.json(modules);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
res.status(500).json({
|
|
42
|
+
error: 'Failed to parse PM2 modules',
|
|
43
|
+
details: error
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
// Install a module
|
|
49
|
+
router.post('/install', (req, res) => {
|
|
50
|
+
const { moduleName } = req.body;
|
|
51
|
+
if (!moduleName) {
|
|
52
|
+
return res.status(400).json({ error: 'Module name is required' });
|
|
53
|
+
}
|
|
54
|
+
const pm2Command = (0, child_process_1.spawn)('pm2', ['install', moduleName]);
|
|
55
|
+
let output = '';
|
|
56
|
+
let errorOutput = '';
|
|
57
|
+
pm2Command.stdout.on('data', (data) => {
|
|
58
|
+
output += data.toString();
|
|
59
|
+
});
|
|
60
|
+
pm2Command.stderr.on('data', (data) => {
|
|
61
|
+
errorOutput += data.toString();
|
|
62
|
+
});
|
|
63
|
+
pm2Command.on('close', (code) => {
|
|
64
|
+
if (code !== 0) {
|
|
65
|
+
return res.status(500).json({
|
|
66
|
+
error: `Failed to install module: ${moduleName}`,
|
|
67
|
+
details: errorOutput
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
res.json({
|
|
71
|
+
success: true,
|
|
72
|
+
message: `Successfully installed module: ${moduleName}`,
|
|
73
|
+
details: output
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
// Uninstall a module
|
|
78
|
+
router.delete('/:moduleName', (req, res) => {
|
|
79
|
+
const { moduleName } = req.params;
|
|
80
|
+
if (!moduleName) {
|
|
81
|
+
return res.status(400).json({ error: 'Module name is required' });
|
|
82
|
+
}
|
|
83
|
+
const pm2Command = (0, child_process_1.spawn)('pm2', ['uninstall', moduleName]);
|
|
84
|
+
let output = '';
|
|
85
|
+
let errorOutput = '';
|
|
86
|
+
pm2Command.stdout.on('data', (data) => {
|
|
87
|
+
output += data.toString();
|
|
88
|
+
});
|
|
89
|
+
pm2Command.stderr.on('data', (data) => {
|
|
90
|
+
errorOutput += data.toString();
|
|
91
|
+
});
|
|
92
|
+
pm2Command.on('close', (code) => {
|
|
93
|
+
if (code !== 0) {
|
|
94
|
+
return res.status(500).json({
|
|
95
|
+
error: `Failed to uninstall module: ${moduleName}`,
|
|
96
|
+
details: errorOutput
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
res.json({
|
|
100
|
+
success: true,
|
|
101
|
+
message: `Successfully uninstalled module: ${moduleName}`,
|
|
102
|
+
details: output
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
exports.default = router;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const express_1 = require("express");
|
|
7
|
+
const pm2_1 = __importDefault(require("pm2"));
|
|
8
|
+
const router = (0, express_1.Router)();
|
|
9
|
+
// Get current configuration for a process
|
|
10
|
+
router.get('/:id', (req, res) => {
|
|
11
|
+
const { id } = req.params;
|
|
12
|
+
pm2_1.default.connect((err) => {
|
|
13
|
+
if (err) {
|
|
14
|
+
console.error(err);
|
|
15
|
+
res.status(500).json({ error: 'Failed to connect to PM2' });
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
pm2_1.default.describe(id, (err, processDesc) => {
|
|
19
|
+
pm2_1.default.disconnect();
|
|
20
|
+
if (err || !processDesc || processDesc.length === 0) {
|
|
21
|
+
res.status(404).json({ error: 'Process not found' });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const process = processDesc[0];
|
|
25
|
+
const pm2Env = process.pm2_env;
|
|
26
|
+
// Extract configuration from PM2 environment
|
|
27
|
+
const config = {
|
|
28
|
+
name: process.name,
|
|
29
|
+
script: pm2Env.pm_exec_path,
|
|
30
|
+
cwd: pm2Env.pm_cwd,
|
|
31
|
+
interpreter: pm2Env.exec_interpreter,
|
|
32
|
+
instances: pm2Env.instances || 1,
|
|
33
|
+
exec_mode: pm2Env.exec_mode === 'cluster_mode' ? 'cluster' : 'fork',
|
|
34
|
+
autorestart: pm2Env.autorestart,
|
|
35
|
+
watch: pm2Env.watch,
|
|
36
|
+
ignore_watch: pm2Env.ignore_watch || [],
|
|
37
|
+
env: pm2Env.env || {},
|
|
38
|
+
max_memory_restart: pm2Env.max_memory_restart || '150M'
|
|
39
|
+
};
|
|
40
|
+
res.json(config);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
// Update configuration for a process
|
|
45
|
+
router.post('/:id', (req, res) => {
|
|
46
|
+
const { id } = req.params;
|
|
47
|
+
const config = req.body;
|
|
48
|
+
if (!config) {
|
|
49
|
+
res.status(400).json({ error: 'Configuration data is required' });
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
pm2_1.default.connect(async (err) => {
|
|
53
|
+
if (err) {
|
|
54
|
+
console.error(err);
|
|
55
|
+
res.status(500).json({ error: 'Failed to connect to PM2' });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
// First get the current process to find its ecosystem file if any
|
|
60
|
+
const describePromise = new Promise((resolve, reject) => {
|
|
61
|
+
pm2_1.default.describe(id, (err, processDesc) => {
|
|
62
|
+
if (err || !processDesc || processDesc.length === 0) {
|
|
63
|
+
reject(new Error('Process not found'));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
resolve(processDesc[0]);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
const process = await describePromise;
|
|
70
|
+
// Update process via PM2 API
|
|
71
|
+
const updatePromise = new Promise((resolve, reject) => {
|
|
72
|
+
// Stop the process first
|
|
73
|
+
pm2_1.default.stop(id, (err) => {
|
|
74
|
+
if (err) {
|
|
75
|
+
reject(new Error(`Failed to stop process: ${err.message}`));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Delete the process
|
|
79
|
+
// TypeScript doesn't recognize 'del' method, so we're using it with a type assertion
|
|
80
|
+
pm2_1.default.del(id, (err) => {
|
|
81
|
+
if (err) {
|
|
82
|
+
reject(new Error(`Failed to delete process: ${err.message}`));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// Start with new configuration
|
|
86
|
+
pm2_1.default.start({
|
|
87
|
+
name: config.name,
|
|
88
|
+
script: config.script,
|
|
89
|
+
cwd: config.cwd,
|
|
90
|
+
interpreter: config.interpreter,
|
|
91
|
+
instances: config.instances,
|
|
92
|
+
exec_mode: config.exec_mode,
|
|
93
|
+
autorestart: config.autorestart,
|
|
94
|
+
watch: config.watch,
|
|
95
|
+
ignore_watch: config.ignore_watch,
|
|
96
|
+
env: config.env,
|
|
97
|
+
max_memory_restart: config.max_memory_restart
|
|
98
|
+
}, (err) => {
|
|
99
|
+
if (err) {
|
|
100
|
+
reject(new Error(`Failed to start process with new config: ${err.message}`));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
resolve(true);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
await updatePromise;
|
|
109
|
+
pm2_1.default.disconnect();
|
|
110
|
+
res.json({ success: true, message: 'Configuration updated successfully' });
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
pm2_1.default.disconnect();
|
|
114
|
+
res.status(500).json({ error: error.message || 'Failed to update configuration' });
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
exports.default = router;
|