From 621cfc931a91b9dc706f29b80c6e49c4f9e2b985 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Fri, 7 Nov 2025 16:22:56 +0800 Subject: [PATCH] upd: upload base64 Deskripsi: - api upload base64 test No Issues --- src/server/lib/seafile.ts | 73 ++++++++++++++++------ src/server/routes/pengaduan_route.ts | 91 +++++++++++++++++++--------- upload_base64.sh | 2 + 3 files changed, 117 insertions(+), 49 deletions(-) create mode 100644 upload_base64.sh diff --git a/src/server/lib/seafile.ts b/src/server/lib/seafile.ts index 776478f..6f42299 100644 --- a/src/server/lib/seafile.ts +++ b/src/server/lib/seafile.ts @@ -136,32 +136,65 @@ export async function catFile(config: Config, fileName: string): Promise } export async function uploadFile(config: Config, file: File): Promise { - const remoteName = path.basename(file.name); + const remoteName = path.basename(file.name); - // 1. Dapatkan upload link (pakai Authorization) - const uploadUrlResponse = await fetchWithAuth( - config, - `${config.URL}/${config.REPO}/upload-link/` - ); - const uploadUrl = (await uploadUrlResponse.text()).replace(/"/g, ""); + // 1. Dapatkan upload link (pakai Authorization) + const uploadUrlResponse = await fetchWithAuth( + config, + `${config.URL}/${config.REPO}/upload-link/` + ); + const uploadUrl = (await uploadUrlResponse.text()).replace(/"/g, ""); - // 2. Siapkan form-data - const formData = new FormData(); - formData.append("parent_dir", "/"); - formData.append("relative_path", "syarat-dokumen"); // tanpa slash di akhir - formData.append("file", file, remoteName); // file langsung, jangan pakai Blob + // 2. Siapkan form-data + const formData = new FormData(); + formData.append("parent_dir", "/"); + formData.append("relative_path", "syarat-dokumen"); // tanpa slash di akhir + formData.append("file", file, remoteName); // file langsung, jangan pakai Blob - // 3. Upload file TANPA Authorization header, token di query param - const res = await fetch(`${uploadUrl}?token=${config.TOKEN}`, { - method: "POST", - body: formData, - }); + // 3. Upload file TANPA Authorization header, token di query param + const res = await fetch(`${uploadUrl}?token=${config.TOKEN}`, { + method: "POST", + body: formData, + }); - const text = await res.text(); + const text = await res.text(); - if (!res.ok) throw new Error(`Upload failed: ${text}`); - return `✅ Uploaded ${file.name} successfully`; + if (!res.ok) throw new Error(`Upload failed: ${text}`); + return `✅ Uploaded ${file.name} successfully`; } +export async function uploadFileBase64(config: Config, base64File: { name: string; data: string }): Promise { + const remoteName = path.basename(base64File.name); + + // 1. Dapatkan upload link (pakai Authorization) + const uploadUrlResponse = await fetchWithAuth( + config, + `${config.URL}/${config.REPO}/upload-link/` + ); + const uploadUrl = (await uploadUrlResponse.text()).replace(/"/g, ""); + + // 2. Konversi base64 ke Blob + const binary = Buffer.from(base64File.data, "base64"); + const blob = new Blob([binary]); + + // 3. Siapkan form-data + const formData = new FormData(); + formData.append("parent_dir", "/"); + formData.append("relative_path", "syarat-dokumen"); // tanpa slash di akhir + formData.append("file", blob, remoteName); + + // 4. Upload file TANPA Authorization header, token di query param + const res = await fetch(`${uploadUrl}?token=${config.TOKEN}`, { + method: "POST", + body: formData, + }); + + const text = await res.text(); + + if (!res.ok) throw new Error(`Upload failed: ${text}`); + return `✅ Uploaded ${base64File.name} successfully`; +} + + export async function removeFile(config: Config, fileName: string): Promise { diff --git a/src/server/routes/pengaduan_route.ts b/src/server/routes/pengaduan_route.ts index 392274c..314afb9 100644 --- a/src/server/routes/pengaduan_route.ts +++ b/src/server/routes/pengaduan_route.ts @@ -4,7 +4,7 @@ import { getLastUpdated } from "../lib/get-last-updated" import { generateNoPengaduan } from "../lib/no-pengaduan" import { normalizePhoneNumber } from "../lib/normalizePhone" import { prisma } from "../lib/prisma" -import { defaultConfigSF, uploadFile } from "../lib/seafile" +import { defaultConfigSF, uploadFile, uploadFileBase64 } from "../lib/seafile" const PengaduanRoute = new Elysia({ prefix: "pengaduan", @@ -432,38 +432,71 @@ const PengaduanRoute = new Elysia({ tags: ["mcp"] } }) - .post("/upload", - async ({ body }) => { - const { file } = body; + .post("/upload", async ({ body }) => { + const { file } = body; - // Validasi file - if (!file) { - return { success: false, message: "File tidak ditemukan" }; - } + // Validasi file + if (!file) { + return { success: false, message: "File tidak ditemukan" }; + } - // Upload ke Seafile (pastikan uploadFile menerima Blob atau ArrayBuffer) - // const buffer = await file.arrayBuffer(); - const result = await uploadFile(defaultConfigSF, file); + // Upload ke Seafile (pastikan uploadFile menerima Blob atau ArrayBuffer) + // const buffer = await file.arrayBuffer(); + const result = await uploadFile(defaultConfigSF, file); - return { - success: true, - message: "Upload berhasil", - filename: file.name, - size: file.size, - seafileResult: result - }; + return { + success: true, + message: "Upload berhasil", + filename: file.name, + size: file.size, + seafileResult: result + }; + }, { + body: t.Object({ + file: t.File({ format: "binary" }) + }), + detail: { + summary: "Upload File", + description: "Tool untuk upload file ke Seafile", + tags: ["mcp"], + consumes: ["multipart/form-data"] }, - { - body: t.Object({ - file: t.File({ format: "binary" }) - }), - detail: { - summary: "Upload File", - description: "Tool untuk upload file ke Seafile", - tags: ["mcp"], - consumes: ["multipart/form-data"] - }, - }) + }) + .post("/upload-base64", async ({ body }) => { + const { file } = body; + + // Validasi file + if (!file) { + return { success: false, message: "File tidak ditemukan" }; + } + + // Konversi file ke base64 + const buffer = await file.arrayBuffer(); + const base64String = Buffer.from(buffer).toString("base64"); + + // (Opsional) jika perlu dikirim ke Seafile sebagai base64 + const result = await uploadFileBase64(defaultConfigSF, { name: file.name, data: base64String }); + + return { + success: true, + message: "Upload berhasil", + filename: file.name, + size: file.size, + base64Preview: base64String.slice(0, 100) + "...", // hanya preview + seafileResult: result + }; + }, { + body: t.Object({ + file: t.File({ format: "binary" }) + }), + detail: { + summary: "Upload File (Base64)", + description: "Tool untuk upload file ke Seafile dalam format Base64", + tags: ["mcp"], + consumes: ["multipart/form-data"] + }, + }) + .get("/list", async ({ query }) => { const { take, page, search, status } = query const skip = !page ? 0 : (Number(page) - 1) * (!take ? 10 : Number(take)) diff --git a/upload_base64.sh b/upload_base64.sh new file mode 100644 index 0000000..19b94c1 --- /dev/null +++ b/upload_base64.sh @@ -0,0 +1,2 @@ +curl -X POST http://localhost:3000/api/pengaduan/upload-base64 \ + -F file=@package.json