vlt
Version:
The vlt CLI
596 lines (591 loc) • 17.4 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 {
Spec,
Spec2
} from "./chunk-264UXZEG.js";
import {
error
} from "./chunk-RV3EHS4P.js";
// ../../src/dep-id/src/browser.ts
var delimiter = "\xB7";
var depIDRegExp = new RegExp(
`^((git)?${delimiter}[^${delimiter}]*${delimiter}[^${delimiter}]*(${delimiter}[^${delimiter}]*)?$|^(file|remote|workspace)${delimiter}[^${delimiter}]*)(${delimiter}[^${delimiter}]*)?$`
);
var isDepID = (str) => typeof str === "string" && depIDRegExp.test(str);
var asDepID = (str) => {
if (!isDepID(str)) {
throw error("Expected dep id", {
found: str
});
}
return str;
};
var joinDepIDTuple = (list) => {
const [type, first, second, extra] = list;
const f = encode(first);
switch (type) {
case "registry":
return `${delimiter}${f}${delimiter}${encode(second)}${extra ? `${delimiter}${encode(extra)}` : ""}`;
case "git":
return `${type}${delimiter}${f}${delimiter}${encode(second)}${extra ? `${delimiter}${encode(extra)}` : ""}`;
default:
return `${type}${delimiter}${f}${second ? `${delimiter}${encode(second)}` : ""}`;
}
};
var encode = (s) => s ? encodeURIComponent(s).replaceAll("%40", "@").replaceAll("%2f", "\xA7").replaceAll("%2F", "\xA7") : s;
var decode = (s) => s ? decodeURIComponent(
s.replaceAll("@", "%40").replaceAll("\xA7", "%2F")
) : s;
var splitDepID = (id) => {
const [type, first = "", second, extra] = id.replaceAll("\xA7", "/").split(delimiter, 4);
const f = decodeURIComponent(first);
switch (type) {
case "git":
case "": {
if (second === void 0) {
throw error(`invalid ${type} id`, { found: id });
}
const t = [
type || "registry",
f,
decodeURIComponent(second),
decode(extra)
];
return t;
}
case "file":
case "remote":
case "workspace": {
const t = [type, f, decode(second)];
return t;
}
default: {
throw error("invalid DepID type", {
found: type,
validOptions: ["git", "file", "workspace", "remote", ""]
});
}
}
};
var baseDepID = (id) => {
const [type, first, second] = splitDepID(id);
switch (type) {
case "git":
case "registry":
return joinDepIDTuple([type, first, second]);
default:
return joinDepIDTuple([type, first]);
}
};
var hydrate = (id, name, options = {}) => hydrateTuple(splitDepID(id), name, options);
var hydrateTuple = (tuple, name, options = {}) => {
const [type, first, second] = tuple;
switch (type) {
case "remote": {
if (!first)
throw error("no remoteURL found on remote id", {
found: tuple
});
return Spec.parse(name ?? "(unknown)", first);
}
case "file": {
if (!first) {
throw error("no file path found on remote id", {
found: tuple
});
}
return Spec.parse(name ?? "(unknown)", `file:${first}`, options);
}
case "registry": {
if (typeof first !== "string") {
throw error("no registry url or name in registry ID", {
found: tuple
});
}
if (!second) {
throw error("no name/specifier in registry ID", {
found: tuple
});
}
if (!first) {
const s2 = Spec.parse(second);
if (name && s2.name !== name) {
return Spec.parse(`${name}:${second}`);
} else {
return s2;
}
}
if (!/^https?:\/\//.test(first)) {
const reg = options.registries?.[first];
if (first !== "npm" && !reg) {
throw error("named registry not found in options", {
name: first,
found: tuple
});
}
return Spec.parse(
name ?? "(unknown)",
`${first}:${second}`,
options
);
}
const s = Spec.parse(
name ?? "(unknown)",
`registry:${first}#${second}`,
options
);
return name && s.final.name !== name ? Spec.parse(s.final.name + "@" + s.bareSpec) : s;
}
case "git": {
if (!first) {
throw error("no git remote in git ID", {
found: tuple
});
}
return Spec.parse(
name ?? "(unknown)",
first + "#" + second,
options
);
}
case "workspace": {
if (!first) {
throw error("no name/path on workspace id", { found: tuple });
}
return name && name !== first ? Spec.parse(name, `workspace:${first}@*`, options) : Spec.parse(first, `workspace:*`, options);
}
}
};
var omitDefReg = (s) => !s || s === "https://registry.npmjs.org" || s === "https://registry.npmjs.org/" ? "" : s;
var getTuple = (spec, mani, extra) => {
const f = spec.final;
switch (f.type) {
case "registry": {
const reg = omitDefReg(f.registry);
if (!f.namedRegistry && reg) {
for (const [alias, host] of Object.entries(
spec.options.registries
)) {
if (reg === host) {
f.namedRegistry = alias;
break;
}
}
}
const version = mani.version ? mani.version.startsWith("v") ? mani.version.slice(1) : mani.version : f.bareSpec;
return [
f.type,
f.namedRegistry ?? reg,
`${isPackageNameConfused(spec, mani.name) ? spec.name : mani.name ?? f.name}@${version}`,
extra
];
}
case "git": {
const {
namedGitHost,
namedGitHostPath,
gitRemote,
gitSelector = ""
} = f;
if (!gitRemote)
throw error("no host on git specifier", { spec });
if (namedGitHost) {
if (!namedGitHostPath) {
throw error("named git host without path portion", {
spec
});
}
return [
f.type,
`${namedGitHost}:${namedGitHostPath}`,
gitSelector,
extra
];
} else {
return [f.type, gitRemote, gitSelector, extra];
}
}
case "remote": {
const { remoteURL } = f;
if (!remoteURL)
throw error("no URL on remote specifier", { spec });
return [f.type, remoteURL, extra];
}
case "file":
case "workspace":
throw error("Path-based dep ids are not supported", { spec });
}
};
var isPackageNameConfused = (spec, name) => !!spec?.name && // a nameless spec can't be checked
!spec.subspec && // it's not an aliased package or using a custom protocol
spec.type === "registry" && // the defined spec is of type registry
spec.name !== name;
var getId = (spec, mani, extra) => joinDepIDTuple(getTuple(spec, mani, extra));
// ../../src/dep-id/src/index.ts
var hydrate2 = (id, name, options = {}) => hydrateTuple2(splitDepID(id), name, options);
var hydrateTuple2 = (tuple, name, options = {}) => {
const [type, first, second] = tuple;
switch (type) {
case "remote": {
if (!first)
throw error("no remoteURL found on remote id", {
found: tuple
});
return Spec2.parse(name ?? "(unknown)", first);
}
case "file": {
if (!first) {
throw error("no file path found on remote id", {
found: tuple
});
}
return Spec2.parse(name ?? "(unknown)", `file:${first}`, options);
}
case "registry": {
if (typeof first !== "string") {
throw error("no registry url or name in registry ID", {
found: tuple
});
}
if (!second) {
throw error("no name/specifier in registry ID", {
found: tuple
});
}
if (!first) {
const s2 = Spec2.parse(second);
if (name && s2.name !== name) {
return Spec2.parse(`${name}:${second}`);
} else {
return s2;
}
}
if (!/^https?:\/\//.test(first)) {
const reg = options.registries?.[first];
if (first !== "npm" && !reg) {
throw error("named registry not found in options", {
name: first,
found: tuple
});
}
return Spec2.parse(
name ?? "(unknown)",
`${first}:${second}`,
options
);
}
const s = Spec2.parse(
name ?? "(unknown)",
`registry:${first}#${second}`,
options
);
return name && s.final.name !== name ? Spec2.parse(s.final.name + "@" + s.bareSpec) : s;
}
case "git": {
if (!first) {
throw error("no git remote in git ID", {
found: tuple
});
}
return Spec2.parse(
name ?? "(unknown)",
first + "#" + second,
options
);
}
case "workspace": {
if (!first) {
throw error("no name/path on workspace id", { found: tuple });
}
return name && name !== first ? Spec2.parse(name, `workspace:${first}@*`, options) : Spec2.parse(first, `workspace:*`, options);
}
}
};
// ../../node_modules/.pnpm/graph-run@1.1.0/node_modules/graph-run/dist/esm/index.js
import { setMaxListeners } from "node:events";
var isGraphRunError = (er) => !!er && typeof er === "object" && "cause" in er && !!er.cause && typeof er.cause === "object" && "code" in er.cause && (er.cause.code === "GRAPHRUN_NO_NODES" && "found" in er.cause && "wanted" in er.cause && typeof er.cause.wanted === "string" || er.cause.code === "GRAPHRUN_TRAVERSAL" && "path" in er.cause && Array.isArray(er.cause.path) && "node" in er.cause && "cause" in er.cause || er.cause.code === "GRAPHRUN_CYCLE_WITHOUT_PATH");
var RunnerBase = class {
results = /* @__PURE__ */ new Map();
settled = /* @__PURE__ */ new Map();
dependents = /* @__PURE__ */ new Map();
directDependents = /* @__PURE__ */ new Map();
options;
abortController;
failFast;
errors = [];
from;
constructor(options, from) {
const ac = new AbortController();
this.from = from ?? this.constructor;
this.abortController = ac;
setMaxListeners(Infinity, ac.signal);
this.options = options;
if (!options.graph.length) {
const er = new Error("no nodes provided to graph traversal", {
cause: {
code: "GRAPHRUN_NO_NODES",
found: options.graph,
wanted: "[first: Node, ...rest: Node[]]"
}
});
Error.captureStackTrace(er, from);
throw er;
}
this.failFast = options.failFast !== false;
const { signal } = options;
if (signal !== void 0) {
signal.addEventListener("abort", (reason) => ac.abort(reason), {
once: true,
signal: ac.signal
});
}
}
route(n, d) {
const dependents = this.dependents.get(d);
if (!dependents?.has(n))
return void 0;
const directDependents = this.directDependents.get(d);
if (!directDependents)
return void 0;
if (directDependents.has(n)) {
return [n, d];
}
const queue = [
...directDependents
].map((dd) => [dd, d]);
let step = void 0;
while (void 0 !== (step = queue.shift())) {
if (!dependents.has(step[0]))
continue;
if (step[0] === n) {
return step;
}
const ddd = this.directDependents.get(step[0]);
if (ddd) {
for (const d2 of ddd) {
queue.push([d2, ...step]);
}
}
}
}
cycleCheck(n, path, d) {
const dependents = this.dependents.get(n) ?? /* @__PURE__ */ new Set();
this.dependents.set(n, dependents);
const isCycle = dependents.has(d);
if (isCycle) {
const cycle = this.route(d, n);
if (!cycle) {
throw new Error("cycle detected, but cycle route not found", {
cause: { code: "GRAPHRUN_CYCLE_WITHOUT_PATH" }
});
}
cycle.unshift(n);
this.onCycle(d, cycle, path);
return true;
}
const depDD = this.directDependents.get(d) ?? /* @__PURE__ */ new Set();
this.directDependents.set(d, depDD);
depDD.add(n);
const depDependents = this.dependents.get(d) ?? /* @__PURE__ */ new Set();
this.dependents.set(d, depDependents);
for (const n2 of dependents) {
depDependents.add(n2);
}
depDependents.add(n);
return false;
}
handleError(er, n, path) {
this.errors.push(er);
this.settled.set(n, {
status: "rejected",
reason: er
});
if (this.failFast) {
this.abortController.abort(er);
const e = new Error("failed graph traversal", {
cause: {
code: "GRAPHRUN_TRAVERSAL",
node: n,
path,
cause: er
}
});
Error.captureStackTrace(e, this.from);
throw e;
}
}
handleValue(value, n) {
this.results.set(n, value);
this.settled.set(n, {
status: "fulfilled",
value
});
}
};
var Runner = class extends RunnerBase {
running = /* @__PURE__ */ new Map();
async getDeps(n) {
if (this.abortController.signal.aborted)
return [];
const deps = await this.options.getDeps(n);
for (const d of deps) {
const dependents = this.dependents.get(d) ?? /* @__PURE__ */ new Set();
this.dependents.set(d, dependents);
dependents.add(n);
const depDD = this.directDependents.get(d) ?? /* @__PURE__ */ new Set();
this.directDependents.set(d, depDD);
depDD.add(n);
}
return deps;
}
async visit(n, path, depResults) {
const { signal } = this.abortController;
return this.options.visit(n, signal, path, depResults);
}
async onCycle(n, cycle, path) {
if (this.abortController.signal.aborted)
return;
await this.options.onCycle?.(n, cycle, path);
}
async #walk(n, path) {
const r = this.running.get(n);
if (r)
return r;
if (this.settled.get(n))
return;
const p = this.#step(n, path).then(() => {
this.running.delete(n);
}, (er) => {
this.running.delete(n);
throw er;
});
this.running.set(n, p);
return p;
}
async #step(n, path) {
const dependents = this.dependents.get(n) ?? /* @__PURE__ */ new Set();
this.dependents.set(n, dependents);
const deps = await this.getDeps(n);
const awaiting = [];
const depPath = [...path, n];
for (const d of deps) {
if (this.abortController.signal.aborted)
return;
if (d === n)
continue;
if (this.cycleCheck(n, depPath, d))
continue;
if (this.settled.get(d))
continue;
awaiting.push(this.running.get(d) ?? this.#walk(d, depPath));
}
if (this.abortController.signal.aborted)
return;
await Promise.all(awaiting);
if (this.abortController.signal.aborted)
return;
const depRes = new Map(deps.map((d) => [d, this.results.get(d)]));
try {
this.handleValue(await this.visit(n, path, depRes), n);
} catch (er) {
this.handleError(er, n, path);
}
}
async run() {
const promises = [];
for (const n of this.options.graph) {
promises.push(this.#walk(n, []));
}
await Promise.all(promises);
}
};
var RunnerSync = class extends RunnerBase {
getDeps(n) {
if (this.abortController.signal.aborted)
return [];
return this.options.getDeps(n);
}
visit(n, path, depResults) {
const { signal } = this.abortController;
return this.options.visit(n, signal, path, depResults);
}
onCycle(n, cycle, path) {
if (this.abortController.signal.aborted)
return;
this.options.onCycle?.(n, cycle, path);
}
#walk(n, path) {
if (this.settled.get(n))
return;
this.#step(n, path);
}
#step(n, path) {
const dependents = this.dependents.get(n) ?? /* @__PURE__ */ new Set();
this.dependents.set(n, dependents);
const deps = this.getDeps(n);
const depPath = [...path, n];
for (const d of deps) {
if (this.abortController.signal.aborted)
return;
if (d === n)
continue;
if (this.cycleCheck(n, depPath, d))
continue;
if (!this.settled.get(d))
this.#walk(d, depPath);
}
if (this.abortController.signal.aborted)
return;
const depRes = new Map(deps.map((d) => [d, this.results.get(d)]));
try {
this.handleValue(this.visit(n, path, depRes), n);
} catch (er) {
this.handleError(er, n, path);
}
}
run() {
for (const n of this.options.graph) {
this.#walk(n, []);
}
return this.results;
}
};
var graphRun = async (options) => {
const runner = new Runner(options, graphRun);
await runner.run();
if (runner.errors.length) {
const e = new AggregateError(runner.errors, "failed graph traversal");
Error.captureStackTrace(e, graphRun);
throw e;
}
return runner.results;
};
var graphRunSync = (options) => {
const runner = new RunnerSync(options, graphRunSync);
runner.run();
if (runner.errors.length) {
const e = new AggregateError(runner.errors, "failed graph traversal");
Error.captureStackTrace(e, graphRunSync);
throw e;
}
return runner.results;
};
export {
asDepID,
joinDepIDTuple,
splitDepID,
baseDepID,
hydrate,
isPackageNameConfused,
getId,
hydrate2,
hydrateTuple2 as hydrateTuple,
isGraphRunError,
graphRun,
graphRunSync
};
//# sourceMappingURL=chunk-L3TCSQZJ.js.map