From 42c561cbdb0c47f28ddc250ca027a1dc9f88f01e Mon Sep 17 00:00:00 2001 From: Dotta Date: Thu, 23 Jul 2026 15:36:22 +0000 Subject: [PATCH] fix(release): install only bundled staging dependencies Co-Authored-By: Paperclip --- scripts/acpx-patch-packaging.test.mjs | 26 +++++++++++++++++++++++++- scripts/prepare-bundled-package.mjs | 25 ++++++++++++++++--------- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/scripts/acpx-patch-packaging.test.mjs b/scripts/acpx-patch-packaging.test.mjs index 3bd10607641..8ed4aafd773 100644 --- a/scripts/acpx-patch-packaging.test.mjs +++ b/scripts/acpx-patch-packaging.test.mjs @@ -16,7 +16,10 @@ import test from "node:test"; import cliEsbuildConfig from "../cli/esbuild.config.mjs"; import { bundledCliNpmDependencies } from "./cli-bundled-npm-dependencies.mjs"; -import { materializePublishManifest } from "./prepare-bundled-package.mjs"; +import { + createBundledInstallManifest, + materializePublishManifest, +} from "./prepare-bundled-package.mjs"; const rootPackage = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8")); const adapterUtilsPackage = JSON.parse( @@ -72,6 +75,27 @@ test("bundled package staging materializes workspace dependency versions", () => }); }); +test("bundled package staging installs only dependencies included in the tarball", () => { + const installManifest = createBundledInstallManifest( + { + name: "@paperclipai/db", + version: "2026.723.0-canary.8", + dependencies: { + "@paperclipai/shared": "2026.723.0-canary.8", + "drizzle-orm": "^0.45.2", + "embedded-postgres": "^18.1.0-beta.16", + }, + bundleDependencies: ["embedded-postgres"], + }, + ["embedded-postgres"], + ); + + assert.deepEqual(installManifest.dependencies, { + "embedded-postgres": "^18.1.0-beta.16", + }); + assert.deepEqual(installManifest.bundleDependencies, ["embedded-postgres"]); +}); + test("bundled package staging rebuilds npm dependencies and applies the acpx patch", (t) => { const fixtureDir = mkdtempSync(join(tmpdir(), "paperclip-bundled-stage-")); const sourceDir = join(fixtureDir, "source"); diff --git a/scripts/prepare-bundled-package.mjs b/scripts/prepare-bundled-package.mjs index 84d92dace0d..90aac8b68f2 100644 --- a/scripts/prepare-bundled-package.mjs +++ b/scripts/prepare-bundled-package.mjs @@ -31,6 +31,21 @@ export function materializePublishManifest(pkg) { return publishManifest; } +export function createBundledInstallManifest(publishManifest, bundledDependencies) { + const bundledDependencyNames = new Set(bundledDependencies); + const installManifest = structuredClone(publishManifest); + + for (const section of ["dependencies", "optionalDependencies", "peerDependencies"]) { + if (!installManifest[section]) continue; + installManifest[section] = Object.fromEntries( + Object.entries(installManifest[section]).filter(([name]) => bundledDependencyNames.has(name)), + ); + if (Object.keys(installManifest[section]).length === 0) delete installManifest[section]; + } + + return installManifest; +} + function patchedDependencyPackageName(specifier) { const versionSeparator = specifier.lastIndexOf("@"); return versionSeparator > 0 ? specifier.slice(0, versionSeparator) : specifier; @@ -77,15 +92,7 @@ export function prepareBundledPackage(sourceDir, destinationDir) { const deployedPackagePath = resolve(destinationDir, "package.json"); const publishManifest = materializePublishManifest(sourcePackage); - const installManifest = structuredClone(publishManifest); - for (const section of ["dependencies", "optionalDependencies", "peerDependencies"]) { - if (!installManifest[section] || !sourcePackage[section]) continue; - for (const [name, specifier] of Object.entries(sourcePackage[section])) { - if (typeof specifier === "string" && specifier.startsWith("workspace:")) { - delete installManifest[section][name]; - } - } - } + const installManifest = createBundledInstallManifest(publishManifest, bundledDependencies); writeFileSync(deployedPackagePath, `${JSON.stringify(installManifest, null, 2)}\n`); execFileSync(