import { copyFile, mkdir, rm, writeFile } from "node:fs/promises"; import path from "node:path"; import { BASIC_HUMAN_TEXTURE_PATHS, PROJECT_ROOT, createContentManifest, scanContentSources, } from "./publish-content.mjs"; const outputDirectory = path.join(PROJECT_ROOT, ".web-public"); if (path.dirname(outputDirectory) !== PROJECT_ROOT || path.basename(outputDirectory) !== ".web-public") { throw new Error(`Refusing to replace unexpected browser staging directory: ${outputDirectory}`); } const sources = [ { directory: path.join(PROJECT_ROOT, "public", "basis"), logicalPrefix: "basis" }, { directory: path.join(PROJECT_ROOT, "public", "data"), logicalPrefix: "data" }, { directory: path.join(PROJECT_ROOT, "public", "assets", "ui"), logicalPrefix: "assets/ui" }, { directory: path.join(PROJECT_ROOT, "public", "assets", "equipment"), logicalPrefix: "assets/equipment" }, { directory: path.join(PROJECT_ROOT, "public", "assets", "characters", "wow335a-v1", "manifest.json"), logicalPrefix: "assets/characters/wow335a-v1/manifest.json", }, { directory: path.join(PROJECT_ROOT, "public", "assets", "characters", "wow335a-v1", "human"), logicalPrefix: "assets/characters/wow335a-v1/human", }, ...BASIC_HUMAN_TEXTURE_PATHS.map((logicalPath) => ({ directory: path.join(PROJECT_ROOT, "public", ...logicalPath.split("/")), logicalPrefix: logicalPath, })), { directory: path.join(PROJECT_ROOT, "public", "assets", "creatures", "wailing-caverns"), logicalPrefix: "assets/creatures/wailing-caverns", }, { directory: path.join(PROJECT_ROOT, "public", "assets", "game", "arenas"), logicalPrefix: "assets/game/arenas", }, { directory: path.join(PROJECT_ROOT, "src", "assets", "game", "dungeons", "wailing-caverns"), logicalPrefix: "assets/game/dungeons/wailing-caverns", }, ]; await rm(outputDirectory, { recursive: true, force: true }); await mkdir(outputDirectory, { recursive: true }); const files = await scanContentSources(sources); for (const file of files) { const destination = path.join(outputDirectory, ...file.logicalPath.split("/")); await mkdir(path.dirname(destination), { recursive: true }); await copyFile(file.sourcePath, destination); } await copyFile( path.join(PROJECT_ROOT, "public", "content-cache-sw.js"), path.join(outputDirectory, "content-cache-sw.js"), ); const generated = createContentManifest(files, { baseUrl: "/" }); const bootstrapManifest = { ...generated, files: Object.fromEntries(Object.entries(generated.files).map(([logicalPath, entry]) => [ logicalPath, { ...entry, url: logicalPath }, ])), }; const manifestPath = path.join(outputDirectory, "content", "bootstrap-manifest.json"); await mkdir(path.dirname(manifestPath), { recursive: true }); await writeFile(manifestPath, `${JSON.stringify(bootstrapManifest, null, 2)}\n`, "utf8"); const bytes = files.reduce((total, file) => total + file.bytes, 0); console.log(`Prepared browser bootstrap content: ${files.length} files (${bytes} bytes)`); console.log(`Bootstrap version: ${bootstrapManifest.version}`);