UNPKG

vlt

Version:
252 lines (247 loc) 8.45 kB
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 { require_lz_string, startGUI } from "./chunk-VNU3TPBK.js"; import { createHostContextsMap } from "./chunk-4ADJWTGC.js"; import "./chunk-PVOBL7T7.js"; import "./chunk-KNHO4BUR.js"; import "./chunk-BQNTW6JU.js"; import "./chunk-YESBS37V.js"; import "./chunk-J25GTXK2.js"; import "./chunk-3VS4XBYN.js"; import "./chunk-YF5FZDHL.js"; import "./chunk-GGPZGJ5H.js"; import "./chunk-OTLTOVZN.js"; import { GraphModifier, Query, SecurityArchive, actual, asNode, humanReadableOutput, jsonOutput, mermaidOutput } from "./chunk-QALMFIGC.js"; import "./chunk-6RYZ5N3C.js"; import { commandUsage } from "./chunk-L3E552CT.js"; import "./chunk-GTAUGWLW.js"; import "./chunk-U5J4TCIV.js"; import "./chunk-KPA4XNCN.js"; import "./chunk-VYJVN3B6.js"; import "./chunk-B4MAUXR2.js"; import "./chunk-W7RMFRDJ.js"; import "./chunk-O57KIW5U.js"; import "./chunk-JBBINXAZ.js"; import "./chunk-OAYCZMD4.js"; import "./chunk-QOAKZNUG.js"; import "./chunk-BA67AKYJ.js"; import { error } from "./chunk-KVH5ECIG.js"; import { __toESM } from "./chunk-AECDW3EJ.js"; // ../../src/cli-sdk/src/commands/query.ts var import_lz_string = __toESM(require_lz_string(), 1); var usage = () => commandUsage({ command: "query", usage: [ "", "<query> --view=<human | json | mermaid | gui>", "<query> --expect-results=<comparison string>", "--target=<query> --view=<human | json | mermaid | gui>" ], description: `List installed dependencies matching the provided query. The vlt Dependency Selector Syntax is a CSS-like query language that allows you to filter installed dependencies using a variety of metadata in the form of CSS-like attributes, pseudo selectors & combinators. The --scope and --target options accepts DSS query selectors to filter packages. Using --scope, you can specify which packages to treat as the top-level items in the output graph. The --target option can be used as an alternative to positional arguments, it allows you to filter what dependencies to include in the output. Using both options allows you to render subgraphs of the dependency graph. Defaults to listing all dependencies of the project root and workspaces.`, examples: { [`'#foo'`]: { description: 'Query dependencies declared as "foo"' }, [`'*:workspace > *:peer'`]: { description: "Query all peer dependencies of workspaces" }, [`':project > *:attr(scripts, [build])'`]: { description: 'Query all direct project dependencies with a "build" script' }, [`'[name^="@vltpkg"]'`]: { description: 'Query packages with names starting with "@vltpkg"' }, [`'*:license(copyleft) --expect-results=0'`]: { description: "Errors if a copyleft licensed package is found" }, '--scope=":root > #dependency-name"': { description: "Defines a direct dependency as the output top-level scope" }, [`'--target="*"'`]: { description: "Query all dependencies using the target option" }, [`'--target=":workspace > *:peer"'`]: { description: "Query all peer dependencies of workspaces using target option" } }, options: { "expect-results": { value: "[number | string]", description: 'Sets an expected number of resulting items. Errors if the number of resulting items does not match the set value. Accepts a specific numeric value or a string value starting with either ">", "<", ">=" or "<=" followed by a numeric value to be compared.' }, scope: { value: "<query>", description: "Query selector to select top-level packages using the DSS query language syntax." }, target: { value: "<query>", description: "Query selector to filter packages using DSS syntax." }, view: { value: "[human | json | mermaid | gui]", description: "Output format. Defaults to human-readable or json if no tty." } } }); var validateExpectedResult = (conf, edges) => { const expectResults = conf.values["expect-results"]; if (expectResults?.startsWith(">=")) { return edges.length >= parseInt(expectResults.slice(2).trim(), 10); } else if (expectResults?.startsWith("<=")) { return edges.length <= parseInt(expectResults.slice(2).trim(), 10); } else if (expectResults?.startsWith(">")) { return edges.length > parseInt(expectResults.slice(1).trim(), 10); } else if (expectResults?.startsWith("<")) { return edges.length < parseInt(expectResults.slice(1).trim(), 10); } else if (expectResults) { return edges.length === parseInt(expectResults.trim(), 10); } return true; }; var views = { json: jsonOutput, mermaid: mermaidOutput, human: humanReadableOutput, gui: async ({ queryString }, _, conf) => { await startGUI( conf, `/explore/${import_lz_string.default.compressToEncodedURIComponent(queryString)}/overview` ); } }; var command = async (conf) => { const modifiers = GraphModifier.maybeLoad(conf.options); const monorepo = conf.options.monorepo; const mainManifest = conf.options.packageJson.maybeRead( conf.options.projectRoot ); let graph; let securityArchive; if (mainManifest) { graph = actual.load({ ...conf.options, mainManifest, modifiers, monorepo, loadManifests: true }); securityArchive = await SecurityArchive.start({ nodes: [...graph.nodes.values()] }); } const defaultProjectQueryString = "*"; const defaultLocalScopeQueryString = ":host(local) *"; const positionalQueryString = conf.positionals[0]; const targetQueryString = conf.get("target"); const scopeQueryString = conf.get("scope"); const queryString = targetQueryString || positionalQueryString; const hostContexts = await createHostContextsMap(conf); const importers = /* @__PURE__ */ new Set(); const scopeIDs = []; let scopeNodes; if (scopeQueryString) { const edges2 = graph?.edges ?? /* @__PURE__ */ new Set(); const nodes2 = graph?.nodes ? new Set(graph.nodes.values()) : /* @__PURE__ */ new Set(); const importers2 = graph?.importers ?? /* @__PURE__ */ new Set(); const scopeQuery = new Query({ edges: edges2, nodes: nodes2, importers: importers2, securityArchive, hostContexts }); const { nodes: resultNodes } = await scopeQuery.search( scopeQueryString, { signal: new AbortController().signal } ); scopeNodes = resultNodes; } if (scopeQueryString && scopeNodes) { for (const queryNode of scopeNodes) { importers.add(asNode(queryNode)); } } else if ("workspace" in conf.values) { if (monorepo && graph) { for (const workspace of monorepo.filter(conf.values)) { const w = graph.nodes.get(workspace.id); if (w) { importers.add(w); scopeIDs.push(workspace.id); } } } } const edges_ = graph?.edges ?? /* @__PURE__ */ new Set(); const nodes_ = graph?.nodes ? new Set(graph.nodes.values()) : /* @__PURE__ */ new Set(); const importers_ = importers.size === 0 && graph ? /* @__PURE__ */ new Set([graph.mainImporter]) : importers; const q = new Query({ edges: edges_, nodes: nodes_, importers: importers_, securityArchive, hostContexts }); const query = queryString || (graph ? defaultProjectQueryString : defaultLocalScopeQueryString); const { edges, nodes, importers: queryResultImporters } = await q.search(query, { signal: new AbortController().signal, scopeIDs: scopeIDs.length > 0 ? scopeIDs : void 0 }); if (!validateExpectedResult(conf, edges)) { throw error("Unexpected number of items", { found: edges.length, wanted: conf.values["expect-results"] }); } return { importers: importers.size === 0 ? new Set(queryResultImporters) : importers, edges, nodes, highlightSelection: !!(targetQueryString || positionalQueryString), queryString: queryString || (graph ? defaultProjectQueryString : defaultLocalScopeQueryString) }; }; export { command, usage, views }; //# sourceMappingURL=query-JFDVUDL3.js.map