UNPKG

vite-plugin-foundryvtt

Version:

Plugin for building for foundryvtt. Enables hmr and manifest substitution.

114 lines (108 loc) 3.65 kB
'use strict'; const fs = require('node:fs'); const path = require('node:path'); const foundryvttCli = require('@foundryvtt/foundryvtt-cli'); const classicLevel = require('classic-level'); const vite = require('vite'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } const fs__default = /*#__PURE__*/_interopDefaultCompat(fs); const path__default = /*#__PURE__*/_interopDefaultCompat(path); async function isLocked(dest) { try { const db = new classicLevel.ClassicLevel(dest); await db.open(); await db.close(); } catch { return true; } return false; } function foundryvtt(manifest, { substitutions = {}, type = "system", packDir = "src/packs", buildPacks = true, packOptions = { yaml: true } } = {}) { for (const [k, v] of Object.entries(substitutions)) if (v === void 0) delete substitutions[k]; let outdir; let pubdir; const hotReload = manifest.flags?.hotReload || null; const extensions = hotReload?.extensions.map((e) => e); const paths = hotReload?.paths?.map((e) => e) ?? [""]; return { name: "foundryvtt-config", config(cfg, { command }) { if (command === "build") cfg.base = "./"; cfg.build ??= {}; cfg.build.rollupOptions ??= {}; cfg.build.rollupOptions.output ??= {}; const afn = { assetFileNames: ({ names: [name] }) => name?.endsWith(".css") ? `styles/${name}` : name ?? "assets/[name]-[hash][extname]" }; if (Array.isArray(cfg.build.rollupOptions.output)) { cfg.build.rollupOptions.output.push(afn); } else { cfg.build.rollupOptions.output = vite.mergeConfig( cfg.build.rollupOptions.output, afn ); } return cfg; }, async configResolved(cfg) { outdir = cfg.build.outDir; pubdir = cfg.publicDir; for (const pack of manifest.packs ?? []) { if (!buildPacks) break; const dest = path__default.resolve( outdir, pack.path ?? path__default.resolve("packs", pack.name) ); if (await isLocked(dest)) buildPacks = false; } }, generateBundle() { const data = vite.mergeConfig(manifest, substitutions); const source = JSON.stringify(data, null, 2); this.emitFile({ type: "asset", fileName: `${type}.json`, source }); }, async writeBundle() { const packs = manifest.packs?.map((p) => ({ ...p, src: path__default.resolve(packDir, p.name), dest: path__default.resolve(outdir, p.path ?? path__default.resolve("packs", p.name)) })); if (!buildPacks || !packs) return; for (const p of packs) { try { await foundryvttCli.compilePack(p.src, p.dest, packOptions); this.info(`Built pack ${p.name}`); } catch (e) { if (e instanceof Error) this.warn(e); } } buildPacks = false; }, handleHotUpdate({ file }) { if (!hotReload || !extensions) return; if (!file.startsWith(pubdir)) return; const file_path = path__default.relative(pubdir, file); const ext = path__default.extname(file_path).slice(1); if (!extensions.includes(ext) || !paths.some((p) => file_path.startsWith(p))) return; const dest = path__default.resolve(outdir, file_path); const k = { css: "css", json: "language", html: "template", hbs: "template", "": "" }; console.log(`Hot updating ${k[ext.toLowerCase()]} file '${file_path}'`); fs__default.copyFileSync(file, dest); } }; } module.exports = foundryvtt;