/** * Chroniques de l'Étrange — Système FoundryVTT * Édité par Antre-Monde Éditions * @file tools/compendiums.mjs — Compile / extrait les compendiums LevelDB * @author LeRatierBretonnien * @copyright 2025 LeRatierBretonnien * @license CC BY-NC-SA 4.0 * @description Ce système a été réalisé avec l'autorisation d'Antre-Monde Éditions. * Le jeu Chroniques de l'Étrange est un jeu de rôle édité par Antre-Monde Éditions. * * Usage: * npm run pack:compile — compile packs-src/ → packs/ (JSON → LevelDB) * npm run pack:extract — extrait packs/ → packs-src/ (LevelDB → JSON) * * Format des fichiers source JSON : * Chaque document DOIT contenir un champ `_key` de la forme : * - Items : `"_key": "!items!<_id>"` * - Actors : `"_key": "!actors!<_id>"` * Sans ce champ, le document est ignoré silencieusement par compilePack. */ import { compilePack, extractPack } from "@foundryvtt/foundryvtt-cli"; import { promises as fs } from "fs"; import path from "path"; const ROOT = new URL("..", import.meta.url).pathname; const SRC_DIR = path.join(ROOT, "packs-src"); const DIST_DIR = path.join(ROOT, "packs"); const action = process.argv[2] ?? "compile"; if (action === "compile") { await compileAll(); } else if (action === "extract") { await extractAll(); } else { console.error(`Action inconnue : ${action}. Utiliser "compile" ou "extract".`); process.exit(1); } /** * Compile tous les sous-dossiers de packs-src/ vers packs/ (JSON → LevelDB). */ async function compileAll() { const packs = await fs.readdir(SRC_DIR); for (const pack of packs) { const src = path.join(SRC_DIR, pack); const dist = path.join(DIST_DIR, pack); const stat = await fs.stat(src); if (!stat.isDirectory()) continue; console.log(`📦 Compilation : ${pack}`); // Supprime l'ancien LevelDB avant recompilation (évite l'erreur LEVEL_ITERATOR_NOT_OPEN) await fs.rm(dist, { recursive: true, force: true }); await compilePack(src, dist, { yaml: false }); } console.log("✅ Compilation terminée."); } /** * Extrait tous les packs LevelDB de packs/ vers packs-src/ (LevelDB → JSON). */ async function extractAll() { const packs = await fs.readdir(DIST_DIR); for (const pack of packs) { const dist = path.join(DIST_DIR, pack); const src = path.join(SRC_DIR, pack); const stat = await fs.stat(dist).catch(() => null); if (!stat?.isDirectory()) continue; console.log(`📂 Extraction : ${pack}`); await fs.mkdir(src, { recursive: true }); await extractPack(dist, src, { yaml: false, transformName: doc => { const safeName = doc.name.replace(/[^a-zA-Z0-9À-ÿ]/g, "_"); const docType = doc._key?.split("!")[1] ?? "doc"; const prefix = ["actors", "items"].includes(docType) ? doc.type : docType; return `${prefix}_${safeName}_${doc._id}.json`; }, }); } console.log("✅ Extraction terminée."); }