import { ESLint } from 'eslint';
import globals from 'globals';
import nPlugin from 'eslint-plugin-n';
import prettierPlugin from 'eslint-plugin-prettier';
const eslint = new ESLint({
fix: true,
overrideConfigFile: 'eslint.config.js',
overrideConfig: {
plugins: {
n: nPlugin,
prettier: prettierPlugin,
},
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
globals: {
...globals.node,
},
},
rules: {
// --- Best Practices & Bug Prevention for JS ---
eqeqeq: ['error', 'always'],
'no-unused-vars': ['warn', { args: 'none', ignoreRestSiblings: true }],
'no-console': ['warn', { allow: ['warn', 'error'] }],
'no-return-await': 'error',
'no-throw-literal': 'error',
// --- Modern JavaScript & Code Style ---
'no-var': 'error',
'prefer-const': 'error',
'object-shorthand': 'error',
'prefer-template': 'error',
'prefer-arrow-callback': 'error',
'prefer-destructuring': ['warn', { object: true, array: false }],
// Re-apply prettier rule to ensure it has priority
'prettier/prettier': 'error',
// --- Node.js Specific Rules ---
'n/handle-callback-err': 'error',
'n/no-deprecated-api': 'error',
'n/no-new-require': 'error',
'n/no-unpublished-import': 'off', // Disabled because at linting stage we have not yet run npm i
'n/no-missing-import': 'off',
},
},
});
/**
* Lints and auto-fixes the given code string.
* @param code The source code generated by the LLM.
* @returns An object with the fixed code and a formatted string of remaining errors.
*/
export async function lintAndRefactorCode(code: string): Promise<{
fixedCode: string;
errorReport: string | null;
}> {
const results = await eslint.lintText(code);
const result = results[0]; // We are only linting one string
// The 'output' property contains the fixed code if fixes were applied.
// If no fixes were needed, it's undefined, so we fall back to the original code.
const fixedCode = result.output ?? code;
// Filter for errors that could not be auto-fixed
const remainingErrors = result.messages.filter(
(msg) => msg.severity === 2 // 2 for 'error'
);
if (remainingErrors.length > 0) {
// Format the remaining errors for feedback
const errorReport = remainingErrors
.map(
(err) => `L${err.line}:${err.column}: ${err.message} (${err.ruleId})`
)
.join('\n');
return { fixedCode, errorReport };
}
return { fixedCode, errorReport: null };
}