Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c31efc2
Copy PNPM patches to isolated directory
0x80 Nov 27, 2025
a9e8943
Merge branch 'main' into thijs/1127-copy-patches-pnpm
0x80 Nov 27, 2025
1343678
1.27.0-0
0x80 Nov 27, 2025
3dd34f0
Use jsdoc comments consistently
0x80 Nov 27, 2025
1f8a8c2
Extract utility
0x80 Nov 27, 2025
979705d
Extract filtering logic
0x80 Nov 27, 2025
f704afe
Avoid patch naming collisions
0x80 Nov 27, 2025
0265999
Add tests for filter patched deps
0x80 Nov 27, 2025
b2ff870
Something
0x80 Nov 27, 2025
e72cae4
Use output manifest consistently
0x80 Nov 27, 2025
182a7cd
Add tests for copy patches
0x80 Nov 27, 2025
41a5251
Add tests for get package name
0x80 Nov 27, 2025
25fc4f2
Use correct log path function and fix formatting
0x80 Nov 27, 2025
f7896fe
Fix lockfile patch paths to match copied file locations
0x80 Nov 27, 2025
923da2e
1.27.0-1
0x80 Nov 27, 2025
52118ec
Format code
0x80 Nov 27, 2025
8b4702e
Rename misleading test for malformed scoped package
0x80 Nov 27, 2025
8ad26f5
Add explicit mocks for package manager and lockfile readers in tests
0x80 Nov 27, 2025
9b2beda
Refactor filterPatchedDependencies to use object parameter and intern…
0x80 Nov 27, 2025
6041e9b
Remove includePatchedDependencies config option
0x80 Nov 27, 2025
af08551
Simplify patch copying to preserve original folder structure
0x80 Nov 27, 2025
39a37aa
1.27.0-2
0x80 Nov 27, 2025
a94fde3
Only copy patches when output uses pnpm
0x80 Nov 27, 2025
c979b93
Format
0x80 Nov 27, 2025
ec48d5e
Update src/lib/lockfile/helpers/generate-pnpm-lockfile.ts
0x80 Nov 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,7 @@ The codebase uses `~/` as path alias for `src/` (configured in tsconfig.json).
## Testing

Tests use Vitest and are co-located with source files (`*.test.ts`).

## Code Style

- Use JSDoc style comments (`/** ... */`) for all comments, including single-line comments
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "isolate-package",
"version": "1.26.1",
"version": "1.27.0-0",
"description": "Isolate a monorepo package with its shared dependencies to form a self-contained directory, compatible with Firebase deploy",
"author": "Thijs Koerselman",
"license": "MIT",
Expand Down
41 changes: 33 additions & 8 deletions src/isolate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
} from "./lib/output";
import { detectPackageManager, shouldUsePnpmPack } from "./lib/package-manager";
import { getVersion } from "./lib/package-manager/helpers/infer-from-files";
import { copyPatches } from "./lib/patches/copy-patches";
import { createPackagesRegistry, listInternalPackages } from "./lib/registry";
import type { PackageManifest } from "./lib/types";
import {
Expand Down Expand Up @@ -211,15 +212,39 @@ export function createIsolator(config?: IsolateConfig) {
config,
});

if (usedFallbackToNpm) {
/**
* When we fall back to NPM, we set the manifest package manager to the
* available NPM version.
*/
/** Copy patch files if includePatchedDependencies is enabled */
const copiedPatches = await copyPatches({
workspaceRootDir,
targetPackageManifest: outputManifest,
isolateDir,
includePatchedDependencies: config.includePatchedDependencies,
includeDevDependencies: config.includeDevDependencies,
});

const hasCopiedPatches = Object.keys(copiedPatches).length > 0;

/** Update manifest if patches were copied or npm fallback is needed */
if (hasCopiedPatches || usedFallbackToNpm) {
const manifest = await readManifest(isolateDir);

const npmVersion = getVersion("npm");
manifest.packageManager = `npm@${npmVersion}`;
if (hasCopiedPatches) {
if (!manifest.pnpm) {
manifest.pnpm = {};
}
manifest.pnpm.patchedDependencies = copiedPatches;
log.debug(
`Added ${Object.keys(copiedPatches).length} patches to isolated package.json`
);
}

if (usedFallbackToNpm) {
/**
* When we fall back to NPM, we set the manifest package manager to the
* available NPM version.
*/
const npmVersion = getVersion("npm");
manifest.packageManager = `npm@${npmVersion}`;
}

await writeManifest(isolateDir, manifest);
}
Expand Down Expand Up @@ -286,7 +311,7 @@ export function createIsolator(config?: IsolateConfig) {
};
}

// Keep the original function for backward compatibility
/** Keep the original function for backward compatibility */
export async function isolate(config?: IsolateConfig): Promise<string> {
return createIsolator(config)();
}
21 changes: 15 additions & 6 deletions src/lib/lockfile/helpers/generate-pnpm-lockfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import { pruneLockfile as pruneLockfile_v9 } from "pnpm_prune_lockfile_v9";
import { pick } from "remeda";
import { useLogger } from "~/lib/logger";
import type { PackageManifest, PackagesRegistry } from "~/lib/types";
import { getErrorMessage, isRushWorkspace } from "~/lib/utils";
import {
filterPatchedDependencies,
getErrorMessage,
isRushWorkspace,
} from "~/lib/utils";
import { pnpmMapImporter } from "./pnpm-map-importer";

export async function generatePnpmLockfile({
Expand Down Expand Up @@ -163,13 +167,18 @@ export async function generatePnpmLockfile({
}

/**
* Don't know how to map the patched dependencies yet, so we just include
* them but I don't think it would work like this. The important thing for
* now is that they are omitted by default, because that is the most common
* use case.
* Filter patched dependencies to only include patches for packages that
* will actually be present in the isolated lockfile based on dependency
* type. We read patchedDependencies from workspace root lockfile, but
* filter based on target package dependencies.
*/
const patchedDependencies = includePatchedDependencies
? lockfile.patchedDependencies
? filterPatchedDependencies(
lockfile.patchedDependencies,
targetPackageManifest,
includeDevDependencies,
log
)
: undefined;

if (useVersion9) {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/lockfile/helpers/pnpm-map-importer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function pnpmMapDependenciesLinks(
return value;
}

// Replace backslashes with forward slashes to support Windows Git Bash
/** Replace backslashes with forward slashes to support Windows Git Bash */
const relativePath = path
.relative(importerPath, got(directoryByPackageName, key))
.replace(path.sep, path.posix.sep);
Expand Down
Loading
Loading