Kembali ke ArsipScraper
S
@saurus
Published 7 hours ago
javascript
Uploader saurus cdn
upload foto video file audio dll ke saurus cdn dan mengembalikan link
javascript· 121 lines
const axios = require('axios');const FormData = require('form-data');const fs = require('fs');const path = require('path'); const BASE_URL = 'https://cdn.saurus.qzz.io';const API_UPLOAD = `${BASE_URL}/api/upload`; async function uploadFiles(filePaths, options = {}) { if (!Array.isArray(filePaths) || filePaths.length === 0) { throw new Error('Minimal 1 file harus di-upload'); } if (filePaths.length > 3) { throw new Error('Maksimal 3 file per request'); } const form = new FormData(); // Tambahkan file-file for (const filePath of filePaths) { if (!fs.existsSync(filePath)) { throw new Error(`File tidak ditemukan: ${filePath}`); } form.append('file', fs.createReadStream(filePath), { filename: path.basename(filePath), }); } // Opsional: expires (detik) if (options.expires != null) { form.append('expires', String(options.expires)); } // Tentukan endpoint let endpoint = API_UPLOAD; if (options.permanent) endpoint += '/permanent'; else if (options.temp) endpoint += '/temp'; // Content-Length WAJIB dihitung oleh form-data const contentLength = form.getLengthSync(); const response = await axios.post(endpoint, form, { headers: { ...form.getHeaders(), 'Content-Length': contentLength, }, maxBodyLength: Infinity, maxContentLength: Infinity, validateStatus: () => true, // biar kita handle 200/201 manual }); return { status: response.status, // 201 = baru, 200 = duplikat duplicate: response.status === 200, body: response.data, };} /** * Hapus file berdasarkan deleteToken */async function deleteFile(fileId, deleteToken) { const url = `${BASE_URL}/api/file/${fileId}`; const res = await axios.delete(url, { headers: { 'X-Delete-Token': deleteToken }, validateStatus: () => true, }); return { status: res.status, body: res.data };} /** * Download partial dengan Range header */async function downloadRange(fileUrl, range = 'bytes=0-1023', outFile = 'part.bin') { const res = await axios.get(fileUrl, { headers: { Range: range }, responseType: 'stream', validateStatus: () => true, }); const writer = fs.createWriteStream(outFile); res.data.pipe(writer); await new Promise((resolve, reject) => { writer.on('finish', resolve); writer.on('error', reject); }); return { status: res.status, outFile };} // ---------- Contoh pemakaian ----------(async () => { try { // 1 file, mode default const r1 = await uploadFiles(['./photo.png']); console.log('Upload:', r1.status, r1.body); // 2 file, expires 1 jam // const r2 = await uploadFiles(['./a.png', './b.jpg'], { expires: 3600 }); // console.log(r2); // 1 file permanent // const r3 = await uploadFiles(['./build.zip'], { permanent: true }); // console.log(r3); // 1 file temp 1 jam // const r4 = await uploadFiles(['./build.zip'], { temp: true, expires: 3600 }); // console.log(r4); // Hapus file pakai deleteToken dari response // if (r1.body?.data?.deleteToken) { // const del = await deleteFile(r1.body.data.id, r1.body.data.deleteToken); // console.log('Delete:', del); // } // Download Range // await downloadRange('https://cdn.saurus.qzz.io/video/dHay.mp4', 'bytes=0-1023', 'part.bin'); } catch (err) { console.error('Error:', err.response?.data || err.message); }})(); module.exports = { uploadFiles, deleteFile, downloadRange };