@visulima/vis 1.0.0-alpha.1 → 1.0.0-alpha.11
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/CHANGELOG.md +403 -12
- package/LICENSE.md +283 -0
- package/README.md +254 -9
- package/dist/bin.js +9 -146
- package/dist/config/index.d.ts +1818 -0
- package/dist/config/index.js +2 -0
- package/dist/generate/index.d.ts +157 -0
- package/dist/generate/index.js +3 -0
- package/dist/packem_chunks/applyDefaults.js +336 -0
- package/dist/packem_chunks/bin.js +9577 -0
- package/dist/packem_chunks/doctor-probe.js +112 -0
- package/dist/packem_chunks/fix.js +234 -0
- package/dist/packem_chunks/handler.js +99 -0
- package/dist/packem_chunks/handler10.js +53 -0
- package/dist/packem_chunks/handler11.js +32 -0
- package/dist/packem_chunks/handler12.js +100 -0
- package/dist/packem_chunks/handler13.js +25 -0
- package/dist/packem_chunks/handler14.js +916 -0
- package/dist/packem_chunks/handler15.js +206 -0
- package/dist/packem_chunks/handler16.js +124 -0
- package/dist/packem_chunks/handler17.js +13 -0
- package/dist/packem_chunks/handler18.js +106 -0
- package/dist/packem_chunks/handler19.js +19 -0
- package/dist/packem_chunks/handler2.js +75 -0
- package/dist/packem_chunks/handler20.js +29 -0
- package/dist/packem_chunks/handler21.js +222 -0
- package/dist/packem_chunks/handler22.js +237 -0
- package/dist/packem_chunks/handler23.js +101 -0
- package/dist/packem_chunks/handler24.js +110 -0
- package/dist/packem_chunks/handler25.js +402 -0
- package/dist/packem_chunks/handler26.js +13 -0
- package/dist/packem_chunks/handler27.js +63 -0
- package/dist/packem_chunks/handler28.js +34 -0
- package/dist/packem_chunks/handler29.js +458 -0
- package/dist/packem_chunks/handler3.js +95 -0
- package/dist/packem_chunks/handler30.js +170 -0
- package/dist/packem_chunks/handler31.js +530 -0
- package/dist/packem_chunks/handler32.js +214 -0
- package/dist/packem_chunks/handler33.js +119 -0
- package/dist/packem_chunks/handler34.js +630 -0
- package/dist/packem_chunks/handler35.js +283 -0
- package/dist/packem_chunks/handler36.js +542 -0
- package/dist/packem_chunks/handler37.js +762 -0
- package/dist/packem_chunks/handler38.js +989 -0
- package/dist/packem_chunks/handler39.js +574 -0
- package/dist/packem_chunks/handler4.js +90 -0
- package/dist/packem_chunks/handler40.js +1685 -0
- package/dist/packem_chunks/handler41.js +1088 -0
- package/dist/packem_chunks/handler42.js +797 -0
- package/dist/packem_chunks/handler43.js +2658 -0
- package/dist/packem_chunks/handler44.js +3886 -0
- package/dist/packem_chunks/handler45.js +2574 -0
- package/dist/packem_chunks/handler46.js +3769 -0
- package/dist/packem_chunks/handler47.js +1491 -0
- package/dist/packem_chunks/handler5.js +174 -0
- package/dist/packem_chunks/handler6.js +95 -0
- package/dist/packem_chunks/handler7.js +115 -0
- package/dist/packem_chunks/handler8.js +12 -0
- package/dist/packem_chunks/handler9.js +29 -0
- package/dist/packem_chunks/heal-accept.js +522 -0
- package/dist/packem_chunks/heal.js +673 -0
- package/dist/packem_chunks/index.js +873 -0
- package/dist/packem_chunks/loader.js +23 -0
- package/dist/packem_shared/VisUpdateApp-D-Yz_wvg.js +1316 -0
- package/dist/packem_shared/_commonjsHelpers-BqLXS_qQ.js +5 -0
- package/dist/packem_shared/ai-analysis-CHeB1joD.js +367 -0
- package/dist/packem_shared/ai-cache-Be_jexe4.js +142 -0
- package/dist/packem_shared/ai-fix-B9iQVcD2.js +379 -0
- package/dist/packem_shared/cache-directory-2qvs4goY.js +98 -0
- package/dist/packem_shared/catalog-BJTtyi-O.js +1371 -0
- package/dist/packem_shared/dependency-scan-A0KSklpG.js +188 -0
- package/dist/packem_shared/docker-2iZzc280.js +181 -0
- package/dist/packem_shared/failure-log-Cz3Z4SKL.js +100 -0
- package/dist/packem_shared/flakiness-goTxXuCX.js +180 -0
- package/dist/packem_shared/otel-DCvqCTz_.js +158 -0
- package/dist/packem_shared/otelPlugin-DFaLDvJf.js +3 -0
- package/dist/packem_shared/registry-CbqXI0rc.js +272 -0
- package/dist/packem_shared/run-summary-utils-PVMl4aIh.js +130 -0
- package/dist/packem_shared/runtime-check-Cobi3p6l.js +127 -0
- package/dist/packem_shared/selectors-SM69TfqC.js +194 -0
- package/dist/packem_shared/symbols-Ta7g2nU-.js +14 -0
- package/dist/packem_shared/toolchain-BdZd9eBi.js +975 -0
- package/dist/packem_shared/typosquats-C-bCh3PX.js +1210 -0
- package/dist/packem_shared/use-measured-height-CNP0vT4M.js +20 -0
- package/dist/packem_shared/utils-CthVdBPS.js +40 -0
- package/dist/packem_shared/xxh3-Ck8mXNg1.js +239 -0
- package/index.js +773 -0
- package/package.json +82 -21
- package/schemas/project.schema.json +420 -0
- package/schemas/vis-config.schema.json +501 -0
- package/skills/vis/SKILL.md +96 -0
- package/templates/buildkite-ci/.buildkite/pipeline.yml.tera +85 -0
- package/templates/buildkite-ci/template.yml +20 -0
- package/dist/ai-analysis.d.ts +0 -40
- package/dist/ai-cache.d.ts +0 -21
- package/dist/bin.d.ts +0 -1
- package/dist/catalog.d.ts +0 -110
- package/dist/commands/affected.d.ts +0 -3
- package/dist/commands/ai.d.ts +0 -3
- package/dist/commands/analyze.d.ts +0 -3
- package/dist/commands/check.d.ts +0 -3
- package/dist/commands/graph.d.ts +0 -3
- package/dist/commands/hook/constants.d.ts +0 -8
- package/dist/commands/hook/index.d.ts +0 -3
- package/dist/commands/hook/install.d.ts +0 -7
- package/dist/commands/hook/migrate.d.ts +0 -27
- package/dist/commands/hook/uninstall.d.ts +0 -3
- package/dist/commands/migrate/constants.d.ts +0 -12
- package/dist/commands/migrate/deps.d.ts +0 -32
- package/dist/commands/migrate/index.d.ts +0 -3
- package/dist/commands/migrate/json.d.ts +0 -20
- package/dist/commands/migrate/lint-staged.d.ts +0 -62
- package/dist/commands/migrate/types.d.ts +0 -20
- package/dist/commands/run.d.ts +0 -3
- package/dist/commands/staged.d.ts +0 -3
- package/dist/commands/update.d.ts +0 -3
- package/dist/config.d.ts +0 -40
- package/dist/config.js +0 -1
- package/dist/package-manager.d.ts +0 -23
- package/dist/workspace.d.ts +0 -58
|
@@ -0,0 +1,630 @@
|
|
|
1
|
+
import { createRequire as __cjs_createRequire } from "node:module";
|
|
2
|
+
|
|
3
|
+
const __cjs_require = __cjs_createRequire(import.meta.url);
|
|
4
|
+
|
|
5
|
+
const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
|
|
6
|
+
|
|
7
|
+
const __cjs_getBuiltinModule = (module) => {
|
|
8
|
+
// Check if we're in Node.js and version supports getBuiltinModule
|
|
9
|
+
if (typeof __cjs_getProcess !== "undefined" && __cjs_getProcess.versions && __cjs_getProcess.versions.node) {
|
|
10
|
+
const [major, minor] = __cjs_getProcess.versions.node.split(".").map(Number);
|
|
11
|
+
// Node.js 20.16.0+ and 22.3.0+
|
|
12
|
+
if (major > 22 || (major === 22 && minor >= 3) || (major === 20 && minor >= 16)) {
|
|
13
|
+
return __cjs_getProcess.getBuiltinModule(module);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// Fallback to createRequire
|
|
17
|
+
return __cjs_require(module);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const {
|
|
21
|
+
execSync
|
|
22
|
+
} = __cjs_getBuiltinModule("node:child_process");
|
|
23
|
+
import { yellow, red } from '@visulima/colorize';
|
|
24
|
+
import { isAccessibleSync, readJsonSync } from '@visulima/fs';
|
|
25
|
+
import { readYamlSync } from '@visulima/fs/yaml';
|
|
26
|
+
import { findPackageManagerSync, getPackageManagerVersion } from '@visulima/package';
|
|
27
|
+
import { join } from '@visulima/path';
|
|
28
|
+
import { render, renderToString, Text } from '@visulima/tui';
|
|
29
|
+
import { K as resolveAubeUpdate, r as resolveInstaller, i as isInCi, j as scoreColor, a as buildSocketOptions } from './bin.js';
|
|
30
|
+
import React from 'react';
|
|
31
|
+
import { v as validateAnalysisType, r as runAiAnalysis, f as formatAiAnalysis } from '../packem_shared/ai-analysis-CHeB1joD.js';
|
|
32
|
+
import { r as runTyposquatCheck, s as scanDepsForTyposquats } from '../packem_shared/typosquats-C-bCh3PX.js';
|
|
33
|
+
import { U as UpdateStore, V as VisUpdateApp, C as CheckProgressApp } from '../packem_shared/VisUpdateApp-D-Yz_wvg.js';
|
|
34
|
+
import { i as hasBackup, j as restoreFromBackup, k as hasCatalogs, l as loadNpmrc, r as readCatalogs, c as checkOutdated, m as fetchChangelogInfo, b as formatSummary, n as promptPackageSelection, t as toFilterArray, o as applyCatalogUpdates, q as formatOutdatedJson, d as formatOutdatedMinimal, h as formatOutdatedTable } from '../packem_shared/catalog-BJTtyi-O.js';
|
|
35
|
+
import { p as parsePackageArgument } from '../packem_shared/utils-CthVdBPS.js';
|
|
36
|
+
|
|
37
|
+
const resolvePnpm = (options) => {
|
|
38
|
+
const args = [];
|
|
39
|
+
for (const filter of options.filters) {
|
|
40
|
+
args.push("--filter", filter);
|
|
41
|
+
}
|
|
42
|
+
if (options.workspaceRoot) {
|
|
43
|
+
args.push("--filter", ".");
|
|
44
|
+
}
|
|
45
|
+
args.push("update");
|
|
46
|
+
if (options.latest) {
|
|
47
|
+
args.push("--latest");
|
|
48
|
+
}
|
|
49
|
+
if (options.recursive) {
|
|
50
|
+
args.push("--recursive");
|
|
51
|
+
}
|
|
52
|
+
if (options.interactive) {
|
|
53
|
+
args.push("--interactive");
|
|
54
|
+
}
|
|
55
|
+
if (options.dev) {
|
|
56
|
+
args.push("--dev");
|
|
57
|
+
}
|
|
58
|
+
if (options.prod) {
|
|
59
|
+
args.push("--prod");
|
|
60
|
+
}
|
|
61
|
+
if (options.noOptional) {
|
|
62
|
+
args.push("--no-optional");
|
|
63
|
+
}
|
|
64
|
+
if (options.noSave) {
|
|
65
|
+
args.push("--no-save");
|
|
66
|
+
}
|
|
67
|
+
args.push(...options.packages);
|
|
68
|
+
return { args, bin: "pnpm" };
|
|
69
|
+
};
|
|
70
|
+
const resolveYarnV1 = (options) => {
|
|
71
|
+
const args = [];
|
|
72
|
+
if (options.filters.length > 0) {
|
|
73
|
+
args.push("workspace", options.filters[0]);
|
|
74
|
+
}
|
|
75
|
+
args.push("upgrade");
|
|
76
|
+
if (options.latest) {
|
|
77
|
+
args.push("--latest");
|
|
78
|
+
}
|
|
79
|
+
args.push(...options.packages);
|
|
80
|
+
return { args, bin: "yarn" };
|
|
81
|
+
};
|
|
82
|
+
const resolveYarnBerry = (options) => {
|
|
83
|
+
const args = [];
|
|
84
|
+
if (options.filters.length > 0 || options.recursive) {
|
|
85
|
+
args.push("workspaces", "foreach", "--all");
|
|
86
|
+
for (const filter of options.filters) {
|
|
87
|
+
args.push("--include", filter);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
args.push("up");
|
|
91
|
+
if (options.interactive) {
|
|
92
|
+
args.push("--interactive");
|
|
93
|
+
}
|
|
94
|
+
args.push(...options.packages);
|
|
95
|
+
return { args, bin: "yarn" };
|
|
96
|
+
};
|
|
97
|
+
const resolveNpm = (options, warnings) => {
|
|
98
|
+
const args = ["update"];
|
|
99
|
+
if (options.latest) {
|
|
100
|
+
warnings.push("npm does not support --latest flag. Packages will be updated within their semver range.");
|
|
101
|
+
}
|
|
102
|
+
if (options.interactive) {
|
|
103
|
+
warnings.push("npm does not support --interactive mode.");
|
|
104
|
+
}
|
|
105
|
+
for (const filter of options.filters) {
|
|
106
|
+
args.push("--workspace", filter);
|
|
107
|
+
}
|
|
108
|
+
if (options.recursive) {
|
|
109
|
+
args.push("--workspaces");
|
|
110
|
+
}
|
|
111
|
+
if (options.workspaceRoot) {
|
|
112
|
+
args.push("--include-workspace-root");
|
|
113
|
+
}
|
|
114
|
+
if (options.dev) {
|
|
115
|
+
args.push("--dev");
|
|
116
|
+
}
|
|
117
|
+
if (options.prod) {
|
|
118
|
+
args.push("--production");
|
|
119
|
+
}
|
|
120
|
+
if (options.noOptional) {
|
|
121
|
+
args.push("--no-optional");
|
|
122
|
+
}
|
|
123
|
+
if (options.noSave) {
|
|
124
|
+
args.push("--no-save");
|
|
125
|
+
}
|
|
126
|
+
args.push(...options.packages);
|
|
127
|
+
return { args, bin: "npm" };
|
|
128
|
+
};
|
|
129
|
+
const resolveBun = (options) => {
|
|
130
|
+
const args = ["update"];
|
|
131
|
+
if (options.latest) {
|
|
132
|
+
args.push("--latest");
|
|
133
|
+
}
|
|
134
|
+
for (const filter of options.filters) {
|
|
135
|
+
args.push("--filter", filter);
|
|
136
|
+
}
|
|
137
|
+
args.push(...options.packages);
|
|
138
|
+
return { args, bin: "bun" };
|
|
139
|
+
};
|
|
140
|
+
const resolveUpdateCommand = (packageManager, version, options) => {
|
|
141
|
+
const warnings = [];
|
|
142
|
+
if (options.global && packageManager !== "aube") {
|
|
143
|
+
const args = ["update", "--global", ...options.packages];
|
|
144
|
+
return { command: { args, bin: "npm" }, warnings };
|
|
145
|
+
}
|
|
146
|
+
let command;
|
|
147
|
+
switch (packageManager) {
|
|
148
|
+
case "aube": {
|
|
149
|
+
const aube = resolveAubeUpdate(options);
|
|
150
|
+
command = { args: aube.args, bin: aube.bin };
|
|
151
|
+
warnings.push(...aube.warnings);
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
case "bun": {
|
|
155
|
+
command = resolveBun(options);
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
case "npm": {
|
|
159
|
+
command = resolveNpm(options, warnings);
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
case "pnpm": {
|
|
163
|
+
command = resolvePnpm(options);
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
case "yarn": {
|
|
167
|
+
command = version.startsWith("1.") ? resolveYarnV1(options) : resolveYarnBerry(options);
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
default: {
|
|
171
|
+
const exhaustiveCheck = packageManager;
|
|
172
|
+
throw new Error(`Unsupported package manager: ${String(exhaustiveCheck)}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return { command, warnings };
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const readPmNativeMinimumReleaseAge = (workspaceRoot, packageManager) => {
|
|
179
|
+
try {
|
|
180
|
+
if (packageManager === "pnpm") {
|
|
181
|
+
const yamlPath = join(workspaceRoot, "pnpm-workspace.yaml");
|
|
182
|
+
if (isAccessibleSync(yamlPath)) {
|
|
183
|
+
const data = readYamlSync(yamlPath);
|
|
184
|
+
if (typeof data?.minimumReleaseAge === "number") {
|
|
185
|
+
return data.minimumReleaseAge;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
} else if (packageManager === "bun") {
|
|
189
|
+
const pkgPath = join(workspaceRoot, "package.json");
|
|
190
|
+
if (isAccessibleSync(pkgPath)) {
|
|
191
|
+
const pkg = readJsonSync(pkgPath);
|
|
192
|
+
if (typeof pkg.minimumReleaseAge === "number") {
|
|
193
|
+
return pkg.minimumReleaseAge;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
} catch {
|
|
198
|
+
}
|
|
199
|
+
return void 0;
|
|
200
|
+
};
|
|
201
|
+
const buildCatalogCheckOptions = (options, configDefaults, argument) => {
|
|
202
|
+
const target = options.latest ? "latest" : options.target ?? configDefaults.target ?? "latest";
|
|
203
|
+
if (!["latest", "minor", "patch"].includes(target)) {
|
|
204
|
+
throw new Error(`Invalid target "${target}". Use: latest, minor, or patch.`);
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
exclude: [...toFilterArray(options.exclude), ...toFilterArray(configDefaults.exclude)],
|
|
208
|
+
ignore: toFilterArray(configDefaults.ignore),
|
|
209
|
+
include: [...toFilterArray(options.include), ...toFilterArray(configDefaults.include), ...argument],
|
|
210
|
+
includeLocked: options.includeLocked || configDefaults.includeLocked || false,
|
|
211
|
+
includePrerelease: options.prerelease || configDefaults.prerelease || false,
|
|
212
|
+
minimumReleaseAge: configDefaults.minimumReleaseAge,
|
|
213
|
+
minimumReleaseAgeExclude: configDefaults.minimumReleaseAgeExclude,
|
|
214
|
+
packageMode: configDefaults.packageMode,
|
|
215
|
+
security: options.security || options.ai || configDefaults.security || false,
|
|
216
|
+
target
|
|
217
|
+
};
|
|
218
|
+
};
|
|
219
|
+
const logFilteredByTarget = (entries, logger) => {
|
|
220
|
+
if (entries.length === 0) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
logger.info(
|
|
224
|
+
`
|
|
225
|
+
${yellow("⚠")} ${String(entries.length)} package${entries.length === 1 ? "" : "s"} skipped by target constraint (use --target latest to include):`
|
|
226
|
+
);
|
|
227
|
+
for (const entry of entries) {
|
|
228
|
+
logger.info(` ${entry.packageName} ${entry.currentRange} → ${entry.newRange} (${entry.updateType})`);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
const writeFormattedOutput = (entries, failed, format, logger) => {
|
|
232
|
+
if (format === "json") {
|
|
233
|
+
process.stdout.write(`${formatOutdatedJson({ checkedCount: 0, failed, filteredByTarget: [], ignored: [], outdated: entries })}
|
|
234
|
+
`);
|
|
235
|
+
} else if (format === "minimal") {
|
|
236
|
+
process.stdout.write(`${formatOutdatedMinimal(entries)}
|
|
237
|
+
`);
|
|
238
|
+
} else {
|
|
239
|
+
formatOutdatedTable(entries, logger);
|
|
240
|
+
logger.info(formatSummary(entries));
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
const applyCatalogAndInstall = async (workspaceRoot, packageManager, toApply, options, logger) => {
|
|
244
|
+
const backupPath = applyCatalogUpdates(workspaceRoot, toApply, packageManager);
|
|
245
|
+
const targetFile = packageManager === "pnpm" ? "pnpm-workspace.yaml" : "package.json";
|
|
246
|
+
logger.info(`
|
|
247
|
+
Updated ${targetFile}`);
|
|
248
|
+
if (backupPath) {
|
|
249
|
+
logger.info(`Backup saved to ${backupPath}`);
|
|
250
|
+
}
|
|
251
|
+
if (options.changelog) {
|
|
252
|
+
logger.info("\nFetching changelogs...");
|
|
253
|
+
const changelogs = await fetchChangelogInfo(toApply);
|
|
254
|
+
for (const info of changelogs) {
|
|
255
|
+
const url = info.releaseUrl ?? info.repoUrl ?? info.npmUrl;
|
|
256
|
+
logger.info(` ${info.packageName}: ${url}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
if (options.install ?? true) {
|
|
260
|
+
const installCommands = {
|
|
261
|
+
bun: "bun install",
|
|
262
|
+
npm: "npm install",
|
|
263
|
+
pnpm: "pnpm install",
|
|
264
|
+
yarn: "yarn install"
|
|
265
|
+
};
|
|
266
|
+
const installCommand = installCommands[packageManager] ?? `${packageManager} install`;
|
|
267
|
+
logger.info(`Running ${installCommand}...
|
|
268
|
+
`);
|
|
269
|
+
try {
|
|
270
|
+
execSync(installCommand, {
|
|
271
|
+
cwd: workspaceRoot,
|
|
272
|
+
env: process.env,
|
|
273
|
+
stdio: "inherit"
|
|
274
|
+
});
|
|
275
|
+
} catch {
|
|
276
|
+
logger.warn(`${installCommand} failed. You may need to run it manually.`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
const executeCatalogUpdate = async (workspaceRoot, packageManager, visConfig, options, argument, logger) => {
|
|
281
|
+
const configDefaults = visConfig.update ?? {};
|
|
282
|
+
const ignoredCatalogFlags = [
|
|
283
|
+
["global", "--global is not supported in catalog mode"],
|
|
284
|
+
["recursive", "--recursive is not needed in catalog mode (catalogs are workspace-level)"],
|
|
285
|
+
["filter", "--filter is not supported in catalog mode (use --include/--exclude instead)"],
|
|
286
|
+
["no-save", "--no-save is not supported in catalog mode"],
|
|
287
|
+
["workspace-root", "--workspace-root is not needed in catalog mode"],
|
|
288
|
+
["no-optional", "--no-optional is not supported in catalog mode"]
|
|
289
|
+
];
|
|
290
|
+
for (const [flag, message] of ignoredCatalogFlags) {
|
|
291
|
+
if (options[flag]) {
|
|
292
|
+
logger.warn(`${yellow("⚠")} ${message}, ignoring.`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
const pmNativeAge = readPmNativeMinimumReleaseAge(workspaceRoot, packageManager);
|
|
296
|
+
const effectiveAge = configDefaults.minimumReleaseAge ?? pmNativeAge;
|
|
297
|
+
if (configDefaults.minimumReleaseAge !== void 0 && pmNativeAge !== void 0 && configDefaults.minimumReleaseAge !== pmNativeAge) {
|
|
298
|
+
const pmConfigFile = packageManager === "pnpm" ? "pnpm-workspace.yaml" : "package.json";
|
|
299
|
+
logger.warn(
|
|
300
|
+
`${yellow("⚠")} minimumReleaseAge mismatch: vis config = ${String(configDefaults.minimumReleaseAge)} min, ${pmConfigFile} = ${String(pmNativeAge)} min. Consider keeping them in sync.`
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
const npmrcConfig = loadNpmrc(workspaceRoot);
|
|
304
|
+
const catalogs = readCatalogs(workspaceRoot, packageManager, {
|
|
305
|
+
depFields: configDefaults.depFields,
|
|
306
|
+
dev: options.dev,
|
|
307
|
+
prod: options.prod
|
|
308
|
+
});
|
|
309
|
+
if (catalogs.size === 0) {
|
|
310
|
+
logger.info("No catalogs found.");
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const resolvedDefaults = { ...configDefaults, minimumReleaseAge: effectiveAge };
|
|
314
|
+
const checkOptions = buildCatalogCheckOptions(options, resolvedDefaults, argument);
|
|
315
|
+
let totalDeps = 0;
|
|
316
|
+
for (const deps of catalogs.values()) {
|
|
317
|
+
totalDeps += deps.size;
|
|
318
|
+
}
|
|
319
|
+
const isTTY = Boolean(process.stdout.isTTY) && !isInCi;
|
|
320
|
+
let progressInstance;
|
|
321
|
+
const onProgress = isTTY ? (current, total) => {
|
|
322
|
+
if (progressInstance) {
|
|
323
|
+
progressInstance.rerender(React.createElement(CheckProgressApp, { current, total }));
|
|
324
|
+
} else {
|
|
325
|
+
process.stdout.write("\n");
|
|
326
|
+
progressInstance = render(React.createElement(CheckProgressApp, { current, total }), {
|
|
327
|
+
interactive: true,
|
|
328
|
+
patchConsole: false
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
} : (current, total) => {
|
|
332
|
+
logger.info(`Checking ${String(current)}/${String(total)} dependencies...`);
|
|
333
|
+
};
|
|
334
|
+
if (!isTTY) {
|
|
335
|
+
logger.info(`Checking ${String(totalDeps)} catalog dependencies...
|
|
336
|
+
`);
|
|
337
|
+
}
|
|
338
|
+
const socketOptions = buildSocketOptions(visConfig.security?.socket);
|
|
339
|
+
const { checkedCount, failed, filteredByTarget, ignored, outdated } = await checkOutdated(
|
|
340
|
+
catalogs,
|
|
341
|
+
checkOptions,
|
|
342
|
+
npmrcConfig,
|
|
343
|
+
onProgress,
|
|
344
|
+
workspaceRoot,
|
|
345
|
+
socketOptions,
|
|
346
|
+
visConfig.security?.socket?.acceptedRisks
|
|
347
|
+
);
|
|
348
|
+
if (progressInstance) {
|
|
349
|
+
progressInstance.clear();
|
|
350
|
+
progressInstance.unmount();
|
|
351
|
+
}
|
|
352
|
+
const upToDate = checkedCount - outdated.length - failed.length;
|
|
353
|
+
if (failed.length > 0) {
|
|
354
|
+
logger.warn(`Failed to fetch: ${failed.join(", ")}`);
|
|
355
|
+
}
|
|
356
|
+
if (ignored.length > 0) {
|
|
357
|
+
logger.info(`Skipped ${String(ignored.length)} ignored package${ignored.length === 1 ? "" : "s"}: ${ignored.join(", ")}`);
|
|
358
|
+
}
|
|
359
|
+
if (!isTTY && checkedCount > outdated.length) {
|
|
360
|
+
const totalCatalogEntries = [...catalogs.values()].reduce((sum, deps) => sum + deps.size, 0);
|
|
361
|
+
const dedupeNote = totalCatalogEntries > checkedCount ? ` (${String(totalCatalogEntries)} catalog entries, ${String(totalCatalogEntries - checkedCount)} duplicates)` : "";
|
|
362
|
+
logger.info(
|
|
363
|
+
`Checked ${String(checkedCount)} unique packages${dedupeNote}: ${String(outdated.length)} outdated, ${String(upToDate)} up-to-date${failed.length > 0 ? `, ${String(failed.length)} failed` : ""}${filteredByTarget.length > 0 ? `, ${String(filteredByTarget.length)} skipped by target` : ""}`
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
if (outdated.length === 0) {
|
|
367
|
+
if (filteredByTarget.length > 0) {
|
|
368
|
+
logger.info(
|
|
369
|
+
`All catalog dependencies are up to date within the current target.
|
|
370
|
+
${String(filteredByTarget.length)} package${filteredByTarget.length === 1 ? " has" : "s have"} newer versions available with --target latest:
|
|
371
|
+
${filteredByTarget.map((e) => ` ${e.packageName} ${e.currentRange} → ${e.newRange} (${e.updateType})`).join("\n")}`
|
|
372
|
+
);
|
|
373
|
+
} else {
|
|
374
|
+
logger.info("All catalog dependencies are up to date.");
|
|
375
|
+
}
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const format = options.format ?? configDefaults.format ?? "table";
|
|
379
|
+
let aiResult;
|
|
380
|
+
if (options.ai) {
|
|
381
|
+
const analysisType = validateAnalysisType(options.aiType ?? "impact");
|
|
382
|
+
aiResult = await runAiAnalysis(outdated, logger, visConfig.ai, analysisType);
|
|
383
|
+
}
|
|
384
|
+
const isDryRun = Boolean(options.dryRun);
|
|
385
|
+
if (isTTY && format === "table") {
|
|
386
|
+
const store = new UpdateStore(outdated, aiResult ?? null);
|
|
387
|
+
let changelogUrls;
|
|
388
|
+
if (options.changelog) {
|
|
389
|
+
logger.info("Fetching changelogs...");
|
|
390
|
+
const changelogs = await fetchChangelogInfo(outdated);
|
|
391
|
+
changelogUrls = /* @__PURE__ */ new Map();
|
|
392
|
+
for (const info of changelogs) {
|
|
393
|
+
const url = info.releaseUrl ?? info.repoUrl ?? info.npmUrl;
|
|
394
|
+
if (url) {
|
|
395
|
+
changelogUrls.set(info.packageName, url);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
const autoExitConfig = visConfig.tui?.autoExit ?? false;
|
|
400
|
+
const autoExitSeconds = autoExitConfig === true ? 3 : typeof autoExitConfig === "number" ? autoExitConfig : 0;
|
|
401
|
+
const instance = render(
|
|
402
|
+
React.createElement(VisUpdateApp, {
|
|
403
|
+
autoExitSeconds,
|
|
404
|
+
changelogUrls,
|
|
405
|
+
checkedCount,
|
|
406
|
+
filteredOutEntries: filteredByTarget,
|
|
407
|
+
isDryRun,
|
|
408
|
+
store,
|
|
409
|
+
totalCatalogEntries: totalDeps
|
|
410
|
+
}),
|
|
411
|
+
{
|
|
412
|
+
alternateScreen: true,
|
|
413
|
+
exitOnCtrlC: false,
|
|
414
|
+
interactive: true,
|
|
415
|
+
patchConsole: true
|
|
416
|
+
}
|
|
417
|
+
);
|
|
418
|
+
const exitResult = await instance.waitUntilExit();
|
|
419
|
+
const columns = process.stdout.columns || 80;
|
|
420
|
+
process.stdout.write("\n");
|
|
421
|
+
for (const entry of outdated) {
|
|
422
|
+
const hasSecurityIssue = entry.vulnerabilities?.length || entry.socketReport && entry.socketReport.alerts.length > 0;
|
|
423
|
+
const isAck = Boolean(entry.acceptedRisk);
|
|
424
|
+
const icon = hasSecurityIssue ? isAck ? "✓" : "⚠" : "✓";
|
|
425
|
+
const iconColor = isAck ? "gray" : entry.updateType === "major" ? "red" : entry.updateType === "minor" ? "yellow" : "green";
|
|
426
|
+
const socketOverall = entry.socketReport?.score.overall;
|
|
427
|
+
const scoreSuffix = socketOverall === void 0 ? "" : ` [${String(Math.round(socketOverall * 100))}%]`;
|
|
428
|
+
const socketColorName = socketOverall === void 0 ? void 0 : scoreColor(socketOverall);
|
|
429
|
+
process.stdout.write(
|
|
430
|
+
`${renderToString(
|
|
431
|
+
React.createElement(
|
|
432
|
+
Text,
|
|
433
|
+
null,
|
|
434
|
+
" ",
|
|
435
|
+
React.createElement(Text, { color: iconColor }, icon),
|
|
436
|
+
` ${entry.packageName} ${entry.currentRange} → ${entry.newRange}`,
|
|
437
|
+
React.createElement(Text, { dimColor: true }, ` ${entry.updateType}`),
|
|
438
|
+
socketColorName ? React.createElement(Text, { color: socketColorName }, scoreSuffix) : null
|
|
439
|
+
),
|
|
440
|
+
{ columns }
|
|
441
|
+
)}
|
|
442
|
+
`
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
process.stdout.write("\n");
|
|
446
|
+
logger.info(formatSummary(outdated));
|
|
447
|
+
if (checkedCount > outdated.length) {
|
|
448
|
+
const totalCatalogEntries = [...catalogs.values()].reduce((sum, deps) => sum + deps.size, 0);
|
|
449
|
+
const dedupeNote = totalCatalogEntries > checkedCount ? ` (${String(totalCatalogEntries)} catalog entries, ${String(totalCatalogEntries - checkedCount)} duplicates)` : "";
|
|
450
|
+
logger.info(
|
|
451
|
+
` Checked ${String(checkedCount)} unique packages${dedupeNote}: ${String(upToDate)} up-to-date${failed.length > 0 ? `, ${String(failed.length)} failed` : ""}`
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
if (filteredByTarget.length > 0) {
|
|
455
|
+
process.stdout.write("\n");
|
|
456
|
+
const skippedLabel = `${String(filteredByTarget.length)} package${filteredByTarget.length === 1 ? "" : "s"} skipped by target constraint (use --target latest to include):`;
|
|
457
|
+
process.stdout.write(`${renderToString(React.createElement(Text, { color: "yellow" }, ` ${skippedLabel}`), { columns })}
|
|
458
|
+
`);
|
|
459
|
+
for (const entry of filteredByTarget) {
|
|
460
|
+
process.stdout.write(
|
|
461
|
+
`${renderToString(
|
|
462
|
+
React.createElement(
|
|
463
|
+
Text,
|
|
464
|
+
null,
|
|
465
|
+
" ",
|
|
466
|
+
React.createElement(Text, { dimColor: true }, entry.packageName),
|
|
467
|
+
` ${entry.currentRange} → ${entry.newRange}`,
|
|
468
|
+
React.createElement(Text, { dimColor: true }, ` ${entry.updateType}`)
|
|
469
|
+
),
|
|
470
|
+
{ columns }
|
|
471
|
+
)}
|
|
472
|
+
`
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
const toApply2 = Array.isArray(exitResult) ? exitResult : [];
|
|
477
|
+
if (toApply2.length > 0 && !isDryRun) {
|
|
478
|
+
logger.info(`
|
|
479
|
+
Applying ${String(toApply2.length)} updates...
|
|
480
|
+
`);
|
|
481
|
+
const mergedOptions2 = { ...options, install: options.install ?? configDefaults.install };
|
|
482
|
+
await applyCatalogAndInstall(workspaceRoot, packageManager, toApply2, mergedOptions2, logger);
|
|
483
|
+
}
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
if (isDryRun) {
|
|
487
|
+
if (format === "json") {
|
|
488
|
+
const output = { failed, filteredByTarget, ignored, outdated };
|
|
489
|
+
if (aiResult) {
|
|
490
|
+
output.aiAnalysis = aiResult;
|
|
491
|
+
}
|
|
492
|
+
process.stdout.write(`${JSON.stringify(output, void 0, 2)}
|
|
493
|
+
`);
|
|
494
|
+
} else {
|
|
495
|
+
logger.info(`Would update ${String(outdated.length)} dependencies:
|
|
496
|
+
`);
|
|
497
|
+
writeFormattedOutput(outdated, failed, format, logger);
|
|
498
|
+
if (aiResult) {
|
|
499
|
+
logger.info("");
|
|
500
|
+
logger.info(formatAiAnalysis(aiResult));
|
|
501
|
+
}
|
|
502
|
+
logFilteredByTarget(filteredByTarget, logger);
|
|
503
|
+
}
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
if (aiResult && format !== "json") {
|
|
507
|
+
logger.info(formatAiAnalysis(aiResult));
|
|
508
|
+
logger.info("");
|
|
509
|
+
}
|
|
510
|
+
let toApply = outdated;
|
|
511
|
+
if (options.interactive) {
|
|
512
|
+
toApply = await promptPackageSelection(outdated);
|
|
513
|
+
if (toApply.length === 0) {
|
|
514
|
+
logger.info("No updates selected.");
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
logger.info(`Updating ${String(toApply.length)} catalog dependencies...
|
|
519
|
+
`);
|
|
520
|
+
writeFormattedOutput(toApply, [], format, logger);
|
|
521
|
+
logFilteredByTarget(filteredByTarget, logger);
|
|
522
|
+
const mergedOptions = { ...options, install: options.install ?? configDefaults.install };
|
|
523
|
+
await applyCatalogAndInstall(workspaceRoot, packageManager, toApply, mergedOptions, logger);
|
|
524
|
+
};
|
|
525
|
+
const executePmWrapper = (workspaceRoot, packageManager, version, options, argument, logger) => {
|
|
526
|
+
const updateOptions = {
|
|
527
|
+
dev: options.dev,
|
|
528
|
+
filters: toFilterArray(options.filter),
|
|
529
|
+
global: options.global,
|
|
530
|
+
interactive: options.interactive,
|
|
531
|
+
latest: options.latest || options.target === "latest",
|
|
532
|
+
noOptional: options.noOptional,
|
|
533
|
+
noSave: options.noSave,
|
|
534
|
+
packages: argument,
|
|
535
|
+
prod: options.prod,
|
|
536
|
+
recursive: options.recursive,
|
|
537
|
+
workspaceRoot: options.workspaceRoot
|
|
538
|
+
};
|
|
539
|
+
const { command, warnings } = resolveUpdateCommand(packageManager, version, updateOptions);
|
|
540
|
+
for (const warning of warnings) {
|
|
541
|
+
logger.warn(warning);
|
|
542
|
+
}
|
|
543
|
+
const fullCommand = `${command.bin} ${command.args.join(" ")}`.trim();
|
|
544
|
+
if (options.dryRun) {
|
|
545
|
+
logger.info(`Would run: ${fullCommand}`);
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
logger.info(`Running: ${fullCommand}`);
|
|
549
|
+
try {
|
|
550
|
+
execSync(fullCommand, {
|
|
551
|
+
cwd: workspaceRoot,
|
|
552
|
+
env: process.env,
|
|
553
|
+
stdio: "inherit"
|
|
554
|
+
});
|
|
555
|
+
} catch (error) {
|
|
556
|
+
const execError = error;
|
|
557
|
+
const exitCode = execError.status ?? 1;
|
|
558
|
+
logger.error(`
|
|
559
|
+
${red("✖")} Update failed (exit code ${String(exitCode)})`);
|
|
560
|
+
logger.error(` Command: ${fullCommand}`);
|
|
561
|
+
logger.error(` Directory: ${workspaceRoot}
|
|
562
|
+
`);
|
|
563
|
+
process.exitCode = exitCode;
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
const execute = async ({ argument: rawArgument, logger, options, visConfig, workspaceRoot: wsRoot }) => {
|
|
567
|
+
if (!wsRoot) {
|
|
568
|
+
throw new Error("Could not determine workspace root. Run this command inside a monorepo.");
|
|
569
|
+
}
|
|
570
|
+
let argument = rawArgument;
|
|
571
|
+
const workspaceRoot = wsRoot;
|
|
572
|
+
const { packageManager } = findPackageManagerSync(workspaceRoot);
|
|
573
|
+
if (!options.noTyposquatCheck) {
|
|
574
|
+
if (argument.length > 0) {
|
|
575
|
+
const parsed = argument.map((a) => parsePackageArgument(a));
|
|
576
|
+
const allowlist = visConfig?.security?.typosquatAllowlist;
|
|
577
|
+
const result = await runTyposquatCheck(
|
|
578
|
+
parsed.map((p) => p.name),
|
|
579
|
+
allowlist
|
|
580
|
+
);
|
|
581
|
+
if (!result.ok) {
|
|
582
|
+
process.exitCode = 1;
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
argument = parsed.map((p, i) => {
|
|
586
|
+
const corrected = result.packages[i];
|
|
587
|
+
if (corrected !== p.name) {
|
|
588
|
+
return p.versionSpec ? `${corrected}@${p.versionSpec}` : corrected ?? "";
|
|
589
|
+
}
|
|
590
|
+
return argument[i] ?? "";
|
|
591
|
+
});
|
|
592
|
+
} else {
|
|
593
|
+
const shouldContinue = await scanDepsForTyposquats(workspaceRoot, visConfig?.security?.typosquatAllowlist);
|
|
594
|
+
if (!shouldContinue) {
|
|
595
|
+
process.exitCode = 1;
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
if (options.rollback) {
|
|
601
|
+
if (!hasBackup(workspaceRoot, packageManager)) {
|
|
602
|
+
logger.info("No backup found. Run 'vis update' first to create a backup.");
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
const restored = restoreFromBackup(workspaceRoot, packageManager);
|
|
606
|
+
if (restored) {
|
|
607
|
+
logger.info("Restored from backup.");
|
|
608
|
+
} else {
|
|
609
|
+
throw new Error("Failed to restore from backup.");
|
|
610
|
+
}
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
const useCatalogMode = !options.noCatalog && hasCatalogs(workspaceRoot, packageManager);
|
|
614
|
+
if (useCatalogMode) {
|
|
615
|
+
await executeCatalogUpdate(
|
|
616
|
+
workspaceRoot,
|
|
617
|
+
packageManager,
|
|
618
|
+
visConfig ?? {},
|
|
619
|
+
options,
|
|
620
|
+
argument,
|
|
621
|
+
logger
|
|
622
|
+
);
|
|
623
|
+
} else {
|
|
624
|
+
const installer = resolveInstaller(workspaceRoot, { configBackend: visConfig?.install?.backend });
|
|
625
|
+
const installerVersion = installer.name === "aube" ? "" : getPackageManagerVersion(installer.name);
|
|
626
|
+
executePmWrapper(workspaceRoot, installer.name, installerVersion, options, argument, logger);
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
export { execute as default };
|