UNPKG

@diullei/codeguardian

Version:

Open-source developer tool to validate and enforce architectural rules, especially for AI-generated code

95 lines 3.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SelectASTNodesRule = void 0; const core_1 = require("../core"); const child_process_1 = require("child_process"); const util_1 = require("util"); const execAsync = (0, util_1.promisify)(child_process_1.exec); const CLI_LANGUAGE_MAP = { typescript: 'ts', javascript: 'js', tsx: 'tsx', html: 'html', css: 'css', }; class SelectASTNodesRule extends core_1.SelectorRule { query; language; constructor(id, query, language) { super(id); this.query = query; this.language = language; } async select(context) { const content = context.currentItem; if (!content || typeof content !== 'string') { return []; } const isAstGrepAvailable = await context.cache.get('isAstGrepAvailable', async () => { try { await execAsync('ast-grep --version'); return true; } catch (e) { return false; } }); if (!isAstGrepAvailable) { if (context.cliArgs?.skipMissingAstGrep) { console.warn('Warning: ast-grep CLI is not installed. Skipping AST-based rule checks.'); console.warn('To install ast-grep, visit: https://ast-grep.github.io'); return []; } else { throw new Error('ast-grep CLI is not installed. Please install it from https://ast-grep.github.io\n' + 'Alternatively, run with --skip-missing-ast-grep flag to skip AST-based rules.'); } } const cliLang = CLI_LANGUAGE_MAP[this.language]; if (!cliLang) { throw new Error(`Unsupported language: ${this.language}`); } try { const escapedContent = content.replace(/'/g, "'\\''"); const command = `echo '${escapedContent}' | ast-grep run --pattern '${this.query}' --lang '${cliLang}' --json=compact --stdin`; const { stdout, stderr } = await execAsync(command, { maxBuffer: 10 * 1024 * 1024, }); if (stderr && !stdout) { throw new Error(`ast-grep error: ${stderr}`); } if (!stdout || stdout.trim() === '') { return []; } const results = JSON.parse(stdout); return results.map((match) => { const node = { type: 'match', text: match.text, }; if (match.range) { node.range = [match.range.byteOffset.start, match.range.byteOffset.end]; node.loc = { start: { line: match.range.start.line + 1, column: match.range.start.column, }, end: { line: match.range.end.line + 1, column: match.range.end.column, }, }; } return node; }); } catch (error) { if (error instanceof SyntaxError) { return []; } throw error; } } } exports.SelectASTNodesRule = SelectASTNodesRule; //# sourceMappingURL=SelectASTNodesRule.js.map