UNPKG

scai

Version:

> AI-powered CLI tool for commit messages **and** pull request reviews — using local models.

73 lines (72 loc) 3.17 kB
import { Project, SyntaxKind } from 'ts-morph'; import path from 'path'; import { generateEmbedding } from '../../lib/generateEmbedding.js'; import { log } from '../../utils/log.js'; import { getDbForRepo } from '../client.js'; import { markFileAsSkippedTemplate, markFileAsExtractedTemplate, markFileAsFailedTemplate } from '../sqlTemplates.js'; export async function extractFromTS(filePath, content, fileId) { const db = getDbForRepo(); try { const project = new Project({ useInMemoryFileSystem: true }); const sourceFile = project.createSourceFile(filePath, content); const functions = []; const allFuncs = [ ...sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration), ...sourceFile.getDescendantsOfKind(SyntaxKind.FunctionExpression), ...sourceFile.getDescendantsOfKind(SyntaxKind.ArrowFunction), ]; for (const fn of allFuncs) { const name = fn.getSymbol()?.getName() ?? `${path.basename(filePath)}:<anon>`; const start = fn.getStartLineNumber(); const end = fn.getEndLineNumber(); const code = fn.getText(); functions.push({ name, start_line: start, end_line: end, content: code }); } if (functions.length === 0) { log(`⚠️ No functions found in TS file: ${filePath}`); db.prepare(markFileAsSkippedTemplate).run({ id: fileId }); return false; } log(`🔍 Found ${functions.length} TypeScript functions in ${filePath}`); for (const fn of functions) { const embedding = await generateEmbedding(fn.content); const result = db.prepare(` INSERT INTO functions ( file_id, name, start_line, end_line, content, embedding, lang ) VALUES ( @file_id, @name, @start_line, @end_line, @content, @embedding, @lang ) `).run({ file_id: fileId, name: fn.name, start_line: fn.start_line, end_line: fn.end_line, content: fn.content, embedding: JSON.stringify(embedding), lang: 'ts' }); const callerId = result.lastInsertRowid; // Simplified call detection (no walking for now) const callMatches = fn.content.matchAll(/(\w+)\s*\(/g); for (const match of callMatches) { db.prepare(` INSERT INTO function_calls (caller_id, callee_name) VALUES (@caller_id, @callee_name) `).run({ caller_id: callerId, callee_name: match[1], }); } log(`📌 Indexed TS function: ${fn.name}`); } db.prepare(markFileAsExtractedTemplate).run({ id: fileId }); log(`✅ Marked TS functions as extracted for ${filePath}`); return true; } catch (err) { log(`❌ Failed to extract from TS file: ${filePath}`); log(` ↳ ${String(err.message)}`); db.prepare(markFileAsFailedTemplate).run({ id: fileId }); return false; } }