Skip to main content
Glama

DevDb MCP Server

laravel-codelens-service.ts4.65 kB
import * as vscode from 'vscode'; import pluralize from 'pluralize'; import Case from 'case'; import { getWorkspaceTables } from '../../messenger'; import { ModelMap } from '../../../types'; export const LaravelCodelensService = { /** * Returns a CodeLens for the Eloquent model class definition in the * given document. The CodeLens provides opening the table in DevDb. */ async getCodelensFor(document: vscode.TextDocument): Promise<vscode.CodeLens[] | undefined> { const isNotPhpFile = document.languageId !== 'php' const isNotAppModelsNamespace = document.fileName.indexOf('app/Models') === -1 if (isNotPhpFile || isNotAppModelsNamespace) { return Promise.resolve(undefined); } const text = document.getText(); const tables = getWorkspaceTables() if (tables.length === 0) { const command: vscode.Command = { /** * We use "DevDB" in the string so user knows where the Codelens * is coming from, and we use "Eloquent" in the string to help * use in debugging, especially indicating that this Codelens * only shows up in Laravel Eloquent models. */ title: `Click to create DevDb database connection for Eloquent actions`, tooltip: `DevDb Eloquent Codelens actions require database connection`, command: 'devdb.focus', }; const classNameDefinitionRegex = new RegExp(`class\\s+\\b[aA-zZ_]+\\b`); let matches = classNameDefinitionRegex.exec(text) if (!matches) { return Promise.resolve(undefined); } const line = document.lineAt(document.positionAt(matches.index).line); const indexOf = line.text.indexOf(matches[0]); const position = new vscode.Position(line.lineNumber, indexOf); const range = document.getWordRangeAtPosition(position, new RegExp(classNameDefinitionRegex)); if (range) { return Promise.resolve([new vscode.CodeLens(range, command)]) } } const tableModelMap: ModelMap = await getTableModelMapForCurrentWorkspace() const filePath = document.fileName; const codelenses: vscode.CodeLens[] = []; for (const [model, entry] of Object.entries(tableModelMap)) { if (filePath !== entry.filePath) continue; const classNameDefinitionRegex = new RegExp(`class\\s+\\b${model}\\b`); let matches = classNameDefinitionRegex.exec(text) if (!matches) { return Promise.resolve(undefined); } const line = document.lineAt(document.positionAt(matches.index).line); const indexOf = line.text.indexOf(matches[0]); const position = new vscode.Position(line.lineNumber, indexOf); const range = document.getWordRangeAtPosition(position, new RegExp(classNameDefinitionRegex)); if (range) { // Add table view codelens const viewTableCommand: vscode.Command = { title: "View table", tooltip: `Open ${entry.table} table`, command: "devdb.codelens.open-laravel-model-table", arguments: [entry.table] }; codelenses.push(new vscode.CodeLens(range, viewTableCommand)); // Add factory generation codelens const generateFactoryCommand: vscode.Command = { title: "Generate Factory", tooltip: `Generate factory for ${model}`, command: "devdb.laravel.generate-factory", arguments: [model, filePath] }; codelenses.push(new vscode.CodeLens(range, generateFactoryCommand)); } } return codelenses; } } /** * It uses heuristics based on Laravel conventions to get Laravel * models in current workspace and their tables. * Returns an object: {table => model} * * TODO: Make getting model map more efficient. We do not need to * get it every time if stuff does not change. Basically, we should * listen for changes to files in app/Models and update the map. */ export async function getTableModelMapForCurrentWorkspace(): Promise<ModelMap> { const modelFiles = await vscode.workspace.findFiles('app/Models/*.php', null, 1000); const modelTableMap: ModelMap = {}; for (const file of modelFiles) { const fileName = file.fsPath.split('/').pop(); if (!fileName) continue; const modelName = fileName.replace('.php', ''); const table = await getTable(file.fsPath, modelName) modelTableMap[modelName] = { filePath: file.fsPath, table }; } return modelTableMap } export async function getTable(fsPath: string, modelName: string): Promise<string> { const fileContent = (await vscode.workspace.fs.readFile(vscode.Uri.file(fsPath))).toString() const tablePropertyDefinition = /protected\s+\$table\s*=\s*['"](.+?)['"]/ const matches = fileContent.match(tablePropertyDefinition) if (matches) { return matches[1] } const modelSnakeCase = Case.snake(modelName) return pluralize(modelSnakeCase); }

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/damms005/devdb-vscode'

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