File size: 3,914 Bytes
d8f7b5b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const express = require('express');
const { chromium } = require('playwright');
const cors = require('cors');
const dotenv = require('dotenv');
const { NodeVM } = require('vm2');
const os = require('os');
const axios = require('axios');
const fetch = require('node-fetch');

dotenv.config();

const app = express();

app.set('json spaces', 2);
app.use(express.json());
app.use(cors());

app.get('/', (req, res) => {
    const formatMemory = (bytes) => {
        const gb = bytes / 1024 / 1024 / 1024;
        if (gb >= 1) {
            return gb.toFixed(2) + ' GB';
        } else {
            return (bytes / 1024 / 1024).toFixed(2) + ' MB';
        }
    };
    
    const cpuModel = os.cpus().length > 0 
        ? os.cpus()[0].model.replace(/\s+/g, ' ').trim()
        : 'Unknown';
    
    const uptime = (() => {
        const totalSeconds = os.uptime();
        const days = Math.floor(totalSeconds / (3600 * 24));
        const hours = Math.floor((totalSeconds % (3600 * 24)) / 3600);
        const minutes = Math.floor((totalSeconds % 3600) / 60);
        return `${days}d ${hours}h ${minutes}m`;
    })();
    
    const memoryUsedPercentage = ((os.totalmem() - os.freemem()) / os.totalmem() * 100).toFixed(2);
    
    res.json({
        status: "online",
        uptime: uptime,
        cpu: {
            model: cpuModel,
            cores: os.cpus().length,
            load: os.loadavg()[0].toFixed(2) + '%'
        },
        memory: {
            total: formatMemory(os.totalmem()),
            used: formatMemory(os.totalmem() - os.freemem()) + ` (${memoryUsedPercentage}%)`,
            free: formatMemory(os.freemem())
        },
        info_api: [
            {
                path: '/run',
                method: 'POST',
                description: 'Run Playwright code in a sandboxed VM environment',
                body: {
                    code: 'JavaScript code to execute (required)',
                    timeout: 'Execution timeout in milliseconds (optional, default: 300000)'
                }
            }
        ]
    });
});

app.post('/run', async (req, res) => {
    const { code, timeout = 300000 } = req.body;
    if (!code) return res.status(400).json({ error: 'Code cannot be empty' });

    let output = [];
    const originalLog = console.log;

    console.log = (...args) => {
        const message = args.map(arg => (typeof arg === 'object' ? JSON.stringify(arg) : arg)).join(' ');
        output.push(message);
        originalLog.apply(console, args);
    };

    const vm = new NodeVM({
        console: 'inherit',
        sandbox: {},
        require: {
            external: true,
            builtin: ['fs', 'path'],
            root: './',
            mock: {
                playwright: { chromium },
                axios,
                'node-fetch': fetch,
            },
        },
    });

    const script = `
        module.exports = async () => {
            ${code}
        };
    `;

    let runCode;
    try {
        runCode = vm.run(script, 'sandbox.js');
    } catch (error) {
        console.log = originalLog;
        return res.status(500).json({ error: 'Failed to run code', details: error.message });
    }

    try {
        await runCode();

        const startTime = Date.now();
        while (output.length === 0 && Date.now() - startTime < timeout) {
            await new Promise(resolve => setTimeout(resolve, 1000));
        }

        const result = output.length > 0 ? output.pop() : 'No results found.';
        console.log = originalLog;

        res.json({ output: result });
    } catch (err) {
        console.log = originalLog;
        res.status(500).json({ error: 'Error while executing code', details: err.message });
    }
});

const PORT = process.env.PORT || 7860;

app.listen(PORT, async () => {
    console.log(`Server running on port ${PORT}`);
});

process.on('SIGINT', async () => {
    process.exit(0);
});