S
@saurus
Published 7 hours ago
javascript

Uploader saurus cdn

upload foto video file audio dll ke saurus cdn dan mengembalikan link

Raw
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 };