@visulima/vis 1.0.0-alpha.11 → 1.0.0-alpha.13
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 +101 -0
- package/LICENSE.md +559 -186
- package/README.md +18 -0
- package/dist/bin.js +1 -9
- package/dist/config/index.d.ts +477 -556
- package/dist/config/index.js +1 -2
- package/dist/generate/index.js +1 -3
- package/dist/packem_chunks/applyDefaults.js +2 -336
- package/dist/packem_chunks/bin.js +234 -9552
- package/dist/packem_chunks/doctor-probe.js +2 -112
- package/dist/packem_chunks/fix.js +11 -234
- package/dist/packem_chunks/handler.js +1 -99
- package/dist/packem_chunks/handler10.js +2 -53
- package/dist/packem_chunks/handler11.js +1 -32
- package/dist/packem_chunks/handler12.js +5 -100
- package/dist/packem_chunks/handler13.js +1 -25
- package/dist/packem_chunks/handler14.js +18 -916
- package/dist/packem_chunks/handler15.js +15 -201
- package/dist/packem_chunks/handler16.js +1 -124
- package/dist/packem_chunks/handler17.js +1 -13
- package/dist/packem_chunks/handler18.js +1 -106
- package/dist/packem_chunks/handler19.js +1 -19
- package/dist/packem_chunks/handler2.js +2 -75
- package/dist/packem_chunks/handler20.js +5 -29
- package/dist/packem_chunks/handler21.js +1 -222
- package/dist/packem_chunks/handler22.js +1 -237
- package/dist/packem_chunks/handler23.js +5 -101
- package/dist/packem_chunks/handler24.js +1 -110
- package/dist/packem_chunks/handler25.js +3 -402
- package/dist/packem_chunks/handler26.js +1 -13
- package/dist/packem_chunks/handler27.js +1 -63
- package/dist/packem_chunks/handler28.js +7 -34
- package/dist/packem_chunks/handler29.js +21 -456
- package/dist/packem_chunks/handler3.js +4 -95
- package/dist/packem_chunks/handler30.js +3 -170
- package/dist/packem_chunks/handler31.js +1 -530
- package/dist/packem_chunks/handler32.js +2 -214
- package/dist/packem_chunks/handler33.js +25 -119
- package/dist/packem_chunks/handler34.js +2 -630
- package/dist/packem_chunks/handler35.js +3 -283
- package/dist/packem_chunks/handler36.js +22 -542
- package/dist/packem_chunks/handler37.js +410 -744
- package/dist/packem_chunks/handler38.js +22 -989
- package/dist/packem_chunks/handler39.js +22 -574
- package/dist/packem_chunks/handler4.js +2 -90
- package/dist/packem_chunks/handler40.js +22 -1685
- package/dist/packem_chunks/handler41.js +6 -1088
- package/dist/packem_chunks/handler42.js +5 -797
- package/dist/packem_chunks/handler43.js +10 -2658
- package/dist/packem_chunks/handler44.js +51 -3784
- package/dist/packem_chunks/handler45.js +25 -2574
- package/dist/packem_chunks/handler46.js +3 -3769
- package/dist/packem_chunks/handler47.js +21 -1485
- package/dist/packem_chunks/handler48.js +42 -0
- package/dist/packem_chunks/handler5.js +8 -174
- package/dist/packem_chunks/handler6.js +1 -95
- package/dist/packem_chunks/handler7.js +1 -115
- package/dist/packem_chunks/handler8.js +1 -12
- package/dist/packem_chunks/handler9.js +1 -29
- package/dist/packem_chunks/heal-accept.js +10 -522
- package/dist/packem_chunks/heal.js +14 -673
- package/dist/packem_chunks/index.js +7 -873
- package/dist/packem_chunks/loader.js +1 -23
- package/dist/packem_chunks/tar.js +3 -0
- package/dist/packem_shared/ai-analysis-hm8d2W7z.js +67 -0
- package/dist/packem_shared/ai-cache-DoiF80AR.js +1 -0
- package/dist/packem_shared/ai-fix-nn4zOE95.js +43 -0
- package/dist/packem_shared/cache-directory-CwHlJhgx.js +1 -0
- package/dist/packem_shared/dependency-scan-COr5n63B.js +2 -0
- package/dist/packem_shared/docker-D6OGr5_S.js +2 -0
- package/dist/packem_shared/failure-log-iUVLf6ts.js +2 -0
- package/dist/packem_shared/flakiness-D9wf0t56.js +1 -0
- package/dist/packem_shared/giget-CcEy_Elm.js +2 -0
- package/dist/packem_shared/index-DH-5hsrC.js +1 -0
- package/dist/packem_shared/otel-DxDUPJJH.js +6 -0
- package/dist/packem_shared/otelPlugin-CQq6poq8.js +1 -0
- package/dist/packem_shared/registry-CkubDdiY.js +2 -0
- package/dist/packem_shared/run-summary-utils-BfBvjzhY.js +1 -0
- package/dist/packem_shared/runtime-check-BXZ43CBW.js +1 -0
- package/dist/packem_shared/selectors-BylODRiM.js +3 -0
- package/dist/packem_shared/symbols-CQmER5MT.js +1 -0
- package/dist/packem_shared/toolchain-BgBOUHII.js +5 -0
- package/dist/packem_shared/typosquats-CcZl99B1.js +1 -0
- package/dist/packem_shared/use-measured-height-DjYgUOKk.js +1 -0
- package/dist/packem_shared/utils-DrNg0XTR.js +1 -0
- package/dist/packem_shared/verify-Baj5mFJ7.js +1 -0
- package/dist/packem_shared/vis-update-app-D1jl0UZZ.js +1 -0
- package/dist/packem_shared/xxh3-DrAUNq4n.js +1 -0
- package/index.js +556 -727
- package/package.json +19 -29
- package/schemas/project.schema.json +739 -297
- package/schemas/vis-config.schema.json +3365 -384
- package/templates/buildkite-ci/template.yml +20 -20
- package/dist/packem_shared/VisUpdateApp-D-Yz_wvg.js +0 -1316
- package/dist/packem_shared/_commonjsHelpers-BqLXS_qQ.js +0 -5
- package/dist/packem_shared/ai-analysis-CHeB1joD.js +0 -367
- package/dist/packem_shared/ai-cache-Be_jexe4.js +0 -142
- package/dist/packem_shared/ai-fix-B9iQVcD2.js +0 -379
- package/dist/packem_shared/cache-directory-2qvs4goY.js +0 -98
- package/dist/packem_shared/catalog-BJTtyi-O.js +0 -1371
- package/dist/packem_shared/dependency-scan-A0KSklpG.js +0 -188
- package/dist/packem_shared/docker-2iZzc280.js +0 -181
- package/dist/packem_shared/failure-log-Cz3Z4SKL.js +0 -100
- package/dist/packem_shared/flakiness-goTxXuCX.js +0 -180
- package/dist/packem_shared/otel-DCvqCTz_.js +0 -158
- package/dist/packem_shared/otelPlugin-DFaLDvJf.js +0 -3
- package/dist/packem_shared/registry-CbqXI0rc.js +0 -272
- package/dist/packem_shared/run-summary-utils-PVMl4aIh.js +0 -130
- package/dist/packem_shared/runtime-check-Cobi3p6l.js +0 -127
- package/dist/packem_shared/selectors-SM69TfqC.js +0 -194
- package/dist/packem_shared/symbols-Ta7g2nU-.js +0 -14
- package/dist/packem_shared/toolchain-BdZd9eBi.js +0 -975
- package/dist/packem_shared/typosquats-C-bCh3PX.js +0 -1210
- package/dist/packem_shared/use-measured-height-CNP0vT4M.js +0 -20
- package/dist/packem_shared/utils-CthVdBPS.js +0 -40
- package/dist/packem_shared/xxh3-Ck8mXNg1.js +0 -239
|
@@ -1,630 +1,2 @@
|
|
|
1
|
-
import {
|
|
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 };
|
|
1
|
+
var L=Object.defineProperty;var h=(e,t)=>L(e,"name",{value:t,configurable:!0});import{createRequire as O}from"node:module";import{isAccessible as V}from"@visulima/fs";import{p as d,ai as z,k as q,aj as B}from"./bin.js";import{join as W}from"@visulima/path";import{R as H,w as F,r as R,i as m,d as $,g as J,s as K,a as Y,b as I,S as Q,c as X,p as Z}from"../packem_shared/registry-CkubDdiY.js";import{formatAge as te}from"./handler14.js";const G=O(import.meta.url),y=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,T=h(e=>{if(typeof y<"u"&&y.versions&&y.versions.node){const[t,r]=y.versions.node.split(".").map(Number);if(t>22||t===22&&r>=3||t===20&&r>=16)return y.getBuiltinModule(e)}return G(e)},"__cjs_getBuiltinModule"),{open:E,stat:x,watch:U}=T("node:fs/promises"),{spawn:ee}=T("node:child_process");var re=Object.defineProperty,oe=h((e,t)=>re(e,"name",{value:t,configurable:!0}),"i");const b=process.platform==="win32",se=oe(async e=>{const{command:t,cwd:r,env:n,logFile:a}=e,o=await E(a,"a",H);let s;try{s=ee(b?"cmd":"/bin/sh",b?["/d","/s","/c",t]:["-c",t],{cwd:r,detached:!0,env:{...process.env,...n},stdio:["ignore",o.fd,o.fd],windowsHide:!0})}finally{await o.close().catch(()=>{})}if(s.pid===void 0&&await new Promise((i,c)=>{s.once("spawn",()=>{i()}),s.once("error",g=>{c(g)})}),s.pid===void 0)throw new Error(`Failed to spawn detached process for command: ${t}`);return s.unref(),{pid:s.pid}},"spawnDetached");var ie=Object.defineProperty,S=h((e,t)=>ie(e,"name",{value:t,configurable:!0}),"t");const _=5e3,D=S(async e=>F(e.workspaceRoot,e.id,async()=>{const t=await R(e.workspaceRoot,e.id);if(t&&m(t.pid))throw new Error(`Service ${e.id} is already running (pid ${String(t.pid)})`);t&&await $(e.workspaceRoot,e.id,t);const r=await J(e.workspaceRoot),n=K(e.id),a=W(r,`${n}.log`),{pid:o}=await se({command:e.command,cwd:e.cwd,env:e.env,logFile:a}),s={command:e.command,config:e.config,cwd:e.cwd,env:e.config.env??{},id:e.id,logFile:a,pid:o,slug:n,startedAt:new Date().toISOString(),visVersion:process.env.VIS_VERSION??"0.0.0"};if(await Y(e.workspaceRoot,s),e.skipReadiness!==!0)try{await I(e.config,{timeoutMs:e.readinessTimeoutMs})}catch(i){throw await P(o,e.config.killGracePeriodMs??_).catch(()=>{}),await $(e.workspaceRoot,e.id,s).catch(()=>{}),i}return{entry:s}}),"startService"),N=S(async e=>F(e.workspaceRoot,e.id,async()=>{const t=await R(e.workspaceRoot,e.id);if(!t)return{stopped:!1};if(!m(t.pid))return await $(e.workspaceRoot,e.id,t),{stopped:!1};const r=e.graceMs??t.config.killGracePeriodMs??_;return await P(t.pid,r),await $(e.workspaceRoot,e.id,t),{stopped:!0}}),"stopService"),P=S(async(e,t)=>{M(e,"SIGTERM");const r=Date.now();for(;Date.now()-r<t;){if(!m(e))return;await new Promise(n=>{setTimeout(n,100)})}m(e)&&M(e,"SIGKILL")},"stopServiceByPid"),M=S((e,t)=>{try{process.platform==="win32"?process.kill(e,t):process.kill(-e,t)}catch(r){if(r.code==="ESRCH")return;throw r}},"sendSignalToServiceGroup");var ae=Object.defineProperty,l=h((e,t)=>ae(e,"name",{value:t,configurable:!0}),"g");const ne=l(e=>{const t=e.trim(),r=t.lastIndexOf(":");if(!(r<=0||r===t.length-1))return{project:t.slice(0,r),target:t.slice(r+1)}},"splitTargetId"),ce=l((e,t,r)=>r||!t?e:t.startsWith("/")?t:`${e}/${t}`,"resolveCwd"),A=l(async(e,t,r)=>{const n=ne(r);if(!n){d.error(`Invalid target id "${r}". Expected "<project>:<target>", e.g. "@my/api:db".`);return}const a=await z(e),{projectOptions:o,workspace:s}=q(e,t,a),i=s.projects[n.project],c=o.get(n.project)?.[n.target];if(!i||!c){d.error(`Target "${r}" not found in this workspace.`);return}const g=c.options?.service;if(!g){d.error(`Target "${r}" is not a service. Add an \`options.service\` block to make it eligible for \`vis service\`.`);return}if(!c.command){d.error(`Target "${r}" has no command — services must be runnable.`);return}const f=ce(e,i.root,c.options?.runFromWorkspaceRoot===!0),w=c.options?.envFile?B(f,c.options.envFile):{};return{command:c.command,cwd:f,env:{...w,...g.env},service:g,target:c,targetId:r}},"resolveTarget"),v=l(e=>{if(!e)throw new Error("Could not determine workspace root. Run `vis service` inside a workspace.");return e},"requireWorkspace"),$e=l(async({argument:e,options:t,visConfig:r,workspaceRoot:n})=>{const a=v(n),o=e[0]?.trim();if(!o){d.error("Missing target id. Usage: vis service start <project>:<target>"),process.exitCode=1;return}const s=await A(a,r,o);if(!s){process.exitCode=1;return}try{const{entry:i}=await D({command:s.command,config:s.service,cwd:s.cwd,env:s.env,id:o,readinessTimeoutMs:t.timeout,skipReadiness:t.noReadiness===!0,workspaceRoot:a});d.success(`Started ${o} (pid ${String(i.pid)})`),d.info(` log: ${i.logFile}`)}catch(i){const c=i instanceof Error?i.message:String(i);i instanceof Q?d.error(`Readiness probe failed for ${o}: ${c}`):d.error(`Failed to start ${o}: ${c}`),process.exitCode=1}},"serviceStartExecute"),C=l(async(e,t,r)=>{const{stopped:n}=await N({graceMs:r,id:t,workspaceRoot:e});return n?(d.success(`Stopped ${t}`),!0):(d.info(`No running service registered for ${t}`),!1)},"stopOne"),Re=l(async({argument:e,options:t,workspaceRoot:r})=>{const n=v(r),{graceMs:a}=t,o=e[0]?.trim();if(t.all===!0){if(o){d.error("Cannot combine --all with a target id. Use one or the other."),process.exitCode=1;return}const s=await X(n);if(s.length===0){d.info("No running services registered for this workspace.");return}for(const i of s)await C(n,i.id,a);return}if(!o){d.error("Missing target id. Usage: vis service stop <project>:<target> | --all"),process.exitCode=1;return}await C(n,o,a)||(process.exitCode=1)},"serviceStopExecute"),de=l(e=>{const t=e.config.readiness?.tcp.port??e.config.port;return t===void 0?"—":String(t)},"formatPort"),j=new Set(["json","table"]),Se=l(async({logger:e,options:t,workspaceRoot:r})=>{const n=v(r),a=t.format??"table";if(!j.has(a)){d.error(`Invalid --format "${a}". Expected one of: ${[...j].sort().join(", ")}.`),process.exitCode=1;return}const{surviving:o}=await Z(n);if(a==="json"){const p=Date.now();process.stdout.write(`${JSON.stringify(o.map(u=>{const k=Date.parse(u.startedAt);return{ageMs:Number.isFinite(k)?p-k:null,alive:m(u.pid),command:u.command,cwd:u.cwd,env:u.env,id:u.id,logFile:u.logFile,pid:u.pid,port:u.config.readiness?.tcp.port??u.config.port??null,startedAt:u.startedAt,visVersion:u.visVersion}}),void 0,2)}
|
|
2
|
+
`);return}if(o.length===0){d.info("No running services registered for this workspace.");return}const s=Date.now(),i=o.map(p=>{const u=Date.parse(p.startedAt);return{age:Number.isFinite(u)?te(u,s):"?",id:p.id,log:p.logFile,pid:String(p.pid),port:de(p)}}),c=Math.max(2,...i.map(p=>p.id.length)),g=Math.max(3,...i.map(p=>p.pid.length)),f=Math.max(4,...i.map(p=>p.port.length)),w=Math.max(3,...i.map(p=>p.age.length));e.info(` ${"id".padEnd(c)} ${"pid".padEnd(g)} ${"port".padEnd(f)} ${"age".padEnd(w)} log`),e.info(` ${"-".repeat(c)} ${"-".repeat(g)} ${"-".repeat(f)} ${"-".repeat(w)} ---`);for(const p of i)e.info(` ${p.id.padEnd(c)} ${p.pid.padEnd(g)} ${p.port.padEnd(f)} ${p.age.padEnd(w)} ${p.log}`)},"serviceListExecute"),Ee=l(async({argument:e,options:t,workspaceRoot:r})=>{const n=v(r),a=e[0]?.trim();if(!a){d.error("Missing target id. Usage: vis service status <project>:<target>"),process.exitCode=1;return}const o=await R(n,a);if(!o){d.error(`No service registered for ${a}.`),process.exitCode=1;return}if(!m(o.pid)){d.error(`Service ${a} is not running (pid ${String(o.pid)} is dead). Run \`vis service start ${a}\` to recover.`),process.exitCode=1;return}try{await I(o.config,{timeoutMs:t.timeout}),d.success(`${a} healthy (pid ${String(o.pid)})`)}catch(s){const i=s instanceof Error?s.message:String(s);d.error(`${a} probe failed: ${i}`),process.exitCode=1}},"serviceStatusExecute"),ke=l(async({argument:e,options:t,visConfig:r,workspaceRoot:n})=>{const a=v(n),o=e[0]?.trim();if(!o){d.error("Missing target id. Usage: vis service restart <project>:<target>"),process.exitCode=1;return}await N({graceMs:t.graceMs,id:o,workspaceRoot:a});const s=await A(a,r,o);if(!s){process.exitCode=1;return}try{const{entry:i}=await D({command:s.command,config:s.service,cwd:s.cwd,env:s.env,id:o,readinessTimeoutMs:t.timeout,skipReadiness:t.noReadiness===!0,workspaceRoot:a});d.success(`Restarted ${o} (pid ${String(i.pid)})`)}catch(i){const c=i instanceof Error?i.message:String(i);d.error(`Failed to restart ${o}: ${c}`),process.exitCode=1}},"serviceRestartExecute"),pe=200,ge=1024*1024,le=l(async e=>{let t=0;try{t=(await x(e)).size}catch{t=0}const r=new AbortController;let n=!1;const a=l(()=>{n=!0,r.abort()},"onSigint"),o=l(()=>{r.abort()},"onSigterm");process.on("SIGINT",a),process.on("SIGTERM",o);let s=!1;const i=l(async()=>{if(!s){s=!0;try{const c=await x(e).catch(()=>{});if(!c||(c.size<t&&(t=0),c.size===t))return;const g=c.size-t,f=Math.min(g,ge),w=await E(e,"r");try{const p=Buffer.alloc(f);await w.read(p,0,f,t),process.stdout.write(p),t+=f}finally{await w.close().catch(()=>{})}}finally{s=!1}}},"tickOnce");try{const c=(async()=>{try{const g=U(e,{signal:r.signal});for(;!(await g.next()).done;)await i()}catch{}})();for(;!r.signal.aborted;)await i(),await new Promise(g=>{const f=setTimeout(g,pe);r.signal.addEventListener("abort",()=>{clearTimeout(f),g()},{once:!0})});await c.catch(()=>{}),await i().catch(()=>{})}finally{process.off("SIGINT",a),process.off("SIGTERM",o)}n&&(process.exitCode=130)},"tailLog"),xe=l(async({argument:e,options:t,workspaceRoot:r})=>{const n=v(r),a=e[0]?.trim();if(!a){d.error("Missing target id. Usage: vis service logs <project>:<target>"),process.exitCode=1;return}const o=await R(n,a);if(!o){d.error(`No service registered for ${a}.`),process.exitCode=1;return}if(!await V(o.logFile)){d.warn(`Log file is missing for ${a}: ${o.logFile}`),process.exitCode=1;return}if(t.follow===!0){await le(o.logFile);return}const s=await E(o.logFile,"r");try{const i=s.createReadStream();await new Promise((c,g)=>{i.on("end",c),i.on("error",g),i.pipe(process.stdout,{end:!1})})}finally{await s.close().catch(()=>{})}},"serviceLogsExecute");export{Se as serviceListExecute,xe as serviceLogsExecute,ke as serviceRestartExecute,$e as serviceStartExecute,Ee as serviceStatusExecute,Re as serviceStopExecute};
|