vlt
Version:
The vlt CLI
325 lines (307 loc) • 8.73 kB
JavaScript
var global = globalThis;
import {Buffer} from "node:buffer";
import {setTimeout,clearTimeout,setImmediate,clearImmediate,setInterval,clearInterval} from "node:timers";
import {createRequire as _vlt_createRequire} from "node:module";
var require = _vlt_createRequire(import.meta.filename);
import {
PackageInfoClient
} from "./chunk-GGPZGJ5H.js";
import {
findCmdShimIfExists,
install
} from "./chunk-QALMFIGC.js";
import {
Spec2 as Spec
} from "./chunk-U5J4TCIV.js";
import {
PathScurry
} from "./chunk-B4MAUXR2.js";
import {
parseScope
} from "./chunk-JBBINXAZ.js";
import {
walkUp
} from "./chunk-QOAKZNUG.js";
import {
XDG
} from "./chunk-BA67AKYJ.js";
import {
error
} from "./chunk-KVH5ECIG.js";
// ../../src/vlx/src/info.ts
import { resolve } from "node:path";
// ../../src/vlx/src/infer-default-executable.ts
var inferDefaultExecutable = ({
name,
bin
}) => {
if (!bin) return void 0;
let [, binName] = parseScope(name ?? "");
if (!binName) return void 0;
const keys = Object.keys(bin);
if (keys.length === 1) {
binName = keys[0];
}
const res = bin[binName];
if (!res) return void 0;
return [binName, res];
};
// ../../src/vlx/src/mount-path.ts
import { join } from "node:path";
var mountPath = (root, path) => {
path = join(path);
path = path.startsWith(root) ? path.substring(root.length) : path;
return join(root, join("/", path));
};
// ../../src/vlx/src/info.ts
var vlxInfo = (path, options, manifest) => {
const root = new XDG("vlt/vlx").data();
path = mountPath(root, path);
try {
const { packageJson } = options;
manifest ??= packageJson.read(path);
const { dependencies = {} } = manifest;
for (const [name, resolved] of Object.entries(dependencies)) {
const p = resolve(path, "node_modules", name);
const pj = packageJson.read(p, { reload: true });
const def = inferDefaultExecutable(pj);
const arg0 = def?.[0];
const { vlx } = manifest;
return {
path,
name,
version: pj.version,
resolved,
arg0,
...vlx
};
}
} catch (er) {
throw error("Could not get vlx information", er);
}
throw error("Could not get vlx information");
};
// ../../src/vlx/src/list.ts
import { opendir } from "node:fs/promises";
import { resolve as resolve2 } from "node:path";
async function* vlxList() {
const path = new XDG("vlt/vlx").data();
const dir = await opendir(path);
for await (const dirent of dir) {
yield resolve2(path, dirent.name);
}
}
// ../../src/vlx/src/delete.ts
import { basename } from "node:path";
var keyMatch = (keys, path) => {
if (!keys.length) return true;
for (const k of keys) {
if (path.includes(k)) return true;
}
return false;
};
var vlxDelete = async (keys, remover, options) => {
const removed = [];
const promises = [];
for await (const p of vlxList()) {
const key = basename(p);
try {
vlxInfo(p, options);
if (keyMatch(keys, key)) {
promises.push(remover.rm(p));
removed.push(key);
}
} catch {
promises.push(remover.rm(p));
removed.push(key);
}
}
await Promise.all(promises);
return removed;
};
// ../../src/vlx/src/install.ts
import { createHash } from "node:crypto";
import { mkdir, writeFile, rm } from "node:fs/promises";
import { resolve as resolve3 } from "node:path";
// ../../src/vlx/src/dir-exists.ts
import { stat } from "node:fs/promises";
var dirExists = async (path) => stat(path).then(
(st) => st.isDirectory(),
() => false
);
// ../../src/vlx/src/do-prompt.ts
var doPrompt = async (spec, dir, resolution, fn) => {
if (!fn) return true;
const result = (await fn(spec, dir, resolution)).trim().toLowerCase();
return !result || result.startsWith("y");
};
// ../../src/vlx/src/infer-name.ts
var inferName = (s, options) => {
const spec = typeof s === "string" ? Spec.parseArgs(s, options) : s;
const { name } = spec;
return !name || name === "(unknown)" ? Spec.parse(
spec.bareSpec.replace(/[^a-zA-Z0-9/]/g, " ").trim().replace(/ /g, "-").replace("/", "\xA7"),
spec.bareSpec,
spec.options
) : spec;
};
// ../../src/vlx/src/install.ts
var vlxInstall = async (spec, options, promptFn) => {
const pkgSpec = inferName(spec, options);
options = {
...options,
["stale-while-revalidate-factor"]: Infinity
};
const packageInfo = options.packageInfo = new PackageInfoClient(
options
);
const resolution = await packageInfo.resolve(pkgSpec, options);
const hash = createHash("sha512").update(resolution.resolved).digest("hex").substring(0, 8);
const xdg = new XDG("vlt/vlx");
const dir = xdg.data(pkgSpec.name.replace("/", "\xA7") + "-" + hash);
if (await dirExists(dir)) {
try {
return vlxInfo(dir, options);
} catch {
await rm(dir, { recursive: true, force: true });
}
}
const ok = options.yes || await doPrompt(pkgSpec, dir, resolution.resolved, promptFn);
if (!ok) throw error("Operation aborted");
await mkdir(resolve3(dir, "node_modules/.vlt"), { recursive: true });
const manifest = {
name: "vlx",
dependencies: {
[pkgSpec.name]: resolution.resolved
},
vlx: {
integrity: resolution.integrity,
signatures: resolution.signatures
}
};
await writeFile(
resolve3(dir, "package.json"),
JSON.stringify(manifest, null, 2) + "\n"
);
await install({
...options,
packageInfo,
projectRoot: dir,
monorepo: void 0,
scurry: new PathScurry(dir),
// vlx always run lifecycle scripts for all packages
allowScripts: "*"
});
return vlxInfo(dir, options, manifest);
};
// ../../src/vlx/src/resolve.ts
import { resolve as resolve6 } from "node:path";
// ../../src/vlx/src/add-to-path.ts
import { delimiter } from "node:path";
var addToPATH = (newPath) => {
process.env.PATH = [
...new Set(
`${newPath}${delimiter}${process.env.PATH ?? ""}`.split(
delimiter
)
)
].filter((p) => !!p).join(delimiter);
};
// ../../src/vlx/src/find-executable.ts
import { relative, resolve as resolve4 } from "node:path";
var findExecutable = async (arg0, projectRoot) => {
for (const path of walkUp(process.cwd())) {
const bin = await findCmdShimIfExists(
resolve4(path, "node_modules/.bin", arg0)
);
if (bin) return bin[0];
if (relative(path, projectRoot) === "") break;
}
};
// ../../src/vlx/src/find-package.ts
import { relative as relative2, resolve as resolve5 } from "node:path";
import { pathToFileURL } from "node:url";
var maybeManifest = (p, packageJson) => {
try {
return packageJson.read(p);
} catch {
return {};
}
};
var findPackage = async (name, projectRoot, packageJson) => {
for (const path of walkUp(process.cwd())) {
const p = resolve5(path, "node_modules", name);
const manifest = maybeManifest(path, packageJson);
try {
const m = packageJson.read(p, { reload: true });
const bin = inferDefaultExecutable(m);
const { vlx = {} } = manifest;
return {
path,
name,
version: m.version,
resolved: String(pathToFileURL(p)),
arg0: bin?.[0],
...vlx
};
} catch {
}
if (relative2(path, projectRoot) === "") break;
}
};
// ../../src/vlx/src/resolve.ts
var vlxResolve = async (positionals, options, promptFn) => {
const noArgs = positionals.length === 0;
let arg0 = positionals[0];
let pkgOption = options.package;
const { projectRoot, packageJson } = options;
if (!pkgOption) {
if (!arg0) {
return void 0;
}
const found = await findExecutable(arg0, projectRoot);
if (found) return found;
pkgOption = arg0;
arg0 = void 0;
}
let pkgTarget = void 0;
if (pkgOption) {
const pkgSpec = Spec.parseArgs(pkgOption, options);
const { name, bareSpec } = pkgSpec.final;
if (!bareSpec) {
pkgTarget = await findPackage(name, projectRoot, packageJson);
}
pkgTarget ??= await vlxInstall(pkgSpec, options, promptFn);
}
if (pkgTarget) {
addToPATH(resolve6(pkgTarget.path, "node_modules/.bin"));
if (noArgs) return void 0;
}
if (!arg0) {
if (!pkgTarget) {
throw error("Must supply a --package option and/or arguments", {
code: "EUSAGE"
});
}
arg0 = pkgTarget.arg0;
if (!arg0) {
const { name, version, bin } = packageJson.read(
resolve6(pkgTarget.path, "node_modules", pkgTarget.name)
);
throw error("Package executable could not be inferred", {
name,
version,
found: bin
});
}
}
return arg0;
};
export {
vlxInfo,
vlxList,
vlxDelete,
vlxInstall,
vlxResolve
};
//# sourceMappingURL=chunk-N47CDNRA.js.map