@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,206 @@
|
|
|
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
|
+
const {
|
|
24
|
+
createInterface
|
|
25
|
+
} = __cjs_getBuiltinModule("node:readline");
|
|
26
|
+
import { isAccessibleSync, writeFileSync } from '@visulima/fs';
|
|
27
|
+
import { join } from '@visulima/path';
|
|
28
|
+
import { findVisConfigFile } from './applyDefaults.js';
|
|
29
|
+
import { c as detectPm, p as pail, s as scanUnapprovedBuildScripts, e as syncAllowBuildsToNativeConfig } from './bin.js';
|
|
30
|
+
|
|
31
|
+
const detectExistingTools = (cwd) => {
|
|
32
|
+
const found = [];
|
|
33
|
+
if (isAccessibleSync(join(cwd, "turbo.json"))) {
|
|
34
|
+
found.push("turborepo");
|
|
35
|
+
}
|
|
36
|
+
if (isAccessibleSync(join(cwd, "nx.json"))) {
|
|
37
|
+
found.push("nx");
|
|
38
|
+
}
|
|
39
|
+
if (isAccessibleSync(join(cwd, ".moon"))) {
|
|
40
|
+
found.push("moon");
|
|
41
|
+
}
|
|
42
|
+
return found;
|
|
43
|
+
};
|
|
44
|
+
const ask = (rl, question) => new Promise((resolve) => {
|
|
45
|
+
rl.question(question, (answer) => {
|
|
46
|
+
resolve(answer.trim());
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
const confirm = async (rl, question, defaultYes = true) => {
|
|
50
|
+
const hint = defaultYes ? "[Y/n]" : "[y/N]";
|
|
51
|
+
const answer = await ask(rl, `${question} ${hint} `);
|
|
52
|
+
if (answer === "") {
|
|
53
|
+
return defaultYes;
|
|
54
|
+
}
|
|
55
|
+
return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
|
|
56
|
+
};
|
|
57
|
+
const generateConfigContent = (_pm, options) => {
|
|
58
|
+
const sections = [];
|
|
59
|
+
const allowBuildsEntries = Object.entries(options.allowBuilds).filter(([, v]) => v).map(([k]) => ` "${k}": true,`).join("\n");
|
|
60
|
+
const allowBuildsBlock = allowBuildsEntries ? `{
|
|
61
|
+
${allowBuildsEntries}
|
|
62
|
+
}` : "{}";
|
|
63
|
+
let securityBlock = ` allowBuilds: ${allowBuildsBlock},`;
|
|
64
|
+
if (options.enableSocket) {
|
|
65
|
+
securityBlock += `
|
|
66
|
+
socket: { enabled: true },`;
|
|
67
|
+
}
|
|
68
|
+
sections.push(` security: {
|
|
69
|
+
${securityBlock}
|
|
70
|
+
},`);
|
|
71
|
+
if (options.staged) {
|
|
72
|
+
sections.push(` staged: {
|
|
73
|
+
"*.{ts,tsx}": "eslint --fix",
|
|
74
|
+
"*.{ts,tsx,js,jsx,json,md}": "prettier --write",
|
|
75
|
+
},`);
|
|
76
|
+
}
|
|
77
|
+
return `import { defineConfig } from "@visulima/vis/config";
|
|
78
|
+
|
|
79
|
+
export default defineConfig({
|
|
80
|
+
${sections.join("\n\n")}
|
|
81
|
+
});
|
|
82
|
+
`;
|
|
83
|
+
};
|
|
84
|
+
const runInteractiveInit = async (cwd, pm, configPath) => {
|
|
85
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
86
|
+
pail.info("\n vis init — interactive setup\n");
|
|
87
|
+
const enableSocket = await confirm(rl, " Enable Socket.dev security scanning?");
|
|
88
|
+
if (enableSocket) {
|
|
89
|
+
pail.success(" Socket.dev enabled — scores, alerts, and supply chain data active.");
|
|
90
|
+
if (!process.env.VIS_SOCKET_TOKEN) {
|
|
91
|
+
pail.notice(" Set VIS_SOCKET_TOKEN for a custom API token (optional).");
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
pail.info("");
|
|
95
|
+
const scanBuilds = await confirm(rl, " Scan for packages with build scripts?");
|
|
96
|
+
const allowBuilds = {};
|
|
97
|
+
if (scanBuilds) {
|
|
98
|
+
pail.info(" Scanning node_modules...");
|
|
99
|
+
const unapproved = scanUnapprovedBuildScripts(cwd, {});
|
|
100
|
+
if (unapproved.length > 0) {
|
|
101
|
+
pail.info(` Found ${String(unapproved.length)} package${unapproved.length === 1 ? "" : "s"} with build scripts:
|
|
102
|
+
`);
|
|
103
|
+
for (const pkg of unapproved) {
|
|
104
|
+
const answer = await confirm(rl, ` Allow ${pkg}?`, false);
|
|
105
|
+
const pkgName = pkg.split(" (")[0] ?? pkg;
|
|
106
|
+
allowBuilds[pkgName] = answer;
|
|
107
|
+
if (answer) {
|
|
108
|
+
pail.success(` ✓ ${pkgName} approved`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
pail.info(" No packages with build scripts found.");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
pail.info("");
|
|
116
|
+
const setupStaged = await confirm(rl, " Set up pre-commit hooks (lint-staged)?", false);
|
|
117
|
+
let syncNative = false;
|
|
118
|
+
if (pm.name === "pnpm" || pm.name === "yarn" || pm.name === "npm" || pm.name === "bun") {
|
|
119
|
+
pail.info("");
|
|
120
|
+
syncNative = await confirm(rl, ` Sync security settings to ${pm.name} config?`);
|
|
121
|
+
}
|
|
122
|
+
const existingTools = detectExistingTools(cwd);
|
|
123
|
+
if (existingTools.length > 0) {
|
|
124
|
+
pail.info("");
|
|
125
|
+
pail.info(` Detected existing tools: ${existingTools.join(", ")}`);
|
|
126
|
+
const shouldMigrate = await confirm(rl, ` Run \`vis migrate\` for ${existingTools.join(", ")}?`, false);
|
|
127
|
+
if (shouldMigrate) {
|
|
128
|
+
rl.close();
|
|
129
|
+
const execPrefix = pm.name === "pnpm" ? "pnpm exec" : pm.name === "yarn" ? "yarn exec" : pm.name === "bun" ? "bunx" : "npx";
|
|
130
|
+
for (const tool of existingTools) {
|
|
131
|
+
pail.info(` Migrating from ${tool}...`);
|
|
132
|
+
try {
|
|
133
|
+
execSync(`${execPrefix} vis migrate ${tool}`, {
|
|
134
|
+
cwd,
|
|
135
|
+
stdio: "inherit"
|
|
136
|
+
});
|
|
137
|
+
} catch {
|
|
138
|
+
pail.warn(` Migration from ${tool} had issues — run \`vis migrate ${tool}\` manually.`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (isAccessibleSync(configPath)) {
|
|
142
|
+
pail.success(`Migrated config written to ${configPath}`);
|
|
143
|
+
} else {
|
|
144
|
+
const content2 = generateConfigContent(pm.name, { allowBuilds, enableSocket, staged: setupStaged });
|
|
145
|
+
writeFileSync(configPath, content2);
|
|
146
|
+
pail.success(`Created ${configPath}`);
|
|
147
|
+
}
|
|
148
|
+
pail.notice(" Run 'vis doctor' to see your project's full health status.");
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
rl.close();
|
|
153
|
+
pail.info("");
|
|
154
|
+
const content = generateConfigContent(pm.name, { allowBuilds, enableSocket, staged: setupStaged });
|
|
155
|
+
writeFileSync(configPath, content);
|
|
156
|
+
pail.success(`Created ${configPath}`);
|
|
157
|
+
if (syncNative) {
|
|
158
|
+
const approvedBuilds = Object.fromEntries(Object.entries(allowBuilds).filter(([, v]) => v));
|
|
159
|
+
const actions = syncAllowBuildsToNativeConfig(pm.name, cwd, approvedBuilds);
|
|
160
|
+
for (const action of actions) {
|
|
161
|
+
pail.success(` ${action}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
pail.info("");
|
|
165
|
+
pail.info(" Setup complete. Your config:");
|
|
166
|
+
pail.info(` Security: ${enableSocket ? "Socket.dev enabled" : "defaults only"}`);
|
|
167
|
+
pail.info(` Build scripts: ${Object.values(allowBuilds).filter(Boolean).length} approved`);
|
|
168
|
+
pail.info(` Git hooks: ${setupStaged ? "lint-staged configured" : "not configured"}`);
|
|
169
|
+
pail.info(` PM sync: ${syncNative ? "done" : "skipped"}`);
|
|
170
|
+
pail.info("");
|
|
171
|
+
pail.notice(" Run 'vis doctor' to see your project's full health status.");
|
|
172
|
+
pail.info("");
|
|
173
|
+
};
|
|
174
|
+
const runStaticInit = (cwd, pm, options, configPath) => {
|
|
175
|
+
const content = generateConfigContent(pm.name, { allowBuilds: {}, enableSocket: false, staged: false });
|
|
176
|
+
writeFileSync(configPath, content);
|
|
177
|
+
pail.success(`Created ${configPath}`);
|
|
178
|
+
pail.info(" Secure defaults applied automatically by defineConfig().");
|
|
179
|
+
if (options.syncNative) {
|
|
180
|
+
const actions = syncAllowBuildsToNativeConfig(pm.name, cwd, {});
|
|
181
|
+
for (const action of actions) {
|
|
182
|
+
pail.success(` ${action}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
pail.info("");
|
|
186
|
+
pail.notice("Run 'vis doctor' for a full health check, or 'vis init' in a terminal for guided setup.");
|
|
187
|
+
};
|
|
188
|
+
const execute = async ({ options, workspaceRoot: wsRoot }) => {
|
|
189
|
+
const cwd = wsRoot ?? process.cwd();
|
|
190
|
+
const pm = detectPm(cwd);
|
|
191
|
+
const existingConfig = findVisConfigFile(cwd);
|
|
192
|
+
if (existingConfig && !options.force) {
|
|
193
|
+
pail.warn(`Config already exists: ${existingConfig}`);
|
|
194
|
+
pail.notice("Use --force to overwrite, or edit the existing file.");
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const configPath = existingConfig ?? join(cwd, "vis.config.ts");
|
|
198
|
+
const isTTY = Boolean(process.stdin.isTTY) && options.interactive !== false;
|
|
199
|
+
if (isTTY && !options.noInteractive) {
|
|
200
|
+
await runInteractiveInit(cwd, pm, configPath);
|
|
201
|
+
} else {
|
|
202
|
+
runStaticInit(cwd, pm, options, configPath);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export { execute as default };
|
|
@@ -0,0 +1,124 @@
|
|
|
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
|
+
rmSync
|
|
22
|
+
} = __cjs_getBuiltinModule("node:fs");
|
|
23
|
+
import { isAccessibleSync } from '@visulima/fs';
|
|
24
|
+
import { join, dirname, parse } from '@visulima/path';
|
|
25
|
+
import { p as pail, c as detectPm, r as resolveInstaller, w as detectLockfileDrift, x as runInstall } from './bin.js';
|
|
26
|
+
import { s as scanDepsForTyposquats } from '../packem_shared/typosquats-C-bCh3PX.js';
|
|
27
|
+
import { t as toStringArray } from '../packem_shared/utils-CthVdBPS.js';
|
|
28
|
+
|
|
29
|
+
const LOCKFILE_NAMES = ["pnpm-lock.yaml", "yarn.lock", "package-lock.json", "npm-shrinkwrap.json", "bun.lock", "bun.lockb"];
|
|
30
|
+
const hasLockfile = (start) => {
|
|
31
|
+
let dir = start;
|
|
32
|
+
while (true) {
|
|
33
|
+
for (const name of LOCKFILE_NAMES) {
|
|
34
|
+
if (isAccessibleSync(join(dir, name))) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const parent = dirname(dir);
|
|
39
|
+
if (parent === dir || parse(dir).root === dir) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
dir = parent;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const ALLOWED_BACKENDS = /* @__PURE__ */ new Set(["aube", "auto", "bun", "npm", "pnpm", "yarn"]);
|
|
46
|
+
const execute = async ({ logger, options, visConfig, workspaceRoot: wsRoot }) => {
|
|
47
|
+
const cwd = wsRoot ?? process.cwd();
|
|
48
|
+
if (!options.noTyposquatCheck) {
|
|
49
|
+
const shouldContinue = await scanDepsForTyposquats(cwd, visConfig?.security?.typosquatAllowlist);
|
|
50
|
+
if (!shouldContinue) {
|
|
51
|
+
process.exitCode = 1;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const flagBackendRaw = options.installer;
|
|
56
|
+
if (flagBackendRaw && !ALLOWED_BACKENDS.has(flagBackendRaw)) {
|
|
57
|
+
pail.error(`Invalid --installer value: "${flagBackendRaw}". Expected one of: ${[...ALLOWED_BACKENDS].join(", ")}.`);
|
|
58
|
+
process.exitCode = 1;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const flagBackend = flagBackendRaw;
|
|
62
|
+
const noAube = options.noAube || false;
|
|
63
|
+
let pm;
|
|
64
|
+
try {
|
|
65
|
+
pm = noAube ? detectPm(cwd) : resolveInstaller(cwd, { backend: flagBackend, configBackend: visConfig?.install?.backend });
|
|
66
|
+
} catch (error) {
|
|
67
|
+
pail.error(error instanceof Error ? error.message : String(error));
|
|
68
|
+
process.exitCode = 1;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const driftWarning = detectLockfileDrift(cwd, pm);
|
|
72
|
+
if (driftWarning) {
|
|
73
|
+
pail.warn(driftWarning);
|
|
74
|
+
}
|
|
75
|
+
const filters = toStringArray(options.filter);
|
|
76
|
+
const ciMode = options.ci || false;
|
|
77
|
+
const explicitFrozen = options.frozenLockfile || ciMode;
|
|
78
|
+
const optedOutOfFrozen = options.noFrozenLockfile || options.force || options.lockfileOnly;
|
|
79
|
+
const lockfilePresent = hasLockfile(cwd);
|
|
80
|
+
const shouldFreeze = explicitFrozen || !optedOutOfFrozen && lockfilePresent;
|
|
81
|
+
if (!explicitFrozen && shouldFreeze && !options.silent) {
|
|
82
|
+
pail.info("Defaulting to frozen lockfile (pass --no-frozen-lockfile to allow lockfile updates).");
|
|
83
|
+
}
|
|
84
|
+
if (ciMode) {
|
|
85
|
+
pail.info("Clean install: removing node_modules...");
|
|
86
|
+
try {
|
|
87
|
+
rmSync(join(cwd, "node_modules"), { force: true, recursive: true });
|
|
88
|
+
} catch (error) {
|
|
89
|
+
pail.error(`Failed to remove node_modules: ${error instanceof Error ? error.message : String(error)}`);
|
|
90
|
+
process.exitCode = 1;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const code = runInstall(
|
|
95
|
+
pm,
|
|
96
|
+
{
|
|
97
|
+
dev: options.dev || false,
|
|
98
|
+
filter: filters,
|
|
99
|
+
force: options.force || false,
|
|
100
|
+
frozenLockfile: shouldFreeze,
|
|
101
|
+
// Block-by-default lifecycle scripts (mirrors pnpm v10).
|
|
102
|
+
// Allowlisted packages from `security.allowBuilds` are executed
|
|
103
|
+
// post-install by the `security-enforcement` plugin's
|
|
104
|
+
// afterCommand hook (`runApprovedScripts`). The escape hatch
|
|
105
|
+
// is `--run-scripts`, which restores the PM's native behavior.
|
|
106
|
+
ignoreScripts: !options.runScripts,
|
|
107
|
+
lockfileOnly: options.lockfileOnly || false,
|
|
108
|
+
noOptional: options.noOptional || false,
|
|
109
|
+
offline: options.offline || false,
|
|
110
|
+
prod: options.prod || false,
|
|
111
|
+
recursive: options.recursive || false,
|
|
112
|
+
silent: options.silent || false,
|
|
113
|
+
workspaceRoot: options.workspaceRoot || false
|
|
114
|
+
},
|
|
115
|
+
cwd,
|
|
116
|
+
logger,
|
|
117
|
+
{ preferOffline: options.preferOffline || false }
|
|
118
|
+
);
|
|
119
|
+
if (code !== 0) {
|
|
120
|
+
process.exitCode = code;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export { execute as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { r as resolveInstaller, y as runLink } from './bin.js';
|
|
2
|
+
|
|
3
|
+
const execute = async ({ argument, logger, visConfig, workspaceRoot: wsRoot }) => {
|
|
4
|
+
const target = argument?.[0] ?? null;
|
|
5
|
+
const cwd = wsRoot ?? process.cwd();
|
|
6
|
+
const pm = resolveInstaller(cwd, { configBackend: visConfig?.install?.backend });
|
|
7
|
+
const code = runLink(pm, target, cwd, logger);
|
|
8
|
+
if (code !== 0) {
|
|
9
|
+
process.exitCode = code;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export { execute as default };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { d as discoverWorkspace } from './bin.js';
|
|
2
|
+
import { f as filterProjectsByQuery } from '../packem_shared/selectors-SM69TfqC.js';
|
|
3
|
+
|
|
4
|
+
const execute = async ({ logger, options, visConfig, workspaceRoot: wsRoot }) => {
|
|
5
|
+
if (!wsRoot) {
|
|
6
|
+
throw new Error("Could not determine workspace root.");
|
|
7
|
+
}
|
|
8
|
+
const { projectOptions, workspace } = discoverWorkspace(wsRoot, visConfig);
|
|
9
|
+
let projectNames = Object.keys(workspace.projects).sort();
|
|
10
|
+
if (options.query) {
|
|
11
|
+
projectNames = filterProjectsByQuery(projectNames, workspace, options.query);
|
|
12
|
+
}
|
|
13
|
+
if (projectNames.length === 0) {
|
|
14
|
+
logger.info("No projects found.");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const inferredOnly = options.inferred === true;
|
|
18
|
+
const showTargets = options.targets === true || inferredOnly;
|
|
19
|
+
if (options.json) {
|
|
20
|
+
const data = projectNames.map((name) => {
|
|
21
|
+
const project = workspace.projects[name];
|
|
22
|
+
const visTargets = projectOptions.get(name) ?? {};
|
|
23
|
+
const targets = Object.entries(project.targets ?? {}).map(([targetName]) => {
|
|
24
|
+
const visTarget = visTargets[targetName];
|
|
25
|
+
const isInferred = visTarget?.inferred === true;
|
|
26
|
+
return {
|
|
27
|
+
aliases: visTarget?.aliases ?? [],
|
|
28
|
+
command: visTarget?.command,
|
|
29
|
+
description: visTarget?.description,
|
|
30
|
+
// Only emit the field when it's true — keeps the JSON
|
|
31
|
+
// shape additive instead of breaking downstream
|
|
32
|
+
// consumers that didn't know about `inferred` yet.
|
|
33
|
+
...isInferred ? { inferred: true } : {},
|
|
34
|
+
name: targetName,
|
|
35
|
+
type: visTarget?.type
|
|
36
|
+
};
|
|
37
|
+
}).filter((target) => !inferredOnly || target.inferred === true);
|
|
38
|
+
return {
|
|
39
|
+
language: project.language,
|
|
40
|
+
layer: project.layer,
|
|
41
|
+
name,
|
|
42
|
+
root: project.root,
|
|
43
|
+
stack: project.stack,
|
|
44
|
+
tags: project.tags ?? [],
|
|
45
|
+
targets,
|
|
46
|
+
type: project.projectType ?? "library"
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
logger.info(JSON.stringify(data, null, 2));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const renderTable = (header2, rows2) => {
|
|
53
|
+
const widths = header2.map((h, i) => {
|
|
54
|
+
const maxData = rows2.reduce((max, row) => Math.max(max, (row[i] ?? "").length), 0);
|
|
55
|
+
return Math.max(h.length, maxData);
|
|
56
|
+
});
|
|
57
|
+
const pad = (str, w) => str.padEnd(w);
|
|
58
|
+
logger.info(header2.map((h, i) => pad(h, widths[i])).join(" "));
|
|
59
|
+
logger.info(widths.map((w) => "─".repeat(w)).join("──"));
|
|
60
|
+
for (const row of rows2) {
|
|
61
|
+
logger.info(row.map((cell, i) => pad(cell, widths[i])).join(" "));
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
if (showTargets) {
|
|
65
|
+
const targetRows = [];
|
|
66
|
+
for (const name of projectNames) {
|
|
67
|
+
const project = workspace.projects[name];
|
|
68
|
+
const visTargets = projectOptions.get(name) ?? {};
|
|
69
|
+
for (const targetName of Object.keys(project.targets ?? {}).sort()) {
|
|
70
|
+
const visTarget = visTargets[targetName];
|
|
71
|
+
const isInferred = visTarget?.inferred === true;
|
|
72
|
+
if (inferredOnly && !isInferred) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const targetConfig = project.targets?.[targetName];
|
|
76
|
+
const cache = targetConfig?.cache === false ? "no" : targetConfig?.cache === true ? "yes" : "default";
|
|
77
|
+
targetRows.push([name, targetName, visTarget?.type ?? "—", cache, isInferred ? "yes" : "no", visTarget?.description ?? "—"]);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (targetRows.length === 0) {
|
|
81
|
+
logger.info(inferredOnly ? "No inferred targets found." : "No targets found.");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
renderTable(["Project", "Target", "Type", "Cache", "Inferred", "Description"], targetRows);
|
|
85
|
+
logger.info("");
|
|
86
|
+
logger.info(`${String(targetRows.length)} target(s) across ${String(projectNames.length)} project(s)`);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const header = ["Project", "Type", "Layer", "Tags", "Targets"];
|
|
90
|
+
const rows = projectNames.map((name) => {
|
|
91
|
+
const project = workspace.projects[name];
|
|
92
|
+
const targets = Object.keys(project.targets ?? {});
|
|
93
|
+
return [
|
|
94
|
+
name,
|
|
95
|
+
project.projectType ?? "library",
|
|
96
|
+
project.layer ?? "—",
|
|
97
|
+
(project.tags ?? []).join(", ") || "—",
|
|
98
|
+
targets.length > 4 ? `${targets.slice(0, 4).join(", ")}… (${String(targets.length)})` : targets.join(", ") || "—"
|
|
99
|
+
];
|
|
100
|
+
});
|
|
101
|
+
renderTable(header, rows);
|
|
102
|
+
logger.info("");
|
|
103
|
+
logger.info(`${String(projectNames.length)} project(s)`);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export { execute as default };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { r as resolveInstaller, z as runPmSubcommand } from './bin.js';
|
|
2
|
+
|
|
3
|
+
const execute = async ({ argument, logger, visConfig, workspaceRoot: wsRoot }) => {
|
|
4
|
+
const args = argument;
|
|
5
|
+
if (!args || args.length === 0) {
|
|
6
|
+
throw new Error(
|
|
7
|
+
"No subcommand specified. Available: cache, publish, audit, list, view, config, whoami, login, logout, pack, owner, dist-tag, search, fund, ping, token, deprecate, rebuild, prune"
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
const [subcommand, ...rest] = args;
|
|
11
|
+
const cwd = wsRoot ?? process.cwd();
|
|
12
|
+
const pm = resolveInstaller(cwd, { configBackend: visConfig?.install?.backend });
|
|
13
|
+
const code = runPmSubcommand(pm, subcommand, rest, cwd, logger);
|
|
14
|
+
if (code !== 0) {
|
|
15
|
+
process.exitCode = code;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { execute as default };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { getAffectedProjects } from '@visulima/task-runner';
|
|
2
|
+
import { d as discoverWorkspace, b as buildProjectGraph } from './bin.js';
|
|
3
|
+
import { f as filterProjectsByQuery } from '../packem_shared/selectors-SM69TfqC.js';
|
|
4
|
+
|
|
5
|
+
const execute = async ({ argument, logger, options, runtime, visConfig, workspaceRoot: wsRoot }) => {
|
|
6
|
+
const target = argument[0];
|
|
7
|
+
if (!target) {
|
|
8
|
+
throw new Error("Missing target. Usage: vis affected <target>");
|
|
9
|
+
}
|
|
10
|
+
if (!wsRoot) {
|
|
11
|
+
throw new Error("Could not determine workspace root. Run this command inside a monorepo.");
|
|
12
|
+
}
|
|
13
|
+
const workspaceRoot = wsRoot;
|
|
14
|
+
const { packageJsons, workspace } = discoverWorkspace(workspaceRoot, visConfig);
|
|
15
|
+
const projectGraph = buildProjectGraph(workspaceRoot, workspace, packageJsons);
|
|
16
|
+
const validScopes = /* @__PURE__ */ new Set(["deep", "direct", "none"]);
|
|
17
|
+
const downstreamValue = options.downstream ?? "deep";
|
|
18
|
+
const upstreamValue = options.upstream ?? "none";
|
|
19
|
+
if (!validScopes.has(downstreamValue)) {
|
|
20
|
+
throw new Error(`Invalid --downstream value: "${downstreamValue}". Must be "none", "direct", or "deep".`);
|
|
21
|
+
}
|
|
22
|
+
if (!validScopes.has(upstreamValue)) {
|
|
23
|
+
throw new Error(`Invalid --upstream value: "${upstreamValue}". Must be "none", "direct", or "deep".`);
|
|
24
|
+
}
|
|
25
|
+
const affectedOptions = {
|
|
26
|
+
base: options.base,
|
|
27
|
+
downstream: downstreamValue,
|
|
28
|
+
head: options.head,
|
|
29
|
+
projectGraph,
|
|
30
|
+
projects: workspace.projects,
|
|
31
|
+
upstream: upstreamValue,
|
|
32
|
+
workspaceRoot
|
|
33
|
+
};
|
|
34
|
+
const result = await getAffectedProjects(affectedOptions);
|
|
35
|
+
if (result.changedFiles.length === 0) {
|
|
36
|
+
logger.info("No files changed. Nothing to run.");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (result.affectedProjects.length === 0) {
|
|
40
|
+
logger.info("No projects affected by the changes.");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
let { affectedProjects } = result;
|
|
44
|
+
if (options.query) {
|
|
45
|
+
affectedProjects = filterProjectsByQuery(affectedProjects, workspace, options.query);
|
|
46
|
+
if (affectedProjects.length === 0) {
|
|
47
|
+
logger.info(`Query "${String(options.query)}" matched no affected projects.`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
logger.info(`Affected projects: ${affectedProjects.join(", ")}`);
|
|
52
|
+
if (result.changedFiles.length > 0) {
|
|
53
|
+
process.env["VIS_AFFECTED_FILES"] = result.changedFiles.join("\n");
|
|
54
|
+
}
|
|
55
|
+
const argv = [target, `--projects=${affectedProjects.join(",")}`];
|
|
56
|
+
if (options.parallel !== void 0) {
|
|
57
|
+
argv.push(`--parallel=${String(options.parallel)}`);
|
|
58
|
+
}
|
|
59
|
+
if (!options.cache) {
|
|
60
|
+
argv.push("--no-cache");
|
|
61
|
+
}
|
|
62
|
+
if (options.dryRun) {
|
|
63
|
+
argv.push("--dry-run");
|
|
64
|
+
}
|
|
65
|
+
if (options.partition) {
|
|
66
|
+
argv.push(`--partition=${String(options.partition)}`);
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
await runtime.runCommand("run", { argv });
|
|
70
|
+
} finally {
|
|
71
|
+
delete process.env["VIS_AFFECTED_FILES"];
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export { execute as default };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { r as resolveInstaller, A as runRemove } from './bin.js';
|
|
2
|
+
import { t as toStringArray } from '../packem_shared/utils-CthVdBPS.js';
|
|
3
|
+
|
|
4
|
+
const execute = async ({ argument, logger, options, visConfig, workspaceRoot: wsRoot }) => {
|
|
5
|
+
const packages = argument;
|
|
6
|
+
if (!packages || packages.length === 0) {
|
|
7
|
+
throw new Error("No packages specified. Usage: vis remove <packages...>");
|
|
8
|
+
}
|
|
9
|
+
const cwd = process.cwd();
|
|
10
|
+
const pm = resolveInstaller(wsRoot ?? cwd, { configBackend: visConfig?.install?.backend });
|
|
11
|
+
const code = runRemove(
|
|
12
|
+
pm,
|
|
13
|
+
{
|
|
14
|
+
filter: toStringArray(options.filter),
|
|
15
|
+
global: options.global || false,
|
|
16
|
+
packages,
|
|
17
|
+
recursive: options.recursive || false,
|
|
18
|
+
saveDev: options.saveDev || false,
|
|
19
|
+
workspaceRoot: options.workspaceRoot || false
|
|
20
|
+
},
|
|
21
|
+
cwd,
|
|
22
|
+
logger
|
|
23
|
+
);
|
|
24
|
+
if (code !== 0) {
|
|
25
|
+
process.exitCode = code;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export { execute as default };
|