diff --git a/lib/xo.ts b/lib/xo.ts index ea4bc770..08565f6c 100644 --- a/lib/xo.ts +++ b/lib/xo.ts @@ -166,8 +166,7 @@ export class Xo { this.xoConfig = [ this.baseXoConfig, - // Ensure resolved options do not mutate between runs - ...structuredClone(flatOptions), + ...flatOptions, ]; // Split off the TS rules in a special case, so that you won't get errors @@ -210,13 +209,16 @@ export class Xo { // Apply TS rules to all files tsConfig.files = [tsFilesGlob]; - // Set the other rules to the original config - config.rules = Object.fromEntries(otherRules); + const otherConfig: XoConfigItem = { + ...config, + // Set the other rules to the original config + rules: Object.fromEntries(otherRules), + }; // These rules should still apply to all files - config.files = [allFilesGlob]; + otherConfig.files = [allFilesGlob]; - return [tsConfig, config]; + return [tsConfig, otherConfig]; }); this.prettier = this.xoConfig.some(config => config.prettier); diff --git a/package.json b/package.json index c1d50057..28ada28a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xo", - "version": "1.0.3", + "version": "1.0.4", "description": "JavaScript/TypeScript linter (ESLint wrapper) with great defaults", "license": "MIT", "repository": "xojs/xo", @@ -25,7 +25,7 @@ "build:watch": "tsc --watch", "clean": "rm -rf dist", "lint": "node dist/cli.js", - "prepare": "npm run build", + "prepare": "npm run build && husky", "release": "np", "test": "npm run build && npm run lint && npm run test:setup && ava", "test:setup": "node scripts/setup-tests" diff --git a/test/xo/lint-text.test.ts b/test/xo/lint-text.test.ts index de514f04..5c5387a8 100644 --- a/test/xo/lint-text.test.ts +++ b/test/xo/lint-text.test.ts @@ -404,3 +404,50 @@ test('lint-text can be ran multiple times in a row with top level typescript rul t.is(results3[0]?.errorCount, 0); t.true(results3[0]?.messages?.length === 0); }); + +test('config with custom plugin', async t => { + const {cwd} = t.context; + + await fs.writeFile( + path.join(cwd, 'xo.config.js'), + dedent` + const testRule = { + create(context) { + return { + Program(node) { + context.report({ + node, + message: 'Custom error', + }); + }, + }; + }, + }; + + export default [ + { + plugins: { + 'test-plugin': { + rules: { + 'test-rule': testRule, + }, + }, + }, + rules: { + 'test-plugin/test-rule': 'error', + }, + }, + ];\n + `, + 'utf8', + ); + + const {results} = await Xo.lintText(dedent`console.log('hello');\n`, { + cwd, + filePath: path.join(cwd, 'test.js'), + }); + + t.is(results[0]?.messages?.length, 1); + t.is(results[0]?.messages[0]?.ruleId, 'test-plugin/test-rule'); + t.is(results[0]?.messages[0]?.message, 'Custom error'); +});