Files
Epicnabbo-Catalogus-Updated…/src/lib/services/import-badge.ts
T
openhands 4d4cbd2211 fix: SQL maker creates wrong categories and badge import fails when ExternalTexts.json missing
- writeSqlMigration now classifies furni via classifyFurni and generates
  correct category sub-pages (imp_<catKey>) instead of hardcoded imp_other
- writeSqlMigration generates idempotent INSERT...SELECT WHERE NOT EXISTS
  for parent and category catalog_pages, with correct numeric page_id
- writeBadgeToExternalTexts creates ExternalTexts.json (and parent dirs)
  when missing instead of failing with ENOENT
2026-08-05 15:25:07 +02:00

124 lines
2.8 KiB
TypeScript

import { promises as fs } from "node:fs";
import path from "node:path";
import { db, WebsiteBadges } from "@/lib/db";
const EXTERNAL_TEXTS_PATH = path.join(
process.cwd(),
"public/nitro-assets/gamedata/ExternalTexts.json",
);
export type ImportBadgeResult =
| { ok: true }
| { ok: false; error: string; status: number };
/** Write badge name/desc into ExternalTexts.json (409 if already present). */
export async function writeBadgeToExternalTexts(
code: string,
name: string,
description: string,
): Promise<ImportBadgeResult> {
const nameKey = `badge_name_${code}`;
const descKey = `badge_desc_${code}`;
let texts: Record<string, string>;
try {
const raw = await fs.readFile(EXTERNAL_TEXTS_PATH, "utf-8");
texts = JSON.parse(raw) as Record<string, string>;
} catch (err) {
// File not present yet (fresh deployment) — start with an empty object.
if ((err as NodeJS.ErrnoException).code !== "ENOENT") {
console.warn(
"[import-badges] Failed to update ExternalTexts.json:",
(err as Error).message,
);
return {
ok: false,
error: "Failed to update ExternalTexts.json",
status: 500,
};
}
texts = {};
}
if (texts[nameKey] !== undefined) {
return {
ok: false,
error: "Badge already exists in ExternalTexts.json",
status: 409,
};
}
texts[nameKey] = name;
texts[descKey] = description || "";
try {
await fs.mkdir(path.dirname(EXTERNAL_TEXTS_PATH), { recursive: true });
await fs.writeFile(
EXTERNAL_TEXTS_PATH,
JSON.stringify(texts, null, 4),
"utf-8",
);
return { ok: true };
} catch (err) {
console.warn(
"[import-badges] Failed to update ExternalTexts.json:",
(err as Error).message,
);
return {
ok: false,
error: "Failed to update ExternalTexts.json",
status: 500,
};
}
}
/** Upsert WebsiteBadges row so CMS badge tables stay in sync. */
export async function upsertWebsiteBadge(
code: string,
name: string,
description: string,
): Promise<void> {
const now = new Date();
await db
.insert(WebsiteBadges)
.values({
badgeKey: code,
badgeName: name,
badgeDescription: description,
createdAt: now,
updatedAt: now,
})
.onDuplicateKeyUpdate({
set: {
badgeName: name,
badgeDescription: description,
updatedAt: now,
},
});
}
/**
* Single import path: ExternalTexts.json + WebsiteBadges.
* Callers should gate with ASSETS_IMPORT.
*/
export async function importBadgeSynced(input: {
code: string;
name: string;
description: string;
}): Promise<ImportBadgeResult> {
const texts = await writeBadgeToExternalTexts(
input.code,
input.name,
input.description,
);
if (!texts.ok) return texts;
try {
await upsertWebsiteBadge(input.code, input.name, input.description);
} catch {
return { ok: false, error: "Failed to import badge", status: 500 };
}
return { ok: true };
}