diff --git a/package.json b/package.json index b8b09baf..a80d30fe 100644 --- a/package.json +++ b/package.json @@ -25,14 +25,9 @@ "contracts/schema", "contracts/spec", "tools", - "tools/cli/psp-toolchain.json", "hosts/web", "assets/brand", "assets/fonts", - "engine/backends/esp32p4-ppa/src", - "engine/backends/esp32p4-ppa/Cargo.toml", - "engine/backends/esp32p4-ppa/Cargo.lock", - "engine/backends/esp32p4-ppa/README.md", "engine/core/src", "engine/core/Cargo.toml", "engine/wasm/src", diff --git a/tests/npm-package.test.ts b/tests/npm-package.test.ts index 10d8b7d4..1edeaa8d 100644 --- a/tests/npm-package.test.ts +++ b/tests/npm-package.test.ts @@ -20,6 +20,55 @@ function packedFiles(cwd: string): string[] { } describe("published npm artifacts", () => { + // The files map is a governed surface, not a mirror of the repo tree: an + // entry ships ONLY when the framework runtime, the compiler, the shipped + // tools, or a `pocket` CLI target consumes it from the tarball. Rust + // sources ride along solely as build inputs for CLI-buildable targets + // (psp, vita, the web/sim wasm) plus the deliberately standalone Pocket3D + // Vita crate pair for out-of-tree Vita 3D apps. Platform source + // integrations without a CLI target (e.g. the ESP32-P4 PPA backend, whose + // ESP-IDF C component cannot ship in npm anyway) stay git-only. Adding an + // entry here means updating this list in the same PR — deliberately. + test("the files map stays exactly the governed surface", async () => { + const manifest = await Bun.file(`${root}package.json`).json(); + expect(manifest.files).toEqual([ + "framework/src", + "framework/compiler", + "contracts/schema", + "contracts/spec", + "tools", + "hosts/web", + "assets/brand", + "assets/fonts", + "engine/core/src", + "engine/core/Cargo.toml", + "engine/wasm/src", + "engine/wasm/Cargo.toml", + "hosts/psp/src", + "hosts/psp/targets", + "hosts/psp/build.rs", + "hosts/psp/Cargo.toml", + "hosts/psp/Cargo.lock", + "hosts/vita/.cargo", + "hosts/vita/assets", + "hosts/vita/src", + "hosts/vita/build.rs", + "hosts/vita/Cargo.toml", + "hosts/vita/Cargo.lock", + "hosts/vita/README.md", + "hosts/vita/rust-toolchain.toml", + "engine/pocket3d/crates/pocket3d-vita/src", + "engine/pocket3d/crates/pocket3d-vita/examples", + "engine/pocket3d/crates/pocket3d-vita/Cargo.toml", + "engine/pocket3d/crates/pocket3d-vita/Cargo.lock", + "engine/pocket3d/crates/pocket3d-bsp/Cargo.toml", + "engine/pocket3d/crates/pocket3d-bsp/src", + "pocket.config.ts", + "pocket.json", + "tsconfig.json", + ]); + }); + test("framework tarball contains every locked native and standalone Pocket3D Vita input", async () => { const files = packedFiles(root); expect(files).toEqual(expect.arrayContaining([ @@ -38,6 +87,12 @@ describe("published npm artifacts", () => { "engine/pocket3d/crates/pocket3d-bsp/src/lib.rs", ])); expect(files).not.toContain("engine/pocket3d/Cargo.toml"); + // Git-only platform integrations must not leak into the tarball. + expect(files).not.toContain("engine/backends/esp32p4-ppa/src/lib.rs"); + expect(files.some((file) => file.startsWith("engine/backends/"))).toBe(false); + expect(files.some((file) => file.startsWith("hosts/esp32p4/"))).toBe(false); + // The CLI toolchain pin still ships via the wholesale "tools" entry. + expect(files).toContain("tools/cli/psp-toolchain.json"); const bspManifest = await Bun.file( `${root}engine/pocket3d/crates/pocket3d-bsp/Cargo.toml`,