/** * Name: gitreverse-scraper.js * Deskripsi: Scraper untuk mendapatkan prompt AI create website/repo dari GitReverse * * Sumber: https://whatsapp.com/channel/0029VbDLqe7EquiSF4STU13o/299 * Credt By Zx **/ function extractSlug(url) { try { const { hostname, pathname } = new URL(url); const cleanPath = pathname.replace(/\/+$/, ''); // buang trailing slash const slug = (hostname + cleanPath) .replace(/^www\./, '') .replace(/[^a-zA-Z0-9]/g, '-') .replace(/-+/g, '-') .replace(/^-|-$/g, '') .toLowerCase(); return slug; } catch { throw new Error(`URL tidak valid: ${url}`); } } async function webtopromt(targetUrl) { const siteSlug = extractSlug(targetUrl); const res = await fetch(`https://www.gitreverse.com/api/reverse-website`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ siteSlug, targetUrl, stream: true }), }); if (!res.ok) { throw new Error(`HTTP ${res.status}: ${res.statusText}`); } const text = await res.text(); const dataLines = text .split('\n') .filter(line => line.startsWith('data: ')) .map(line => line.slice(6)); // buang prefix "data: " for (const dataStr of dataLines) { try { const data = JSON.parse(dataStr); if (data.prompt) { return { prompt: data.prompt, designPath: data.designPath || null, fromCache: data.fromCache ?? false, }; } } catch { } } throw new Error('Tidak ditemukan prompt dalam response SSE'); } async function repotopromt(repoUrl) { // Terima format "owner/repo" atau full URL GitHub let cleanRepo = repoUrl .replace(/^https?:\/\/(www\.)?github\.com\//, '') .replace(/\/+$/, ''); console.log(`šŸ” Scraping repo prompt...`); console.log(` Repo: ${cleanRepo}`); const res = await fetch(`https://www.gitreverse.com/api/reverse-prompt`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ repoUrl: cleanRepo }), }); if (!res.ok) { throw new Error(`HTTP ${res.status}: ${res.statusText}`); } const data = await res.json(); if (!data.prompt) { throw new Error('Tidak ditemukan prompt dalam response'); } return { prompt: data.prompt }; } /** async function main() { const args = process.argv.slice(2); if (args.length === 0) { console.log(` ╔══════════════════════════════════════════════════════════╗ ā•‘ GitReverse - AI Prompt Generator ā•‘ ╠══════════════════════════════════════════════════════════╣ ā•‘ ā•‘ ā•‘ Usage: ā•‘ ā•‘ node gitreverse-scraper.js ā•‘ ā•‘ node gitreverse-scraper.js --website ā•‘ ā•‘ node gitreverse-scraper.js --repo ā•‘ ā•‘ node gitreverse-scraper.js --json ā•‘ ā•‘ ā•‘ ā•‘ Examples: ā•‘ ā•‘ node gitreverse-scraper.js https://pastebin.com/ ā•‘ ā•‘ node gitreverse-scraper.js --repo shahednur/RideZen ā•‘ ā•‘ node gitreverse-scraper.js --json https://linear.app ā•‘ ā•‘ ā•‘ ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā• `); process.exit(0); } let mode = 'auto'; // auto | website | repo let outputJson = false; let target = null; for (let i = 0; i < args.length; i++) { if (args[i] === '--website') mode = 'website'; else if (args[i] === '--repo') mode = 'repo'; else if (args[i] === '--json') outputJson = true; else target = args[i]; } if (!target) { console.error('āŒ Error: URL atau repo tidak diberikan.'); process.exit(1); } try { let result; if ( mode === 'repo' || (mode === 'auto' && ( target.includes('github.com') || /^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_.-]+$/.test(target) )) ) { result = await repotopromt(target); } else { if (!/^https?:\/\//.test(target)) { target = 'https://' + target; } result = await webtopromt(target); } if (outputJson) { console.log(JSON.stringify(result, null, 2)); } else { console.log('\nāœ… PROMPT AI:\n'); console.log('─'.repeat(60)); console.log(result.prompt); console.log('─'.repeat(60)); if (result.designPath) { console.log(`\nšŸŽØ Design System: https://www.gitreverse.com${result.designPath}`); } if (result.fromCache) { console.log('šŸ“¦ (dari cache)'); } } } catch (err) { console.error(`\nāŒ Error: ${err.message}`); process.exit(1); } } module.exports = { webtopromt, repotopromt, extractSlug }; if (require.main === module) { main(); } */