135 lines
4.1 KiB
TypeScript
135 lines
4.1 KiB
TypeScript
import { PrismaClient } from '@prisma/client';
|
||
import fs from 'fs';
|
||
import path from 'path';
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
const OPENINARY_API_URL = process.env.OPENINARY_API_URL;
|
||
const OPENINARY_API_KEY = process.env.OPENINARY_API_KEY;
|
||
const NEXT_PUBLIC_OPENINARY_URL = process.env.NEXT_PUBLIC_OPENINARY_URL;
|
||
|
||
async function downloadImageAsBlob(url: string, filename: string): Promise<Blob> {
|
||
const response = await fetch(url);
|
||
if (!response.ok) throw new Error(`Failed to download ${url}`);
|
||
const arrayBuffer = await response.arrayBuffer();
|
||
|
||
// Create a Blob from the ArrayBuffer
|
||
return new Blob([arrayBuffer], { type: response.headers.get('content-type') || 'application/octet-stream' });
|
||
}
|
||
|
||
async function uploadToOpeninary(blob: Blob, filename: string): Promise<string> {
|
||
const formData = new FormData();
|
||
// Next.js node fetch environment allows passing Blob to FormData
|
||
formData.append('files', blob, filename);
|
||
formData.append('folder', 'moybeach');
|
||
|
||
const res = await fetch(`${OPENINARY_API_URL}/api/upload`, {
|
||
method: 'POST',
|
||
headers: { Authorization: `Bearer ${OPENINARY_API_KEY}` },
|
||
body: formData,
|
||
});
|
||
|
||
if (!res.ok) {
|
||
const text = await res.text();
|
||
console.error('Openinary upload error:', text);
|
||
throw new Error('Upload başarısız');
|
||
}
|
||
|
||
const data = await res.json();
|
||
return `${NEXT_PUBLIC_OPENINARY_URL}${data.files[0].url}`;
|
||
}
|
||
|
||
async function migrateImage(url: string | null): Promise<string | null> {
|
||
if (!url || !url.includes('cloudinary.com')) return url;
|
||
|
||
try {
|
||
console.log(`Migrating: ${url}`);
|
||
const filename = url.split('/').pop() || 'image.jpg';
|
||
const blob = await downloadImageAsBlob(url, filename);
|
||
const newUrl = await uploadToOpeninary(blob, filename);
|
||
console.log(`Success: ${newUrl}`);
|
||
return newUrl;
|
||
} catch (error) {
|
||
console.error(`Error migrating ${url}:`, error);
|
||
return url;
|
||
}
|
||
}
|
||
|
||
async function main() {
|
||
if (!OPENINARY_API_URL || !OPENINARY_API_KEY) {
|
||
console.error('Missing Openinary Env Variables!');
|
||
process.exit(1);
|
||
}
|
||
|
||
console.log('Starting migration from Cloudinary to Openinary...');
|
||
|
||
// 1. Gallery
|
||
const galleries = await prisma.gallery.findMany();
|
||
for (const item of galleries) {
|
||
if (item.imageUrl.includes('cloudinary.com')) {
|
||
const newUrl = await migrateImage(item.imageUrl);
|
||
if (newUrl && newUrl !== item.imageUrl) {
|
||
await prisma.gallery.update({ where: { id: item.id }, data: { imageUrl: newUrl } });
|
||
}
|
||
}
|
||
}
|
||
|
||
// 2. Service
|
||
const services = await prisma.service.findMany();
|
||
for (const item of services) {
|
||
if (item.iconUrl && item.iconUrl.includes('cloudinary.com')) {
|
||
const newUrl = await migrateImage(item.iconUrl);
|
||
if (newUrl && newUrl !== item.iconUrl) {
|
||
await prisma.service.update({ where: { id: item.id }, data: { iconUrl: newUrl } });
|
||
}
|
||
}
|
||
}
|
||
|
||
// 3. HeroMedia
|
||
const heroMedias = await prisma.heroMedia.findMany();
|
||
for (const item of heroMedias) {
|
||
if (item.url.includes('cloudinary.com')) {
|
||
const newUrl = await migrateImage(item.url);
|
||
if (newUrl && newUrl !== item.url) {
|
||
await prisma.heroMedia.update({ where: { id: item.id }, data: { url: newUrl } });
|
||
}
|
||
}
|
||
}
|
||
|
||
// 4. SiteSettings
|
||
const siteSettings = await prisma.siteSettings.findMany();
|
||
for (const item of siteSettings) {
|
||
let changed = false;
|
||
let newLogoUrl = item.logoUrl;
|
||
let newOgImage = item.ogImage;
|
||
|
||
if (item.logoUrl && item.logoUrl.includes('cloudinary.com')) {
|
||
newLogoUrl = await migrateImage(item.logoUrl) ?? item.logoUrl;
|
||
if (newLogoUrl !== item.logoUrl) changed = true;
|
||
}
|
||
|
||
if (item.ogImage && item.ogImage.includes('cloudinary.com')) {
|
||
newOgImage = await migrateImage(item.ogImage) ?? item.ogImage;
|
||
if (newOgImage !== item.ogImage) changed = true;
|
||
}
|
||
|
||
if (changed) {
|
||
await prisma.siteSettings.update({
|
||
where: { id: item.id },
|
||
data: { logoUrl: newLogoUrl, ogImage: newOgImage }
|
||
});
|
||
}
|
||
}
|
||
|
||
console.log('Migration completed!');
|
||
}
|
||
|
||
main()
|
||
.catch(e => {
|
||
console.error(e);
|
||
process.exit(1);
|
||
})
|
||
.finally(async () => {
|
||
await prisma.$disconnect();
|
||
});
|