@gordon1210/depup
Version:
a dependency upgrade tool for node projects
101 lines (100 loc) • 5.41 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Box, render, Text, useApp, useInput } from "ink";
import path from "path";
import { useState } from "react";
import { PackageList } from "./components/PackageList.js";
import { SideNav } from "./components/SideNav.js";
import { usePackageController } from "./hooks/usePackageController.js";
import { usePackageData } from "./hooks/usePackageData.js";
// Clear the console when starting the app
console.clear();
const VISIBLE_ROWS = 20;
const App = () => {
const { packages, loading, updatePackages, updateDependencies } = usePackageData();
const [isUpdating, setIsUpdating] = useState(false);
const [isConfirming, setIsConfirming] = useState(false);
const [packagesToUpdate, setPackagesToUpdate] = useState([]);
const { cursor, setCursor, grouped, currentGroup, handleTabChange, toggleSelection, changeVersionType, changeGlobalVersionType, equalizeVersions, areVersionsEqual, checkDivergingVersions, hasHigherUpdates, } = usePackageController(packages);
const { exit } = useApp();
useInput((input, key) => {
if (isUpdating) {
return;
} // Prevent input handling during updates
if (input.toLowerCase() === "w" && !isConfirming) {
handleTabChange("prev");
}
else if (input.toLowerCase() === "s" && !isConfirming) {
handleTabChange("next");
}
else if (input.toLowerCase() === "e" && !isConfirming) {
updatePackages(equalizeVersions());
}
else if (input.toLowerCase() === "r" && !isConfirming) {
// Add handler for global strategy change
updatePackages(changeGlobalVersionType("next"));
}
else if (key.downArrow && !isConfirming) {
setCursor((prev) => Math.min(prev + 1, currentGroup.packages.length - 1));
}
else if (key.upArrow && !isConfirming) {
setCursor((prev) => Math.max(prev - 1, 0));
}
else if (input === " " && !isConfirming) {
updatePackages(toggleSelection(cursor));
}
else if (key.leftArrow && !isConfirming) {
updatePackages(changeVersionType(cursor, "prev"));
}
else if (key.rightArrow && !isConfirming) {
updatePackages(changeVersionType(cursor, "next"));
}
else if (key.return) {
if (isConfirming) {
// User confirmed the updates
setIsUpdating(true);
setTimeout(() => {
updateDependencies(packagesToUpdate);
exit();
}, 100); // Small delay to ensure render happens before updates start
}
else {
// Show confirmation screen
const toUpdate = packages.filter((p) => p.selected);
if (toUpdate.length > 0) {
setPackagesToUpdate(toUpdate);
setIsConfirming(true);
}
}
}
else if (input === "q") {
if (isConfirming) {
// Go back to selection screen
setIsConfirming(false);
setPackagesToUpdate([]);
}
else {
exit();
}
}
});
if (packages.length === 0) {
return _jsx(Text, { children: "\u2705 No dependencies found." });
}
if (isUpdating) {
return _jsx(Text, { children: "\uD83D\uDCE6 Installing selected dependencies..." });
}
if (isConfirming) {
// Group packages by directory for a cleaner confirmation view
const packagesByDir = packagesToUpdate.reduce((acc, pkg) => {
const dir = path.relative(process.cwd(), pkg.packagePath) || ".";
if (!acc[dir]) {
acc[dir] = [];
}
acc[dir].push(pkg);
return acc;
}, {});
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "The following dependencies will be updated:" }), Object.entries(packagesByDir).map(([dir, pkgs]) => (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { bold: true, underline: true, children: [dir, "/package.json"] }), pkgs.map((pkg) => (_jsxs(Text, { children: ["\u2022 ", pkg.name, ": ", pkg.currentVersion, " \u2192 ", pkg.displayVersion] }, `${dir}-${pkg.name}`)))] }, dir))), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "This will update package.json files and run a single -pnpm install- at the end." }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { bold: true, children: "Press Enter to confirm or q to cancel" }) })] }));
}
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "\uD83D\uDCE6 Select packages to update (\u2B06\u2B07 + Space, \u23CE confirm, q quit, \u2190\u2192 Version, W/S pkg, E equalize, R rotate strategy)" }), _jsxs(Box, { flexDirection: "row", children: [_jsx(SideNav, { groups: grouped, activeTab: grouped.indexOf(currentGroup), visibleCount: VISIBLE_ROWS, loading: loading }), _jsx(PackageList, { packages: currentGroup.packages, cursor: cursor, visibleCount: VISIBLE_ROWS, checkDivergingVersions: checkDivergingVersions, areVersionsEqual: areVersionsEqual, hasHigherUpdates: hasHigherUpdates })] })] }));
};
render(_jsx(App, {}));