import fs from "node:fs" import path from "node:path" import crypto from "node:crypto" import { Level } from "level" const rootDir = path.resolve(import.meta.dirname, "..") const packageJson = JSON.parse(fs.readFileSync(path.join(rootDir, "package.json"), "utf8")) const systemJson = JSON.parse(fs.readFileSync(path.join(rootDir, "system.json"), "utf8")) const PACK_SOURCES = [ { sourcePath: path.join(rootDir, "packs-src", "armes.json"), outputPath: path.join(rootDir, "packs", "armes"), type: "Item", }, { sourcePath: path.join(rootDir, "packs-src", "armures.json"), outputPath: path.join(rootDir, "packs", "armures"), type: "Item", }, { sourcePath: path.join(rootDir, "packs-src", "equipements.json"), outputPath: path.join(rootDir, "packs", "equipements"), type: "Item", }, { sourcePath: path.join(rootDir, "packs-src", "pouvoirs-compagnie.json"), outputPath: path.join(rootDir, "packs", "pouvoirs-compagnie"), type: "Item", }, { sourcePath: path.join(rootDir, "packs-src", "competences.json"), outputPath: path.join(rootDir, "packs", "competences"), type: "Item", }, { sourcePath: path.join(rootDir, "packs-src", "races.json"), outputPath: path.join(rootDir, "packs", "races"), type: "Item", }, { sourcePath: path.join(rootDir, "packs-src", "tribus.json"), outputPath: path.join(rootDir, "packs", "tribus"), type: "Item", }, { sourcePath: path.join(rootDir, "packs-src", "metiers.json"), outputPath: path.join(rootDir, "packs", "metiers"), type: "Item", }, { sourcePath: path.join(rootDir, "packs-src", "sortileges.json"), outputPath: path.join(rootDir, "packs", "sortileges"), type: "Item", }, ] const now = Date.now() const systemId = systemJson.id const systemVersion = packageJson.version const coreVersion = String(systemJson.compatibility?.verified ?? systemJson.compatibility?.minimum ?? "") function slugId(input) { const hash = crypto.createHash("sha256").update(input).digest() const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" let id = "" for (let index = 0; id.length < 16; index += 1) { id += alphabet[hash[index % hash.length] % alphabet.length] } return id } function toPackDocument(entry, index) { const docId = slugId(`${entry.type}:${entry.name}`) return { name: entry.name, type: entry.type, img: entry.img ?? "icons/svg/item-bag.svg", system: entry.system ?? {}, effects: Array.isArray(entry.effects) ? entry.effects : [], flags: entry.flags ?? {}, _stats: { systemId, systemVersion, coreVersion, createdTime: now, modifiedTime: now, lastModifiedBy: "Copilot", compendiumSource: null, duplicateSource: null, exportSource: null, }, _id: docId, folder: null, sort: index * 1000, ownership: { default: 0, }, } } async function buildPack({ sourcePath, outputPath, type }) { const source = JSON.parse(fs.readFileSync(sourcePath, "utf8")) if (!Array.isArray(source)) { throw new Error(`Pack source must be an array: ${sourcePath}`) } fs.rmSync(outputPath, { recursive: true, force: true }) fs.mkdirSync(outputPath, { recursive: true }) const db = new Level(outputPath, { valueEncoding: "utf8" }) try { await db.open() const batch = db.batch() source.forEach((entry, index) => { if (!entry.type) { throw new Error(`Missing document type in ${sourcePath}: ${entry.name}`) } const doc = toPackDocument(entry, index) batch.put(`!items!${doc._id}`, JSON.stringify(doc)) }) await batch.write() } finally { await db.close() } } for (const pack of PACK_SOURCES) { await buildPack(pack) }