Skip to main content
Glama
nrwl

Nx MCP Server

Official
by nrwl
target-link.ts3.54 kB
import { findProperty, getLanguageModelCache, isStringNode, lspLogger, } from '@nx-console/language-server-utils'; import { nxWorkspace } from '@nx-console/shared-nx-workspace-info'; import { fileExists, readFile } from '@nx-console/shared-file-system'; import { parseTargetString } from '@nx-console/shared-npm'; import { join } from 'path'; import { ASTNode, JSONDocument, Range, TextDocument, } from 'vscode-json-languageservice'; import { URI } from 'vscode-uri'; import { createRange } from './create-range'; const tempDocumentCounter = new Map<string, number>(); export async function targetLink( workingPath: string, node: ASTNode, ): Promise<string | undefined> { if (!isStringNode(node)) { return; } const { projectGraph } = await nxWorkspace(workingPath, lspLogger); const targetString = node.value; let project, target, configuration; try { const parsedTarget = await parseTargetString( targetString, projectGraph, workingPath, ); project = parsedTarget.project; target = parsedTarget.target; configuration = parsedTarget.configuration; } catch (e) { return; } const workspaceProject = projectGraph.nodes[project]; if (!workspaceProject) { lspLogger.log(`Could not find project ${project}`); return; } const baseTargetPath = join(workingPath, workspaceProject.data.root); const baseTargetProjectPath = join(baseTargetPath, 'project.json'); if (!(await fileExists(baseTargetProjectPath))) { lspLogger.log(`Could not find target project: ${baseTargetProjectPath}`); return; } const projectJson = await readFile(baseTargetProjectPath); let versionNumber = 0; if (tempDocumentCounter.has(baseTargetProjectPath)) { versionNumber = tempDocumentCounter.get(baseTargetProjectPath) ?? 0; tempDocumentCounter.set(baseTargetProjectPath, versionNumber + 1); } else { tempDocumentCounter.set(baseTargetProjectPath, versionNumber); } const languageModelCache = getLanguageModelCache(); const { document, jsonAst } = languageModelCache.retrieve( TextDocument.create( baseTargetProjectPath, 'json', versionNumber, projectJson, ), false, ); languageModelCache.dispose(); const range = findLinkedTargetRange(document, jsonAst, target, configuration) ?? findTargetsRange(document, jsonAst); if (!range) { return; } return URI.from({ scheme: 'file', path: baseTargetProjectPath, fragment: `${range.start.line + 1}`, }).toString(); } function findLinkedTargetRange( document: TextDocument, jsonAst: JSONDocument, target: string, configuration: string | undefined, ): Range | undefined { if (!jsonAst.root) { return; } const targetNode = findProperty(jsonAst.root, 'targets'); if (!targetNode) { return; } // Find the target within the target object const targetProperty = findProperty(targetNode, target); if (!targetProperty) { return; } if (configuration) { const configurationNode = findProperty(targetProperty, configuration); if (configurationNode) { return createRange(document, configurationNode); } } else { return createRange(document, targetProperty); } } function findTargetsRange( document: TextDocument, jsonAst: JSONDocument, ): Range | undefined { if (!jsonAst.root) { return; } const targetNode = findProperty(jsonAst.root, 'targets'); if (!targetNode) { return; } return createRange(document, targetNode); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/nrwl/nx-console'

If you have feedback or need assistance with the MCP directory API, please join our Discord server