RustyCMS: file-based headless CMS — API, Admin UI (content, types, assets), Docker/Caddy, image transform; only demo type and demo content in version control
Made-with: Cursor
This commit is contained in:
86
scripts/migrate-image-to-src-description.mjs
Normal file
86
scripts/migrate-image-to-src-description.mjs
Normal file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Migriert content/<locale>/image/*.json5 auf Schema { description, src }.
|
||||
* - Wenn image eine URL ist (http/https): src = image, description = caption || ""
|
||||
* - Wenn image ein img-Slug (Referenz): lädt img/<slug>.json5, src = img.src, description = caption || img.description || ""
|
||||
*/
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const CONTENT_ROOT = path.join(__dirname, "..", "content");
|
||||
|
||||
function parseJson(str) {
|
||||
try {
|
||||
return JSON.parse(str);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function isUrl(s) {
|
||||
return typeof s === "string" && (s.startsWith("http://") || s.startsWith("https://"));
|
||||
}
|
||||
|
||||
function* findImageDirs() {
|
||||
const locales = fs.readdirSync(CONTENT_ROOT, { withFileTypes: true });
|
||||
for (const loc of locales) {
|
||||
if (!loc.isDirectory()) continue;
|
||||
const imageDir = path.join(CONTENT_ROOT, loc.name, "image");
|
||||
if (fs.existsSync(imageDir)) yield { locale: loc.name, dir: imageDir };
|
||||
}
|
||||
}
|
||||
|
||||
let total = 0;
|
||||
let updated = 0;
|
||||
|
||||
for (const { locale, dir: imageDir } of findImageDirs()) {
|
||||
const imgDir = path.join(CONTENT_ROOT, locale, "img");
|
||||
const files = fs.readdirSync(imageDir).filter((f) => f.endsWith(".json5"));
|
||||
for (const file of files) {
|
||||
total++;
|
||||
const filePath = path.join(imageDir, file);
|
||||
const data = parseJson(fs.readFileSync(filePath, "utf8"));
|
||||
if (!data) {
|
||||
console.warn("Skip (parse error):", filePath);
|
||||
continue;
|
||||
}
|
||||
const slug = data._slug ?? file.replace(/\.json5$/, "");
|
||||
const caption = data.caption != null ? String(data.caption).trim() : "";
|
||||
let description = "";
|
||||
let src = "";
|
||||
|
||||
if (isUrl(data.image)) {
|
||||
src = data.image;
|
||||
description = caption;
|
||||
} else {
|
||||
const imgSlug = data.image;
|
||||
if (!imgSlug) {
|
||||
console.warn("Kein image (URL oder Referenz):", filePath);
|
||||
} else {
|
||||
const imgPath = path.join(imgDir, imgSlug + ".json5");
|
||||
if (!fs.existsSync(imgPath)) {
|
||||
console.warn("Img nicht gefunden:", imgPath);
|
||||
} else {
|
||||
const img = parseJson(fs.readFileSync(imgPath, "utf8"));
|
||||
if (img) {
|
||||
src = img.src ?? "";
|
||||
description = caption || img.description || "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const out = {
|
||||
_slug: slug,
|
||||
...(description !== "" && { description }),
|
||||
src,
|
||||
};
|
||||
fs.writeFileSync(filePath, JSON.stringify(out, null, 2) + "\n", "utf8");
|
||||
updated++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Image-Migration:", updated, "von", total, "Dateien auf { description, src } umgestellt.");
|
||||
Reference in New Issue
Block a user