import express from 'express'; import { chromium } from 'playwright-extra'; import StealthPlugin from 'puppeteer-extra-plugin-stealth'; import cors from 'cors'; import { promises as fs } from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); chromium.use(StealthPlugin()); const app = express(); const PORT = process.env.PORT || 7860; app.use(cors()); app.use(express.json({ limit: '50mb' })); app.use('/files', express.static('public')); const publicDir = path.join(__dirname, 'public'); await fs.mkdir(publicDir, { recursive: true }).catch(console.error); function convertPlaywrightCode(code) { let converted = code; const replacements = [ [/const\s+{\s*chromium\s*}\s*=\s*require\(['"](.*?playwright.*?)['"]\)/gi, 'const chromium = globalThis.chromium'], [/from\s+['"]playwright['"]/gi, ''], [/import\s+{\s*chromium\s*}\s+from\s+['"]playwright['"]/gi, 'const chromium = globalThis.chromium'], ]; replacements.forEach(([pattern, replacement]) => { converted = converted.replace(pattern, replacement); }); return converted; } app.post('/api/s-playwright', async (req, res) => { const { code, lang } = req.body; if (!code || !lang) { return res.status(400).json({ success: false, error: 'Missing required fields: code and lang' }); } const supportedLangs = ['javascript']; const normalizedLang = lang.toLowerCase(); if (!supportedLangs.includes(normalizedLang)) { return res.status(400).json({ success: false, error: `Unsupported language: "${lang}". Supported: ${supportedLangs.join(', ')}` }); } let browser = null; try { const convertedCode = convertPlaywrightCode(code); globalThis.chromium = { launch: async (options = {}) => { return await chromium.launch({ headless: options.headless !== false, args: [ '--disable-blink-features=AutomationControlled', '--no-sandbox', '--disable-setuid-sandbox', '--disable-web-security', '--disable-features=IsolateOrigins,site-per-process', '--disable-dev-shm-usage', '--disable-accelerated-2d-canvas', '--disable-gpu', '--window-size=1920,1080', '--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36', ...(options.args || []) ] }); } }; const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor; const executableCode = new AsyncFunction('chromium', 'publicDir', 'path', 'fs', convertedCode); const result = await executableCode(globalThis.chromium, publicDir, path, fs); const timestamp = Date.now(); const baseUrl = `${req.protocol}://${req.get('host')}`; const screenshotFiles = await fs.readdir(publicDir); const recentFiles = screenshotFiles .filter(f => f.startsWith('screenshot-') && f.endsWith('.png')) .map(f => ({ name: f, publicURL: `${baseUrl}/files/${f}` })); res.json({ success: true, data: { result: result, files: recentFiles, timestamp: timestamp } }); } catch (error) { res.status(500).json({ success: false, error: error.message, stack: error.stack }); } finally { if (browser) { try { await browser.close(); } catch (e) { console.error('Error closing browser:', e.message); } } } }); app.get('/', (req, res) => { res.json({ message: 'Playwright Stealth API is running', endpoints: { 'POST /api/s-playwright': 'Execute playwright code with stealth mode' }, features: [ 'Advanced Anti-Fingerprinting', 'Stealth Plugin Enabled', 'Human-like Behavior', 'Cloudflare WAF Bypass', 'Auto Playwright code execution' ] }); }); app.listen(PORT, '0.0.0.0', () => { console.log(`🚀 Playwright Stealth API running on port ${PORT}`); console.log(`📝 Endpoint: POST /api/s-playwright`); console.log(`🎭 Features: Anti-fingerprinting, WAF bypass, stealth mode`); }); process.on('SIGTERM', async () => { console.log('SIGTERM received, shutting down gracefully...'); process.exit(0); }); process.on('SIGINT', async () => { console.log('SIGINT received, shutting down gracefully...'); process.exit(0); });