fix(javascript): scope Next package admission by container identity

This commit is contained in:
morluto
2026-10-24 03:11:12 +08:00
parent ca01cf5a1f
commit 6103fddd45
2 changed files with 33 additions and 6 deletions
@@ -15,6 +15,30 @@ const file = (path: string, text = ""): JavaScriptArtifactFile => ({
text: { included: true, value: text },
});
it("keeps package applicability and its root cache scoped to the source container", () => {
const manifest = file("package.json", '{"dependencies":{"next":"16.4.2"}}');
const foreign = {
...file("package.json", '{"name":"plain"}'),
container_sha256: "c".repeat(64),
};
const page = file("app/page.js");
const foreignPage = { ...page, container_sha256: foreign.container_sha256 };
const context = createJavaScriptNextAppContext(
[manifest, foreign, page, foreignPage],
new JavaScriptJsonDocuments(),
new Set(["app"]),
);
expect(context(page)).toMatchObject({
kind: "app-directory",
package: { container_sha256: manifest.container_sha256 },
});
expect(context(foreignPage)).toMatchObject({
kind: "unknown",
package: { container_sha256: foreign.container_sha256 },
});
expect(context(page).kind).toBe("app-directory");
});
it("uses the nearest declared Next package and root directory precedence", () => {
const files = [
file("package.json", '{"dependencies":{"next":"16.4.2"}}'),
@@ -2,6 +2,7 @@ import { posix } from "node:path";
import type { JavaScriptArtifactFile } from "../../domain/javascript/javascriptArtifactFiles.js";
import type { NextAppSourceContext } from "../../domain/javascript/javascriptRoutePaths.js";
import { compositeKey } from "../../domain/unicodeCodePointOrder.js";
import type { JavaScriptJsonDocuments } from "./JavaScriptJsonDocuments.js";
/** Package declarations and inventoried directories own source-router applicability. */
@@ -15,7 +16,10 @@ export const createJavaScriptNextAppContext = (
const packages = new Map(
files
.filter(({ kind }) => kind === "package-json")
.map((file) => [posix.dirname(file.path), file]),
.map((file) => [
compositeKey([file.container_sha256, posix.dirname(file.path)]),
file,
]),
);
const roots = new Map<JavaScriptArtifactFile, string | null>();
return (file) => {
@@ -24,11 +28,10 @@ export const createJavaScriptNextAppContext = (
;
directory = posix.dirname(directory)
) {
const manifest = packages.get(directory);
if (
manifest !== undefined &&
manifest.container_sha256 === file.container_sha256
) {
const manifest = packages.get(
compositeKey([file.container_sha256, directory]),
);
if (manifest !== undefined) {
const identity = {
path: manifest.path,
sha256: manifest.sha256,