Files
rustycms/scripts/rename-campaigns.mjs

94 lines
2.8 KiB
JavaScript

#!/usr/bin/env node
/**
* Benennt content/de/campaign/*.json5 um: _slug und Dateiname = "campaign-" + slugify(campaignName).
* Aktualisiert Referenzen in content/de/campaigns/*.json5.
*/
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const CONTENT_DE = path.join(__dirname, "..", "content", "de");
const CAMPAIGN_DIR = path.join(CONTENT_DE, "campaign");
function slugify(s) {
if (!s || typeof s !== "string") return "";
return s
.trim()
.toLowerCase()
.replace(/\s+/g, "-")
.replace(/[^a-z0-9-]/g, "-")
.replace(/-+/g, "-")
.replace(/^-|-$/g, "");
}
function parseJson5(str) {
try {
return JSON.parse(str);
} catch {
return null;
}
}
const campaignFiles = fs.readdirSync(CAMPAIGN_DIR).filter((f) => f.endsWith(".json5"));
const oldToNew = new Map();
const newSlugs = new Set();
for (const file of campaignFiles) {
const oldSlug = file.replace(/\.json5$/, "");
const raw = fs.readFileSync(path.join(CAMPAIGN_DIR, file), "utf8");
const data = parseJson5(raw);
if (!data) continue;
const name = (data.campaignName || oldSlug).trim();
let base = slugify(name) || slugify(oldSlug);
if (!base) base = "campaign";
let newSlug = "campaign-" + base;
let n = 0;
while (newSlugs.has(newSlug)) {
n++;
newSlug = "campaign-" + base + "-" + n;
}
newSlugs.add(newSlug);
oldToNew.set(oldSlug, newSlug);
}
console.log("Slug-Map:", Object.fromEntries(oldToNew));
for (const file of campaignFiles) {
const oldSlug = file.replace(/\.json5$/, "");
const newSlug = oldToNew.get(oldSlug);
if (!newSlug) continue;
const filePath = path.join(CAMPAIGN_DIR, file);
const data = parseJson5(fs.readFileSync(filePath, "utf8"));
data._slug = newSlug;
const newPath = path.join(CAMPAIGN_DIR, newSlug + ".json5");
fs.writeFileSync(newPath, JSON.stringify(data, null, 2) + "\n", "utf8");
if (newPath !== filePath) fs.unlinkSync(filePath);
}
function walkDir(dir, fn) {
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const e of entries) {
const full = path.join(dir, e.name);
if (e.isDirectory()) walkDir(full, fn);
else if (e.name.endsWith(".json5")) fn(full);
}
}
walkDir(CONTENT_DE, (filePath) => {
let content = fs.readFileSync(filePath, "utf8");
let changed = false;
for (const [oldSlug, newSlug] of oldToNew) {
if (oldSlug === newSlug) continue;
const regex = new RegExp('"' + oldSlug.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + '"', "g");
if (regex.test(content)) {
content = content.replace(regex, '"' + newSlug + '"');
changed = true;
}
}
if (changed) fs.writeFileSync(filePath, content, "utf8");
});
console.log("Fertig. Campaigns umbenannt und Referenzen aktualisiert.");