Files
mb-grid-solutions.com/scripts/upload-s3.ts
Marc Mintel 55cb073a6d
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 4s
Build & Deploy / 🧪 QA (push) Successful in 2m55s
Build & Deploy / 🏗️ Build (push) Successful in 11m40s
Build & Deploy / 🚀 Deploy (push) Failing after 8s
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s
feat(cms): migrate from directus to payloadcms
2026-02-27 12:56:35 +01:00

87 lines
2.9 KiB
TypeScript

import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import * as fs from "fs";
import * as path from "path";
const S3_ENDPOINT = process.env.S3_ENDPOINT;
const S3_REGION = process.env.S3_REGION || "fsn1";
const S3_BUCKET = process.env.S3_BUCKET;
const S3_PREFIX = process.env.S3_PREFIX;
const S3_ACCESS_KEY = process.env.S3_ACCESS_KEY;
const S3_SECRET_KEY = process.env.S3_SECRET_KEY;
if (!S3_ENDPOINT || !S3_BUCKET || !S3_ACCESS_KEY || !S3_SECRET_KEY) {
console.error("Missing S3 credentials in environment");
process.exit(1);
}
const s3Client = new S3Client({
region: S3_REGION,
endpoint: S3_ENDPOINT,
credentials: {
accessKeyId: S3_ACCESS_KEY,
secretAccessKey: S3_SECRET_KEY,
},
forcePathStyle: true,
});
async function uploadDirectory(dirPath: string, prefix: string) {
const files = fs.readdirSync(dirPath, { withFileTypes: true });
for (const file of files) {
if (file.name === ".DS_Store" || file.name === ".gitkeep") continue;
const fullPath = path.join(dirPath, file.name);
// Combine prefix with filename, ensuring no double slashes, e.g., mb-grid-solutions/media/filename.ext
const s3Key = `${prefix}/${file.name}`.replace(/\/+/g, "/");
if (file.isDirectory()) {
await uploadDirectory(fullPath, s3Key);
} else {
const fileContent = fs.readFileSync(fullPath);
let contentType = "application/octet-stream";
if (file.name.endsWith(".png")) contentType = "image/png";
else if (file.name.endsWith(".jpg") || file.name.endsWith(".jpeg"))
contentType = "image/jpeg";
else if (file.name.endsWith(".svg")) contentType = "image/svg+xml";
else if (file.name.endsWith(".webp")) contentType = "image/webp";
else if (file.name.endsWith(".pdf")) contentType = "application/pdf";
try {
await s3Client.send(
new PutObjectCommand({
Bucket: S3_BUCKET,
Key: s3Key,
Body: fileContent,
ContentType: contentType,
ACL: "public-read", // Hetzner requires public-read for public access usually
}),
);
console.log(`✅ Uploaded ${file.name} to ${S3_BUCKET}/${s3Key}`);
} catch (err) {
console.error(`❌ Failed to upload ${file.name}:`, err);
}
}
}
}
async function main() {
const mediaDir = path.resolve(process.cwd(), "public/media");
if (fs.existsSync(mediaDir)) {
console.log("Uploading public/media...");
// Media inside Payload CMS uses prefix/media usually, like mb-grid-solutions/media
await uploadDirectory(mediaDir, `${S3_PREFIX}/media`);
} else {
console.log("No public/media directory found.");
}
const assetsDir = path.resolve(process.cwd(), "public/assets");
if (fs.existsSync(assetsDir)) {
console.log("Uploading public/assets...");
await uploadDirectory(assetsDir, `${S3_PREFIX}/assets`);
} else {
console.log("No public/assets directory found.");
}
}
main().catch(console.error);