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.
Files changed (28) hide show
  1. package/dist/server/config/project-configs.json +236 -0
  2. package/dist/server/index.js +30 -5
  3. package/dist/server/logs/deployment.log +12 -0
  4. package/dist/server/routes/deployApplication.js +174 -27
  5. package/dist/server/routes/logStreaming.js +174 -0
  6. package/dist/server/routes/remoteConnections.d.ts +3 -0
  7. package/dist/server/routes/remoteConnections.js +634 -0
  8. package/dist/server/services/ProjectSetupService.d.ts +72 -0
  9. package/dist/server/services/ProjectSetupService.js +327 -0
  10. package/dist/server/utils/dialog.d.ts +1 -0
  11. package/dist/server/utils/dialog.js +16 -0
  12. package/dist/server/utils/encryption.d.ts +12 -0
  13. package/dist/server/utils/encryption.js +72 -0
  14. package/dist/server/utils/remote-connection.d.ts +152 -0
  15. package/dist/server/utils/remote-connection.js +590 -0
  16. package/dist/server/utils/upload.d.ts +3 -0
  17. package/dist/server/utils/upload.js +39 -0
  18. package/package.json +65 -63
  19. package/src/client/build/asset-manifest.json +3 -3
  20. package/src/client/build/favicon.ico +2 -0
  21. package/src/client/build/index.html +1 -1
  22. package/src/client/build/logo192.svg +7 -0
  23. package/src/client/build/logo512.svg +7 -0
  24. package/src/client/build/manifest.json +5 -6
  25. package/src/client/build/static/js/{main.1d7f99ff.js → main.31323a04.js} +13 -13
  26. package/src/client/build/static/js/main.31323a04.js.map +1 -0
  27. package/src/client/build/static/js/main.1d7f99ff.js.map +0 -1
  28. /package/src/client/build/static/js/{main.1d7f99ff.js.LICENSE.txt → main.31323a04.js.LICENSE.txt} +0 -0
@@ -8,9 +8,11 @@ const express_1 = require("express");
8
8
  const pm2_1 = __importDefault(require("pm2"));
9
9
  const fs_1 = __importDefault(require("fs"));
10
10
  const child_process_1 = require("child_process");
11
+ const remote_connection_1 = require("../utils/remote-connection");
11
12
  const router = (0, express_1.Router)();
12
13
  // This variable will hold references to active log streams
13
14
  const activeStreams = {};
15
+ const activeRemoteStreams = {};
14
16
  // Get active stream (or create a new one)
15
17
  const getLogStream = (io, processId, logType) => {
16
18
  const streamKey = `${processId}-${logType}`;
@@ -57,6 +59,137 @@ const getLogStream = (io, processId, logType) => {
57
59
  });
58
60
  });
59
61
  };
62
+ // Get remote log stream (or create a new one)
63
+ const getRemoteLogStream = async (io, connectionId, processId) => {
64
+ const streamKey = `${connectionId}-${processId}`;
65
+ // If stream already exists, return it
66
+ if (activeRemoteStreams[streamKey]) {
67
+ return activeRemoteStreams[streamKey];
68
+ }
69
+ const connection = remote_connection_1.remoteConnectionManager.getConnection(connectionId);
70
+ if (!connection || !connection.isConnected()) {
71
+ throw new Error('Connection not found or not connected');
72
+ }
73
+ // Get process info to find log paths
74
+ console.log(`Getting process info for: ${processId}`);
75
+ const processInfoResult = await connection.executeCommand(`pm2 jlist`, false); // Don't use sudo for listing
76
+ if (processInfoResult.code !== 0) {
77
+ throw new Error(`Failed to get process list: ${processInfoResult.stderr}`);
78
+ }
79
+ let processInfo;
80
+ try {
81
+ const processList = JSON.parse(processInfoResult.stdout);
82
+ console.log(`Found ${processList.length} processes`);
83
+ // Find the process by ID
84
+ processInfo = processList.find((proc) => proc.pm_id === parseInt(processId));
85
+ if (!processInfo) {
86
+ throw new Error(`Process with ID ${processId} not found`);
87
+ }
88
+ console.log(`Found process: ${processInfo.name} (ID: ${processInfo.pm_id})`);
89
+ }
90
+ catch (parseError) {
91
+ console.error('Parse error:', parseError);
92
+ throw new Error(`Failed to parse process list: ${parseError}`);
93
+ }
94
+ const processName = processInfo.name;
95
+ // Create streams using pm2 logs instead of tail for better permission handling
96
+ const streams = {};
97
+ try {
98
+ console.log(`Setting up pm2 logs stream for process: ${processName} (ID: ${processId})`);
99
+ // Use pm2 logs with --lines 0 --raw to stream only new logs
100
+ // Use sudo since PM2 processes are running as root
101
+ const pm2LogsCommand = `pm2 logs ${processId} --lines 0 --raw`;
102
+ console.log(`About to create pm2 log stream with command: ${pm2LogsCommand} (using sudo)`);
103
+ const logStream = await connection.createLogStream(pm2LogsCommand, true);
104
+ console.log(`Successfully created pm2 logs stream for ${processName}`);
105
+ logStream.on('data', (data) => {
106
+ console.log(`Raw pm2 logs data received for ${processName}:`, data);
107
+ const lines = data.toString().split('\n').filter((line) => line.trim() !== '');
108
+ lines.forEach((line) => {
109
+ // Skip PM2 startup messages, system messages, and errors
110
+ if (line.trim() === '' ||
111
+ line.includes('PM2') ||
112
+ line.includes('---') ||
113
+ line.includes('watching') ||
114
+ line.includes('change detected') ||
115
+ line.includes('Runtime Edition') ||
116
+ line.includes('Production Process Manager') ||
117
+ line.includes('built-in Load Balancer') ||
118
+ line.includes('$ pm2') ||
119
+ line.includes('http://pm2.io') ||
120
+ line.includes('Start and Daemonize') ||
121
+ line.includes('Load Balance') ||
122
+ line.includes('Monitor in production') ||
123
+ line.includes('Make pm2 auto-boot') ||
124
+ line.includes('To go further') ||
125
+ line.includes('ENOENT') ||
126
+ line.includes('module_conf.json') ||
127
+ line.includes('pm2.log') ||
128
+ line.includes('node:fs:') ||
129
+ line.includes('at Object.') ||
130
+ line.includes('at Client.') ||
131
+ line.includes('at processTicksAndRejections') ||
132
+ line.includes('errno:') ||
133
+ line.includes('syscall:') ||
134
+ line.includes('Node.js v') ||
135
+ line.startsWith(' at ') ||
136
+ line.match(/^\s*\^?\s*$/) ||
137
+ line.match(/^[\s_\/\\|]+$/)) {
138
+ console.log(`Skipping PM2 system/error line: "${line}"`);
139
+ return;
140
+ }
141
+ // Parse PM2 log format: timestamp | app-name | message
142
+ // PM2 logs typically come in format like: "2023-01-01T12:00:00: PM2 log: [TAILING]"
143
+ // or just the raw log content depending on version
144
+ let logType = 'stdout'; // Default to stdout
145
+ let cleanLine = line;
146
+ // Try to detect if this is stderr (PM2 usually prefixes with different indicators)
147
+ if (line.includes('ERROR') || line.includes('error') || line.includes('stderr')) {
148
+ logType = 'stderr';
149
+ }
150
+ // Clean up the line by removing PM2 prefixes if present
151
+ // PM2 log format can vary, but often includes timestamps and app names
152
+ const logMatch = line.match(/^.*?\|\s*(.+)$/);
153
+ if (logMatch) {
154
+ cleanLine = logMatch[1];
155
+ }
156
+ console.log(`Emitting remote-log-line for ${connectionId}-${processId} (${logType}):`, cleanLine);
157
+ io.emit('remote-log-line', {
158
+ connectionId,
159
+ processId,
160
+ processName,
161
+ logType,
162
+ line: cleanLine
163
+ });
164
+ });
165
+ });
166
+ logStream.on('error', (error) => {
167
+ console.error(`Error in pm2 logs stream for ${processName}:`, error);
168
+ io.emit('remote-log-error', {
169
+ connectionId,
170
+ processId,
171
+ processName,
172
+ error: error.message
173
+ });
174
+ });
175
+ logStream.on('close', (code) => {
176
+ console.log(`PM2 logs stream closed for ${processName} with code:`, code);
177
+ });
178
+ streams.combined = logStream;
179
+ }
180
+ catch (error) {
181
+ console.error(`Failed to create pm2 logs stream for ${processName}:`, error);
182
+ io.emit('remote-log-error', {
183
+ connectionId,
184
+ processId,
185
+ processName,
186
+ error: `Failed to start log streaming: ${error}`
187
+ });
188
+ }
189
+ // Store the streams
190
+ activeRemoteStreams[streamKey] = streams;
191
+ return streams;
192
+ };
60
193
  // Setup socket.io handlers for log streaming
61
194
  const setupLogStreaming = (io) => {
62
195
  io.on('connection', (socket) => {
@@ -95,6 +228,47 @@ const setupLogStreaming = (io) => {
95
228
  // Cleanup on disconnect
96
229
  socket.on('disconnect', () => {
97
230
  console.log('Client disconnected from log streaming');
231
+ }); // Subscribe to remote log stream
232
+ socket.on('subscribe-remote-logs', async ({ connectionId, processId }) => {
233
+ try {
234
+ console.log(`Subscribing to remote logs - Connection: ${connectionId}, Process: ${processId}`);
235
+ const streamKey = `${connectionId}-${processId}`;
236
+ // Add socket to a room for this specific log stream
237
+ socket.join(streamKey);
238
+ console.log(`Client subscribed to remote logs: ${streamKey}`);
239
+ // Get or create the remote log stream
240
+ await getRemoteLogStream(io, connectionId, processId);
241
+ }
242
+ catch (error) {
243
+ console.error('Error subscribing to remote logs:', error);
244
+ socket.emit('remote-log-error', {
245
+ connectionId,
246
+ processId,
247
+ error: error instanceof Error ? error.message : 'Unknown error'
248
+ });
249
+ }
250
+ });
251
+ // Unsubscribe from remote log stream
252
+ socket.on('unsubscribe-remote-logs', ({ connectionId, processId }) => {
253
+ const streamKey = `${connectionId}-${processId}`;
254
+ // Remove socket from the room
255
+ socket.leave(streamKey);
256
+ console.log(`Client unsubscribed from remote logs: ${streamKey}`);
257
+ // If no more clients in this room, stop the streams
258
+ const room = io.sockets.adapter.rooms.get(streamKey);
259
+ if (!room || room.size === 0) {
260
+ const streams = activeRemoteStreams[streamKey];
261
+ if (streams) {
262
+ console.log(`Stopping remote log streams: ${streamKey}`);
263
+ if (streams.stdout && streams.stdout.kill) {
264
+ streams.stdout.kill();
265
+ }
266
+ if (streams.stderr && streams.stderr.kill) {
267
+ streams.stderr.kill();
268
+ }
269
+ delete activeRemoteStreams[streamKey];
270
+ }
271
+ }
98
272
  });
99
273
  });
100
274
  };
@@ -0,0 +1,3 @@
1
+ import { Router } from 'express';
2
+ declare const router: Router;
3
+ export default router;