import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import { buildExtension } from "./build.ts"; import { readBuildSpec } from "./spec.ts"; const roots: string[] = []; afterEach(async () => { await Promise.all( roots.splice(0).map((root) => rm(root, { recursive: true, force: true })), ); }); async function fixture(): Promise<{ root: string; source: string }> { const root = await mkdtemp(join(tmpdir(), "canvas-browser-build-")); roots.push(root); const source = join(root, "extensions", "canvas"); await mkdir(join(source, "browser"), { recursive: true }); await mkdir(join(source, "node_modules", "fonts", "files"), { recursive: true, }); await writeFile( join(root, "package.json"), JSON.stringify({ version: "1.0.0" }), ); await writeFile( join(source, "package.json"), JSON.stringify({ name: "@test/canvas", main: "index.ts", "pi-ext": { browserEntries: ["browser/main.tsx"], assets: { "browser/fonts": "fonts/files" }, }, }), ); await writeFile( join(source, "index.ts"), "export default function register() {}\n", ); await writeFile( join(source, "browser", "main.tsx"), "document.title = 'browser-only-canvas'; export const client = true;\n", ); await writeFile( join(source, "node_modules", "fonts", "files", "font.woff2"), "font fixture", ); return { root, source }; } describe("browser package entries", () => { it("emits flat browser entries and dependency directories independently of node startup", async () => { const { root, source } = await fixture(); expect(readBuildSpec(source).browserEntries).toEqual({ main: "browser/main.tsx", }); const built = await buildExtension("canvas", { root }); expect(built.entries).toEqual(["index.ts"]); expect( await readFile(join(built.dir, "browser", "main.js"), "utf8"), ).toContain("browser-only-canvas"); expect(await readFile(join(built.dir, "index.ts"), "utf8")).not.toContain( "browser-only-canvas", ); expect( await readFile(join(built.dir, "browser", "fonts", "font.woff2"), "utf8"), ).toBe("font fixture"); const release = await buildExtension("canvas", { root, release: true }); expect( await readFile(join(release.dir, "browser", "main.js"), "utf8"), ).toContain("browser-only-canvas"); }); it("preserves usable package when a browser source becomes invalid", async () => { const { root, source } = await fixture(); const built = await buildExtension("canvas", { root }); const original = await readFile( join(built.dir, "browser", "main.js"), "utf8", ); await rm(join(source, "browser", "main.tsx")); await expect(buildExtension("canvas", { root })).rejects.toThrow( "does not exist", ); expect(await readFile(join(built.dir, "browser", "main.js"), "utf8")).toBe( original, ); }); });