fix: badge import uses configured gamedata root for ExternalTexts.json
CI / check (push) Successful in 30s
CI / release (push) Skipped
CI / deploy (push) Successful in 44s

- import-badge.ts, badges route, and badges edit route now resolve
  ExternalTexts.json via getGamedataRoot() instead of the hardcoded
  public/nitro-assets/gamedata/ path
- writeBadgeToExternalTexts creates the file (and parent dirs) when
  missing, so fresh deployments no longer fail with ENOENT
- upload-import SQL maker now classifies furni via classifyFurni and
  generates correct category sub-pages (imp_<catKey>) instead of
  hardcoded imp_other
This commit is contained in:
openhands committed 2026-08-05 15:34:40 +02:00
1 parent 4d4cbd2211
commit 79b82e0a31
4 files changed
+439 -26

No files matched your search

@@ -3,11 +3,11 @@ import path from "node:path";
import { withAdmin } from "@/lib/api-handler";
import { apiError, apiOk } from "@/lib/api-response";
import { PERMS } from "@/lib/permissions";
import { getGamedataRoot } from "@/lib/services/furni-asset-dirs";
const EXTERNAL_TEXTS_PATH = path.join(
process.cwd(),
"public/nitro-assets/gamedata/ExternalTexts.json",
);
function externalTextsPath(gamedataRoot: string): string {
return path.join(gamedataRoot, "config", "ExternalTexts.json");
}
/** GET - Read badge name/desc from ExternalTexts.json */
export const GET = withAdmin(
@@ -16,8 +16,11 @@ export const GET = withAdmin(
const code = request.nextUrl.searchParams.get("code")?.toUpperCase();
if (!code) return apiError("Missing code", 400);
const gamedataRoot = await getGamedataRoot();
if (!gamedataRoot) return apiError("gamedata_root not configured", 500);
try {
const raw = await fs.readFile(EXTERNAL_TEXTS_PATH, "utf-8");
const raw = await fs.readFile(externalTextsPath(gamedataRoot), "utf-8");
const texts: Record<string, string> = JSON.parse(raw);
const name =
+12 -9
View File
@@ -4,13 +4,13 @@ import { withAdmin } from "@/lib/api-handler";
import { apiError, apiOk } from "@/lib/api-response";
import { PERMS } from "@/lib/permissions";
import { logAudit } from "@/lib/services/audit";
import { getGamedataRoot } from "@/lib/services/furni-asset-dirs";
import { searchBadges } from "@/lib/services/habboassets";
import { importBadgeSynced } from "@/lib/services/import-badge";
const EXTERNAL_TEXTS_PATH = path.join(
process.cwd(),
"public/nitro-assets/gamedata/ExternalTexts.json",
);
function externalTextsPath(gamedataRoot: string): string {
return path.join(gamedataRoot, "config", "ExternalTexts.json");
}
// ── Search badges via official Habbo external texts ────────────────
export const GET = withAdmin(
@@ -33,11 +33,14 @@ export const GET = withAdmin(
// Check which badges already exist in ExternalTexts.json
const existingCodes = new Set<string>();
try {
const raw = await fs.readFile(EXTERNAL_TEXTS_PATH, "utf-8");
const texts = JSON.parse(raw);
for (const badge of badges) {
if (texts[`badge_name_${badge.code}`] !== undefined) {
existingCodes.add(badge.code);
const gamedataRoot = await getGamedataRoot();
if (gamedataRoot) {
const raw = await fs.readFile(externalTextsPath(gamedataRoot), "utf-8");
const texts = JSON.parse(raw);
for (const badge of badges) {
if (texts[`badge_name_${badge.code}`] !== undefined) {
existingCodes.add(badge.code);
}
}
}
} catch {