Files
wehub-resource-sync 70bf21e064
Deploy (to testing) and Test Playground Preview Worker / Deploy Playground Preview Worker (testing) (push) Has been skipped
Deploy Workers Shared Staging / Deploy Workers Shared Staging (push) Failing after 0s
Prerelease / build (push) Has been skipped
Handle Changesets / Handle Changesets (push) Has been cancelled
Semgrep OSS scan / semgrep-oss (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:11 +08:00

344 lines
8.1 KiB
TypeScript

import * as fs from "node:fs";
import * as path from "node:path";
import { runInTempDir } from "@cloudflare/workers-utils/test-helpers";
import { describe, it } from "vitest";
import { collectPackageDependencies } from "../src/deploy/helpers/package-dependencies";
describe("collectPackageDependencies", () => {
runInTempDir();
it("should return undefined when no package.json exists", async ({
expect,
}) => {
const result = await collectPackageDependencies(process.cwd());
expect(result).toBeUndefined();
});
it("should return undefined when package.json has no dependencies", async ({
expect,
}) => {
fs.writeFileSync(
"package.json",
JSON.stringify({ name: "test-project" }, null, 2)
);
const result = await collectPackageDependencies(process.cwd());
expect(result).toBeUndefined();
});
it("should skip workspace dependencies", async ({ expect }) => {
fs.writeFileSync(
"package.json",
JSON.stringify(
{
name: "test-project",
dependencies: {
"local-package": "workspace:*",
"another-local": "workspace:^",
},
},
null,
2
)
);
const result = await collectPackageDependencies(process.cwd());
expect(result).toBeUndefined();
});
it("should skip catalog dependencies", async ({ expect }) => {
fs.writeFileSync(
"package.json",
JSON.stringify(
{
name: "test-project",
dependencies: {
"catalog-package": "catalog:",
"catalog-named": "catalog:default",
},
},
null,
2
)
);
const result = await collectPackageDependencies(process.cwd());
expect(result).toBeUndefined();
});
it("should collect public package dependencies", async ({ expect }) => {
const nodeModulesPath = path.join(process.cwd(), "node_modules");
const packagePath = path.join(nodeModulesPath, "test-public-package");
fs.mkdirSync(packagePath, { recursive: true });
fs.writeFileSync(path.join(packagePath, "index.js"), "module.exports = {}");
fs.writeFileSync(
path.join(packagePath, "package.json"),
JSON.stringify(
{
name: "test-public-package",
version: "1.2.3",
},
null,
2
)
);
fs.writeFileSync(
"package.json",
JSON.stringify(
{
name: "test-project",
dependencies: {
"test-public-package": "^1.0.0",
},
},
null,
2
)
);
const result = await collectPackageDependencies(process.cwd());
expect(result).toEqual([
{
name: "test-public-package",
packageJsonVersion: "^1.0.0",
installedVersion: "1.2.3",
},
]);
});
it("should collect from both dependencies and devDependencies", async ({
expect,
}) => {
const nodeModulesPath = path.join(process.cwd(), "node_modules");
// Create a regular dependency
const depPath = path.join(nodeModulesPath, "prod-dep");
fs.mkdirSync(depPath, { recursive: true });
fs.writeFileSync(path.join(depPath, "index.js"), "module.exports = {}");
fs.writeFileSync(
path.join(depPath, "package.json"),
JSON.stringify({ name: "prod-dep", version: "1.0.0" }, null, 2)
);
// Create a dev dependency
const devDepPath = path.join(nodeModulesPath, "dev-dep");
fs.mkdirSync(devDepPath, { recursive: true });
fs.writeFileSync(path.join(devDepPath, "index.js"), "module.exports = {}");
fs.writeFileSync(
path.join(devDepPath, "package.json"),
JSON.stringify({ name: "dev-dep", version: "2.0.0" }, null, 2)
);
fs.writeFileSync(
"package.json",
JSON.stringify(
{
name: "test-project",
dependencies: {
"prod-dep": "^1.0.0",
},
devDependencies: {
"dev-dep": "^2.0.0",
},
},
null,
2
)
);
const result = await collectPackageDependencies(process.cwd());
expect(result).toEqual([
{
name: "prod-dep",
packageJsonVersion: "^1.0.0",
installedVersion: "1.0.0",
},
{
name: "dev-dep",
packageJsonVersion: "^2.0.0",
installedVersion: "2.0.0",
},
]);
});
it("should skip file: and link: dependencies", async ({ expect }) => {
fs.writeFileSync(
"package.json",
JSON.stringify(
{
name: "test-project",
dependencies: {
"local-file-pkg": "file:../local-file-pkg",
"local-link-pkg": "link:../local-link-pkg",
},
},
null,
2
)
);
const result = await collectPackageDependencies(process.cwd());
expect(result).toBeUndefined();
});
it("should skip dependencies that cannot be resolved", async ({ expect }) => {
fs.writeFileSync(
"package.json",
JSON.stringify(
{
name: "test-project",
dependencies: {
"nonexistent-package": "^1.0.0",
},
},
null,
2
)
);
const result = await collectPackageDependencies(process.cwd());
expect(result).toBeUndefined();
});
it("should handle mixed dependencies correctly", async ({ expect }) => {
const nodeModulesPath = path.join(process.cwd(), "node_modules");
// Create an installed package
const publicPath = path.join(nodeModulesPath, "public-pkg");
fs.mkdirSync(publicPath, { recursive: true });
fs.writeFileSync(path.join(publicPath, "index.js"), "module.exports = {}");
fs.writeFileSync(
path.join(publicPath, "package.json"),
JSON.stringify({ name: "public-pkg", version: "1.0.0" }, null, 2)
);
// Create another installed package
const anotherPath = path.join(nodeModulesPath, "another-pkg");
fs.mkdirSync(anotherPath, { recursive: true });
fs.writeFileSync(path.join(anotherPath, "index.js"), "module.exports = {}");
fs.writeFileSync(
path.join(anotherPath, "package.json"),
JSON.stringify({ name: "another-pkg", version: "2.0.0" }, null, 2)
);
fs.writeFileSync(
"package.json",
JSON.stringify(
{
name: "test-project",
dependencies: {
"public-pkg": "^1.0.0",
"another-pkg": "^2.0.0",
"workspace-pkg": "workspace:^",
"local-pkg": "file:../local-pkg",
"nonexistent-pkg": "^3.0.0",
},
},
null,
2
)
);
const result = await collectPackageDependencies(process.cwd());
expect(result).toEqual([
{
name: "public-pkg",
packageJsonVersion: "^1.0.0",
installedVersion: "1.0.0",
},
{
name: "another-pkg",
packageJsonVersion: "^2.0.0",
installedVersion: "2.0.0",
},
]);
});
it("should cap at 200 entries", async ({ expect }) => {
const nodeModulesPath = path.join(process.cwd(), "node_modules");
const dependencies: Record<string, string> = {};
// Create 210 packages
for (let i = 0; i < 210; i++) {
const pkgName = `pkg-${String(i).padStart(3, "0")}`;
const pkgPath = path.join(nodeModulesPath, pkgName);
fs.mkdirSync(pkgPath, { recursive: true });
fs.writeFileSync(path.join(pkgPath, "index.js"), "module.exports = {}");
fs.writeFileSync(
path.join(pkgPath, "package.json"),
JSON.stringify({ name: pkgName, version: `1.0.${i}` }, null, 2)
);
dependencies[pkgName] = `^1.0.${i}`;
}
fs.writeFileSync(
"package.json",
JSON.stringify(
{
name: "test-project",
dependencies,
},
null,
2
)
);
const result = await collectPackageDependencies(process.cwd());
expect(result).toBeDefined();
expect(result).toHaveLength(200);
});
it("should use devDependencies version when duplicate exists in dependencies", async ({
expect,
}) => {
const nodeModulesPath = path.join(process.cwd(), "node_modules");
const pkgPath = path.join(nodeModulesPath, "shared-pkg");
fs.mkdirSync(pkgPath, { recursive: true });
fs.writeFileSync(path.join(pkgPath, "index.js"), "module.exports = {}");
fs.writeFileSync(
path.join(pkgPath, "package.json"),
JSON.stringify({ name: "shared-pkg", version: "1.5.0" }, null, 2)
);
fs.writeFileSync(
"package.json",
JSON.stringify(
{
name: "test-project",
dependencies: {
"shared-pkg": "^1.0.0",
},
devDependencies: {
"shared-pkg": "^1.5.0",
},
},
null,
2
)
);
const result = await collectPackageDependencies(process.cwd());
// devDependencies spread over dependencies, so devDependencies version wins
expect(result).toEqual([
{
name: "shared-pkg",
packageJsonVersion: "^1.5.0",
installedVersion: "1.5.0",
},
]);
});
});