@reliverse/dler 1.7.140 → 1.7.142

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.
@@ -1,22 +1,14 @@
1
- import path from "@reliverse/pathkit";
2
1
  import fs from "@reliverse/relifso";
3
2
  import { relinka } from "@reliverse/relinka";
4
- import { multiselectPrompt } from "@reliverse/rempts";
3
+ import rematch from "@reliverse/rematch";
5
4
  import { $ } from "bun";
6
- import { lookpath } from "lookpath";
7
- import pMap from "p-map";
8
- import { readPackageJSON } from "pkg-types";
5
+ import path from "path";
9
6
  import semver from "semver";
10
- import { glob } from "tinyglobby";
11
7
  import {
12
8
  getAllPkgManagers
13
9
  } from "../utils/dependencies/getUserPkgManager.js";
14
- import { x } from "../utils/exec/exec-mod.js";
15
- import { detectPackageManager } from "../utils/pm/pm-detect.js";
16
10
  import { latestVersion } from "../utils/pm/pm-meta.js";
17
11
  import { getCurrentWorkingDirectory } from "../utils/terminalHelpers.js";
18
- export const versionCache = /* @__PURE__ */ new Map();
19
- export const CACHE_TTL = 5 * 60 * 1e3;
20
12
  export function isNpmAlias(versionSpec) {
21
13
  return versionSpec.startsWith("npm:");
22
14
  }
@@ -45,88 +37,76 @@ export function isSemverCompatible(currentVersionRange, latestVersion2) {
45
37
  return false;
46
38
  }
47
39
  }
48
- export function collectTargetDependencies(pkg, args) {
40
+ export function collectTargetDependencies(pkg) {
49
41
  const map = {};
50
42
  const dependencies = pkg.dependencies || {};
51
43
  const devDependencies = pkg.devDependencies || {};
52
44
  const peerDependencies = pkg.peerDependencies || {};
53
45
  const optionalDependencies = pkg.optionalDependencies || {};
54
- const includeDeps = !args["dev-only"] && !args["peer-only"] && !args["optional-only"] && !args["catalogs-only"];
55
- const includeCatalogs = !args["dev-only"] && !args["peer-only"] && !args["optional-only"] && !args["prod-only"];
56
- if (args["prod-only"] || includeDeps) {
57
- for (const dep of Object.keys(dependencies)) {
58
- const version = dependencies[dep];
46
+ for (const dep of Object.keys(dependencies)) {
47
+ const version = dependencies[dep];
48
+ if (!version) continue;
49
+ if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
50
+ map[dep].versionSpec = version;
51
+ map[dep].locations.add("dependencies");
52
+ }
53
+ for (const dep of Object.keys(devDependencies)) {
54
+ const version = devDependencies[dep];
55
+ if (!version) continue;
56
+ if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
57
+ map[dep].versionSpec = version;
58
+ map[dep].locations.add("devDependencies");
59
+ }
60
+ for (const dep of Object.keys(peerDependencies)) {
61
+ const version = peerDependencies[dep];
62
+ if (!version) continue;
63
+ if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
64
+ map[dep].versionSpec = version;
65
+ map[dep].locations.add("peerDependencies");
66
+ }
67
+ for (const dep of Object.keys(optionalDependencies)) {
68
+ const version = optionalDependencies[dep];
69
+ if (!version) continue;
70
+ if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
71
+ map[dep].versionSpec = version;
72
+ map[dep].locations.add("optionalDependencies");
73
+ }
74
+ const workspacesCatalog = pkg.workspaces?.catalog || {};
75
+ for (const dep of Object.keys(workspacesCatalog)) {
76
+ const version = workspacesCatalog[dep];
77
+ if (!version) continue;
78
+ if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
79
+ map[dep].versionSpec = version;
80
+ map[dep].locations.add("catalog");
81
+ }
82
+ const workspacesCatalogs = pkg.workspaces?.catalogs || {};
83
+ for (const catalogName of Object.keys(workspacesCatalogs)) {
84
+ const catalog = workspacesCatalogs[catalogName] || {};
85
+ for (const dep of Object.keys(catalog)) {
86
+ const version = catalog[dep];
59
87
  if (!version) continue;
60
88
  if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
61
89
  map[dep].versionSpec = version;
62
- map[dep].locations.add("dependencies");
63
- }
64
- }
65
- if (args["dev-only"] || includeDeps) {
66
- for (const dep of Object.keys(devDependencies)) {
67
- const version = devDependencies[dep];
68
- if (!version) continue;
69
- if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
70
- map[dep].versionSpec = version;
71
- map[dep].locations.add("devDependencies");
72
- }
73
- }
74
- if (args["peer-only"] || includeDeps) {
75
- for (const dep of Object.keys(peerDependencies)) {
76
- const version = peerDependencies[dep];
77
- if (!version) continue;
78
- if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
79
- map[dep].versionSpec = version;
80
- map[dep].locations.add("peerDependencies");
81
- }
82
- }
83
- if (args["optional-only"] || includeDeps) {
84
- for (const dep of Object.keys(optionalDependencies)) {
85
- const version = optionalDependencies[dep];
90
+ map[dep].locations.add(`catalogs.${catalogName}`);
91
+ }
92
+ }
93
+ const topLevelCatalog = pkg.catalog || {};
94
+ for (const dep of Object.keys(topLevelCatalog)) {
95
+ const version = topLevelCatalog[dep];
96
+ if (!version) continue;
97
+ if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
98
+ map[dep].versionSpec = version;
99
+ map[dep].locations.add("catalog");
100
+ }
101
+ const topLevelCatalogs = pkg.catalogs || {};
102
+ for (const catalogName of Object.keys(topLevelCatalogs)) {
103
+ const catalog = topLevelCatalogs[catalogName] || {};
104
+ for (const dep of Object.keys(catalog)) {
105
+ const version = catalog[dep];
86
106
  if (!version) continue;
87
107
  if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
88
108
  map[dep].versionSpec = version;
89
- map[dep].locations.add("optionalDependencies");
90
- }
91
- }
92
- if (args["catalogs-only"] || includeCatalogs) {
93
- const workspacesCatalog = pkg.workspaces?.catalog || {};
94
- for (const dep of Object.keys(workspacesCatalog)) {
95
- const version = workspacesCatalog[dep];
96
- if (!version) continue;
97
- if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
98
- map[dep].versionSpec = version;
99
- map[dep].locations.add("catalog");
100
- }
101
- const workspacesCatalogs = pkg.workspaces?.catalogs || {};
102
- for (const catalogName of Object.keys(workspacesCatalogs)) {
103
- const catalog = workspacesCatalogs[catalogName] || {};
104
- for (const dep of Object.keys(catalog)) {
105
- const version = catalog[dep];
106
- if (!version) continue;
107
- if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
108
- map[dep].versionSpec = version;
109
- map[dep].locations.add(`catalogs.${catalogName}`);
110
- }
111
- }
112
- const topLevelCatalog = pkg.catalog || {};
113
- for (const dep of Object.keys(topLevelCatalog)) {
114
- const version = topLevelCatalog[dep];
115
- if (!version) continue;
116
- if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
117
- map[dep].versionSpec = version;
118
- map[dep].locations.add("catalog");
119
- }
120
- const topLevelCatalogs = pkg.catalogs || {};
121
- for (const catalogName of Object.keys(topLevelCatalogs)) {
122
- const catalog = topLevelCatalogs[catalogName] || {};
123
- for (const dep of Object.keys(catalog)) {
124
- const version = catalog[dep];
125
- if (!version) continue;
126
- if (!map[dep]) map[dep] = { versionSpec: version, locations: /* @__PURE__ */ new Set() };
127
- map[dep].versionSpec = version;
128
- map[dep].locations.add(`catalogs.${catalogName}`);
129
- }
109
+ map[dep].locations.add(`catalogs.${catalogName}`);
130
110
  }
131
111
  }
132
112
  return { map };
@@ -173,67 +153,6 @@ export function applyVersionUpdate(pkg, depName, newVersion, locations) {
173
153
  }
174
154
  }
175
155
  }
176
- export async function findWorkspacePackageJsons(cwd) {
177
- const root = await readPackageJSON(cwd);
178
- const ws = root.workspaces;
179
- let patterns = [];
180
- if (Array.isArray(ws)) {
181
- patterns = ws;
182
- } else if (ws && Array.isArray(ws.packages)) {
183
- patterns = ws.packages;
184
- }
185
- if (!patterns.length) return [];
186
- const dirs = await glob(patterns, {
187
- cwd,
188
- onlyDirectories: true,
189
- absolute: true,
190
- ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**"]
191
- });
192
- const pkgJsonPaths = [];
193
- for (const dir of dirs) {
194
- const pj = path.join(dir, "package.json");
195
- if (await fs.pathExists(pj)) pkgJsonPaths.push(pj);
196
- }
197
- return pkgJsonPaths;
198
- }
199
- export async function isMonorepo(cwd) {
200
- try {
201
- const root = await readPackageJSON(cwd);
202
- const ws = root.workspaces;
203
- if (Array.isArray(ws) && ws.length > 0) {
204
- return true;
205
- }
206
- if (ws && Array.isArray(ws.packages) && ws.packages.length > 0) {
207
- return true;
208
- }
209
- return false;
210
- } catch {
211
- return false;
212
- }
213
- }
214
- export async function findAllPackageJsons(cwd) {
215
- const packageJsonFiles = await glob("**/package.json", {
216
- cwd,
217
- absolute: true,
218
- ignore: [
219
- "**/node_modules/**",
220
- "**/dist/**",
221
- "**/build/**",
222
- "**/.git/**",
223
- "**/coverage/**",
224
- "**/.next/**",
225
- "**/.nuxt/**",
226
- "**/out/**"
227
- ]
228
- });
229
- const existingFiles = [];
230
- for (const file of packageJsonFiles) {
231
- if (await fs.pathExists(file)) {
232
- existingFiles.push(file);
233
- }
234
- }
235
- return existingFiles;
236
- }
237
156
  export async function fetchVersionFromRegistry(packageName) {
238
157
  const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`);
239
158
  if (!response.ok) {
@@ -243,25 +162,13 @@ export async function fetchVersionFromRegistry(packageName) {
243
162
  return data.version;
244
163
  }
245
164
  export async function getLatestVersion(packageName) {
246
- const cached = versionCache.get(packageName);
247
- const now = Date.now();
248
- if (cached && now - cached.timestamp < CACHE_TTL) {
249
- return cached.version;
250
- }
251
165
  try {
252
- const version = await latestVersion(packageName);
253
- versionCache.set(packageName, { version, timestamp: now });
254
- return version;
166
+ return await latestVersion(packageName);
255
167
  } catch (error) {
256
- const errorMessage = error instanceof Error ? error.message : String(error);
257
168
  try {
258
- const version = await fetchVersionFromRegistry(packageName);
259
- versionCache.set(packageName, { version, timestamp: now });
260
- return version;
169
+ return await fetchVersionFromRegistry(packageName);
261
170
  } catch (fallbackError) {
262
- throw new Error(
263
- `Latest version main check and npm registry fallback failed. Main check error: ${errorMessage}. Registry error: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`
264
- );
171
+ throw new Error(`Failed to get latest version for ${packageName}: ${error}`);
265
172
  }
266
173
  }
267
174
  }
@@ -298,14 +205,54 @@ export function prepareDependenciesForUpdate(allDepsMap, args) {
298
205
  const depsToUpdate = Object.keys(allDepsMap);
299
206
  let filteredDeps = [];
300
207
  if (args.name && args.name.length > 0) {
301
- filteredDeps = args.name.filter((dep) => dep in allDepsMap);
302
- const notFound = args.name.filter((dep) => !(dep in allDepsMap));
303
- if (notFound.length > 0) {
304
- relinka("warn", `Dependencies not found: ${notFound.join(", ")}`);
208
+ const namePatterns = args.name;
209
+ filteredDeps = depsToUpdate.filter((dep) => {
210
+ return namePatterns.some((pattern) => {
211
+ if (pattern.includes("*") || pattern.includes("?") || pattern.includes("[") || pattern.includes("{")) {
212
+ return rematch(pattern, dep);
213
+ }
214
+ return dep === pattern;
215
+ });
216
+ });
217
+ const exactMatches = filteredDeps.filter((dep) => namePatterns.includes(dep));
218
+ const patternMatches = filteredDeps.length - exactMatches.length;
219
+ if (patternMatches > 0) {
220
+ relinka(
221
+ "verbose",
222
+ `Found ${exactMatches.length} exact matches and ${patternMatches} pattern matches`
223
+ );
224
+ }
225
+ if (filteredDeps.length === 0) {
226
+ relinka("warn", `No dependencies found matching patterns: ${namePatterns.join(", ")}`);
305
227
  }
306
228
  } else {
307
229
  const ignoreList = args.ignore || [];
308
- filteredDeps = depsToUpdate.filter((dep) => !ignoreList.includes(dep));
230
+ filteredDeps = depsToUpdate.filter((dep) => {
231
+ return !ignoreList.some((ignorePattern) => {
232
+ if (ignorePattern.includes("*") || ignorePattern.includes("?") || ignorePattern.includes("[") || ignorePattern.includes("{")) {
233
+ return rematch(ignorePattern, dep);
234
+ }
235
+ return dep === ignorePattern;
236
+ });
237
+ });
238
+ const ignoredCount = depsToUpdate.length - filteredDeps.length;
239
+ if (ignoredCount > 0 && ignoreList.length > 0) {
240
+ relinka("verbose", `Ignored ${ignoredCount} dependencies matching ignore patterns`);
241
+ }
242
+ }
243
+ const ignoreFields = args.ignoreFields || [];
244
+ if (ignoreFields.length > 0) {
245
+ filteredDeps = filteredDeps.filter((dep) => {
246
+ const locations = allDepsMap[dep]?.locations || /* @__PURE__ */ new Set();
247
+ return !Array.from(locations).some((location) => ignoreFields.includes(location));
248
+ });
249
+ const ignoredFieldsCount = depsToUpdate.length - filteredDeps.length;
250
+ if (ignoredFieldsCount > 0) {
251
+ relinka(
252
+ "verbose",
253
+ `Ignored ${ignoredFieldsCount} dependencies in ignored fields: ${ignoreFields.join(", ")}`
254
+ );
255
+ }
309
256
  }
310
257
  return filteredDeps.filter((dep) => {
311
258
  const versionSpec = allDepsMap[dep]?.versionSpec ?? "";
@@ -314,15 +261,30 @@ export function prepareDependenciesForUpdate(allDepsMap, args) {
314
261
  return true;
315
262
  });
316
263
  }
317
- export async function updatePackageJsonFile(packageJsonPath, dependencies, updatesToApply, savePrefix) {
264
+ export async function updatePackageJsonFile(packageJsonPath, dependencies, updatesToApply, savePrefix, fieldsToIgnore = []) {
318
265
  if (updatesToApply.length === 0) return 0;
319
266
  try {
320
267
  const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf8"));
321
268
  const updatedPackageJson = { ...packageJson };
322
269
  for (const update of updatesToApply) {
323
- const prefix = savePrefix === "none" ? "" : savePrefix;
324
- const newVersion = `${prefix}${update.latestVersion}`;
325
270
  const locations = dependencies[update.package]?.locations || /* @__PURE__ */ new Set();
271
+ const shouldIgnore = Array.from(locations).some(
272
+ (location) => fieldsToIgnore.includes(location)
273
+ );
274
+ if (shouldIgnore) {
275
+ continue;
276
+ }
277
+ let newVersion;
278
+ if (locations.has("peerDependencies")) {
279
+ const currentVersion = dependencies[update.package]?.versionSpec || "";
280
+ if (currentVersion.startsWith(">=")) {
281
+ newVersion = `>=${update.latestVersion}`;
282
+ } else {
283
+ newVersion = savePrefix === "none" ? update.latestVersion : `${savePrefix}${update.latestVersion}`;
284
+ }
285
+ } else {
286
+ newVersion = savePrefix === "none" ? update.latestVersion : `${savePrefix}${update.latestVersion}`;
287
+ }
326
288
  applyVersionUpdate(updatedPackageJson, update.package, newVersion, locations);
327
289
  }
328
290
  await fs.writeFile(packageJsonPath, JSON.stringify(updatedPackageJson, null, 2) + "\n", "utf8");
@@ -335,56 +297,7 @@ export async function updatePackageJsonFile(packageJsonPath, dependencies, updat
335
297
  return 0;
336
298
  }
337
299
  }
338
- export async function updateWorkspacePackages(workspacePaths, args, options) {
339
- if (workspacePaths.length === 0) return 0;
340
- relinka("log", `Scanning ${workspacePaths.length} workspace packages...`);
341
- let totalWorkspaceUpdated = 0;
342
- for (const packageJsonPath of workspacePaths) {
343
- try {
344
- const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf8"));
345
- const { map } = collectTargetDependencies(packageJson, args);
346
- const candidates = prepareDependenciesForUpdate(map, args);
347
- if (candidates.length === 0) continue;
348
- const results = await pMap(
349
- candidates,
350
- (dep) => {
351
- const depInfo = map[dep];
352
- if (!depInfo?.versionSpec) {
353
- return Promise.resolve({
354
- package: dep,
355
- currentVersion: "unknown",
356
- latestVersion: "unknown",
357
- updated: false,
358
- error: "Current version not found",
359
- semverCompatible: false,
360
- location: Array.from(depInfo?.locations || ["unknown"]).join(", ")
361
- });
362
- }
363
- return checkPackageUpdate(dep, depInfo.versionSpec, depInfo.locations, options);
364
- },
365
- { concurrency: options.concurrency }
366
- );
367
- const toUpdate = results.filter((r) => r.updated && !r.error);
368
- const updated = await updatePackageJsonFile(
369
- packageJsonPath,
370
- map,
371
- toUpdate,
372
- options.savePrefix
373
- );
374
- if (updated > 0) {
375
- totalWorkspaceUpdated += updated;
376
- relinka("log", `Updated ${updated} deps in ${packageJsonPath}`);
377
- }
378
- } catch (error) {
379
- relinka(
380
- "warn",
381
- `Skipping ${packageJsonPath}: ${error instanceof Error ? error.message : String(error)}`
382
- );
383
- }
384
- }
385
- return totalWorkspaceUpdated;
386
- }
387
- export function displayUpdateResults(results) {
300
+ export function displayStructuredUpdateResults(results, packageJsonFiles, fileDepsMap, showDetails = false) {
388
301
  const toUpdate = results.filter((r) => r.updated && !r.error);
389
302
  const errors = results.filter((r) => r.error);
390
303
  const upToDate = results.filter((r) => !r.updated && !r.error && r.semverCompatible);
@@ -393,78 +306,109 @@ export function displayUpdateResults(results) {
393
306
  for (const error of errors) {
394
307
  relinka("warn", ` ${error.package} (${error.location}): ${error.error}`);
395
308
  }
309
+ relinka("log", "");
396
310
  }
397
- if (upToDate.length > 0) {
398
- relinka("log", `${upToDate.length} deps are already up to date`);
399
- }
400
- if (toUpdate.length === 0) {
401
- relinka("verbose", `All ${upToDate.length} deps are already up to date`);
311
+ if (!showDetails) {
312
+ if (toUpdate.length === 0) {
313
+ relinka("log", `All ${upToDate.length} dependencies are already up to date`);
314
+ } else {
315
+ relinka(
316
+ "log",
317
+ `${toUpdate.length} dependencies can be updated across ${packageJsonFiles.length} package.json files`
318
+ );
319
+ }
402
320
  return;
403
321
  }
404
- relinka("log", `${toUpdate.length} deps can be updated:`);
405
- const byLocation = /* @__PURE__ */ new Map();
406
- for (const update of toUpdate) {
407
- const location = update.location || "unknown";
408
- if (!byLocation.has(location)) {
409
- byLocation.set(location, []);
322
+ const resultsByFile = /* @__PURE__ */ new Map();
323
+ for (const result of results) {
324
+ let filePath = "unknown";
325
+ for (const [pkgPath, deps] of fileDepsMap.entries()) {
326
+ if (deps[result.package]) {
327
+ filePath = pkgPath;
328
+ break;
329
+ }
410
330
  }
411
- byLocation.get(location).push(update);
412
- }
413
- for (const [location, updates] of byLocation.entries()) {
414
- relinka("log", ` ${location}:`);
415
- for (const update of updates) {
416
- relinka("log", ` ${update.package}: ${update.currentVersion} \u2192 ${update.latestVersion}`);
331
+ if (!resultsByFile.has(filePath)) {
332
+ resultsByFile.set(filePath, []);
333
+ }
334
+ const fileResults = resultsByFile.get(filePath);
335
+ if (fileResults) {
336
+ fileResults.push(result);
417
337
  }
418
338
  }
419
- }
420
- export async function getGlobalPackages(packageManager) {
421
- try {
422
- let result;
423
- if (packageManager === "npm") {
424
- result = await $`npm list -g --depth=0 --json`.json();
425
- } else if (packageManager === "yarn") {
426
- try {
427
- result = await $`yarn global list --json`.json();
428
- } catch {
429
- result = await $`yarn global list`.text();
430
- const packages2 = {};
431
- const lines = result.split("\n");
432
- for (const line of lines) {
433
- const match = line.match(/^(.+)@([^@]+)$/);
434
- if (match) {
435
- packages2[match[1]] = match[2];
339
+ for (const [filePath, fileResults] of resultsByFile.entries()) {
340
+ const relativePath = filePath !== "unknown" ? path.relative(process.cwd(), filePath) : "unknown";
341
+ relinka("info", `${relativePath}`);
342
+ const byCategory = /* @__PURE__ */ new Map();
343
+ for (const result of fileResults) {
344
+ const category = result.location || "unknown";
345
+ if (!byCategory.has(category)) {
346
+ byCategory.set(category, []);
347
+ }
348
+ byCategory.get(category).push(result);
349
+ }
350
+ const upToDateInFile = fileResults.filter((r) => !r.updated && !r.error && r.semverCompatible);
351
+ if (upToDateInFile.length > 0) {
352
+ relinka("log", ` * ${upToDateInFile.length} deps are already up to date`);
353
+ }
354
+ const toUpdateInFile = fileResults.filter((r) => r.updated && !r.error);
355
+ if (toUpdateInFile.length > 0) {
356
+ relinka("log", ` * ${toUpdateInFile.length} deps can be updated:`);
357
+ const sortedCategories = Array.from(byCategory.entries()).sort(([a], [b]) => {
358
+ const order = {
359
+ catalog: 0,
360
+ dependencies: 1,
361
+ devDependencies: 2,
362
+ peerDependencies: 3,
363
+ optionalDependencies: 4
364
+ };
365
+ const aOrder = order[a] ?? 999;
366
+ const bOrder = order[b] ?? 999;
367
+ return aOrder - bOrder;
368
+ });
369
+ for (const [category, updates] of sortedCategories) {
370
+ const categoryUpdates = updates.filter((r) => r.updated && !r.error);
371
+ if (categoryUpdates.length > 0) {
372
+ let displayCategory = category;
373
+ if (category.startsWith("catalogs.")) {
374
+ displayCategory = `workspaces.${category}`;
375
+ } else if (category === "catalog") {
376
+ displayCategory = "workspaces.catalog";
377
+ }
378
+ relinka("log", ` - ${displayCategory}:`);
379
+ for (const update of categoryUpdates) {
380
+ relinka(
381
+ "log",
382
+ ` ${update.package}: ${update.currentVersion} \u2192 ${update.latestVersion}`
383
+ );
436
384
  }
437
385
  }
438
- return packages2;
439
386
  }
440
- } else if (packageManager === "pnpm") {
441
- result = await $`pnpm list -g --depth=0 --json`.json();
442
- } else if (packageManager === "bun") {
443
- result = await $`bun pm ls -g --json`.json();
444
- } else {
445
- throw new Error(`Unsupported package manager: ${packageManager}`);
446
387
  }
447
- const dependencies = result?.dependencies || {};
448
- const packages = {};
449
- for (const [name, info] of Object.entries(dependencies)) {
450
- if (info && typeof info === "object" && "version" in info) {
451
- packages[name] = info.version;
388
+ const errorsInFile = fileResults.filter((r) => r.error);
389
+ if (errorsInFile.length > 0) {
390
+ relinka("warn", ` * ${errorsInFile.length} deps failed to check:`);
391
+ for (const error of errorsInFile) {
392
+ relinka("warn", ` ${error.package}: ${error.error}`);
452
393
  }
453
394
  }
454
- return packages;
455
- } catch (error) {
456
- relinka("warn", `Failed to get global packages for ${packageManager}: ${error}`);
457
- return {};
395
+ relinka("log", "");
396
+ }
397
+ if (toUpdate.length === 0) {
398
+ relinka("log", `All ${upToDate.length} dependencies are already up to date`);
399
+ } else {
400
+ relinka(
401
+ "success",
402
+ `Summary: ${toUpdate.length} dependencies can be updated across ${packageJsonFiles.length} package.json files`
403
+ );
458
404
  }
459
405
  }
460
- export async function runInstallCommand(packageManager, linker) {
406
+ export async function runInstallCommand(packageManager) {
461
407
  try {
462
408
  switch (packageManager.name) {
463
- case "bun": {
464
- const linkerArg = linker ? `--linker ${linker}` : "";
465
- await $`bun install ${linkerArg}`;
409
+ case "bun":
410
+ await $`bun install`;
466
411
  break;
467
- }
468
412
  case "npm":
469
413
  await $`npm install`;
470
414
  break;
@@ -474,44 +418,6 @@ export async function runInstallCommand(packageManager, linker) {
474
418
  case "pnpm":
475
419
  await $`pnpm install`;
476
420
  break;
477
- case "deno":
478
- await $`deno cache --reload import_map.json`;
479
- break;
480
- default:
481
- throw new Error(`Unsupported package manager: ${packageManager.name}`);
482
- }
483
- } catch (error) {
484
- relinka("warn", `Failed to run install command for ${packageManager.name}: ${error}`);
485
- throw error;
486
- }
487
- }
488
- export async function runInstallCommandWithFilter(packageManager, linker, filterArgs = []) {
489
- try {
490
- switch (packageManager.name) {
491
- case "bun": {
492
- const linkerArg = linker ? `--linker ${linker}` : "";
493
- const filterStr = filterArgs.join(" ");
494
- await $`bun install ${linkerArg} ${filterStr}`;
495
- break;
496
- }
497
- case "npm": {
498
- const npmFilterStr = filterArgs.join(" ");
499
- await $`npm install ${npmFilterStr}`;
500
- break;
501
- }
502
- case "yarn": {
503
- const yarnFilterStr = filterArgs.join(" ");
504
- await $`yarn install ${yarnFilterStr}`;
505
- break;
506
- }
507
- case "pnpm": {
508
- const pnpmFilterStr = filterArgs.join(" ");
509
- await $`pnpm install ${pnpmFilterStr}`;
510
- break;
511
- }
512
- case "deno":
513
- await $`deno cache --reload import_map.json`;
514
- break;
515
421
  default:
516
422
  throw new Error(`Unsupported package manager: ${packageManager.name}`);
517
423
  }
@@ -520,180 +426,6 @@ export async function runInstallCommandWithFilter(packageManager, linker, filter
520
426
  throw error;
521
427
  }
522
428
  }
523
- export async function updateGlobalPackage(packageManager, packageName) {
524
- try {
525
- if (packageManager === "npm") {
526
- await $`npm install -g ${packageName}@latest`;
527
- } else if (packageManager === "yarn") {
528
- await $`yarn global add ${packageName}@latest`;
529
- } else if (packageManager === "pnpm") {
530
- await $`pnpm add -g ${packageName}@latest`;
531
- } else if (packageManager === "bun") {
532
- await $`bun install -g ${packageName}@latest`;
533
- } else {
534
- throw new Error(`Unsupported package manager: ${packageManager}`);
535
- }
536
- return true;
537
- } catch (error) {
538
- relinka(
539
- "warn",
540
- `Failed to update global package ${packageName} with ${packageManager}: ${error}`
541
- );
542
- return false;
543
- }
544
- }
545
- export async function handleGlobalUpdates(args) {
546
- const packageManagers = ["bun", "npm", "yarn", "pnpm"];
547
- const availablePackageManagers = [];
548
- for (const pm of packageManagers) {
549
- if (await lookpath(pm)) {
550
- availablePackageManagers.push(pm);
551
- }
552
- }
553
- if (availablePackageManagers.length === 0) {
554
- relinka("error", "No supported package managers found");
555
- return process.exit(1);
556
- }
557
- relinka("log", `Found package managers: ${availablePackageManagers.join(", ")}`);
558
- const allGlobalPackages = {};
559
- for (const pm of availablePackageManagers) {
560
- const packages = await getGlobalPackages(pm);
561
- for (const [name, version] of Object.entries(packages)) {
562
- if (!allGlobalPackages[name] || semver.gt(version, allGlobalPackages[name].version)) {
563
- allGlobalPackages[name] = { version, packageManager: pm };
564
- }
565
- }
566
- }
567
- const globalPackageNames = Object.keys(allGlobalPackages);
568
- if (globalPackageNames.length === 0) {
569
- relinka("warn", "No global packages found");
570
- return;
571
- }
572
- let filteredPackages = [];
573
- if (args.name && args.name.length > 0) {
574
- filteredPackages = args.name.filter((pkg) => pkg in allGlobalPackages);
575
- const notFound = args.name.filter((pkg) => !(pkg in allGlobalPackages));
576
- if (notFound.length > 0) {
577
- relinka("warn", `Global packages not found: ${notFound.join(", ")}`);
578
- }
579
- } else {
580
- const ignoreList = args.ignore || [];
581
- filteredPackages = globalPackageNames.filter((pkg) => !ignoreList.includes(pkg));
582
- }
583
- if (filteredPackages.length === 0) {
584
- relinka("warn", "No global packages to update");
585
- return;
586
- }
587
- relinka("log", `Checking ${filteredPackages.length} global packages for updates...`);
588
- const results = await pMap(
589
- filteredPackages,
590
- async (packageName) => {
591
- const globalPackage = allGlobalPackages[packageName];
592
- if (!globalPackage) {
593
- return {
594
- package: packageName,
595
- currentVersion: "unknown",
596
- latestVersion: "unknown",
597
- updated: false,
598
- error: "Package not found in global packages",
599
- location: "global"
600
- };
601
- }
602
- try {
603
- const latest = await getLatestVersion(packageName);
604
- const needsUpdate = semver.gt(latest, globalPackage.version);
605
- return {
606
- package: packageName,
607
- currentVersion: globalPackage.version,
608
- latestVersion: latest,
609
- updated: needsUpdate,
610
- location: `global (${globalPackage.packageManager})`
611
- };
612
- } catch (error) {
613
- return {
614
- package: packageName,
615
- currentVersion: globalPackage.version,
616
- latestVersion: globalPackage.version,
617
- updated: false,
618
- error: error instanceof Error ? error.message : String(error),
619
- location: `global (${globalPackage.packageManager})`
620
- };
621
- }
622
- },
623
- { concurrency: args.concurrency }
624
- );
625
- let toUpdate = results.filter((r) => r.updated && !r.error);
626
- const errors = results.filter((r) => r.error);
627
- const upToDate = results.filter((r) => !r.updated && !r.error);
628
- if (errors.length > 0) {
629
- relinka("warn", `Failed to check ${errors.length} global packages:`);
630
- for (const error of errors) {
631
- relinka("warn", ` ${error.package} (${error.location}): ${error.error}`);
632
- }
633
- }
634
- if (upToDate.length > 0) {
635
- relinka("log", `${upToDate.length} global packages are up to date`);
636
- }
637
- if (toUpdate.length === 0) {
638
- relinka("log", "All global packages are up to date");
639
- return;
640
- }
641
- relinka("log", `${toUpdate.length} global packages can be updated:`);
642
- for (const update of toUpdate) {
643
- relinka(
644
- "log",
645
- ` ${update.package} (${update.location}): ${update.currentVersion} \u2192 ${update.latestVersion}`
646
- );
647
- }
648
- if (args.interactive) {
649
- const allGlobalPackages2 = [
650
- ...toUpdate.map((pkg) => ({ ...pkg, canUpdate: true, isUpToDate: false, hasError: false })),
651
- ...upToDate.map((pkg) => ({ ...pkg, canUpdate: false, isUpToDate: true, hasError: false })),
652
- ...errors.map((pkg) => ({ ...pkg, canUpdate: false, isUpToDate: false, hasError: true }))
653
- ];
654
- const selectedPackages = await multiselectPrompt({
655
- title: "Select global packages to update",
656
- options: [
657
- { label: "Exit", value: "exit" },
658
- ...allGlobalPackages2.map((pkg) => {
659
- let label = `${pkg.package} (${pkg.location})`;
660
- if (pkg.canUpdate) {
661
- label += `: ${pkg.currentVersion} \u2192 ${pkg.latestVersion}`;
662
- } else if (pkg.isUpToDate) {
663
- label += `: ${pkg.currentVersion} (up-to-date)`;
664
- } else if (pkg.hasError) {
665
- label += `: ${pkg.currentVersion} (has errors)`;
666
- }
667
- return {
668
- label,
669
- value: pkg.package,
670
- disabled: !pkg.canUpdate,
671
- hint: pkg.hasError ? pkg.error : void 0
672
- };
673
- })
674
- ]
675
- });
676
- if (selectedPackages.length === 0 || selectedPackages.includes("exit")) {
677
- relinka("log", "Exiting global update process");
678
- return;
679
- }
680
- const actualSelectedPackages = selectedPackages.filter((pkg) => pkg !== "exit");
681
- toUpdate = toUpdate.filter((update) => actualSelectedPackages.includes(update.package));
682
- relinka("log", `Updating ${actualSelectedPackages.length} selected global packages...`);
683
- }
684
- if (args["dry-run"]) {
685
- relinka("log", "Dry run mode - no changes were made");
686
- return;
687
- }
688
- let successCount = 0;
689
- for (const update of toUpdate) {
690
- const globalPackage = allGlobalPackages[update.package];
691
- if (globalPackage && await updateGlobalPackage(globalPackage.packageManager, update.package)) {
692
- successCount++;
693
- }
694
- }
695
- relinka("log", `Successfully updated ${successCount}/${toUpdate.length} global packages`);
696
- }
697
429
  export async function getPmOptions() {
698
430
  const projectPath = getCurrentWorkingDirectory();
699
431
  const detectedPMs = await getAllPkgManagers(projectPath);
@@ -712,190 +444,3 @@ export async function getPmOptions() {
712
444
  const defaultValue = [...detectedPMMap.keys()][0] ?? "npm";
713
445
  return { pmOptions, defaultValue };
714
446
  }
715
- export async function upgradeDlerLocal() {
716
- try {
717
- const pkg = await readPackageJSON();
718
- const hasDler = pkg.dependencies && "@reliverse/dler" in pkg.dependencies || pkg.devDependencies && "@reliverse/dler" in pkg.devDependencies;
719
- if (!hasDler) {
720
- return { tool: "dler (local)", status: "not-found" };
721
- }
722
- const packageManager = await detectPackageManager(process.cwd());
723
- if (!packageManager) {
724
- return { tool: "dler (local)", status: "error", message: "No package manager detected" };
725
- }
726
- const { exitCode } = await x(packageManager.command, ["update", "@reliverse/dler"], {
727
- nodeOptions: { stdio: "pipe" }
728
- });
729
- return exitCode === 0 ? { tool: "dler (local)", status: "upgraded", message: `via ${packageManager.command}` } : { tool: "dler (local)", status: "error", message: "Upgrade failed" };
730
- } catch (error) {
731
- return {
732
- tool: "dler (local)",
733
- status: "not-found"
734
- };
735
- }
736
- }
737
- export async function upgradeDlerGlobal() {
738
- try {
739
- const dlerPath = await lookpath("dler");
740
- if (!dlerPath) {
741
- return { tool: "dler (global)", status: "not-found" };
742
- }
743
- const packageManagers = ["bun", "npm", "yarn", "pnpm"];
744
- for (const pm of packageManagers) {
745
- const pmPath = await lookpath(pm);
746
- if (pmPath) {
747
- try {
748
- const args = pm === "npm" ? ["install", "-g", "@reliverse/dler@latest"] : pm === "yarn" ? ["global", "add", "@reliverse/dler@latest"] : ["install", "-g", "@reliverse/dler@latest"];
749
- const { exitCode } = await x(pm, args, {
750
- nodeOptions: { stdio: "pipe" }
751
- });
752
- if (exitCode === 0) {
753
- return { tool: "dler (global)", status: "upgraded", message: `via ${pm}` };
754
- }
755
- } catch {
756
- }
757
- }
758
- }
759
- return { tool: "dler (global)", status: "error", message: "No suitable package manager found" };
760
- } catch (error) {
761
- return { tool: "dler (global)", status: "error", message: String(error) };
762
- }
763
- }
764
- export async function upgradeGit() {
765
- try {
766
- const gitPath = await lookpath("git");
767
- if (!gitPath) {
768
- return { tool: "git", status: "not-found" };
769
- }
770
- const { stdout } = await x("git", ["--version"], {
771
- nodeOptions: { stdio: "pipe" }
772
- });
773
- return {
774
- tool: "git",
775
- status: "up-to-date",
776
- message: `${stdout.trim()} - manual upgrade required`
777
- };
778
- } catch (error) {
779
- return { tool: "git", status: "error", message: String(error) };
780
- }
781
- }
782
- export async function upgradeNode() {
783
- try {
784
- const nodePath = await lookpath("node");
785
- if (!nodePath) {
786
- return { tool: "node.js", status: "not-found" };
787
- }
788
- const { stdout } = await x("node", ["--version"], {
789
- nodeOptions: { stdio: "pipe" }
790
- });
791
- return {
792
- tool: "node.js",
793
- status: "up-to-date",
794
- message: `${stdout.trim()} - manual upgrade required`
795
- };
796
- } catch (error) {
797
- return { tool: "node.js", status: "error", message: String(error) };
798
- }
799
- }
800
- export async function upgradeNpm() {
801
- try {
802
- const npmPath = await lookpath("npm");
803
- if (!npmPath) {
804
- return { tool: "npm", status: "not-found" };
805
- }
806
- try {
807
- const { exitCode, stdout, stderr } = await x("npm", ["install", "-g", "npm@latest"], {
808
- nodeOptions: { stdio: "pipe" }
809
- });
810
- if (exitCode === 0) {
811
- const output = (stdout + stderr).toLowerCase();
812
- if (output.includes("unchanged") || output.includes("up-to-date") || output.includes("already")) {
813
- return { tool: "npm", status: "up-to-date" };
814
- }
815
- return { tool: "npm", status: "upgraded" };
816
- } else {
817
- return { tool: "npm", status: "error", message: "Upgrade failed" };
818
- }
819
- } catch (pipeError) {
820
- const { exitCode } = await x("npm", ["install", "-g", "npm@latest"], {
821
- nodeOptions: { stdio: "inherit" }
822
- });
823
- return exitCode === 0 ? { tool: "npm", status: "upgraded" } : { tool: "npm", status: "error", message: "Upgrade failed" };
824
- }
825
- } catch (error) {
826
- return { tool: "npm", status: "error", message: String(error) };
827
- }
828
- }
829
- export async function upgradeBun() {
830
- try {
831
- const bunPath = await lookpath("bun");
832
- if (!bunPath) {
833
- return { tool: "bun", status: "not-found" };
834
- }
835
- const { exitCode, stdout, stderr } = await x("bun", ["upgrade"], {
836
- nodeOptions: { stdio: "pipe" }
837
- });
838
- if (exitCode !== 0) {
839
- return { tool: "bun", status: "error", message: "Upgrade failed" };
840
- }
841
- const output = (stdout + stderr).toLowerCase();
842
- if (output.includes("already") || output.includes("up-to-date") || output.includes("latest")) {
843
- return { tool: "bun", status: "up-to-date" };
844
- }
845
- return { tool: "bun", status: "upgraded" };
846
- } catch (error) {
847
- return { tool: "bun", status: "error", message: String(error) };
848
- }
849
- }
850
- export async function upgradeYarn() {
851
- try {
852
- const yarnPath = await lookpath("yarn");
853
- if (!yarnPath) {
854
- return { tool: "yarn", status: "not-found" };
855
- }
856
- try {
857
- const { exitCode: upgradeResult } = await x("yarn", ["self-update"], {
858
- nodeOptions: { stdio: "pipe" }
859
- });
860
- if (upgradeResult === 0) {
861
- return { tool: "yarn", status: "upgraded", message: "self-update" };
862
- }
863
- } catch {
864
- }
865
- const npmPath = await lookpath("npm");
866
- if (npmPath) {
867
- const { exitCode } = await x("npm", ["install", "-g", "yarn@latest"], {
868
- nodeOptions: { stdio: "pipe" }
869
- });
870
- return exitCode === 0 ? { tool: "yarn", status: "upgraded", message: "via npm" } : { tool: "yarn", status: "error", message: "Upgrade failed" };
871
- }
872
- return { tool: "yarn", status: "error", message: "No upgrade method available" };
873
- } catch (error) {
874
- return { tool: "yarn", status: "error", message: String(error) };
875
- }
876
- }
877
- export async function upgradePnpm() {
878
- try {
879
- const pnpmPath = await lookpath("pnpm");
880
- if (!pnpmPath) {
881
- return { tool: "pnpm", status: "not-found" };
882
- }
883
- try {
884
- const { exitCode } = await x("pnpm", ["add", "-g", "pnpm@latest"], {
885
- nodeOptions: { stdio: "pipe" }
886
- });
887
- return exitCode === 0 ? { tool: "pnpm", status: "upgraded" } : { tool: "pnpm", status: "error", message: "Upgrade failed" };
888
- } catch {
889
- const npmPath = await lookpath("npm");
890
- if (npmPath) {
891
- const { exitCode } = await x("npm", ["install", "-g", "pnpm@latest"], {
892
- nodeOptions: { stdio: "pipe" }
893
- });
894
- return exitCode === 0 ? { tool: "pnpm", status: "upgraded", message: "via npm" } : { tool: "pnpm", status: "error", message: "Upgrade failed" };
895
- }
896
- return { tool: "pnpm", status: "error", message: "No upgrade method available" };
897
- }
898
- } catch (error) {
899
- return { tool: "pnpm", status: "error", message: String(error) };
900
- }
901
- }