@reliverse/dler 1.7.68 → 1.7.70

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.
Files changed (84) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +148 -98
  3. package/bin/app/build/cmd.js +0 -2
  4. package/bin/app/cmds.d.ts +1 -0
  5. package/bin/app/cmds.js +1 -0
  6. package/bin/app/create/cmd.d.ts +47 -0
  7. package/bin/app/create/cmd.js +170 -0
  8. package/bin/app/get/cmd.d.ts +1 -0
  9. package/bin/app/get/cmd.js +1 -0
  10. package/bin/app/init/cmd.d.ts +2 -0
  11. package/bin/app/init/cmd.js +14 -0
  12. package/bin/app/install/cmd.d.ts +50 -0
  13. package/bin/app/install/cmd.js +83 -0
  14. package/bin/app/remove/cmd.d.ts +48 -0
  15. package/bin/app/remove/cmd.js +255 -0
  16. package/bin/app/update/cmd.d.ts +11 -0
  17. package/bin/app/update/cmd.js +277 -2
  18. package/bin/app/upgrade/cmd.d.ts +8 -0
  19. package/bin/app/upgrade/cmd.js +295 -0
  20. package/bin/app/x/cmd.d.ts +18 -31
  21. package/bin/app/x/cmd.js +133 -137
  22. package/bin/cli.js +16 -10
  23. package/bin/libs/cfg/cfg-impl/cfg-consts.d.ts +1 -1
  24. package/bin/libs/cfg/cfg-impl/cfg-consts.js +1 -1
  25. package/bin/libs/cfg/cfg-mod.d.ts +1 -23
  26. package/bin/libs/cfg/cfg-mod.js +1 -85
  27. package/bin/libs/get/mod.d.ts +37 -0
  28. package/bin/libs/get/mod.js +509 -0
  29. package/bin/libs/sdk/sdk-impl/config/default.d.ts +1 -1
  30. package/bin/libs/sdk/sdk-impl/config/default.js +1 -1
  31. package/bin/libs/sdk/sdk-impl/config/info.js +1 -1
  32. package/bin/libs/sdk/sdk-impl/config/init.d.ts +1 -0
  33. package/bin/libs/sdk/sdk-impl/config/init.js +98 -5
  34. package/bin/libs/sdk/sdk-impl/config/load.js +4 -4
  35. package/bin/libs/sdk/sdk-impl/utils/exec/exec-mod.js +0 -8
  36. package/bin/libs/sdk/sdk-mod.d.ts +1 -1
  37. package/bin/libs/sdk/sdk-mod.js +1 -1
  38. package/bin/mod.d.ts +1 -1
  39. package/bin/mod.js +1 -1
  40. package/package.json +3 -9
  41. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-biome.d.ts +0 -2
  42. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-biome.js +0 -34
  43. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-comments.d.ts +0 -1
  44. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-comments.js +0 -57
  45. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-consts.d.ts +0 -34
  46. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-consts.js +0 -36
  47. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-content.d.ts +0 -14
  48. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-content.js +0 -15
  49. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-core.d.ts +0 -14
  50. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-core.js +0 -63
  51. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-create.d.ts +0 -36
  52. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-create.js +0 -275
  53. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-def-utils.d.ts +0 -6
  54. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-def-utils.js +0 -225
  55. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-default.d.ts +0 -3
  56. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-default.js +0 -155
  57. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-define.d.ts +0 -125
  58. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-define.js +0 -4
  59. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-detect.d.ts +0 -23
  60. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-detect.js +0 -347
  61. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-gen-cfg.d.ts +0 -3
  62. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-gen-cfg.js +0 -186
  63. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-migrate.d.ts +0 -5
  64. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-migrate.js +0 -56
  65. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-path.d.ts +0 -11
  66. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-path.js +0 -33
  67. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-prompts.d.ts +0 -5
  68. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-prompts.js +0 -12
  69. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-read.d.ts +0 -11
  70. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-read.js +0 -84
  71. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-repair.d.ts +0 -16
  72. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-repair.js +0 -137
  73. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-schema.d.ts +0 -130
  74. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-schema.js +0 -438
  75. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-types.d.ts +0 -75
  76. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-types.js +0 -0
  77. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-unstable.d.ts +0 -11
  78. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-unstable.js +0 -41
  79. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-update.d.ts +0 -10
  80. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-update.js +0 -152
  81. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-utils.d.ts +0 -17
  82. package/bin/libs/cfg/cfg-impl/rse-config/rse-impl/rse-utils.js +0 -86
  83. package/bin/libs/cfg/cfg-impl/rse-config/rse-mod.d.ts +0 -20
  84. package/bin/libs/cfg/cfg-impl/rse-config/rse-mod.js +0 -20
@@ -1,8 +1,9 @@
1
1
  import path from "@reliverse/pathkit";
2
2
  import fs from "@reliverse/relifso";
3
3
  import { relinka } from "@reliverse/relinka";
4
- import { defineArgs, defineCommand } from "@reliverse/rempts";
4
+ import { defineArgs, defineCommand, multiselectPrompt } from "@reliverse/rempts";
5
5
  import { $ } from "bun";
6
+ import { lookpath } from "lookpath";
6
7
  import pMap from "p-map";
7
8
  import { readPackageJSON } from "pkg-types";
8
9
  import semver from "semver";
@@ -52,6 +53,220 @@ async function getLatestVersion(packageName) {
52
53
  }
53
54
  }
54
55
  }
56
+ async function getGlobalPackages(packageManager) {
57
+ try {
58
+ let result;
59
+ if (packageManager === "npm") {
60
+ result = await $`npm list -g --depth=0 --json`.json();
61
+ } else if (packageManager === "yarn") {
62
+ try {
63
+ result = await $`yarn global list --json`.json();
64
+ } catch {
65
+ result = await $`yarn global list`.text();
66
+ const packages2 = {};
67
+ const lines = result.split("\n");
68
+ for (const line of lines) {
69
+ const match = line.match(/^(.+)@([^@]+)$/);
70
+ if (match) {
71
+ packages2[match[1]] = match[2];
72
+ }
73
+ }
74
+ return packages2;
75
+ }
76
+ } else if (packageManager === "pnpm") {
77
+ result = await $`pnpm list -g --depth=0 --json`.json();
78
+ } else if (packageManager === "bun") {
79
+ result = await $`bun pm ls -g --json`.json();
80
+ } else {
81
+ throw new Error(`Unsupported package manager: ${packageManager}`);
82
+ }
83
+ const dependencies = result?.dependencies || {};
84
+ const packages = {};
85
+ for (const [name, info] of Object.entries(dependencies)) {
86
+ if (info && typeof info === "object" && "version" in info) {
87
+ packages[name] = info.version;
88
+ }
89
+ }
90
+ return packages;
91
+ } catch (error) {
92
+ relinka("warn", `Failed to get global packages for ${packageManager}: ${error}`);
93
+ return {};
94
+ }
95
+ }
96
+ async function updateGlobalPackage(packageManager, packageName) {
97
+ try {
98
+ if (packageManager === "npm") {
99
+ await $`npm install -g ${packageName}@latest`;
100
+ } else if (packageManager === "yarn") {
101
+ await $`yarn global add ${packageName}@latest`;
102
+ } else if (packageManager === "pnpm") {
103
+ await $`pnpm add -g ${packageName}@latest`;
104
+ } else if (packageManager === "bun") {
105
+ await $`bun install -g ${packageName}@latest`;
106
+ } else {
107
+ throw new Error(`Unsupported package manager: ${packageManager}`);
108
+ }
109
+ return true;
110
+ } catch (error) {
111
+ relinka(
112
+ "warn",
113
+ `Failed to update global package ${packageName} with ${packageManager}: ${error}`
114
+ );
115
+ return false;
116
+ }
117
+ }
118
+ async function handleGlobalUpdates(args) {
119
+ const packageManagers = ["bun", "npm", "yarn", "pnpm"];
120
+ const availablePackageManagers = [];
121
+ for (const pm of packageManagers) {
122
+ if (await lookpath(pm)) {
123
+ availablePackageManagers.push(pm);
124
+ }
125
+ }
126
+ if (availablePackageManagers.length === 0) {
127
+ relinka("error", "No supported package managers found");
128
+ return process.exit(1);
129
+ }
130
+ relinka("info", `Found package managers: ${availablePackageManagers.join(", ")}`);
131
+ const allGlobalPackages = {};
132
+ for (const pm of availablePackageManagers) {
133
+ const packages = await getGlobalPackages(pm);
134
+ for (const [name, version] of Object.entries(packages)) {
135
+ if (!allGlobalPackages[name] || semver.gt(version, allGlobalPackages[name].version)) {
136
+ allGlobalPackages[name] = { version, packageManager: pm };
137
+ }
138
+ }
139
+ }
140
+ const globalPackageNames = Object.keys(allGlobalPackages);
141
+ if (globalPackageNames.length === 0) {
142
+ relinka("warn", "No global packages found");
143
+ return;
144
+ }
145
+ let filteredPackages = [];
146
+ if (args.name && args.name.length > 0) {
147
+ filteredPackages = args.name.filter((pkg) => pkg in allGlobalPackages);
148
+ const notFound = args.name.filter((pkg) => !(pkg in allGlobalPackages));
149
+ if (notFound.length > 0) {
150
+ relinka("warn", `Global packages not found: ${notFound.join(", ")}`);
151
+ }
152
+ } else {
153
+ const ignoreList = args.ignore || [];
154
+ filteredPackages = globalPackageNames.filter((pkg) => !ignoreList.includes(pkg));
155
+ }
156
+ if (filteredPackages.length === 0) {
157
+ relinka("warn", "No global packages to update");
158
+ return;
159
+ }
160
+ relinka("info", `Checking ${filteredPackages.length} global packages for updates...`);
161
+ const results = await pMap(
162
+ filteredPackages,
163
+ async (packageName) => {
164
+ const globalPackage = allGlobalPackages[packageName];
165
+ if (!globalPackage) {
166
+ return {
167
+ package: packageName,
168
+ currentVersion: "unknown",
169
+ latestVersion: "unknown",
170
+ updated: false,
171
+ error: "Package not found in global packages",
172
+ location: "global"
173
+ };
174
+ }
175
+ try {
176
+ const latest = await getLatestVersion(packageName);
177
+ const needsUpdate = semver.gt(latest, globalPackage.version);
178
+ return {
179
+ package: packageName,
180
+ currentVersion: globalPackage.version,
181
+ latestVersion: latest,
182
+ updated: needsUpdate,
183
+ location: `global (${globalPackage.packageManager})`
184
+ };
185
+ } catch (error) {
186
+ return {
187
+ package: packageName,
188
+ currentVersion: globalPackage.version,
189
+ latestVersion: globalPackage.version,
190
+ updated: false,
191
+ error: error instanceof Error ? error.message : String(error),
192
+ location: `global (${globalPackage.packageManager})`
193
+ };
194
+ }
195
+ },
196
+ { concurrency: args.concurrency }
197
+ );
198
+ let toUpdate = results.filter((r) => r.updated && !r.error);
199
+ const errors = results.filter((r) => r.error);
200
+ const upToDate = results.filter((r) => !r.updated && !r.error);
201
+ if (errors.length > 0) {
202
+ relinka("warn", `Failed to check ${errors.length} global packages:`);
203
+ for (const error of errors) {
204
+ relinka("warn", ` ${error.package} (${error.location}): ${error.error}`);
205
+ }
206
+ }
207
+ if (upToDate.length > 0) {
208
+ relinka("success", `${upToDate.length} global packages are up to date`);
209
+ }
210
+ if (toUpdate.length === 0) {
211
+ relinka("success", "All global packages are up to date");
212
+ return;
213
+ }
214
+ relinka("info", `${toUpdate.length} global packages can be updated:`);
215
+ for (const update of toUpdate) {
216
+ relinka(
217
+ "log",
218
+ ` ${update.package} (${update.location}): ${update.currentVersion} \u2192 ${update.latestVersion}`
219
+ );
220
+ }
221
+ if (args.interactive) {
222
+ const allGlobalPackages2 = [
223
+ ...toUpdate.map((pkg) => ({ ...pkg, canUpdate: true, isUpToDate: false, hasError: false })),
224
+ ...upToDate.map((pkg) => ({ ...pkg, canUpdate: false, isUpToDate: true, hasError: false })),
225
+ ...errors.map((pkg) => ({ ...pkg, canUpdate: false, isUpToDate: false, hasError: true }))
226
+ ];
227
+ const selectedPackages = await multiselectPrompt({
228
+ title: "Select global packages to update",
229
+ options: [
230
+ { label: "Exit", value: "exit" },
231
+ ...allGlobalPackages2.map((pkg) => {
232
+ let label = `${pkg.package} (${pkg.location})`;
233
+ if (pkg.canUpdate) {
234
+ label += `: ${pkg.currentVersion} \u2192 ${pkg.latestVersion}`;
235
+ } else if (pkg.isUpToDate) {
236
+ label += `: ${pkg.currentVersion} (up-to-date)`;
237
+ } else if (pkg.hasError) {
238
+ label += `: ${pkg.currentVersion} (has errors)`;
239
+ }
240
+ return {
241
+ label,
242
+ value: pkg.package,
243
+ disabled: !pkg.canUpdate,
244
+ hint: pkg.hasError ? pkg.error : void 0
245
+ };
246
+ })
247
+ ]
248
+ });
249
+ if (selectedPackages.length === 0 || selectedPackages.includes("exit")) {
250
+ relinka("info", "Exiting global update process");
251
+ return;
252
+ }
253
+ const actualSelectedPackages = selectedPackages.filter((pkg) => pkg !== "exit");
254
+ toUpdate = toUpdate.filter((update) => actualSelectedPackages.includes(update.package));
255
+ relinka("info", `Updating ${actualSelectedPackages.length} selected global packages...`);
256
+ }
257
+ if (args["dry-run"]) {
258
+ relinka("info", "Dry run mode - no changes were made");
259
+ return;
260
+ }
261
+ let successCount = 0;
262
+ for (const update of toUpdate) {
263
+ const globalPackage = allGlobalPackages[update.package];
264
+ if (globalPackage && await updateGlobalPackage(globalPackage.packageManager, update.package)) {
265
+ successCount++;
266
+ }
267
+ }
268
+ relinka("success", `Successfully updated ${successCount}/${toUpdate.length} global packages`);
269
+ }
55
270
  export default defineCommand({
56
271
  meta: {
57
272
  name: "update",
@@ -117,10 +332,24 @@ export default defineCommand({
117
332
  description: "Skip the install step after updating dependencies",
118
333
  default: false,
119
334
  alias: "no-i"
335
+ },
336
+ global: {
337
+ type: "boolean",
338
+ description: "Update global packages instead of local dependencies",
339
+ default: false,
340
+ alias: "g"
341
+ },
342
+ interactive: {
343
+ type: "boolean",
344
+ description: "Interactively select which dependencies to update",
345
+ default: false
120
346
  }
121
347
  }),
122
348
  async run({ args }) {
123
349
  try {
350
+ if (args.global) {
351
+ return await handleGlobalUpdates(args);
352
+ }
124
353
  const packageJsonPath = path.resolve(process.cwd(), "package.json");
125
354
  if (!await fs.pathExists(packageJsonPath)) {
126
355
  relinka("error", "No package.json found in current directory");
@@ -288,7 +517,7 @@ export default defineCommand({
288
517
  },
289
518
  { concurrency: args.concurrency }
290
519
  );
291
- const toUpdate = results.filter((r) => r.updated && !r.error);
520
+ let toUpdate = results.filter((r) => r.updated && !r.error);
292
521
  const errors = results.filter((r) => r.error);
293
522
  const upToDate = results.filter((r) => !r.updated && !r.error && r.semverCompatible);
294
523
  if (errors.length > 0) {
@@ -315,6 +544,52 @@ export default defineCommand({
315
544
  ` ${update.package} (${update.location}): ${update.currentVersion} \u2192 ${update.latestVersion}`
316
545
  );
317
546
  }
547
+ if (args.interactive) {
548
+ const allPackages = [
549
+ ...toUpdate.map((pkg) => ({
550
+ ...pkg,
551
+ canUpdate: true,
552
+ isUpToDate: false,
553
+ hasError: false
554
+ })),
555
+ ...upToDate.map((pkg) => ({
556
+ ...pkg,
557
+ canUpdate: false,
558
+ isUpToDate: true,
559
+ hasError: false
560
+ })),
561
+ ...errors.map((pkg) => ({ ...pkg, canUpdate: false, isUpToDate: false, hasError: true }))
562
+ ];
563
+ const selectedPackages = await multiselectPrompt({
564
+ title: "Select dependencies to update",
565
+ options: [
566
+ { label: "Exit", value: "exit" },
567
+ ...allPackages.map((pkg) => {
568
+ let label = `${pkg.package} (${pkg.location})`;
569
+ if (pkg.canUpdate) {
570
+ label += `: ${pkg.currentVersion} \u2192 ${pkg.latestVersion}`;
571
+ } else if (pkg.isUpToDate) {
572
+ label += `: ${pkg.currentVersion} (up-to-date)`;
573
+ } else if (pkg.hasError) {
574
+ label += `: ${pkg.currentVersion} (has errors)`;
575
+ }
576
+ return {
577
+ label,
578
+ value: pkg.package,
579
+ disabled: !pkg.canUpdate,
580
+ hint: pkg.hasError ? pkg.error : void 0
581
+ };
582
+ })
583
+ ]
584
+ });
585
+ if (selectedPackages.length === 0 || selectedPackages.includes("exit")) {
586
+ relinka("info", "Exiting update process");
587
+ return;
588
+ }
589
+ const actualSelectedPackages = selectedPackages.filter((pkg) => pkg !== "exit");
590
+ toUpdate = toUpdate.filter((update) => actualSelectedPackages.includes(update.package));
591
+ relinka("info", `Updating ${actualSelectedPackages.length} selected dependencies...`);
592
+ }
318
593
  if (args["dry-run"]) {
319
594
  relinka("info", "Dry run mode - no changes were made");
320
595
  return;
@@ -0,0 +1,8 @@
1
+ declare const _default: import("@reliverse/rempts").Command<{
2
+ interactive: {
3
+ type: "boolean";
4
+ description: string;
5
+ default: true;
6
+ };
7
+ }>;
8
+ export default _default;
@@ -0,0 +1,295 @@
1
+ import { relinka } from "@reliverse/relinka";
2
+ import { defineArgs, defineCommand, multiselectPrompt } from "@reliverse/rempts";
3
+ import { lookpath } from "lookpath";
4
+ import { readPackageJSON } from "pkg-types";
5
+ import { x } from "../../libs/sdk/sdk-impl/utils/exec/exec-mod.js";
6
+ import { detectPackageManager } from "../../libs/sdk/sdk-impl/utils/pm/pm-detect.js";
7
+ export default defineCommand({
8
+ meta: {
9
+ name: "upgrade",
10
+ version: "1.0.0",
11
+ description: "Upgrade system development tools"
12
+ },
13
+ args: defineArgs({
14
+ interactive: {
15
+ type: "boolean",
16
+ description: "Interactively select which tools to upgrade",
17
+ default: true
18
+ }
19
+ }),
20
+ async run({ args }) {
21
+ const toolUpgradeFunctions = [
22
+ { name: "dler (local)", fn: upgradeDlerLocal },
23
+ { name: "dler (global)", fn: upgradeDlerGlobal },
24
+ { name: "git", fn: upgradeGit },
25
+ { name: "node.js", fn: upgradeNode },
26
+ { name: "npm", fn: upgradeNpm },
27
+ { name: "bun", fn: upgradeBun },
28
+ { name: "yarn", fn: upgradeYarn },
29
+ { name: "pnpm", fn: upgradePnpm }
30
+ ];
31
+ let results = [];
32
+ if (args.interactive) {
33
+ const preliminaryResults = await Promise.all(
34
+ toolUpgradeFunctions.map(async ({ fn }) => await fn())
35
+ );
36
+ const availableTools = toolUpgradeFunctions.map((tool, index) => ({
37
+ ...tool,
38
+ result: preliminaryResults[index]
39
+ })).filter(({ result }) => result && result.status !== "not-found");
40
+ if (availableTools.length === 0) {
41
+ relinka("warn", "No tools available for upgrade");
42
+ return;
43
+ }
44
+ const selectedTools = await multiselectPrompt({
45
+ title: "Select tools to upgrade",
46
+ displayInstructions: true,
47
+ options: [
48
+ { label: "Exit", value: "exit", disabled: true },
49
+ ...availableTools.map(({ name, result }) => {
50
+ const isUpToDate = result && result.status === "up-to-date";
51
+ const hasErrors = result && result.status === "error";
52
+ const canUpgrade = result && result.status === "upgraded";
53
+ let label = name;
54
+ if (isUpToDate) {
55
+ label += " (up-to-date)";
56
+ } else if (hasErrors) {
57
+ label += " (has errors)";
58
+ } else if (canUpgrade) {
59
+ label += " (can be upgraded)";
60
+ }
61
+ return {
62
+ label,
63
+ value: name,
64
+ disabled: isUpToDate,
65
+ hint: hasErrors ? result.message : void 0
66
+ };
67
+ })
68
+ ]
69
+ });
70
+ if (selectedTools.length === 0 || selectedTools.includes("exit")) {
71
+ relinka("info", "Exiting upgrade process");
72
+ return;
73
+ }
74
+ const actualSelectedTools = selectedTools.filter((tool) => tool !== "exit");
75
+ relinka("info", `Upgrading ${actualSelectedTools.length} selected tools...`);
76
+ for (const toolName of actualSelectedTools) {
77
+ const tool = availableTools.find((t) => t.name === toolName);
78
+ if (tool) {
79
+ const result = await tool.fn();
80
+ results.push(result);
81
+ }
82
+ }
83
+ } else {
84
+ results = await Promise.all(toolUpgradeFunctions.map(async ({ fn }) => await fn()));
85
+ }
86
+ const upgraded = results.filter((r) => r.status === "upgraded");
87
+ const upToDate = results.filter((r) => r.status === "up-to-date");
88
+ const notFound = results.filter((r) => r.status === "not-found");
89
+ const errors = results.filter((r) => r.status === "error");
90
+ if (upgraded.length > 0) {
91
+ relinka("success", `Upgraded ${upgraded.length} tools:`);
92
+ upgraded.forEach((r) => relinka("log", ` \u2713 ${r.tool}${r.message ? ` - ${r.message}` : ""}`));
93
+ }
94
+ if (upToDate.length > 0) {
95
+ relinka("info", `${upToDate.length} tools already up-to-date:`);
96
+ upToDate.forEach((r) => relinka("log", ` \u2022 ${r.tool}${r.message ? ` - ${r.message}` : ""}`));
97
+ }
98
+ if (notFound.length > 0) {
99
+ relinka("warn", `${notFound.length} tools not installed (skipped):`);
100
+ notFound.forEach((r) => relinka("log", ` - ${r.tool}`));
101
+ }
102
+ if (errors.length > 0) {
103
+ relinka("error", `${errors.length} tools had errors:`);
104
+ errors.forEach((r) => relinka("log", ` \u2717 ${r.tool}${r.message ? ` - ${r.message}` : ""}`));
105
+ }
106
+ relinka("success", "Upgrade check completed!");
107
+ }
108
+ });
109
+ async function upgradeDlerLocal() {
110
+ try {
111
+ const pkg = await readPackageJSON();
112
+ const hasDler = pkg.dependencies && "@reliverse/dler" in pkg.dependencies || pkg.devDependencies && "@reliverse/dler" in pkg.devDependencies;
113
+ if (!hasDler) {
114
+ return { tool: "dler (local)", status: "not-found" };
115
+ }
116
+ const packageManager = await detectPackageManager(process.cwd());
117
+ if (!packageManager) {
118
+ return { tool: "dler (local)", status: "error", message: "No package manager detected" };
119
+ }
120
+ const { exitCode } = await x(packageManager.command, ["update", "@reliverse/dler"], {
121
+ nodeOptions: { stdio: "pipe" }
122
+ });
123
+ return exitCode === 0 ? { tool: "dler (local)", status: "upgraded", message: `via ${packageManager.command}` } : { tool: "dler (local)", status: "error", message: "Upgrade failed" };
124
+ } catch (error) {
125
+ return {
126
+ tool: "dler (local)",
127
+ status: "not-found"
128
+ };
129
+ }
130
+ }
131
+ async function upgradeDlerGlobal() {
132
+ try {
133
+ const dlerPath = await lookpath("dler");
134
+ if (!dlerPath) {
135
+ return { tool: "dler (global)", status: "not-found" };
136
+ }
137
+ const packageManagers = ["bun", "npm", "yarn", "pnpm"];
138
+ for (const pm of packageManagers) {
139
+ const pmPath = await lookpath(pm);
140
+ if (pmPath) {
141
+ try {
142
+ const args = pm === "npm" ? ["install", "-g", "@reliverse/dler@latest"] : pm === "yarn" ? ["global", "add", "@reliverse/dler@latest"] : ["install", "-g", "@reliverse/dler@latest"];
143
+ const { exitCode } = await x(pm, args, {
144
+ nodeOptions: { stdio: "pipe" }
145
+ });
146
+ if (exitCode === 0) {
147
+ return { tool: "dler (global)", status: "upgraded", message: `via ${pm}` };
148
+ }
149
+ } catch {
150
+ }
151
+ }
152
+ }
153
+ return { tool: "dler (global)", status: "error", message: "No suitable package manager found" };
154
+ } catch (error) {
155
+ return { tool: "dler (global)", status: "error", message: String(error) };
156
+ }
157
+ }
158
+ async function upgradeGit() {
159
+ try {
160
+ const gitPath = await lookpath("git");
161
+ if (!gitPath) {
162
+ return { tool: "git", status: "not-found" };
163
+ }
164
+ const { stdout } = await x("git", ["--version"], {
165
+ nodeOptions: { stdio: "pipe" }
166
+ });
167
+ return {
168
+ tool: "git",
169
+ status: "up-to-date",
170
+ message: `${stdout.trim()} - manual upgrade required`
171
+ };
172
+ } catch (error) {
173
+ return { tool: "git", status: "error", message: String(error) };
174
+ }
175
+ }
176
+ async function upgradeNode() {
177
+ try {
178
+ const nodePath = await lookpath("node");
179
+ if (!nodePath) {
180
+ return { tool: "node.js", status: "not-found" };
181
+ }
182
+ const { stdout } = await x("node", ["--version"], {
183
+ nodeOptions: { stdio: "pipe" }
184
+ });
185
+ return {
186
+ tool: "node.js",
187
+ status: "up-to-date",
188
+ message: `${stdout.trim()} - manual upgrade required`
189
+ };
190
+ } catch (error) {
191
+ return { tool: "node.js", status: "error", message: String(error) };
192
+ }
193
+ }
194
+ async function upgradeNpm() {
195
+ try {
196
+ const npmPath = await lookpath("npm");
197
+ if (!npmPath) {
198
+ return { tool: "npm", status: "not-found" };
199
+ }
200
+ try {
201
+ const { exitCode, stdout, stderr } = await x("npm", ["install", "-g", "npm@latest"], {
202
+ nodeOptions: { stdio: "pipe" }
203
+ });
204
+ if (exitCode === 0) {
205
+ const output = (stdout + stderr).toLowerCase();
206
+ if (output.includes("unchanged") || output.includes("up-to-date") || output.includes("already")) {
207
+ return { tool: "npm", status: "up-to-date" };
208
+ }
209
+ return { tool: "npm", status: "upgraded" };
210
+ } else {
211
+ return { tool: "npm", status: "error", message: "Upgrade failed" };
212
+ }
213
+ } catch (pipeError) {
214
+ const { exitCode } = await x("npm", ["install", "-g", "npm@latest"], {
215
+ nodeOptions: { stdio: "inherit" }
216
+ });
217
+ return exitCode === 0 ? { tool: "npm", status: "upgraded" } : { tool: "npm", status: "error", message: "Upgrade failed" };
218
+ }
219
+ } catch (error) {
220
+ return { tool: "npm", status: "error", message: String(error) };
221
+ }
222
+ }
223
+ async function upgradeBun() {
224
+ try {
225
+ const bunPath = await lookpath("bun");
226
+ if (!bunPath) {
227
+ return { tool: "bun", status: "not-found" };
228
+ }
229
+ const { exitCode, stdout, stderr } = await x("bun", ["upgrade"], {
230
+ nodeOptions: { stdio: "pipe" }
231
+ });
232
+ if (exitCode !== 0) {
233
+ return { tool: "bun", status: "error", message: "Upgrade failed" };
234
+ }
235
+ const output = (stdout + stderr).toLowerCase();
236
+ if (output.includes("already") || output.includes("up-to-date") || output.includes("latest")) {
237
+ return { tool: "bun", status: "up-to-date" };
238
+ }
239
+ return { tool: "bun", status: "upgraded" };
240
+ } catch (error) {
241
+ return { tool: "bun", status: "error", message: String(error) };
242
+ }
243
+ }
244
+ async function upgradeYarn() {
245
+ try {
246
+ const yarnPath = await lookpath("yarn");
247
+ if (!yarnPath) {
248
+ return { tool: "yarn", status: "not-found" };
249
+ }
250
+ try {
251
+ const { exitCode: upgradeResult } = await x("yarn", ["self-update"], {
252
+ nodeOptions: { stdio: "pipe" }
253
+ });
254
+ if (upgradeResult === 0) {
255
+ return { tool: "yarn", status: "upgraded", message: "self-update" };
256
+ }
257
+ } catch {
258
+ }
259
+ const npmPath = await lookpath("npm");
260
+ if (npmPath) {
261
+ const { exitCode } = await x("npm", ["install", "-g", "yarn@latest"], {
262
+ nodeOptions: { stdio: "pipe" }
263
+ });
264
+ return exitCode === 0 ? { tool: "yarn", status: "upgraded", message: "via npm" } : { tool: "yarn", status: "error", message: "Upgrade failed" };
265
+ }
266
+ return { tool: "yarn", status: "error", message: "No upgrade method available" };
267
+ } catch (error) {
268
+ return { tool: "yarn", status: "error", message: String(error) };
269
+ }
270
+ }
271
+ async function upgradePnpm() {
272
+ try {
273
+ const pnpmPath = await lookpath("pnpm");
274
+ if (!pnpmPath) {
275
+ return { tool: "pnpm", status: "not-found" };
276
+ }
277
+ try {
278
+ const { exitCode } = await x("pnpm", ["add", "-g", "pnpm@latest"], {
279
+ nodeOptions: { stdio: "pipe" }
280
+ });
281
+ return exitCode === 0 ? { tool: "pnpm", status: "upgraded" } : { tool: "pnpm", status: "error", message: "Upgrade failed" };
282
+ } catch {
283
+ const npmPath = await lookpath("npm");
284
+ if (npmPath) {
285
+ const { exitCode } = await x("npm", ["install", "-g", "pnpm@latest"], {
286
+ nodeOptions: { stdio: "pipe" }
287
+ });
288
+ return exitCode === 0 ? { tool: "pnpm", status: "upgraded", message: "via npm" } : { tool: "pnpm", status: "error", message: "Upgrade failed" };
289
+ }
290
+ return { tool: "pnpm", status: "error", message: "No upgrade method available" };
291
+ }
292
+ } catch (error) {
293
+ return { tool: "pnpm", status: "error", message: String(error) };
294
+ }
295
+ }