@diullei/codeguardian
Version:
Open-source developer tool to validate and enforce architectural rules, especially for AI-generated code
95 lines • 3.46 kB
JavaScript
;
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