import { extractPack, compilePack } from '@foundryvtt/foundryvtt-cli'; import { ClassicLevel } from 'classic-level'; import fs from 'fs'; import path from 'path'; const { readdir, rm, mkdir, unlink } = fs.promises; const MODULE_ID = process.cwd(); export class CompendiumsManager { static async packToDistDir(srcDir = 'packs_src', distDir = 'packs-system', mode = 'yaml') { const yaml = mode === 'yaml'; const packs = await readdir('./' + srcDir); for (const pack of packs) { if (pack === '.gitattributes') continue; const target = `${MODULE_ID}/${distDir}/${pack}`; await rm(target, { recursive: true, force: true }); console.log('Packing ' + pack); await compilePack( `${MODULE_ID}/${srcDir}/${pack}`, target, { yaml, log: true } ); // CLI bundles classic-level@1.x — compact with v3 for Foundry V14 compat const db = new ClassicLevel(target, { keyEncoding: 'utf8', valueEncoding: 'json', createIfMissing: false }); await db.open(); const fwd = db.keys({ limit: 1, fillCache: false }); const firstKey = await fwd.next(); await fwd.close(); const bwd = db.keys({ limit: 1, reverse: true, fillCache: false }); const lastKey = await bwd.next(); await bwd.close(); if (firstKey && lastKey) { await db.compactRange(firstKey, lastKey, { keyEncoding: 'utf8' }); } await db.close(); } } static async unpackToSrcDir(srcDir = 'packs_src', distDir = 'packs-system', mode = 'yaml') { const yaml = mode === 'yaml'; const packs = await readdir('./' + distDir); for (const pack of packs) { if (pack === '.gitattributes') continue; if (pack === '.directory') continue; if (pack.endsWith('.db')) continue; console.log('Unpacking ' + pack); const directory = `./${srcDir}/${pack}`; await mkdir(directory, { recursive: true }); try { for (const file of await readdir(directory)) { await unlink(path.join(directory, file)); } } catch (error) { if (error.code === 'ENOENT') console.log('No files inside of ' + pack); else console.log(error); } await extractPack( `${MODULE_ID}/${distDir}/${pack}`, `${MODULE_ID}/${srcDir}/${pack}`, { yaml: mode === 'yaml', transformName: doc => CompendiumsManager.transformName(doc, mode === 'yaml'), } ); } } static transformName(doc, yaml) { const safeFileName = doc.name.replace(/[^a-zA-Z0-9]/g, '_'); const type = doc._key.split('!')[1]; const prefix = ['actors', 'items'].includes(type) ? doc.type : type; return `${prefix}_${safeFileName}.${yaml ? 'yaml' : 'json'}`; } }