Skip to content

Commit ce95744

Browse files
author
Rishi Raj Jain
committed
use npm-check-updates
1 parent 232b7cd commit ce95744

File tree

3 files changed

+7300
-6660
lines changed

3 files changed

+7300
-6660
lines changed

packages/cli/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
"trigger-cli": "./dist/index.js"
3636
},
3737
"devDependencies": {
38-
"@trigger.dev/tsconfig": "workspace:*",
3938
"@gmrchk/cli-testing-library": "^0.1.2",
39+
"@trigger.dev/tsconfig": "workspace:*",
4040
"@types/gradient-string": "^1.1.2",
4141
"@types/inquirer": "^9.0.3",
4242
"@types/jest": "^29.5.3",
@@ -71,6 +71,7 @@
7171
"nanoid": "^4.0.2",
7272
"ngrok": "5.0.0-beta.2",
7373
"node-fetch": "^3.3.0",
74+
"npm-check-updates": "^16.12.2",
7475
"openai": "^3.3.0",
7576
"ora": "^6.1.2",
7677
"path-to-regexp": "^6.2.1",

packages/cli/src/commands/update.ts

Lines changed: 80 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,119 @@
1-
import z from "zod";
21
import fs from "fs";
32
import path from "path";
4-
import fetch from "node-fetch";
53
import inquirer from "inquirer";
6-
import { spawnSync } from "child_process";
4+
import ncu from "npm-check-updates";
75
import { installDependencies } from "../utils/installDependencies.js";
8-
import { getUserPackageManager } from "../utils/getUserPkgManager.js";
6+
import { Index } from "npm-check-updates/build/src/types/IndexType.js";
97

10-
interface YarnListOutput {
11-
data: {
12-
trees: Array<{ name: string; version: string }>;
13-
};
14-
}
15-
16-
function getInstalledVersion(packageName: string, packageManager: string, projectPath: string) {
17-
let installedVersion = null;
18-
if (packageManager === "npm") {
19-
const { stdout } = spawnSync(packageManager, ["list", packageName, "--json", "--depth=0"], {
20-
cwd: projectPath,
21-
});
22-
installedVersion = JSON.parse(stdout.toString()).dependencies[packageName].version;
23-
} else if (packageManager === "yarn") {
24-
const { stdout } = spawnSync(packageManager, ["list", "--json", "--depth=0"], {
25-
cwd: projectPath,
26-
});
27-
const parsedOutput: YarnListOutput = JSON.parse(stdout.toString());
28-
if (Array.isArray(parsedOutput.data.trees)) {
29-
const tree = parsedOutput.data.trees.find((tree) => tree.name === packageName);
30-
if (tree) {
31-
installedVersion = tree.version;
32-
}
33-
}
34-
}
35-
else {
36-
const { stdout } = spawnSync(packageManager, ["list", packageName, "--json", "--depth=0"], {
37-
cwd: projectPath,
38-
});
39-
installedVersion = JSON.parse(stdout.toString())[0].dependencies[packageName].version;
8+
function getPackageJSON(projectPath: string) {
9+
const packageJsonPath = path.join(projectPath, "package.json");
10+
if (!fs.existsSync(packageJsonPath)) {
11+
console.error(`package.json not found in the ${projectPath} directory.`);
12+
return;
4013
}
41-
return installedVersion;
14+
return JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
4215
}
4316

44-
export async function updateCommand(projectPath: string) {
45-
const triggerDevPackage = "@trigger.dev";
46-
const packageManager = await getUserPackageManager(projectPath);
17+
function setPackageJSON(projectPath: string, updatedPackageJSON: Object) {
4718
const packageJsonPath = path.join(projectPath, "package.json");
48-
// In case no package.json found
4919
if (!fs.existsSync(packageJsonPath)) {
5020
console.error(`package.json not found in the ${projectPath} directory.`);
5121
return;
5222
}
53-
const packageJsonData = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
54-
const dependencies = packageJsonData.dependencies || {};
55-
const devDependencies = packageJsonData.devDependencies || {};
56-
const allDependencies = Object.keys({ ...dependencies, ...devDependencies });
23+
fs.writeFileSync(packageJsonPath, JSON.stringify(updatedPackageJSON, null, 2), "utf8");
24+
return;
25+
}
26+
27+
export async function updateCommand(projectPath: string) {
28+
const triggerDevPackage = "";
29+
const packageData = getPackageJSON(projectPath);
30+
31+
if (!packageData) {
32+
return;
33+
}
34+
35+
const packageMaps: { [k: string]: { type: string; version: string } } = {};
36+
const packageDependencies = packageData.dependencies || {};
37+
const packageDevDependencies = packageData.devDependencies || {};
38+
Object.keys(packageDependencies).forEach((i) => {
39+
packageMaps[i] = { type: "dependencies", version: packageDependencies[i] };
40+
});
41+
Object.keys(packageDevDependencies).forEach((i) => {
42+
packageMaps[i] = {
43+
type: "devDependencies",
44+
version: packageDevDependencies[i],
45+
};
46+
});
47+
48+
// Use npm-check-updates to get updated dependency versions
49+
const ncuOptions = {
50+
packageData,
51+
upgrade: true,
52+
jsonUpgraded: true,
53+
};
54+
55+
// Can either give a json like package.json or just with deps and their new versions
56+
const updatedDependencies: Index | void = await new Promise((resolve, reject) =>
57+
ncu(ncuOptions).then(resolve).catch(reject)
58+
);
59+
60+
if (!updatedDependencies) return;
61+
62+
const ifUpdatedDependenciesIsPackageJSON =
63+
updatedDependencies.hasOwnProperty("dependencies") ||
64+
updatedDependencies.hasOwnProperty("devDependencies");
65+
66+
const dependencies = updatedDependencies.dependencies || {};
67+
const devDependencies = updatedDependencies.devDependencies || {};
68+
69+
const allDependencies = ifUpdatedDependenciesIsPackageJSON
70+
? Object.keys({ ...dependencies, ...devDependencies })
71+
: Object.keys(updatedDependencies);
72+
5773
const triggerPackages = allDependencies.filter((pkg) => pkg.startsWith(triggerDevPackage));
74+
5875
// If there are no @trigger.dev packages
5976
if (triggerPackages.length === 0) {
6077
console.log("No @trigger.dev/* packages found in package.json.");
6178
return;
6279
}
63-
// Get an array of the latest versions of @trigger.dev packages
64-
const newVersions = await Promise.all(
65-
triggerPackages.map(async (packageName) => {
66-
try {
67-
const installedVersion = getInstalledVersion(packageName, packageManager, projectPath);
68-
const response = await fetch(`https://registry.npmjs.org/${packageName}`);
69-
if (response.ok) {
70-
const data = await response.json();
71-
const schema = z.object({
72-
"dist-tags": z.object({
73-
latest: z.string(),
74-
}),
75-
});
76-
const parsed = schema.parse(data);
77-
return { packageName, installedVersion, latestVersion: parsed["dist-tags"].latest };
78-
}
79-
return null;
80-
} catch (error) {
81-
// @ts-ignore
82-
console.error(`Error fetching version for ${packageName}: ${error.message}`);
83-
return null;
84-
}
85-
})
86-
);
80+
8781
// Filter the packages with null and what don't match what
8882
// they are installed with so that they can be updated
89-
const packagesToUpdate = newVersions.filter(
90-
(pkg) => pkg && pkg.latestVersion !== pkg.installedVersion
91-
);
83+
const packagesToUpdate = triggerPackages.filter((pkg: string) => updatedDependencies[pkg]);
84+
9285
// If no packages require any updation
9386
if (packagesToUpdate.length === 0) {
9487
console.log("All @trigger.dev/* packages are up to date.");
9588
return;
9689
}
90+
9791
// Inform the user of the dependencies that can be updated
98-
console.log("Newer versions found for the following packages:");
99-
packagesToUpdate.forEach((entry) => {
100-
if (entry) {
101-
console.log(
102-
`- ${entry.packageName}: current ${dependencies[entry.packageName]} -> latest ${
103-
entry.latestVersion
104-
}`
105-
);
106-
}
107-
});
92+
console.log("\nNewer versions found for the following packages:");
93+
console.table(
94+
packagesToUpdate.map((i) => ({
95+
name: i,
96+
old: packageMaps[i]?.version,
97+
new: updatedDependencies[i],
98+
}))
99+
);
100+
108101
// Ask the user if they want to update the dependencies
109102
const { confirm } = await inquirer.prompt({
110103
type: "confirm",
111104
name: "confirm",
112105
message: "Do you want to update these packages in package.json and re-install dependencies?",
113106
});
107+
114108
if (confirm) {
115-
packagesToUpdate.forEach((entry) => {
116-
if (entry) {
117-
dependencies[entry.packageName] = entry.latestVersion;
109+
const newPackageJSON = packageData;
110+
packagesToUpdate.forEach((packageName) => {
111+
const tmp = packageMaps[packageName];
112+
if (tmp) {
113+
newPackageJSON[tmp.type][packageName] = updatedDependencies[packageName];
118114
}
119115
});
120-
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJsonData, null, 2));
116+
setPackageJSON(projectPath, newPackageJSON);
121117
console.log("package.json updated. Reinstalling dependencies...");
122118
await installDependencies(projectPath);
123119
} else {

0 commit comments

Comments
 (0)