import { exec } from 'child_process';
import { promisify } from 'util';
import { getBinaryPath, buildCliArgs, escapeString } from './utils.js';
const execAsync = promisify(exec);
const QUERY_FLAG_MAP = {
language: '--language',
ignore: '--ignore',
allowTests: '--allow-tests',
maxResults: '--max-results',
format: '--format'
};
export async function query(options) {
if (!options || !options.path) {
throw new Error('Path is required');
}
if (!options.pattern) {
throw new Error('Pattern is required');
}
const binaryPath = await getBinaryPath(options.binaryOptions || {});
const cliArgs = buildCliArgs(options, QUERY_FLAG_MAP);
if (options.json && !options.format) {
cliArgs.push('--format', 'json');
}
cliArgs.push(escapeString(options.pattern), escapeString(options.path));
let logMessage = `Query: pattern="${options.pattern}" path="${options.path}"`;
if (options.language) logMessage += ` language=${options.language}`;
if (options.maxResults) logMessage += ` maxResults=${options.maxResults}`;
if (options.allowTests) logMessage += " allowTests=true";
console.error(logMessage);
const command = `${binaryPath} query ${cliArgs.join(' ')}`;
try {
const { stdout, stderr } = await execAsync(command);
if (stderr) {
console.error(`stderr: ${stderr}`);
}
let resultCount = 0;
const lines = stdout.split('\n');
for (const line of lines) {
if (line.startsWith('```') && !line.includes('```language')) {
resultCount++;
}
}
console.error(`Query results: ${resultCount} matches`);
if (options.json || options.format === 'json') {
try {
return JSON.parse(stdout);
} catch (error) {
console.error('Error parsing JSON output:', error);
return stdout; }
}
return stdout;
} catch (error) {
const errorMessage = `Error executing query command: ${error.message}\nCommand: ${command}`;
throw new Error(errorMessage);
}
}