init
This commit is contained in:
41
mc_test/dist/main/electron.js
vendored
Executable file
41
mc_test/dist/main/electron.js
vendored
Executable file
@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
const { app, BrowserWindow, ipcMain } = require('electron');
|
||||
const path = require('path');
|
||||
function createWindow() {
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 1200,
|
||||
height: 800,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: true,
|
||||
preload: path.join(__dirname, '../preload.js'),
|
||||
},
|
||||
});
|
||||
// In development, load from Vite dev server
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
mainWindow.loadURL('http://localhost:5173');
|
||||
mainWindow.webContents.openDevTools();
|
||||
}
|
||||
else {
|
||||
// In production, load the built index.html
|
||||
mainWindow.loadFile(path.join(__dirname, '../renderer/index.html'));
|
||||
}
|
||||
}
|
||||
app.whenReady().then(() => {
|
||||
createWindow();
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
});
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
// Handle machine connection (stub)
|
||||
ipcMain.handle('connect-to-machine', async (_event, machine) => {
|
||||
console.log('Connecting to machine:', machine);
|
||||
return { success: true, message: 'Connection successful (stub)' };
|
||||
});
|
||||
182
mc_test/dist/main/main/electron.js
vendored
Executable file
182
mc_test/dist/main/main/electron.js
vendored
Executable file
@ -0,0 +1,182 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const { app, BrowserWindow, ipcMain } = require('electron');
|
||||
const path = require('path');
|
||||
const logger_1 = require("./logger");
|
||||
// Временное хранилище для демо
|
||||
const machinesStore = {
|
||||
'test-vm-01': {
|
||||
id: 'test-vm-01',
|
||||
name: 'Test VM 1',
|
||||
status: 'running',
|
||||
os: 'Windows 10',
|
||||
ip: '192.168.1.100',
|
||||
hypervisor: 'VMware',
|
||||
specs: {
|
||||
cpu: '4 cores',
|
||||
ram: '8GB',
|
||||
disk: '256GB'
|
||||
},
|
||||
testLinks: [
|
||||
{ name: 'RDP', url: 'rdp://192.168.1.100' },
|
||||
{ name: 'Web Console', url: 'https://192.168.1.100:8080' }
|
||||
],
|
||||
logs: [
|
||||
{ timestamp: new Date().toISOString(), message: 'System started', level: 'info' }
|
||||
]
|
||||
}
|
||||
};
|
||||
function createWindow() {
|
||||
logger_1.log.info('startup', 'Creating main window...');
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 1200,
|
||||
height: 800,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: true,
|
||||
preload: path.join(__dirname, '..', 'preload.js'),
|
||||
},
|
||||
});
|
||||
// In development, load from Vite dev server
|
||||
const VITE_DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL;
|
||||
logger_1.log.debug('startup', 'VITE_DEV_SERVER_URL:', { url: VITE_DEV_SERVER_URL });
|
||||
if (VITE_DEV_SERVER_URL) {
|
||||
logger_1.log.info('startup', 'Loading from dev server', { url: VITE_DEV_SERVER_URL });
|
||||
mainWindow.loadURL(VITE_DEV_SERVER_URL);
|
||||
mainWindow.webContents.openDevTools();
|
||||
}
|
||||
else {
|
||||
const indexPath = path.join(__dirname, '..', 'renderer', 'index.html');
|
||||
logger_1.log.info('startup', 'Loading from file', { path: indexPath });
|
||||
mainWindow.loadFile(indexPath);
|
||||
}
|
||||
// Handle window close
|
||||
mainWindow.on('closed', () => {
|
||||
logger_1.log.info('window', 'Main window closed, quitting application');
|
||||
app.quit();
|
||||
});
|
||||
}
|
||||
// This method will be called when Electron has finished initialization
|
||||
app.whenReady().then(() => {
|
||||
logger_1.log.info('startup', 'Application ready, initializing...');
|
||||
createWindow();
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
logger_1.log.info('window', 'No windows available, creating new window');
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
});
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
logger_1.log.info('window', 'All windows closed, quitting application');
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
// Обработка событий логирования от renderer процесса
|
||||
ipcMain.on('log-event', (_event, { level, tag, message, context }) => {
|
||||
logger_1.log[level](tag, message, context);
|
||||
});
|
||||
// Обработчики IPC событий
|
||||
// Подключение к машине
|
||||
ipcMain.handle('connect-to-machine', async (_event, machine) => {
|
||||
logger_1.log.info('connect-machine', 'Connection request received', {
|
||||
machineId: machine.id,
|
||||
machineName: machine.name
|
||||
});
|
||||
try {
|
||||
// TODO: Реальная логика подключения будет добавлена позже
|
||||
return {
|
||||
success: true,
|
||||
message: 'Connection successful',
|
||||
details: { machineId: machine.id }
|
||||
};
|
||||
}
|
||||
catch (error) {
|
||||
logger_1.log.error('connect-machine', 'Connection failed', {
|
||||
machineId: machine.id,
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
// Управление состоянием машины
|
||||
ipcMain.handle('control-machine', async (_event, { machineId, action }) => {
|
||||
logger_1.log.info('control-machine', `Machine ${action} requested`, { machineId, action });
|
||||
try {
|
||||
const machine = machinesStore[machineId];
|
||||
if (!machine) {
|
||||
throw new Error(`Machine ${machineId} not found`);
|
||||
}
|
||||
// Симуляция изменения состояния
|
||||
switch (action) {
|
||||
case 'start':
|
||||
machine.status = 'running';
|
||||
machine.logs.unshift({
|
||||
timestamp: new Date().toISOString(),
|
||||
message: 'Machine started',
|
||||
level: 'info'
|
||||
});
|
||||
break;
|
||||
case 'stop':
|
||||
machine.status = 'stopped';
|
||||
machine.logs.unshift({
|
||||
timestamp: new Date().toISOString(),
|
||||
message: 'Machine stopped',
|
||||
level: 'info'
|
||||
});
|
||||
break;
|
||||
case 'restart':
|
||||
machine.status = 'stopped';
|
||||
machine.logs.unshift({
|
||||
timestamp: new Date().toISOString(),
|
||||
message: 'Machine restarting',
|
||||
level: 'info'
|
||||
});
|
||||
setTimeout(() => {
|
||||
machine.status = 'running';
|
||||
machine.logs.unshift({
|
||||
timestamp: new Date().toISOString(),
|
||||
message: 'Machine restarted successfully',
|
||||
level: 'info'
|
||||
});
|
||||
logger_1.log.info('control-machine', 'Machine restarted', { machineId });
|
||||
}, 2000);
|
||||
break;
|
||||
}
|
||||
return {
|
||||
success: true,
|
||||
message: `Machine ${action} successful`,
|
||||
details: { machineId, newStatus: machine.status }
|
||||
};
|
||||
}
|
||||
catch (error) {
|
||||
logger_1.log.error('control-machine', `Machine ${action} failed`, {
|
||||
machineId,
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
// Получение статуса машины
|
||||
ipcMain.handle('get-machine-status', async (_event, machineId) => {
|
||||
logger_1.log.debug('get-machine-status', 'Status requested', { machineId });
|
||||
const machine = machinesStore[machineId];
|
||||
if (!machine) {
|
||||
throw new Error(`Machine ${machineId} not found`);
|
||||
}
|
||||
return {
|
||||
success: true,
|
||||
message: 'Status retrieved',
|
||||
status: machine.status
|
||||
};
|
||||
});
|
||||
// Получение списка машин
|
||||
ipcMain.handle('get-machine-list', async () => {
|
||||
logger_1.log.debug('get-machine-list', 'Machine list requested');
|
||||
return {
|
||||
success: true,
|
||||
message: 'Machine list retrieved',
|
||||
machines: Object.values(machinesStore)
|
||||
};
|
||||
});
|
||||
84
mc_test/dist/main/main/logger.js
vendored
Executable file
84
mc_test/dist/main/main/logger.js
vendored
Executable file
@ -0,0 +1,84 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.log = void 0;
|
||||
const winston_1 = __importDefault(require("winston"));
|
||||
const winston_daily_rotate_file_1 = __importDefault(require("winston-daily-rotate-file"));
|
||||
const path_1 = __importDefault(require("path"));
|
||||
// Создание кастомного формата
|
||||
const customFormat = winston_1.default.format.printf(({ level, message, timestamp, tag, context }) => {
|
||||
const contextStr = context ? ` | context: ${JSON.stringify(context)}` : '';
|
||||
return `[${timestamp}] [${tag || 'main'}] [${level.toUpperCase()}]: ${message}${contextStr}`;
|
||||
});
|
||||
// Конфигурация логгера
|
||||
const logger = winston_1.default.createLogger({
|
||||
level: process.env.NODE_ENV === 'development' ? 'debug' : 'info',
|
||||
format: winston_1.default.format.combine(winston_1.default.format.timestamp({
|
||||
format: 'YYYY-MM-DD HH:mm:ss'
|
||||
}), winston_1.default.format.errors({ stack: true }), customFormat),
|
||||
transports: [
|
||||
// Логирование в файл с ротацией
|
||||
new winston_daily_rotate_file_1.default({
|
||||
dirname: path_1.default.join(process.cwd(), 'logs'),
|
||||
filename: 'app-%DATE%.log',
|
||||
datePattern: 'YYYY-MM-DD',
|
||||
zippedArchive: true,
|
||||
maxSize: '20m',
|
||||
maxFiles: '14d',
|
||||
level: 'info'
|
||||
}),
|
||||
// Логирование в консоль с цветами
|
||||
new winston_1.default.transports.Console({
|
||||
format: winston_1.default.format.combine(winston_1.default.format.colorize(), customFormat)
|
||||
})
|
||||
]
|
||||
});
|
||||
// Обработка необработанных исключений и промисов
|
||||
logger.exceptions.handle(new winston_1.default.transports.File({ filename: path_1.default.join(process.cwd(), 'logs', 'exceptions.log') }));
|
||||
logger.rejections.handle(new winston_1.default.transports.File({ filename: path_1.default.join(process.cwd(), 'logs', 'rejections.log') }));
|
||||
// Создание методов для разных уровней логирования
|
||||
const createLogMethod = (level) => {
|
||||
return (tag, message, context) => {
|
||||
logger.log({
|
||||
level,
|
||||
message,
|
||||
tag,
|
||||
context
|
||||
});
|
||||
};
|
||||
};
|
||||
// Экспорт интерфейса логгера
|
||||
exports.log = {
|
||||
error: createLogMethod('error'),
|
||||
warn: createLogMethod('warn'),
|
||||
info: createLogMethod('info'),
|
||||
debug: createLogMethod('debug'),
|
||||
// Метод для логирования необработанных ошибок
|
||||
fatal: (error, context) => {
|
||||
logger.error({
|
||||
level: 'error',
|
||||
message: error.message,
|
||||
tag: 'uncaught',
|
||||
context: {
|
||||
...context,
|
||||
stack: error.stack
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
// Настройка обработчиков необработанных ошибок
|
||||
process.on('uncaughtException', (error) => {
|
||||
exports.log.fatal(error);
|
||||
process.exit(1);
|
||||
});
|
||||
process.on('unhandledRejection', (reason) => {
|
||||
if (reason instanceof Error) {
|
||||
exports.log.fatal(reason);
|
||||
}
|
||||
else {
|
||||
exports.log.error('unhandledRejection', 'Unhandled promise rejection', { reason });
|
||||
}
|
||||
});
|
||||
exports.default = exports.log;
|
||||
17
mc_test/dist/main/preload.js
vendored
Executable file
17
mc_test/dist/main/preload.js
vendored
Executable file
@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const { contextBridge, ipcRenderer } = require('electron');
|
||||
// Expose protected methods that allow the renderer process to use
|
||||
// the ipcRenderer without exposing the entire object
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
// Подключение к машине
|
||||
connectToMachine: (machine) => ipcRenderer.invoke('connect-to-machine', machine),
|
||||
// Управление состоянием машины
|
||||
controlMachine: (machineId, action) => ipcRenderer.invoke('control-machine', { machineId, action }),
|
||||
// Получение статуса машины
|
||||
getMachineStatus: (machineId) => ipcRenderer.invoke('get-machine-status', machineId),
|
||||
// Получение списка машин
|
||||
getMachineList: () => ipcRenderer.invoke('get-machine-list'),
|
||||
// Логирование
|
||||
logEvent: (level, tag, message, context) => ipcRenderer.send('log-event', { level, tag, message, context }),
|
||||
});
|
||||
2
mc_test/dist/main/renderer/types.js
vendored
Executable file
2
mc_test/dist/main/renderer/types.js
vendored
Executable file
@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
Reference in New Issue
Block a user