// // Commands are invoked from three places — a sidebar section, the Extensions // menu, and notifications — and each passes something different. These helpers // normalise that into "the node the user meant" and "the repository it is in". // const ui = require("../ui.js"); let registry = { store: null, treeViews: [] }; function configure(store, treeViews) { registry = { store: store, treeViews: treeViews }; } /** Unwraps a TreeView, a node, or nothing at all into a node. */ function selectedNode(argument) { if (argument && Array.isArray(argument.selection)) { return argument.selection[0] || null; } if (argument && argument.kind) return argument; // Menu and palette invocations carry no argument; fall back to whichever // visible section currently has a selection. for (const view of registry.treeViews) { if (view.visible && view.selection && view.selection.length) return view.selection[0]; } return null; } function repoOf(node) { if (!node) return null; if (node.repo) return node.repo; if (node.data && node.data.repoKey) return registry.store.repoFor(node.data.repoKey); return null; } /** * Resolves the repository to act on: the selected node's, the only discovered * one, or whichever the user picks. */ async function resolveRepo(argument, { prompt = "Choose a repository" } = {}) { const node = selectedNode(argument); const fromNode = repoOf(node); if (fromNode) return fromNode; const repos = registry.store.repos; if (!repos.length) { ui.warn("No Gitea repositories are available yet."); return null; } if (repos.length === 1) return repos[0]; return await ui.choose(repos, { placeholder: prompt, label: (repo) => `${repo.fullName} — ${repo.baseUrl.replace(/^https?:\/\//, "")}`, }); } /** Walks up from `node` to the nearest ancestor of the given kind. */ function ancestorOfKind(node, kind) { let current = node; while (current) { if (current.kind === kind) return current; current = current.parent; } return null; } /** Finds the pull request a node belongs to, looking at the node and its parents. */ function pullRequestFor(node) { let current = node; while (current) { if (current.data && current.data.pull) return current.data.pull; if (current.kind === "pr" && current.data && current.data.pull) return current.data.pull; current = current.parent; } return null; } function runFor(node) { let current = node; while (current) { if (current.data && current.data.run) return current.data.run; current = current.parent; } return null; } exports.configure = configure; exports.selectedNode = selectedNode; exports.repoOf = repoOf; exports.resolveRepo = resolveRepo; exports.ancestorOfKind = ancestorOfKind; exports.pullRequestFor = pullRequestFor; exports.runFor = runFor; exports.store = () => registry.store;