inup 1.4.3 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -21
- package/dist/core/package-detector.js +4 -12
- package/dist/services/changelog-fetcher.js +13 -16
- package/dist/services/jsdelivr-registry.js +76 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
# inup
|
|
1
|
+
# 🚀 inup
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/inup)
|
|
4
4
|
[](https://www.npmjs.com/package/inup)
|
|
5
5
|
[](https://www.npmjs.com/package/inup)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Upgrade your dependencies interactively. Works with npm, yarn, pnpm, and bun.
|
|
8
8
|
|
|
9
9
|

|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## 🚀 Usage
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
npx inup
|
|
@@ -20,24 +20,17 @@ Or install globally:
|
|
|
20
20
|
npm install -g inup
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
## Usage
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
npx inup
|
|
27
|
-
```
|
|
28
|
-
|
|
29
23
|
That's it. The tool scans your project, finds outdated packages, and lets you pick what to upgrade.
|
|
30
24
|
|
|
31
|
-
##
|
|
25
|
+
## 💡 Why inup?
|
|
32
26
|
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
- Package info modal (press `i`)
|
|
27
|
+
- **Inclusive by Default**: We load Dev, Peer, and Optional dependencies automatically. No more restarting the tool because you forgot a `--peer` flag.
|
|
28
|
+
- **Live Toggles**: Toggle dependency types (`d`, `p`, `o`) on the fly without exiting.
|
|
29
|
+
- **Zero Config**: Auto-detects your package manager.
|
|
30
|
+
- **Monorepo Ready**: Seamlessly handles workspaces.
|
|
31
|
+
- **Modern UX**: Search with `/`, view package details with `i`, and swap themes with `t`.
|
|
39
32
|
|
|
40
|
-
## Keyboard Shortcuts
|
|
33
|
+
## ⌨️ Keyboard Shortcuts
|
|
41
34
|
|
|
42
35
|
- `↑/↓` - Navigate packages
|
|
43
36
|
- `←/→` - Select version (current, patch, minor, major)
|
|
@@ -50,18 +43,22 @@ That's it. The tool scans your project, finds outdated packages, and lets you pi
|
|
|
50
43
|
- `i` - View package info
|
|
51
44
|
- `Enter` - Confirm and upgrade
|
|
52
45
|
|
|
53
|
-
## Options
|
|
46
|
+
## ⚙️ Options
|
|
54
47
|
|
|
55
48
|
```bash
|
|
56
49
|
inup [options]
|
|
57
50
|
|
|
58
51
|
-d, --dir <path> Run in specific directory
|
|
59
52
|
-e, --exclude <patterns> Skip directories (comma-separated regex)
|
|
60
|
-
-p, --peer Include peer dependencies
|
|
61
|
-
-o, --optional Include optional dependencies
|
|
62
53
|
--package-manager <name> Force package manager (npm, yarn, pnpm, bun)
|
|
63
54
|
```
|
|
64
55
|
|
|
65
|
-
##
|
|
56
|
+
## 🔒 Privacy
|
|
57
|
+
|
|
58
|
+
We don't track anything. Ever.
|
|
59
|
+
|
|
60
|
+
The only network requests made are to the npm registry and jsDelivr CDN to fetch package version data. That's it.
|
|
61
|
+
|
|
62
|
+
## 📄 License
|
|
66
63
|
|
|
67
64
|
MIT
|
|
@@ -88,19 +88,11 @@ class PackageDetector {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
const allPackageData = config_1.DEFAULT_REGISTRY === 'jsdelivr'
|
|
91
|
-
? await (0, services_1.getAllPackageDataFromJsdelivr)(packageNames, currentVersions, (
|
|
92
|
-
|
|
93
|
-
const truncatedPackage = currentPackage.length > 40
|
|
94
|
-
? currentPackage.substring(0, 37) + '...'
|
|
95
|
-
: currentPackage;
|
|
96
|
-
this.showProgress(`🌐 Fetching ${percentage}% (${truncatedPackage})`);
|
|
91
|
+
? await (0, services_1.getAllPackageDataFromJsdelivr)(packageNames, currentVersions, (_currentPackage, completed, total) => {
|
|
92
|
+
this.showProgress(`🌐 Checking versions... (${completed}/${total} packages)`);
|
|
97
93
|
})
|
|
98
|
-
: await (0, services_1.getAllPackageData)(packageNames, (
|
|
99
|
-
|
|
100
|
-
const truncatedPackage = currentPackage.length > 40
|
|
101
|
-
? currentPackage.substring(0, 37) + '...'
|
|
102
|
-
: currentPackage;
|
|
103
|
-
this.showProgress(`🌐 Fetching ${percentage}% (${truncatedPackage})`);
|
|
94
|
+
: await (0, services_1.getAllPackageData)(packageNames, (_currentPackage, completed, total) => {
|
|
95
|
+
this.showProgress(`🌐 Checking versions... (${completed}/${total} packages)`);
|
|
104
96
|
});
|
|
105
97
|
try {
|
|
106
98
|
for (const dep of allDeps) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.changelogFetcher = exports.ChangelogFetcher = void 0;
|
|
4
|
+
const constants_1 = require("../config/constants");
|
|
4
5
|
/**
|
|
5
6
|
* Fetches package metadata from npm registry
|
|
6
7
|
* Includes description, repository info, and basic metadata
|
|
@@ -69,12 +70,13 @@ class ChangelogFetcher {
|
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
/**
|
|
72
|
-
* Fetch data from
|
|
73
|
-
* Returns the package data from
|
|
73
|
+
* Fetch data from jsdelivr CDN
|
|
74
|
+
* Returns the package data by fetching package.json directly from jsdelivr
|
|
74
75
|
*/
|
|
75
76
|
async fetchFromRegistry(packageName) {
|
|
76
77
|
try {
|
|
77
|
-
|
|
78
|
+
// Fetch package.json directly from jsdelivr CDN (resolves to latest automatically)
|
|
79
|
+
const response = await fetch(`${constants_1.JSDELIVR_CDN_URL}/${encodeURIComponent(packageName)}@latest/package.json`, {
|
|
78
80
|
method: 'GET',
|
|
79
81
|
headers: {
|
|
80
82
|
accept: 'application/json',
|
|
@@ -83,20 +85,15 @@ class ChangelogFetcher {
|
|
|
83
85
|
if (!response.ok) {
|
|
84
86
|
return null;
|
|
85
87
|
}
|
|
86
|
-
const
|
|
87
|
-
// Get the latest version data
|
|
88
|
-
const distTags = data['dist-tags'];
|
|
89
|
-
const latestVersion = distTags?.latest;
|
|
90
|
-
const versions = data.versions;
|
|
91
|
-
const latestPackageData = latestVersion ? versions?.[latestVersion] : undefined;
|
|
88
|
+
const pkgData = (await response.json());
|
|
92
89
|
return {
|
|
93
|
-
description:
|
|
94
|
-
homepage:
|
|
95
|
-
repository:
|
|
96
|
-
bugs:
|
|
97
|
-
keywords: (
|
|
98
|
-
author:
|
|
99
|
-
license:
|
|
90
|
+
description: pkgData.description,
|
|
91
|
+
homepage: pkgData.homepage,
|
|
92
|
+
repository: pkgData.repository,
|
|
93
|
+
bugs: pkgData.bugs,
|
|
94
|
+
keywords: (pkgData.keywords || []),
|
|
95
|
+
author: pkgData.author,
|
|
96
|
+
license: pkgData.license,
|
|
100
97
|
};
|
|
101
98
|
}
|
|
102
99
|
catch {
|
|
@@ -49,6 +49,9 @@ const jsdelivrPool = new undici_1.Pool('https://cdn.jsdelivr.net', {
|
|
|
49
49
|
keepAliveMaxTimeout: config_1.REQUEST_TIMEOUT, // Maximum keep-alive timeout
|
|
50
50
|
connectTimeout: config_1.REQUEST_TIMEOUT, // 60 seconds connect timeout
|
|
51
51
|
});
|
|
52
|
+
// Batch configuration for progressive loading
|
|
53
|
+
const BATCH_SIZE = 5;
|
|
54
|
+
const BATCH_TIMEOUT_MS = 500;
|
|
52
55
|
const packageCache = new Map();
|
|
53
56
|
/**
|
|
54
57
|
* Fetches package.json from jsdelivr CDN for a specific version tag using undici pool.
|
|
@@ -86,23 +89,51 @@ async function fetchPackageJsonFromJsdelivr(packageName, versionTag) {
|
|
|
86
89
|
/**
|
|
87
90
|
* Fetches package version data from jsdelivr CDN for multiple packages.
|
|
88
91
|
* Uses undici connection pool for blazing fast performance with connection reuse.
|
|
89
|
-
* Falls back to npm registry
|
|
92
|
+
* Falls back to npm registry immediately when jsdelivr fails (interleaved, not sequential).
|
|
93
|
+
* Supports batched callbacks for progressive UI updates.
|
|
90
94
|
* @param packageNames - Array of package names to fetch
|
|
91
95
|
* @param currentVersions - Optional map of package names to their current versions
|
|
92
96
|
* @param onProgress - Optional progress callback
|
|
97
|
+
* @param onBatchReady - Optional callback for batch updates (fires every BATCH_SIZE packages or BATCH_TIMEOUT_MS)
|
|
93
98
|
* @returns Map of package names to their version data
|
|
94
99
|
*/
|
|
95
|
-
async function getAllPackageDataFromJsdelivr(packageNames, currentVersions, onProgress) {
|
|
100
|
+
async function getAllPackageDataFromJsdelivr(packageNames, currentVersions, onProgress, onBatchReady) {
|
|
96
101
|
const packageData = new Map();
|
|
97
102
|
if (packageNames.length === 0) {
|
|
98
103
|
return packageData;
|
|
99
104
|
}
|
|
100
105
|
const total = packageNames.length;
|
|
101
106
|
let completedCount = 0;
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
107
|
+
// Batch buffer for progressive updates
|
|
108
|
+
let batchBuffer = [];
|
|
109
|
+
let batchTimer = null;
|
|
110
|
+
// Helper to flush the current batch
|
|
111
|
+
const flushBatch = () => {
|
|
112
|
+
if (batchBuffer.length > 0 && onBatchReady) {
|
|
113
|
+
onBatchReady([...batchBuffer]);
|
|
114
|
+
batchBuffer = [];
|
|
115
|
+
}
|
|
116
|
+
if (batchTimer) {
|
|
117
|
+
clearTimeout(batchTimer);
|
|
118
|
+
batchTimer = null;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
// Helper to add package to batch and flush if needed
|
|
122
|
+
const addToBatch = (packageName, data) => {
|
|
123
|
+
if (onBatchReady) {
|
|
124
|
+
batchBuffer.push({ name: packageName, data });
|
|
125
|
+
// Flush if batch is full
|
|
126
|
+
if (batchBuffer.length >= BATCH_SIZE) {
|
|
127
|
+
flushBatch();
|
|
128
|
+
}
|
|
129
|
+
else if (!batchTimer) {
|
|
130
|
+
// Set timer to flush batch after timeout
|
|
131
|
+
batchTimer = setTimeout(flushBatch, BATCH_TIMEOUT_MS);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
// Process individual package fetch with immediate npm fallback on failure
|
|
136
|
+
const fetchPackageWithFallback = async (packageName) => {
|
|
106
137
|
const currentVersion = currentVersions?.get(packageName);
|
|
107
138
|
// Try to get from cache first
|
|
108
139
|
const cached = packageCache.get(packageName);
|
|
@@ -112,6 +143,7 @@ async function getAllPackageDataFromJsdelivr(packageNames, currentVersions, onPr
|
|
|
112
143
|
if (onProgress) {
|
|
113
144
|
onProgress(packageName, completedCount, total);
|
|
114
145
|
}
|
|
146
|
+
addToBatch(packageName, cached.data);
|
|
115
147
|
return;
|
|
116
148
|
}
|
|
117
149
|
try {
|
|
@@ -131,8 +163,21 @@ async function getAllPackageDataFromJsdelivr(packageNames, currentVersions, onPr
|
|
|
131
163
|
const latestResult = results[0];
|
|
132
164
|
const majorResult = results[1];
|
|
133
165
|
if (!latestResult) {
|
|
134
|
-
// Package not on jsDelivr,
|
|
135
|
-
|
|
166
|
+
// Package not on jsDelivr, immediately try npm fallback
|
|
167
|
+
const npmData = await (0, npm_registry_1.getAllPackageData)([packageName]);
|
|
168
|
+
const result = npmData.get(packageName);
|
|
169
|
+
if (result) {
|
|
170
|
+
packageData.set(packageName, result);
|
|
171
|
+
packageCache.set(packageName, {
|
|
172
|
+
data: result,
|
|
173
|
+
timestamp: Date.now(),
|
|
174
|
+
});
|
|
175
|
+
addToBatch(packageName, result);
|
|
176
|
+
}
|
|
177
|
+
completedCount++;
|
|
178
|
+
if (onProgress) {
|
|
179
|
+
onProgress(packageName, completedCount, total);
|
|
180
|
+
}
|
|
136
181
|
return;
|
|
137
182
|
}
|
|
138
183
|
const latestVersion = latestResult.version;
|
|
@@ -155,31 +200,35 @@ async function getAllPackageDataFromJsdelivr(packageNames, currentVersions, onPr
|
|
|
155
200
|
if (onProgress) {
|
|
156
201
|
onProgress(packageName, completedCount, total);
|
|
157
202
|
}
|
|
203
|
+
addToBatch(packageName, result);
|
|
158
204
|
}
|
|
159
205
|
catch (error) {
|
|
160
|
-
// On error,
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
206
|
+
// On error, immediately try npm fallback
|
|
207
|
+
try {
|
|
208
|
+
const npmData = await (0, npm_registry_1.getAllPackageData)([packageName]);
|
|
209
|
+
const result = npmData.get(packageName);
|
|
210
|
+
if (result) {
|
|
211
|
+
packageData.set(packageName, result);
|
|
212
|
+
packageCache.set(packageName, {
|
|
213
|
+
data: result,
|
|
214
|
+
timestamp: Date.now(),
|
|
215
|
+
});
|
|
216
|
+
addToBatch(packageName, result);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch (npmError) {
|
|
220
|
+
// If both fail, just continue
|
|
221
|
+
}
|
|
169
222
|
completedCount++;
|
|
170
223
|
if (onProgress) {
|
|
171
|
-
onProgress(
|
|
224
|
+
onProgress(packageName, completedCount, total);
|
|
172
225
|
}
|
|
173
|
-
});
|
|
174
|
-
// Merge npm data into results and cache it
|
|
175
|
-
for (const [packageName, data] of npmData.entries()) {
|
|
176
|
-
packageData.set(packageName, data);
|
|
177
|
-
packageCache.set(packageName, {
|
|
178
|
-
data,
|
|
179
|
-
timestamp: Date.now(),
|
|
180
|
-
});
|
|
181
226
|
}
|
|
182
|
-
}
|
|
227
|
+
};
|
|
228
|
+
// Fire all requests simultaneously - they handle fallback internally and immediately
|
|
229
|
+
await Promise.all(packageNames.map(fetchPackageWithFallback));
|
|
230
|
+
// Flush any remaining batch items
|
|
231
|
+
flushBatch();
|
|
183
232
|
// Clear the progress line and show completion time if no custom progress handler
|
|
184
233
|
if (!onProgress) {
|
|
185
234
|
process.stdout.write('\r' + ' '.repeat(80) + '\r');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inup",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.4",
|
|
4
4
|
"description": "Interactive CLI tool for upgrading dependencies with ease. Auto-detects and works with npm, yarn, pnpm, and bun. Inspired by yarn upgrade-interactive. Supports monorepos, workspaces, and batch upgrades.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|