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
344 lines
8.1 KiB
TypeScript
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",
|
|
},
|
|
]);
|
|
});
|
|
});
|