diff --git a/packages/eslint-plugin/src/migrations/update-19-1-0-migrate-no-extra-semi/migrate-no-extra-semi.spec.ts b/packages/eslint-plugin/src/migrations/update-19-1-0-migrate-no-extra-semi/migrate-no-extra-semi.spec.ts index a21d2b763b0b2..2f971b98349ec 100644 --- a/packages/eslint-plugin/src/migrations/update-19-1-0-migrate-no-extra-semi/migrate-no-extra-semi.spec.ts +++ b/packages/eslint-plugin/src/migrations/update-19-1-0-migrate-no-extra-semi/migrate-no-extra-semi.spec.ts @@ -76,6 +76,52 @@ describe('update-19-1-0-migrate-no-extra-semi', () => { `); }); + it('should update top level config that extends @nx/typescript and "rules" is not defined', async () => { + writeJson(tree, '.eslintrc.json', { + plugins: ['@nx'], + extends: ['@nx/typescript'], + }); + + await migrate(tree); + + expect(readJson(tree, '.eslintrc.json')).toMatchInlineSnapshot(` + { + "extends": [ + "@nx/typescript", + ], + "plugins": [ + "@nx", + ], + "rules": { + "@typescript-eslint/no-extra-semi": "error", + "no-extra-semi": "off", + }, + } + `); + + writeJson(tree, '.eslintrc.json', { + plugins: ['@nx'], + extends: ['plugin:@nx/typescript'], // alt syntax + }); + + await migrate(tree); + + expect(readJson(tree, '.eslintrc.json')).toMatchInlineSnapshot(` + { + "extends": [ + "plugin:@nx/typescript", + ], + "plugins": [ + "@nx", + ], + "rules": { + "@typescript-eslint/no-extra-semi": "error", + "no-extra-semi": "off", + }, + } + `); + }); + it('should update top level config that extends @nx/javascript', async () => { writeJson(tree, '.eslintrc.json', { plugins: ['@nx'], @@ -124,6 +170,52 @@ describe('update-19-1-0-migrate-no-extra-semi', () => { `); }); + it('should update top level config that extends @nx/javascript and "rules" is not defined', async () => { + writeJson(tree, '.eslintrc.json', { + plugins: ['@nx'], + extends: ['@nx/javascript'], + }); + + await migrate(tree); + + expect(readJson(tree, '.eslintrc.json')).toMatchInlineSnapshot(` + { + "extends": [ + "@nx/javascript", + ], + "plugins": [ + "@nx", + ], + "rules": { + "@typescript-eslint/no-extra-semi": "error", + "no-extra-semi": "off", + }, + } + `); + + writeJson(tree, '.eslintrc.json', { + plugins: ['@nx'], + extends: ['plugin:@nx/javascript'], // alt syntax + }); + + await migrate(tree); + + expect(readJson(tree, '.eslintrc.json')).toMatchInlineSnapshot(` + { + "extends": [ + "plugin:@nx/javascript", + ], + "plugins": [ + "@nx", + ], + "rules": { + "@typescript-eslint/no-extra-semi": "error", + "no-extra-semi": "off", + }, + } + `); + }); + it('should not update top level config that already defines the rules', async () => { writeJson(tree, '.eslintrc.json', { plugins: ['@nx'], @@ -263,6 +355,69 @@ describe('update-19-1-0-migrate-no-extra-semi', () => { `); }); + it('should update overrides config that extends @nx/typescript and "rules" is not defined', async () => { + writeJson(tree, 'path/to/.eslintrc.json', { + overrides: [ + { + files: ['*.ts'], + extends: ['@nx/typescript'], + }, + { + files: ['*.tsx'], + extends: ['plugin:@nx/typescript'], // alt syntax + }, + { + // Should be untouched + files: ['*.js'], + plugins: ['@nx'], + rules: {}, + }, + ], + }); + + await migrate(tree); + + expect(readJson(tree, 'path/to/.eslintrc.json')).toMatchInlineSnapshot(` + { + "overrides": [ + { + "extends": [ + "@nx/typescript", + ], + "files": [ + "*.ts", + ], + "rules": { + "@typescript-eslint/no-extra-semi": "error", + "no-extra-semi": "off", + }, + }, + { + "extends": [ + "plugin:@nx/typescript", + ], + "files": [ + "*.tsx", + ], + "rules": { + "@typescript-eslint/no-extra-semi": "error", + "no-extra-semi": "off", + }, + }, + { + "files": [ + "*.js", + ], + "plugins": [ + "@nx", + ], + "rules": {}, + }, + ], + } + `); + }); + it('should update overrides config that extends @nx/javascript', async () => { writeJson(tree, '.eslintrc.json', { overrides: [ @@ -328,6 +483,69 @@ describe('update-19-1-0-migrate-no-extra-semi', () => { `); }); + it('should update overrides config that extends @nx/javascript and "rules" is not defined', async () => { + writeJson(tree, '.eslintrc.json', { + overrides: [ + { + files: ['*.js'], + extends: ['@nx/javascript'], + }, + { + files: ['*.jsx'], + extends: ['plugin:@nx/javascript'], // alt syntax + }, + { + // Should be untouched + files: ['*.js'], + plugins: ['@nx'], + rules: {}, + }, + ], + }); + + await migrate(tree); + + expect(readJson(tree, '.eslintrc.json')).toMatchInlineSnapshot(` + { + "overrides": [ + { + "extends": [ + "@nx/javascript", + ], + "files": [ + "*.js", + ], + "rules": { + "@typescript-eslint/no-extra-semi": "error", + "no-extra-semi": "off", + }, + }, + { + "extends": [ + "plugin:@nx/javascript", + ], + "files": [ + "*.jsx", + ], + "rules": { + "@typescript-eslint/no-extra-semi": "error", + "no-extra-semi": "off", + }, + }, + { + "files": [ + "*.js", + ], + "plugins": [ + "@nx", + ], + "rules": {}, + }, + ], + } + `); + }); + it('should not update overrides config that already defines the rules', async () => { writeJson(tree, '.eslintrc.json', { overrides: [ diff --git a/packages/eslint-plugin/src/migrations/update-19-1-0-migrate-no-extra-semi/migrate-no-extra-semi.ts b/packages/eslint-plugin/src/migrations/update-19-1-0-migrate-no-extra-semi/migrate-no-extra-semi.ts index e4a8cf5ed43e9..0e4b7162a2283 100644 --- a/packages/eslint-plugin/src/migrations/update-19-1-0-migrate-no-extra-semi/migrate-no-extra-semi.ts +++ b/packages/eslint-plugin/src/migrations/update-19-1-0-migrate-no-extra-semi/migrate-no-extra-semi.ts @@ -59,11 +59,13 @@ function addNoExtraSemiExplicitly(json: Record): boolean { ) { return wasUpdated; } - if (!json.rules['@typescript-eslint/no-extra-semi']) { + if (!json.rules?.['@typescript-eslint/no-extra-semi']) { + json.rules ??= {}; json.rules['@typescript-eslint/no-extra-semi'] = 'error'; wasUpdated = true; } - if (!json.rules['no-extra-semi']) { + if (!json.rules?.['no-extra-semi']) { + json.rules ??= {}; json.rules['no-extra-semi'] = 'off'; wasUpdated = true; }