66 lines
2.3 KiB
TypeScript
66 lines
2.3 KiB
TypeScript
import crypto from 'crypto'
|
|
|
|
export async function uploadToOpeninary(file: File, folder: string = "marmarislocal"): Promise<string> {
|
|
const baseUrl = process.env.OPENINARY_API_URL?.replace(/\/+$/, '');
|
|
const url = `${baseUrl}/api/upload`;
|
|
const key = process.env.OPENINARY_API_KEY;
|
|
|
|
if (!baseUrl || !key) {
|
|
throw new Error("Openinary configuration (OPENINARY_API_URL or OPENINARY_API_KEY) is missing in environment variables.");
|
|
}
|
|
|
|
// 1. ENAMETOOLONG Fix: Shorten very long folder parts (e.g. slugs)
|
|
const safeFolder = folder
|
|
.split('/')
|
|
.filter(Boolean) // Avoid double slashes in folder path
|
|
.map(part => {
|
|
if (part.length > 25) {
|
|
const hash = crypto.createHash('md5').update(part).digest('hex').substring(0, 5);
|
|
return `${part.substring(0, 20)}-${hash}`;
|
|
}
|
|
return part;
|
|
})
|
|
.join('/');
|
|
|
|
// 2. ENAMETOOLONG Fix: Shorten very long filenames
|
|
const lastDotIndex = file.name.lastIndexOf('.');
|
|
const ext = lastDotIndex !== -1 ? file.name.substring(lastDotIndex) : '';
|
|
let nameWithoutExt = lastDotIndex !== -1 ? file.name.substring(0, lastDotIndex) : file.name;
|
|
|
|
if (nameWithoutExt.length > 25) {
|
|
const hash = crypto.createHash('md5').update(nameWithoutExt).digest('hex').substring(0, 5);
|
|
nameWithoutExt = `${nameWithoutExt.substring(0, 20)}-${hash}`;
|
|
}
|
|
const safeFileName = `${nameWithoutExt}${ext}`;
|
|
|
|
const formData = new FormData();
|
|
formData.append("files", file, safeFileName);
|
|
formData.append("folder", safeFolder);
|
|
|
|
const response = await fetch(url, {
|
|
method: "POST",
|
|
headers: {
|
|
"Authorization": `Bearer ${key}`,
|
|
},
|
|
body: formData,
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const errText = await response.text();
|
|
throw new Error(`Openinary upload failed: ${response.statusText} - ${errText}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
// Openinary standard response is usually an array: [{ url: "...", name: "..." }]
|
|
if (Array.isArray(data) && data.length > 0) {
|
|
const fileUrl = data[0].url || data[0].secure_url;
|
|
return fileUrl.startsWith('/') ? `${baseUrl}${fileUrl}` : fileUrl;
|
|
} else if (data && typeof data === "object") {
|
|
const fileUrl = data.url || data.secure_url || (data.files && data.files[0]?.url);
|
|
return fileUrl.startsWith('/') ? `${baseUrl}${fileUrl}` : fileUrl;
|
|
}
|
|
|
|
throw new Error("Invalid response format from Openinary server.");
|
|
}
|