Files

126 lines
4.2 KiB
JavaScript

#!/usr/bin/env node
/**
* Befüllt .cache/cms mit allen relevanten API-Responses.
* CMS muss erreichbar sein (PUBLIC_CMS_URL, Standard: http://localhost:3000).
* Nutzung: yarn cache:warm oder node scripts/warm-cache.mjs
*/
import { createHash } from "node:crypto";
import { writeFile, mkdir } from "node:fs/promises";
import { existsSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const root = join(__dirname, "..");
const CACHE_DIR = join(root, ".cache", "cms");
const BASE =
process.env.PUBLIC_CMS_URL?.trim() || "http://localhost:3000";
function cacheKey(url) {
return createHash("sha256").update(url).digest("hex");
}
async function fetchAndCache(url) {
const key = cacheKey(url);
try {
const res = await fetch(url);
const body = await res.text();
if (!existsSync(CACHE_DIR)) {
await mkdir(CACHE_DIR, { recursive: true });
}
const path = join(CACHE_DIR, `${key}.json`);
await writeFile(
path,
JSON.stringify({ status: res.status, body }),
"utf-8"
);
return { url, ok: res.ok, status: res.status };
} catch (err) {
return { url, ok: false, error: err.message };
}
}
/** Basis-URLs, die beim Build/Dev immer angefragt werden. */
const BASE_URLS = [
`${BASE}/api-docs/openapi.json`,
`${BASE}/api/content/page`,
`${BASE}/api/content/page_config?_per_page=50&_locale=de`,
`${BASE}/api/content/translation_bundle/app?_resolve=all&_locale=de`,
`${BASE}/api/content/navigation?_locale=de&_resolve=links&_page=1&_per_page=50`,
`${BASE}/api/content/navigation?_locale=de&_resolve=all&_page=1&_per_page=50`,
`${BASE}/api/content/post?_per_page=100`,
`${BASE}/api/content/tag`,
`${BASE}/api/content/footer/footer-main?_locale=de&_resolve=row1Content,row2Content,row3Content`,
`${BASE}/api/content/page_config/page-config-default?_locale=de&_resolve=logo`,
`${BASE}/api/content/page_config/default?_locale=de&_resolve=logo`,
];
async function main() {
console.log("Cache befüllen: .cache/cms");
console.log("CMS-Basis:", BASE);
const results = [];
for (const url of BASE_URLS) {
const r = await fetchAndCache(url);
results.push(r);
const status = r.ok ? r.status : r.error || r.status;
console.log(r.ok ? " ✓" : " ✗", url.replace(BASE, ""), status);
}
// Page-Slugs und einzelne Pages
try {
const pageRes = await fetch(`${BASE}/api/content/page?_per_page=200`);
const pageData = await pageRes.json();
const items = pageData?.items ?? [];
for (const p of items.slice(0, 50)) {
const slug = p._slug ?? p.slug ?? "";
if (!slug) continue;
const url = `${BASE}/api/content/page/${encodeURIComponent(slug)}?_locale=de&_resolve=all`;
const r = await fetchAndCache(url);
results.push(r);
if (!r.ok) console.log(" ✗", slug, r.error || r.status);
}
if (items.length > 0) {
console.log(" ✓", items.length, "Pages (erste 50 gecacht)");
}
} catch (e) {
console.log(" ✗ Pages-Liste", e.message);
}
// Post-Slugs und einzelne Posts
try {
const postRes = await fetch(
`${BASE}/api/content/post?_per_page=200&_resolve=postImage,postTag,row1Content,row2Content,row3Content`
);
const postData = await postRes.json();
const items = postData?.items ?? [];
for (const p of items.slice(0, 50)) {
const slug = p._slug ?? p.slug ?? "";
if (!slug) continue;
const url = `${BASE}/api/content/post/${encodeURIComponent(slug)}?_locale=de&_resolve=postImage,postTag,row1Content,row2Content,row3Content`;
const r = await fetchAndCache(url);
results.push(r);
if (!r.ok) console.log(" ✗", slug, r.error || r.status);
}
if (items.length > 0) {
console.log(" ✓", items.length, "Posts (erste 50 gecacht)");
}
} catch (e) {
console.log(" ✗ Posts-Liste", e.message);
}
const failed = results.filter((r) => !r.ok);
if (failed.length > 0) {
console.log("\nFehlgeschlagen:", failed.length);
process.exitCode = 1;
} else {
console.log("\nCache befüllt.");
}
}
main().catch((e) => {
console.error(e);
process.exit(1);
});