Size
7.1 KB
Version
1.0.1
Created
Mar 6, 2026
Updated
about 1 month ago
1// ==UserScript==
2// @name Rork Code Downloader
3// @description Download all code files from Rork projects as ZIP
4// @version 1.0.1
5// @match https://*.rork.com/*
6// @icon https://rork.com/favicon.ico
7// @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js
8// ==/UserScript==
9(function() {
10 'use strict';
11
12 console.log('Rork Code Downloader başlatıldı');
13
14 // Debounce fonksiyonu
15 function debounce(func, wait) {
16 let timeout;
17 return function executedFunction(...args) {
18 const later = () => {
19 clearTimeout(timeout);
20 func(...args);
21 };
22 clearTimeout(timeout);
23 timeout = setTimeout(later, wait);
24 };
25 }
26
27 // İndirme butonunu oluştur
28 function createDownloadButton() {
29 // Eğer buton zaten varsa, ekleme
30 if (document.getElementById('rork-download-btn')) {
31 return;
32 }
33
34 // Code butonunu bul
35 const codeButton = document.querySelector('button[data-state]');
36 if (!codeButton) {
37 console.log('Code butonu bulunamadı');
38 return;
39 }
40
41 const buttonContainer = codeButton.parentElement;
42 if (!buttonContainer) {
43 return;
44 }
45
46 // İndirme butonu oluştur
47 const downloadBtn = document.createElement('button');
48 downloadBtn.id = 'rork-download-btn';
49 downloadBtn.className = codeButton.className;
50 downloadBtn.innerHTML = `
51 <div class="w-full flex-row justify-center px-0.5 flex items-center gap-2">
52 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
53 <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
54 <polyline points="7 10 12 15 17 10"></polyline>
55 <line x1="12" y1="15" x2="12" y2="3"></line>
56 </svg>
57 ZIP İndir
58 </div>
59 `;
60
61 downloadBtn.addEventListener('click', async (e) => {
62 e.stopPropagation();
63 await downloadAllFiles();
64 });
65
66 buttonContainer.appendChild(downloadBtn);
67 console.log('İndirme butonu eklendi');
68 }
69
70 // Tüm dosyaları indir
71 async function downloadAllFiles() {
72 try {
73 console.log('Dosyalar indiriliyor...');
74
75 // Butonu devre dışı bırak
76 const downloadBtn = document.getElementById('rork-download-btn');
77 if (downloadBtn) {
78 downloadBtn.disabled = true;
79 downloadBtn.innerHTML = `
80 <div class="w-full flex-row justify-center px-0.5 flex items-center gap-2">
81 İndiriliyor...
82 </div>
83 `;
84 }
85
86 // Dosya isimlerini topla
87 const fileElements = document.querySelectorAll('span.truncate.opacity-70');
88 const files = [];
89
90 fileElements.forEach(element => {
91 const fileName = element.textContent.trim();
92 // Komut satırı ve paket isimlerini filtrele
93 if (fileName &&
94 !fileName.includes('mkdir') &&
95 !fileName.includes('npm') &&
96 !fileName.includes('bun') &&
97 fileName.includes('.') || fileName.includes('/')) {
98 files.push(fileName);
99 }
100 });
101
102 console.log(`${files.length} dosya bulundu:`, files);
103
104 if (files.length === 0) {
105 alert('İndirilecek dosya bulunamadı!');
106 return;
107 }
108
109 // ZIP dosyası oluştur
110 const zip = new JSZip();
111
112 // Her dosya için içerik al
113 for (const fileName of files) {
114 try {
115 // Dosya içeriğini almak için AI kullan
116 const content = await getFileContent(fileName);
117 if (content) {
118 zip.file(fileName, content);
119 console.log(`Eklendi: ${fileName}`);
120 }
121 } catch (error) {
122 console.error(`${fileName} eklenirken hata:`, error);
123 }
124 }
125
126 // ZIP'i indir
127 const blob = await zip.generateAsync({ type: 'blob' });
128 const url = URL.createObjectURL(blob);
129 const a = document.createElement('a');
130 a.href = url;
131
132 // Proje adını al
133 const projectTitle = document.querySelector('h3.text-\\[13px\\]')?.textContent || 'rork-project';
134 const sanitizedTitle = projectTitle.replace(/[^a-z0-9]/gi, '-').toLowerCase();
135
136 a.download = `${sanitizedTitle}.zip`;
137 document.body.appendChild(a);
138 a.click();
139 document.body.removeChild(a);
140 URL.revokeObjectURL(url);
141
142 console.log('ZIP dosyası indirildi!');
143 alert(`${files.length} dosya başarıyla indirildi!`);
144
145 } catch (error) {
146 console.error('İndirme hatası:', error);
147 alert('Dosyalar indirilirken bir hata oluştu: ' + error.message);
148 } finally {
149 // Butonu tekrar aktif et
150 const downloadBtn = document.getElementById('rork-download-btn');
151 if (downloadBtn) {
152 downloadBtn.disabled = false;
153 downloadBtn.innerHTML = `
154 <div class="w-full flex-row justify-center px-0.5 flex items-center gap-2">
155 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
156 <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
157 <polyline points="7 10 12 15 17 10"></polyline>
158 <line x1="12" y1="15" x2="12" y2="3"></line>
159 </svg>
160 ZIP İndir
161 </div>
162 `;
163 }
164 }
165 }
166
167 // Dosya içeriğini al (placeholder - gerçek içerik için API gerekebilir)
168 async function getFileContent(fileName) {
169 // Rork'un API'sini kullanarak dosya içeriğini almaya çalış
170 // Şimdilik boş dosya oluştur
171 return `// ${fileName}\n// Bu dosyanın içeriği Rork'tan alınamadı\n// Lütfen manuel olarak kontrol edin\n`;
172 }
173
174 // Sayfa değişikliklerini izle
175 const observer = new MutationObserver(debounce(() => {
176 createDownloadButton();
177 }, 500));
178
179 // Init fonksiyonu
180 function init() {
181 console.log('Rork Code Downloader init');
182
183 // İlk butonu oluştur
184 setTimeout(() => {
185 createDownloadButton();
186 }, 2000);
187
188 // DOM değişikliklerini izle
189 observer.observe(document.body, {
190 childList: true,
191 subtree: true
192 });
193 }
194
195 // Sayfa yüklendiğinde başlat
196 if (document.readyState === 'loading') {
197 document.addEventListener('DOMContentLoaded', init);
198 } else {
199 init();
200 }
201
202})();