Skip to content

Commit 8499022

Browse files
committed
fix(cli): handle catalog: protocol in dependency update check (#3905)
1 parent 414e5a2 commit 8499022

3 files changed

Lines changed: 175 additions & 42 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"trigger.dev": patch
3+
---
4+
5+
Prevent CLI crash when @trigger.dev dependencies use bun/pnpm catalog: protocol.
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { describe, expect, it } from "vitest";
2+
import { getTriggerDependencies, getVersionMismatches, type Dependency } from "./update.js";
3+
4+
describe("getTriggerDependencies", () => {
5+
it("skips dependencies using catalog: and workspace: protocols", async () => {
6+
const packageJson = {
7+
dependencies: {
8+
"@trigger.dev/sdk": "catalog:",
9+
"@trigger.dev/core": "catalog:default",
10+
"@trigger.dev/react-hooks": "workspace:*",
11+
lodash: "^4.17.21",
12+
},
13+
devDependencies: {
14+
"@trigger.dev/build": "catalog:tools",
15+
"@trigger.dev/schema-to-json": "workspace:^3.0.0",
16+
"@trigger.dev/companyicons": "^1.0.0",
17+
},
18+
};
19+
20+
const deps = await getTriggerDependencies(packageJson, "/fake/project/package.json");
21+
22+
expect(deps).toEqual([]);
23+
});
24+
25+
it("includes normal @trigger.dev dependencies", async () => {
26+
const packageJson = {
27+
dependencies: {
28+
"@trigger.dev/sdk": "^3.0.0",
29+
},
30+
devDependencies: {
31+
"@trigger.dev/core": "~3.0.0",
32+
},
33+
};
34+
35+
const deps = await getTriggerDependencies(packageJson, "/fake/project/package.json");
36+
37+
expect(deps).toHaveLength(2);
38+
expect(deps).toContainEqual({
39+
type: "dependencies",
40+
name: "@trigger.dev/sdk",
41+
version: "^3.0.0",
42+
});
43+
expect(deps).toContainEqual({
44+
type: "devDependencies",
45+
name: "@trigger.dev/core",
46+
version: "~3.0.0",
47+
});
48+
});
49+
});
50+
51+
describe("getVersionMismatches", () => {
52+
it("does not throw when encountering non-semver strings like catalog: or workspace:", () => {
53+
const deps: Dependency[] = [
54+
{
55+
type: "dependencies",
56+
name: "@trigger.dev/sdk",
57+
version: "catalog:",
58+
},
59+
{
60+
type: "dependencies",
61+
name: "@trigger.dev/core",
62+
version: "catalog:named",
63+
},
64+
{
65+
type: "devDependencies",
66+
name: "@trigger.dev/build",
67+
version: "workspace:*",
68+
},
69+
{
70+
type: "devDependencies",
71+
name: "@trigger.dev/react-hooks",
72+
version: "invalid-semver-string",
73+
},
74+
];
75+
76+
expect(() => getVersionMismatches(deps, "3.0.0")).not.toThrow();
77+
78+
const { mismatches, isDowngrade } = getVersionMismatches(deps, "3.0.0");
79+
expect(mismatches).toHaveLength(4);
80+
expect(isDowngrade).toBe(false);
81+
});
82+
83+
it("correctly identifies downgrades when valid semver is newer than target CLI version", () => {
84+
const deps: Dependency[] = [
85+
{
86+
type: "dependencies",
87+
name: "@trigger.dev/sdk",
88+
version: "^4.0.0",
89+
},
90+
];
91+
92+
const { mismatches, isDowngrade } = getVersionMismatches(deps, "3.0.0");
93+
expect(mismatches).toHaveLength(1);
94+
expect(isDowngrade).toBe(true);
95+
});
96+
97+
it("ignores packages matching targetVersion, 0.0.0, or pkg.pr.new", () => {
98+
const deps: Dependency[] = [
99+
{
100+
type: "dependencies",
101+
name: "@trigger.dev/sdk",
102+
version: "3.0.0",
103+
},
104+
{
105+
type: "dependencies",
106+
name: "@trigger.dev/core",
107+
version: "0.0.0-prerelease",
108+
},
109+
{
110+
type: "devDependencies",
111+
name: "@trigger.dev/build",
112+
version: "https://pkg.pr.new/@trigger.dev/build@123",
113+
},
114+
];
115+
116+
const { mismatches, isDowngrade } = getVersionMismatches(deps, "3.0.0");
117+
expect(mismatches).toHaveLength(0);
118+
expect(isDowngrade).toBe(false);
119+
});
120+
});

packages/cli-v3/src/commands/update.ts

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -116,45 +116,6 @@ export async function updateTriggerPackages(
116116

117117
logger.debug("Resolved trigger deps", { triggerDependencies });
118118

119-
function getVersionMismatches(
120-
deps: Dependency[],
121-
targetVersion: string
122-
): {
123-
mismatches: Dependency[];
124-
isDowngrade: boolean;
125-
} {
126-
logger.debug("Checking for version mismatches", { deps, targetVersion });
127-
128-
const mismatches: Dependency[] = [];
129-
130-
for (const dep of deps) {
131-
if (
132-
dep.version === targetVersion ||
133-
dep.version.startsWith("https://pkg.pr.new") ||
134-
dep.version.startsWith("0.0.0")
135-
) {
136-
continue;
137-
}
138-
139-
mismatches.push(dep);
140-
}
141-
142-
const isDowngrade = mismatches.some((dep) => {
143-
const depMinVersion = semver.minVersion(dep.version);
144-
145-
if (!depMinVersion) {
146-
return false;
147-
}
148-
149-
return semver.gt(depMinVersion, targetVersion);
150-
});
151-
152-
return {
153-
mismatches,
154-
isDowngrade,
155-
};
156-
}
157-
158119
const { mismatches, isDowngrade } = getVersionMismatches(triggerDependencies, cliVersion);
159120

160121
logger.debug("Version mismatches", { mismatches, isDowngrade });
@@ -314,13 +275,60 @@ export async function updateTriggerPackages(
314275
return hasOutput;
315276
}
316277

317-
type Dependency = {
278+
export type Dependency = {
318279
type: "dependencies" | "devDependencies";
319280
name: string;
320281
version: string;
321282
};
322283

323-
async function getTriggerDependencies(
284+
export function getVersionMismatches(
285+
deps: Dependency[],
286+
targetVersion: string
287+
): {
288+
mismatches: Dependency[];
289+
isDowngrade: boolean;
290+
} {
291+
logger.debug("Checking for version mismatches", { deps, targetVersion });
292+
293+
const mismatches: Dependency[] = [];
294+
295+
for (const dep of deps) {
296+
if (
297+
dep.version === targetVersion ||
298+
dep.version.startsWith("https://pkg.pr.new") ||
299+
dep.version.startsWith("0.0.0")
300+
) {
301+
continue;
302+
}
303+
304+
mismatches.push(dep);
305+
}
306+
307+
const isDowngrade = mismatches.some((dep) => {
308+
if (!semver.validRange(dep.version)) {
309+
return false;
310+
}
311+
312+
try {
313+
const depMinVersion = semver.minVersion(dep.version);
314+
315+
if (!depMinVersion) {
316+
return false;
317+
}
318+
319+
return semver.gt(depMinVersion, targetVersion);
320+
} catch {
321+
return false;
322+
}
323+
});
324+
325+
return {
326+
mismatches,
327+
isDowngrade,
328+
};
329+
}
330+
331+
export async function getTriggerDependencies(
324332
packageJson: PackageJson,
325333
packageJsonPath: string
326334
): Promise<Dependency[]> {
@@ -332,7 +340,7 @@ async function getTriggerDependencies(
332340
continue;
333341
}
334342

335-
if (version.startsWith("workspace")) {
343+
if (version.startsWith("workspace") || version.startsWith("catalog:")) {
336344
continue;
337345
}
338346

0 commit comments

Comments
 (0)