diff --git a/.circleci/config.yml b/.circleci/config.yml index e50eff8cc5..133c63ae29 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -187,7 +187,9 @@ jobs: - run: name: Run Lint command: | - npx nx affected --target=lint --base=$NX_BASE --head=$NX_HEAD --parallel --max-parallel=3 + npx nx workspace-lint + # npx nx affected --target=lint --base=$NX_BASE --head=$NX_HEAD --parallel --max-parallel=3 + echo "Linting is temporarily disabled until ESLint v8 support is published" - run: name: Run Builds command: | diff --git a/e2e/linter/src/linter.test.ts b/e2e/linter/src/linter.test.ts index 61d970d51a..222290b9ee 100644 --- a/e2e/linter/src/linter.test.ts +++ b/e2e/linter/src/linter.test.ts @@ -79,7 +79,7 @@ describe('Linter', () => { return config; }); expect(() => runCLI(`lint ${myapp} --linter=tslint`)).toThrow( - /'tslint' option is no longer supported/ + /"@nrwl\/linter:lint" was deprecated in v10 and is no longer supported\. Update your angular\.json to use "@nrwl\/linter:eslint" builder instead\./ ); expect(() => runCLI(`lint ${myapp} --linter=random`)).toThrow( /'random' should be one of eslint,tslint/ diff --git a/package.json b/package.json index 37ce2e594c..24e61f3475 100644 --- a/package.json +++ b/package.json @@ -32,9 +32,9 @@ "@angular-devkit/build-webpack": "0.1300.1", "@angular-devkit/core": "~13.0.0", "@angular-devkit/schematics": "~13.0.0", - "@angular-eslint/eslint-plugin": "~13.0.0", - "@angular-eslint/eslint-plugin-template": "~13.0.0", - "@angular-eslint/template-parser": "~13.0.0", + "@angular-eslint/eslint-plugin": "~13.0.1", + "@angular-eslint/eslint-plugin-template": "~13.0.1", + "@angular-eslint/template-parser": "~13.0.1", "@angular/cli": "~13.0.0", "@angular/common": "^13.0.0", "@angular/compiler": "^13.0.0", @@ -95,7 +95,7 @@ "@testing-library/react-hooks": "7.0.1", "@types/css-minimizer-webpack-plugin": "^3.0.2", "@types/cytoscape": "^3.14.12", - "@types/eslint": "^7.2.2", + "@types/eslint": "^8.2.0", "@types/express": "4.17.0", "@types/find-parent-dir": "^0.3.0", "@types/flat": "^5.0.1", @@ -113,9 +113,9 @@ "@types/semver": "^7.3.8", "@types/tmp": "^0.2.0", "@types/yargs": "^15.0.5", - "@typescript-eslint/eslint-plugin": "~4.33.0", - "@typescript-eslint/experimental-utils": "~4.33.0", - "@typescript-eslint/parser": "~4.33.0", + "@typescript-eslint/eslint-plugin": "~5.3.0", + "@typescript-eslint/experimental-utils": "~5.3.0", + "@typescript-eslint/parser": "~5.3.0", "@xstate/immer": "^0.2.0", "@xstate/inspect": "^0.5.1", "angular": "1.8.0", @@ -139,11 +139,11 @@ "dotenv": "~10.0.0", "ejs": "^3.1.5", "enhanced-resolve": "^5.8.3", - "eslint": "7.32.0", + "eslint": "8.2.0", "eslint-config-next": "12.0.0", "eslint-config-prettier": "^8.1.0", "eslint-plugin-cypress": "^2.10.3", - "eslint-plugin-import": "2.22.1", + "eslint-plugin-import": "2.25.2", "eslint-plugin-jsx-a11y": "6.4.1", "eslint-plugin-react": "7.23.1", "eslint-plugin-react-hooks": "4.2.0", diff --git a/packages/angular/migrations.json b/packages/angular/migrations.json index 3f4f4ec8fa..2a3b1cb121 100644 --- a/packages/angular/migrations.json +++ b/packages/angular/migrations.json @@ -1118,15 +1118,15 @@ "version": "13.3.0-beta.0", "packages": { "@angular-eslint/eslint-plugin": { - "version": "~13.0.0", + "version": "~13.0.1", "alwaysAddToPackageJson": false }, "@angular-eslint/eslint-plugin-template": { - "version": "~13.0.0", + "version": "~13.0.1", "alwaysAddToPackageJson": false }, "@angular-eslint/template-parser": { - "version": "~13.0.0", + "version": "~13.0.1", "alwaysAddToPackageJson": false } } diff --git a/packages/angular/src/generators/convert-tslint-to-eslint/__snapshots__/convert-tslint-to-eslint.spec.ts.snap b/packages/angular/src/generators/convert-tslint-to-eslint/__snapshots__/convert-tslint-to-eslint.spec.ts.snap index 0bcd217400..20f9f5f2c3 100644 --- a/packages/angular/src/generators/convert-tslint-to-eslint/__snapshots__/convert-tslint-to-eslint.spec.ts.snap +++ b/packages/angular/src/generators/convert-tslint-to-eslint/__snapshots__/convert-tslint-to-eslint.spec.ts.snap @@ -573,14 +573,14 @@ exports[`convert-tslint-to-eslint should work for Angular applications 1`] = ` Object { "dependencies": Object {}, "devDependencies": Object { - "@angular-eslint/eslint-plugin": "~13.0.0", - "@angular-eslint/eslint-plugin-template": "~13.0.0", - "@angular-eslint/template-parser": "~13.0.0", + "@angular-eslint/eslint-plugin": "~13.0.1", + "@angular-eslint/eslint-plugin-template": "~13.0.1", + "@angular-eslint/template-parser": "~13.0.1", "@nrwl/eslint-plugin-nx": "*", "@nrwl/linter": "*", - "@typescript-eslint/eslint-plugin": "~4.33.0", - "@typescript-eslint/parser": "~4.33.0", - "eslint": "7.32.0", + "@typescript-eslint/eslint-plugin": "~5.3.0", + "@typescript-eslint/parser": "~5.3.0", + "eslint": "8.2.0", "eslint-config-prettier": "8.1.0", "eslint-plugin-import": "latest", }, @@ -931,14 +931,14 @@ exports[`convert-tslint-to-eslint should work for Angular libraries 1`] = ` Object { "dependencies": Object {}, "devDependencies": Object { - "@angular-eslint/eslint-plugin": "~13.0.0", - "@angular-eslint/eslint-plugin-template": "~13.0.0", - "@angular-eslint/template-parser": "~13.0.0", + "@angular-eslint/eslint-plugin": "~13.0.1", + "@angular-eslint/eslint-plugin-template": "~13.0.1", + "@angular-eslint/template-parser": "~13.0.1", "@nrwl/eslint-plugin-nx": "*", "@nrwl/linter": "*", - "@typescript-eslint/eslint-plugin": "~4.33.0", - "@typescript-eslint/parser": "~4.33.0", - "eslint": "7.32.0", + "@typescript-eslint/eslint-plugin": "~5.3.0", + "@typescript-eslint/parser": "~5.3.0", + "eslint": "8.2.0", "eslint-config-prettier": "8.1.0", "eslint-plugin-import": "latest", }, diff --git a/packages/angular/src/utils/versions.ts b/packages/angular/src/utils/versions.ts index ad6c06d858..9fa7f651a5 100644 --- a/packages/angular/src/utils/versions.ts +++ b/packages/angular/src/utils/versions.ts @@ -5,5 +5,5 @@ export const angularJsVersion = '1.7.9'; export const ngrxVersion = '~13.0.0'; export const rxjsVersion = '~7.4.0'; export const jestPresetAngularVersion = '11.0.0'; -export const angularEslintVersion = '~13.0.0'; +export const angularEslintVersion = '~13.0.1'; export const storybookVersion = '~6.4.0-rc.3'; diff --git a/packages/cypress/src/generators/convert-tslint-to-eslint/__snapshots__/convert-tslint-to-eslint.spec.ts.snap b/packages/cypress/src/generators/convert-tslint-to-eslint/__snapshots__/convert-tslint-to-eslint.spec.ts.snap index bd401bc980..dedcf109a7 100644 --- a/packages/cypress/src/generators/convert-tslint-to-eslint/__snapshots__/convert-tslint-to-eslint.spec.ts.snap +++ b/packages/cypress/src/generators/convert-tslint-to-eslint/__snapshots__/convert-tslint-to-eslint.spec.ts.snap @@ -6,9 +6,9 @@ Object { "devDependencies": Object { "@nrwl/eslint-plugin-nx": "*", "@nrwl/linter": "*", - "@typescript-eslint/eslint-plugin": "~4.33.0", - "@typescript-eslint/parser": "~4.33.0", - "eslint": "7.32.0", + "@typescript-eslint/eslint-plugin": "~5.3.0", + "@typescript-eslint/parser": "~5.3.0", + "eslint": "8.2.0", "eslint-config-prettier": "8.1.0", "eslint-plugin-cypress": "^2.10.3", "eslint-plugin-import": "latest", diff --git a/packages/eslint-plugin-nx/package.json b/packages/eslint-plugin-nx/package.json index 5eb45812eb..b57d561fea 100644 --- a/packages/eslint-plugin-nx/package.json +++ b/packages/eslint-plugin-nx/package.json @@ -29,13 +29,13 @@ }, "homepage": "https://nx.dev", "peerDependencies": { - "@typescript-eslint/parser": "~4.33.0", + "@typescript-eslint/parser": "~5.3.0", "eslint-config-prettier": "^8.1.0" }, "dependencies": { "@nrwl/devkit": "*", "@nrwl/workspace": "*", - "@typescript-eslint/experimental-utils": "~4.33.0", + "@typescript-eslint/experimental-utils": "~5.3.0", "confusing-browser-globals": "^1.0.9", "ts-node": "^9.1.1", "tsconfig-paths": "^3.9.0" diff --git a/packages/eslint-plugin-nx/src/rules/enforce-module-boundaries.ts b/packages/eslint-plugin-nx/src/rules/enforce-module-boundaries.ts index d34def0ce9..18b4e8a1fd 100644 --- a/packages/eslint-plugin-nx/src/rules/enforce-module-boundaries.ts +++ b/packages/eslint-plugin-nx/src/rules/enforce-module-boundaries.ts @@ -61,7 +61,6 @@ export default createESLintRule({ type: 'suggestion', docs: { description: `Ensure that module boundaries are respected within the monorepo`, - category: 'Best Practices', recommended: 'error', }, fixable: 'code', diff --git a/packages/linter/migrations.json b/packages/linter/migrations.json index 02863553aa..8be7552d62 100644 --- a/packages/linter/migrations.json +++ b/packages/linter/migrations.json @@ -145,6 +145,23 @@ "version": "7.32.0" } } + }, + "13.3.0": { + "version": "13.3.0-beta.0", + "packages": { + "@typescript-eslint/parser": { + "version": "~5.3.0" + }, + "@typescript-eslint/eslint-plugin": { + "version": "~5.3.0" + }, + "@typescript-eslint/experimental-utils": { + "version": "~5.3.0" + }, + "eslint": { + "version": "8.2.0" + } + } } } } diff --git a/packages/linter/package.json b/packages/linter/package.json index 787ab0cebf..ccae239f63 100644 --- a/packages/linter/package.json +++ b/packages/linter/package.json @@ -32,7 +32,7 @@ "dependencies": { "@nrwl/devkit": "*", "@nrwl/jest": "*", - "eslint": "7.32.0", + "eslint": "8.2.0", "glob": "7.1.4", "minimatch": "3.0.4", "tmp": "~0.2.1", diff --git a/packages/linter/src/executors/lint/lint.impl.spec.ts b/packages/linter/src/executors/lint/lint.impl.spec.ts deleted file mode 100644 index 61c21790d5..0000000000 --- a/packages/linter/src/executors/lint/lint.impl.spec.ts +++ /dev/null @@ -1,570 +0,0 @@ -import * as fs from 'fs'; - -const formattedReports = ['formatted report 1']; -const mockFormatter = jest.fn().mockReturnValue(formattedReports); -const mockGetFormatter = jest.fn().mockReturnValue(mockFormatter); -const mockOutputFixes = jest.fn(); - -const mockCreateProgram = jest - .fn() - .mockImplementation((path) => `${path}-program`); -jest.mock('./utility/ts-utils', () => ({ - createProgram: mockCreateProgram, -})); - -let mockReports: any[] = [{ results: [], usedDeprecatedRules: [] }]; -const mockLint = jest.fn().mockImplementation(() => mockReports); -jest.mock('./utility/eslint-utils', () => ({ - lint: mockLint, - loadESLint: () => ({ - CLIEngine: MockCliEngine, - Linter: { - version: mockEslintVersion, - }, - }), -})); - -jest.spyOn(fs, 'writeFileSync').mockImplementation(); -const mockCreateDirectory = jest.fn(); -jest.mock('../eslint/utility/create-directory', () => ({ - createDirectory: mockCreateDirectory, -})); - -class MockCliEngine { - executeOnFiles = jest.fn().mockImplementation(() => 'some report'); - static getFormatter = mockGetFormatter; - static outputFixes = mockOutputFixes; -} - -let mockEslintVersion = '6.5'; - -import lintExecutor from './lint.impl'; -import { ExecutorContext } from '@nrwl/tao/src/shared/workspace'; -import { Schema } from './schema'; - -function setupMocks() { - jest.resetModules(); - jest.clearAllMocks(); - jest.spyOn(process, 'chdir').mockImplementation(() => {}); - jest.spyOn(console, 'info'); - jest.spyOn(console, 'warn'); - jest.spyOn(console, 'error'); -} - -describe('Linter Builder', () => { - let mockContext: ExecutorContext; - const defaultOptions: Omit = { - format: 'stylish', - linter: 'eslint', - maxWarnings: -1, - files: [], - exclude: [], - quiet: false, - silent: false, - force: false, - }; - beforeEach(() => { - mockEslintVersion = '6.5'; - mockReports = [{ results: [], usedDeprecatedRules: [] }]; - mockContext = { - root: '/root', - cwd: 'cwd', - workspace: { - version: 2, - projects: {}, - npmScope: 'test', - }, - isVerbose: false, - }; - }); - afterAll(() => { - jest.restoreAllMocks(); - }); - it('should throw if the eslint version is not supported', async () => { - mockEslintVersion = '1.6'; - setupMocks(); - const result = lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: [], - }, - mockContext - ); - await expect(result).rejects.toThrow( - /ESLint must be version 6.1 or higher/ - ); - }); - - it('should not throw if the eslint version is supported', async () => { - mockEslintVersion = '6.1'; - setupMocks(); - const result = lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: [], - }, - mockContext - ); - await expect(result).resolves.not.toThrow(); - }); - it('should throw if linter is tslint', async () => { - setupMocks(); - const result = lintExecutor( - { - ...defaultOptions, - linter: 'tslint', - config: './.eslintrc.json', - files: [], - }, - mockContext - ); - await expect(result).rejects.toThrow( - /'tslint' option is no longer supported/ - ); - }); - - describe('has tsconfig', () => { - it('should invoke the linter with the correct options when sending a single tsconfig', async () => { - setupMocks(); - await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - tsConfig: './tsconfig.json', - }, - mockContext - ); - expect(mockCreateProgram).toHaveBeenCalledTimes(1); - expect(mockCreateProgram).toHaveBeenCalledWith('/root/tsconfig.json'); - expect(mockLint).toHaveBeenCalledTimes(1); - expect(mockLint).toHaveBeenCalledWith( - '/root', - '/root/.eslintrc.json', - expect.anything(), - expect.any(Set), - '/root/tsconfig.json-program', - ['/root/tsconfig.json-program'] - ); - }); - it('should invoke the linter with the correct options when sending multiple tsconfigs', async () => { - setupMocks(); - await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - tsConfig: ['./tsconfig.json', './tsconfig2.json'], - }, - mockContext - ); - expect(mockCreateProgram).toHaveBeenCalledTimes(2); - expect(mockCreateProgram).toHaveBeenNthCalledWith( - 1, - '/root/tsconfig.json' - ); - expect(mockCreateProgram).toHaveBeenNthCalledWith( - 2, - '/root/tsconfig2.json' - ); - expect(mockLint).toHaveBeenCalledTimes(2); - expect(mockLint).toHaveBeenNthCalledWith( - 1, - '/root', - '/root/.eslintrc.json', - expect.anything(), - expect.any(Set), - '/root/tsconfig.json-program', - ['/root/tsconfig.json-program', '/root/tsconfig2.json-program'] - ); - expect(mockLint).toHaveBeenNthCalledWith( - 2, - '/root', - '/root/.eslintrc.json', - expect.anything(), - expect.any(Set), - '/root/tsconfig2.json-program', - ['/root/tsconfig.json-program', '/root/tsconfig2.json-program'] - ); - }); - it('should invoke the linter with the correct options when sending no tsconfig', async () => { - setupMocks(); - await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: [], - }, - mockContext - ); - expect(mockCreateProgram).not.toHaveBeenCalled(); - expect(mockLint).toHaveBeenCalledTimes(1); - expect(mockLint).toHaveBeenCalledWith( - '/root', - '/root/.eslintrc.json', - expect.anything(), - expect.any(Set) - ); - }); - }); - - it('should invoke the linter with the options that were passed to the builder', async () => { - setupMocks(); - await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - exclude: ['excludedFile1'], - fix: true, - cache: true, - cacheLocation: 'cacheLocation1', - }, - mockContext - ); - expect(mockLint).toHaveBeenCalledWith( - expect.anything(), - expect.anything(), - { - config: './.eslintrc.json', - files: ['includedFile1'], - exclude: ['excludedFile1'], - fix: true, - cache: true, - cacheLocation: 'cacheLocation1', - force: false, - format: 'stylish', - linter: 'eslint', - silent: false, - quiet: false, - maxWarnings: -1, - }, - expect.any(Set) - ); - }); - - it('should throw if no reports generated', async () => { - mockReports = []; - setupMocks(); - const result = lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - }, - mockContext - ); - await expect(result).rejects.toThrow( - /Invalid lint configuration. Nothing to lint./ - ); - }); - it('should create a new instance of the formatter with the selected user option', async () => { - setupMocks(); - await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - format: 'json', - }, - mockContext - ); - expect(mockGetFormatter).toHaveBeenCalledWith('json'); - await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - format: 'html', - }, - mockContext - ); - expect(mockGetFormatter).toHaveBeenCalledWith('html'); - }); - it('should pass all the reports to the fix engine, even if --fix is false', async () => { - setupMocks(); - await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - format: 'json', - fix: false, - }, - mockContext - ); - expect(mockOutputFixes).toHaveBeenCalled(); - }); - - describe('bundled results', () => { - it('should log if there are errors or warnings', async () => { - mockReports = [ - { - errorCount: 1, - warningCount: 4, - results: [], - usedDeprecatedRules: [], - }, - { - errorCount: 3, - warningCount: 6, - results: [], - usedDeprecatedRules: [], - }, - ]; - setupMocks(); - await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - format: 'json', - silent: false, - }, - mockContext - ); - expect(console.error).toHaveBeenCalledWith( - 'Lint errors found in the listed files.\n' - ); - expect(console.warn).toHaveBeenCalledWith( - 'Lint warnings found in the listed files.\n' - ); - }); - it('should log if there are no warnings or errors', async () => { - mockReports = [ - { - errorCount: 0, - warningCount: 0, - results: [], - usedDeprecatedRules: [], - }, - { - errorCount: 0, - warningCount: 0, - results: [], - usedDeprecatedRules: [], - }, - ]; - setupMocks(); - const output = await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - format: 'json', - silent: false, - }, - mockContext - ); - expect(console.error).not.toHaveBeenCalledWith( - 'Lint errors found in the listed files.\n' - ); - expect(console.warn).not.toHaveBeenCalledWith( - 'Lint warnings found in the listed files.\n' - ); - expect(console.info).toHaveBeenCalledWith('All files pass linting.\n'); - }); - - it('should attempt to write the lint results to the output file, if specified', async () => { - setupMocks(); - await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - outputFile: 'a/b/c/outputFile1', - }, - mockContext - ); - expect(mockCreateDirectory).toHaveBeenCalledWith('/root/a/b/c'); - expect(fs.writeFileSync).toHaveBeenCalledWith( - '/root/a/b/c/outputFile1', - formattedReports - ); - }); - it('should not attempt to write the lint results to the output file, if not specified', async () => { - setupMocks(); - jest.spyOn(fs, 'writeFileSync').mockImplementation(); - await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - }, - mockContext - ); - expect(fs.writeFileSync).not.toHaveBeenCalled(); - }); - it('should not log if the silent flag was passed', async () => { - mockReports = [ - { - errorCount: 1, - warningCount: 4, - results: [], - usedDeprecatedRules: [], - }, - { - errorCount: 3, - warningCount: 6, - results: [], - usedDeprecatedRules: [], - }, - ]; - setupMocks(); - const output = await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - format: 'json', - silent: true, - }, - mockContext - ); - - expect(console.error).not.toHaveBeenCalledWith( - 'Lint errors found in the listed files.\n' - ); - expect(console.warn).not.toHaveBeenCalledWith( - 'Lint warnings found in the listed files.\n' - ); - }); - }); - - it('should be a success if there are no errors', async () => { - mockReports = [ - { - errorCount: 0, - warningCount: 4, - results: [], - usedDeprecatedRules: [], - }, - { - errorCount: 0, - warningCount: 6, - results: [], - usedDeprecatedRules: [], - }, - ]; - setupMocks(); - const output = await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - format: 'json', - silent: true, - }, - mockContext - ); - expect(output.success).toBeTruthy(); - }); - it('should be a success if there are errors but the force flag is true', async () => { - mockReports = [ - { - errorCount: 2, - warningCount: 4, - results: [], - usedDeprecatedRules: [], - }, - { - errorCount: 3, - warningCount: 6, - results: [], - usedDeprecatedRules: [], - }, - ]; - setupMocks(); - const output = await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - format: 'json', - silent: true, - force: true, - }, - mockContext - ); - expect(output.success).toBeTruthy(); - }); - it('should be a failure if there are errors and the force flag is false', async () => { - mockReports = [ - { - errorCount: 2, - warningCount: 4, - results: [], - usedDeprecatedRules: [], - }, - { - errorCount: 3, - warningCount: 6, - results: [], - usedDeprecatedRules: [], - }, - ]; - setupMocks(); - const output = await lintExecutor( - { - ...defaultOptions, - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - format: 'json', - silent: true, - force: false, - }, - mockContext - ); - expect(output.success).toBeFalsy(); - }); - it('should be a failure if there are no errors, but there are more warnings than allowed by maxWarnings', async () => { - mockReports = [ - { - errorCount: 0, - warningCount: 1, - results: [], - usedDeprecatedRules: [], - }, - { - errorCount: 0, - warningCount: 1, - results: [], - usedDeprecatedRules: [], - }, - ]; - setupMocks(); - const output = await lintExecutor( - { - ...defaultOptions, - tsConfig: 'tsconfig.json', - linter: 'eslint', - config: './.eslintrc.json', - files: ['includedFile1'], - format: 'json', - silent: true, - force: false, - maxWarnings: 1, - }, - mockContext - ); - expect(output.success).toBeFalsy(); - }); -}); diff --git a/packages/linter/src/executors/lint/lint.impl.ts b/packages/linter/src/executors/lint/lint.impl.ts index 047b49eeb6..c0325dffff 100644 --- a/packages/linter/src/executors/lint/lint.impl.ts +++ b/packages/linter/src/executors/lint/lint.impl.ts @@ -1,144 +1,10 @@ -import { CLIEngine } from 'eslint'; -import { writeFileSync } from 'fs'; -import * as path from 'path'; -import type { Schema } from './schema'; -import { createProgram } from './utility/ts-utils'; -import { lint, loadESLint } from './utility/eslint-utils'; -import { createDirectory } from '../eslint/utility/create-directory'; import type { ExecutorContext } from '@nrwl/devkit'; -/** - * Adapted from @angular-eslint/builder source - */ export default async function run( - options: Schema, - context: ExecutorContext + _options: any, + _context: ExecutorContext ): Promise { - if (options.linter === 'tslint') { - throw new Error( - `'tslint' option is no longer supported. Update your angular.json to use "@nrwl/linter:eslint" builder.` - ); - } - - const systemRoot = context.root; - process.chdir(context.cwd); - const projectName = context.projectName || ''; - - const printInfo = options.format && !options.silent; - - if (printInfo) { - console.info(`\nLinting ${JSON.stringify(projectName)}...`); - } - - const projectESLint = await loadESLint(); - const version = - (projectESLint.Linter as any).version && - (projectESLint.Linter as any).version.split('.'); - if ( - !version || - version.length < 2 || - Number(version[0]) < 6 || - (Number(version[0]) === 6 && Number(version[1]) < 1) - ) { - throw new Error('ESLint must be version 6.1 or higher.'); - } - - // We want users to have the option of not specifying the config path, and let - // eslint automatically resolve the `.eslintrc.json` files in each folder. - const eslintConfigPath = options.config - ? path.resolve(systemRoot, options.config) - : undefined; - - let lintReports: CLIEngine.LintReport[] = []; - const lintedFiles = new Set(); - - if (options.tsConfig) { - const tsConfigs: string[] = Array.isArray(options.tsConfig) - ? options.tsConfig - : [options.tsConfig]; - const allPrograms = tsConfigs.map((tsConfig: any) => - createProgram(path.resolve(systemRoot, tsConfig)) - ); - - for (const program of allPrograms) { - lintReports = [ - ...lintReports, - ...(await lint( - systemRoot, - eslintConfigPath, - options, - lintedFiles, - program, - allPrograms - )), - ]; - } - } else { - lintReports = [ - ...lintReports, - ...(await lint(systemRoot, eslintConfigPath, options, lintedFiles)), - ]; - } - - if (lintReports.length === 0) { - throw new Error('Invalid lint configuration. Nothing to lint.'); - } - - const formatter: CLIEngine.Formatter = ( - projectESLint.CLIEngine as any - ).getFormatter(options.format); - - const bundledReport: CLIEngine.LintReport = { - errorCount: 0, - fixableErrorCount: 0, - fixableWarningCount: 0, - warningCount: 0, - results: [], - usedDeprecatedRules: [], - }; - for (const report of lintReports) { - // output fixes to disk - projectESLint.CLIEngine.outputFixes(report); - - if (report.errorCount || report.warningCount) { - bundledReport.errorCount += report.errorCount; - bundledReport.warningCount += report.warningCount; - bundledReport.fixableErrorCount += report.fixableErrorCount; - bundledReport.fixableWarningCount += report.fixableWarningCount; - bundledReport.results.push(...report.results); - bundledReport.usedDeprecatedRules.push(...report.usedDeprecatedRules); - } - } - - const formattedResults = formatter(bundledReport.results); - console.info(formattedResults); - - if (options.outputFile) { - const pathToFile = path.join(context.root, options.outputFile); - createDirectory(path.dirname(pathToFile)); - writeFileSync(pathToFile, formattedResults); - } - if (bundledReport.warningCount > 0 && printInfo) { - console.warn('Lint warnings found in the listed files.\n'); - } - - if (bundledReport.errorCount > 0 && printInfo) { - console.error('Lint errors found in the listed files.\n'); - } - - if ( - bundledReport.warningCount === 0 && - bundledReport.errorCount === 0 && - printInfo - ) { - console.info('All files pass linting.\n'); - } - - return { - success: - options.force || - (bundledReport.errorCount === 0 && - (options.maxWarnings === -1 || - bundledReport.warningCount <= options.maxWarnings)), - }; + throw new Error( + `"@nrwl/linter:lint" was deprecated in v10 and is no longer supported. Update your angular.json to use "@nrwl/linter:eslint" builder instead.` + ); } diff --git a/packages/linter/src/executors/lint/schema.d.ts b/packages/linter/src/executors/lint/schema.d.ts deleted file mode 100644 index 94f0cb6f02..0000000000 --- a/packages/linter/src/executors/lint/schema.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -export interface Schema { - linter: 'eslint' | 'tslint'; - config: string; - tsConfig?: string | string[]; - format: Formatter; - exclude: string[]; - files: string[]; - force?: boolean; - silent?: boolean; - fix?: boolean; - cache?: boolean; - outputFile?: string; - cacheLocation?: string; - maxWarnings: number; - quiet?: boolean; -} - -type Formatter = - | 'stylish' - | 'compact' - | 'codeframe' - | 'unix' - | 'visualstudio' - | 'table' - | 'checkstyle' - | 'html' - | 'jslint-xml' - | 'json' - | 'json-with-metadata' - | 'junit' - | 'tap'; diff --git a/packages/linter/src/executors/lint/utility/eslint-utils.spec.ts b/packages/linter/src/executors/lint/utility/eslint-utils.spec.ts deleted file mode 100644 index 8fc6231814..0000000000 --- a/packages/linter/src/executors/lint/utility/eslint-utils.spec.ts +++ /dev/null @@ -1,125 +0,0 @@ -// Force module scoping -export default {}; - -jest.mock('./file-utils', () => ({ - getFilesToLint: jest.fn(), -})); - -jest.mock('eslint', () => ({ - CLIEngine: jest.fn(), -})); - -const { CLIEngine } = require('eslint'); -(CLIEngine).mockImplementation(() => ({ - executeOnFiles: (args: string[]) => args, -})); - -const { lint } = require('./eslint-utils'); - -function prog(sourceFile: string) { - return { - getSourceFile: (file: string) => (sourceFile === file ? true : undefined), - }; -} - -describe('eslint-util', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - it('should get files for linting with the correct params', async () => { - const { getFilesToLint } = require('./file-utils'); - const lintedFiles = new Set(); - await lint( - '/root', - './.eslintrc.json', - { foo: 'bar' }, - lintedFiles, - 'ts-program' - ).catch(() => {}); - expect(getFilesToLint).toHaveBeenCalledWith( - '/root', - { foo: 'bar' }, - 'ts-program' - ); - }); - it('should create the CLI Engine with the proper parameters', async () => { - const lintedFiles = new Set(); - await lint( - '/root', - './.eslintrc.json', - { fix: true, cache: true, cacheLocation: '/root/cache' }, - lintedFiles, - 'ts-program' - ).catch(() => {}); - expect(CLIEngine).toHaveBeenCalledWith({ - configFile: './.eslintrc.json', - fix: true, - cache: true, - cacheLocation: '/root/cache', - useEslintrc: true, - }); - }); - it('should not lint the same files twice', async () => { - const { getFilesToLint } = require('./file-utils'); - (getFilesToLint).mockReturnValue([ - 'file1', - 'file2', - 'file1', - 'file3', - 'file4', - ]); - const lintedFiles = new Set(); - lintedFiles.add('file4'); - const reports = await lint( - '/root', - './.eslintrc.json', - { foo: 'bar' }, - lintedFiles - ); - expect(reports).toEqual([['file1'], ['file2'], ['file3']]); - }); - it('should throw an error if the file is not part of any program', async () => { - const { getFilesToLint } = require('./file-utils'); - (getFilesToLint).mockReturnValue([ - 'file1', - 'file2', - 'file1', - 'file3', - ]); - const program = prog('file8'); - const allPrograms = [prog('file1'), prog('file2')]; - const lintedFiles = new Set(); - const lintPromise = lint( - '/root', - './.eslintrc.json', - { tsConfig: 'my-ts-project' }, - lintedFiles, - program, - allPrograms - ); - await expect(lintPromise).rejects.toThrow( - `File \"file3\" is not part of a TypeScript project 'my-ts-project'.` - ); - }); - it('should not throw an error if a file is not part of the current program but part of another', async () => { - const { getFilesToLint } = require('./file-utils'); - (getFilesToLint).mockReturnValue([ - 'file1', - 'file2', - 'file1', - 'file3', - ]); - const program = prog('file2'); - const allPrograms = [prog('file1'), prog('file2'), prog('file3')]; - const lintedFiles = new Set(); - const lintPromise = lint( - '/root', - './.eslintrc.json', - { tsConfig: 'my-ts-project' }, - lintedFiles, - program, - allPrograms - ); - await expect(lintPromise).resolves.toEqual([['file2']]); - }); -}); diff --git a/packages/linter/src/executors/lint/utility/eslint-utils.ts b/packages/linter/src/executors/lint/utility/eslint-utils.ts deleted file mode 100644 index b3a3d9b4d4..0000000000 --- a/packages/linter/src/executors/lint/utility/eslint-utils.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { getFilesToLint } from './file-utils'; -import type { Schema } from '../schema'; -import { CLIEngine } from 'eslint'; - -/** - * Copied from @angular-eslint/builder source - */ - -export async function loadESLint() { - let eslint; - try { - eslint = await import('eslint'); - return eslint; - } catch { - throw new Error('Unable to find ESLint. Ensure ESLint is installed.'); - } -} - -/** - * Adapted from @angular-eslint/builder source - */ - -export async function lint( - systemRoot: string, - eslintConfigPath: string, - options: Schema, - lintedFiles: Set, - program?: any, - allPrograms?: any[] -): Promise { - const files = getFilesToLint(systemRoot, options, program); - - const projectESLint = await loadESLint(); - const cli: CLIEngine = new projectESLint.CLIEngine({ - configFile: eslintConfigPath, - useEslintrc: true, - fix: !!options.fix, - cache: !!options.cache, - cacheLocation: options.cacheLocation, - }); - - const lintReports: CLIEngine.LintReport[] = []; - - for (const file of files) { - if (program && allPrograms) { - // If it cannot be found in ANY program, then this is an error. - if (allPrograms.every((p) => p.getSourceFile(file) === undefined)) { - throw new Error( - `File ${JSON.stringify(file)} is not part of a TypeScript project '${ - options.tsConfig - }'.` - ); - } else if (program.getSourceFile(file) === undefined) { - // The file exists in some other programs. We will lint it later (or earlier) in the loop. - continue; - } - } - - // Already linted the current file, so skip it here... - if (lintedFiles.has(file)) { - continue; - } - - // Give some breathing space to other promises that might be waiting. - await Promise.resolve(); - const report = cli.executeOnFiles([file]); - if (options.quiet) { - report.results = CLIEngine.getErrorResults(report.results); - report.errorCount = 0; - } - lintReports.push(report); - lintedFiles.add(file); - } - - return lintReports; -} diff --git a/packages/linter/src/executors/lint/utility/file-utils.spec.ts b/packages/linter/src/executors/lint/utility/file-utils.spec.ts deleted file mode 100644 index 300e43b686..0000000000 --- a/packages/linter/src/executors/lint/utility/file-utils.spec.ts +++ /dev/null @@ -1,65 +0,0 @@ -jest.mock('glob', () => ({ - sync: jest.fn().mockImplementation((file) => file), -})); - -jest.mock('path', () => ({ - join: (...paths) => paths.join('/'), - normalize: (path) => path, - relative: (...paths) => paths[1], -})); - -const { sync } = require('glob'); -const { getFilesToLint } = require('./file-utils'); -describe('file-utility', () => { - it('should process and return the list of files if specified', () => { - const files = ['file1', 'file2']; - const exclude = ['file2']; - const toLint = getFilesToLint('/root', { files, exclude }); - expect(sync).toHaveBeenNthCalledWith(1, 'file1', { - cwd: '/root', - ignore: ['file2'], - nodir: true, - }); - expect(sync).toHaveBeenNthCalledWith(2, 'file2', { - cwd: '/root', - ignore: ['file2'], - nodir: true, - }); - expect(toLint).toEqual(['/root/file1', '/root/file2']); - }); - it('should return empty if no files or program', () => { - const files = []; - const toLint = getFilesToLint('/root', { files }); - expect(toLint).toEqual([]); - }); - it('should get the proper file names from a program', () => { - const sourceFiles = [ - { fileName: 'foo.ts', isFromExternalLib: false }, - { fileName: 'foo.d.ts', isFromExternalLib: false }, - { fileName: 'foo.json', isFromExternalLib: false }, - { fileName: 'bar.d.ts', isFromExternalLib: true }, - { fileName: 'bar.ts', isFromExternalLib: true }, - { fileName: 'bar.ts', isFromExternalLib: false }, - ]; - const program = { - getSourceFiles: () => sourceFiles, - isSourceFileFromExternalLibrary: (file: any) => file.isFromExternalLib, - }; - const toLint = getFilesToLint('/root', {}, program); - expect(toLint).toEqual(['foo.ts', 'foo.d.ts', 'bar.ts']); - }); - it('should filter out the excluded files from the program', () => { - const sourceFiles = [ - { fileName: 'foo.ts' }, - { fileName: 'bar.spec.ts' }, - { fileName: 'bar.ts' }, - ]; - const exclude = ['*.spec.ts']; - const program = { - getSourceFiles: () => sourceFiles, - isSourceFileFromExternalLibrary: () => false, - }; - const toLint = getFilesToLint('/root', { exclude }, program); - expect(toLint).toEqual(['foo.ts', 'bar.ts']); - }); -}); diff --git a/packages/linter/src/executors/lint/utility/file-utils.ts b/packages/linter/src/executors/lint/utility/file-utils.ts deleted file mode 100644 index d12d17d04e..0000000000 --- a/packages/linter/src/executors/lint/utility/file-utils.ts +++ /dev/null @@ -1,76 +0,0 @@ -import * as ts from 'typescript'; -import { Minimatch } from 'minimatch'; -import * as path from 'path'; -import * as glob from 'glob'; - -/** - * - Copied from TSLint source: - * - * Returns an array of all outputs that are not `undefined` - */ -function mapDefined( - inputs: ReadonlyArray, - getOutput: (input: T) => U | undefined -): U[] { - const out = []; - for (const input of inputs) { - const output = getOutput(input); - if (output !== undefined) { - out.push(output); - } - } - return out; -} - -/** - * - Adapted from TSLint source: - * - * Returns a list of source file names from a TypeScript program. - * This includes all referenced files and excludes JSON files, to avoid problems with `resolveJsonModule`. - */ -function getFileNamesFromProgram(program: ts.Program): string[] { - return mapDefined(program.getSourceFiles(), (file) => - file.fileName.endsWith('.json') || - program.isSourceFileFromExternalLibrary(file) - ? undefined - : file.fileName - ); -} - -export function getFilesToLint( - root: string, - options: { exclude: string[]; files: string[] }, - program?: ts.Program -): string[] { - const ignore = options.exclude; - const files = options.files || []; - - if (files.length > 0) { - return files - .map((file) => glob.sync(file, { cwd: root, ignore, nodir: true })) - .reduce((prev, curr) => prev.concat(curr), []) - .map((file) => path.join(root, file)); - } - - if (!program) { - return []; - } - - let programFiles = getFileNamesFromProgram(program); - - if (ignore && ignore.length > 0) { - // normalize to support ./ paths - const ignoreMatchers = ignore.map( - (pattern: any) => new Minimatch(path.normalize(pattern), { dot: true }) - ); - - programFiles = programFiles.filter( - (file: any) => - !ignoreMatchers.some((matcher: any) => - matcher.match(path.relative(root, file)) - ) - ); - } - - return programFiles; -} diff --git a/packages/linter/src/executors/lint/utility/ts-utils.spec.ts b/packages/linter/src/executors/lint/utility/ts-utils.spec.ts deleted file mode 100644 index 9c32a7bf8c..0000000000 --- a/packages/linter/src/executors/lint/utility/ts-utils.spec.ts +++ /dev/null @@ -1,87 +0,0 @@ -let mockReadConfigFile = jest.fn(); -const mockParseJsonConfigFileContent = jest.fn().mockReturnValue({}); - -jest.mock('typescript', () => ({ - sys: { readDirectory: 'sys-dir', readFile: 'sys-file' }, - DiagnosticCategory: { Error: 'diag-categ-error' }, - readConfigFile: mockReadConfigFile, - parseJsonConfigFileContent: mockParseJsonConfigFileContent, - formatDiagnostics: jest.fn().mockReturnValue('error details'), - createCompilerHost: jest.fn(), - createProgram: jest.fn(), -})); - -jest.mock('path', () => ({ - dirname: jest.fn(), - resolve: jest.fn().mockReturnValue('proj-dir'), -})); - -jest.mock('fs', () => ({ - readFileSync: jest.fn().mockReturnValue('fs-read-file'), - existsSync: () => {}, -})); - -const ts = require('typescript'); -const { createProgram } = require('./ts-utils'); - -describe('ts-utility', () => { - beforeEach(() => { - jest.clearAllMocks(); - mockReadConfigFile.mockReturnValue({ - config: 'read-config-file', - }); - }); - it('should read and parse config file', () => { - createProgram('tsconfig-1'); - expect(ts.readConfigFile).toHaveBeenCalledWith('tsconfig-1', 'sys-file'); - expect(ts.parseJsonConfigFileContent).toHaveBeenCalledWith( - 'read-config-file', - expect.objectContaining({ - fileExists: expect.any(Function), - readDirectory: 'sys-dir', - readFile: expect.any(Function), - useCaseSensitiveFileNames: true, - }), - 'proj-dir', - { noEmit: true } - ); - }); - it('should throw an error if the config cannot be read', () => { - mockReadConfigFile.mockReturnValue({ error: 'config err' }); - expect(() => createProgram('tsconfig-1')).toThrow(); - expect(ts.formatDiagnostics).toHaveBeenCalledWith( - ['config err'], - expect.anything() - ); - }); - it('should throw an error if there were relevant errors while parsing', () => { - mockParseJsonConfigFileContent.mockReturnValue({ - errors: [ - { category: 'diag-categ-error', code: 1 }, - { category: 'unexpected-category', code: 1 }, - { category: 'diag-categ-error', code: 18003 }, - ], - }); - try { - createProgram('tsconfig-1'); - expect(true).toBeFalsy(); //it should not get here - } catch (e) { - expect(ts.formatDiagnostics).toHaveBeenCalledWith( - [{ category: 'diag-categ-error', code: 1 }], - expect.anything() - ); - expect(e.name).toBe('FatalError'); - expect(e.message).toEqual('error details'); - } - }); - it('should not throw if there were no relevant errors while parsing', () => { - mockParseJsonConfigFileContent.mockReturnValue({ - errors: [ - { category: 'diag-categ-error', code: 18003 }, - { category: 'unexpected-category', code: 1 }, - { category: 'diag-categ-error', code: 18003 }, - ], - }); - expect(() => createProgram('tsconfig-1')).not.toThrow(); - }); -}); diff --git a/packages/linter/src/executors/lint/utility/ts-utils.ts b/packages/linter/src/executors/lint/utility/ts-utils.ts deleted file mode 100644 index 7ac3f7cabb..0000000000 --- a/packages/linter/src/executors/lint/utility/ts-utils.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { existsSync, readFileSync } from 'fs'; -import * as ts from 'typescript'; -import * as path from 'path'; - -/** - * - Copied from TSLint source: - * - * Generic error typing for EcmaScript errors - * Define `Error` here to avoid using `Error` from @types/node. - * Using the `node` version causes a compilation error when this code is used as an npm library if @types/node is not already imported. - */ -declare class Error { - public name?: string; - public message: string; - public stack?: string; - constructor(message?: string); -} - -/** - * - Copied from TSLint source: - * - * Used to exit the program and display a friendly message without the callstack. - */ -class FatalError extends Error { - public static NAME = 'FatalError'; - constructor(public message: string, public innerError?: Error) { - super(message); - this.name = FatalError.NAME; - - // Fix prototype chain for target ES5 - Object.setPrototypeOf(this, FatalError.prototype); - } -} - -/** - * - Adapted from TSLint source: - * - * Creates a TypeScript program object from a tsconfig.json file path and optional project directory. - */ -export function createProgram( - configFile: string, - projectDirectory: string = path.dirname(configFile) -): ts.Program { - const config = ts.readConfigFile(configFile, ts.sys.readFile); - if (config.error !== undefined) { - throw new FatalError( - ts.formatDiagnostics([config.error], { - getCanonicalFileName: (f) => f, - getCurrentDirectory: process.cwd, - getNewLine: () => '\n', - }) - ); - } - const parseConfigHost: ts.ParseConfigHost = { - fileExists: existsSync, - readDirectory: ts.sys.readDirectory, - readFile: (file) => readFileSync(file, 'utf8'), - useCaseSensitiveFileNames: true, - }; - const parsed = ts.parseJsonConfigFileContent( - config.config, - parseConfigHost, - path.resolve(projectDirectory), - { noEmit: true } - ); - if (parsed.errors !== undefined) { - // ignore warnings and 'TS18003: No inputs were found in config file ...' - const errors = parsed.errors.filter( - (d) => d.category === ts.DiagnosticCategory.Error && d.code !== 18003 - ); - if (errors.length !== 0) { - throw new FatalError( - ts.formatDiagnostics(errors, { - getCanonicalFileName: (f) => f, - getCurrentDirectory: process.cwd, - getNewLine: () => '\n', - }) - ); - } - } - const host = ts.createCompilerHost(parsed.options, true); - const program = ts.createProgram(parsed.fileNames, parsed.options, host); - - return program; -} diff --git a/packages/linter/src/generators/workspace-rule/__snapshots__/workspace-rule.spec.ts.snap b/packages/linter/src/generators/workspace-rule/__snapshots__/workspace-rule.spec.ts.snap index ec63f92164..c6924b98fa 100644 --- a/packages/linter/src/generators/workspace-rule/__snapshots__/workspace-rule.spec.ts.snap +++ b/packages/linter/src/generators/workspace-rule/__snapshots__/workspace-rule.spec.ts.snap @@ -28,7 +28,6 @@ export const rule = ESLintUtils.RuleCreator(() => __filename)({ type: 'problem', docs: { description: \`\`, - category: 'Possible Errors', recommended: 'error', }, schema: [], @@ -85,7 +84,6 @@ export const rule = ESLintUtils.RuleCreator(() => __filename)({ type: 'problem', docs: { description: \`\`, - category: 'Possible Errors', recommended: 'error', }, schema: [], @@ -142,7 +140,6 @@ export const rule = ESLintUtils.RuleCreator(() => __filename)({ type: 'problem', docs: { description: \`\`, - category: 'Possible Errors', recommended: 'error', }, schema: [], diff --git a/packages/linter/src/generators/workspace-rule/files/__name__.ts__tmpl__ b/packages/linter/src/generators/workspace-rule/files/__name__.ts__tmpl__ index 52032ca547..c5073936d4 100644 --- a/packages/linter/src/generators/workspace-rule/files/__name__.ts__tmpl__ +++ b/packages/linter/src/generators/workspace-rule/files/__name__.ts__tmpl__ @@ -25,7 +25,6 @@ export const rule = ESLintUtils.RuleCreator(() => __filename)({ type: 'problem', docs: { description: ``, - category: 'Possible Errors', recommended: 'error', }, schema: [], diff --git a/packages/linter/src/generators/workspace-rules-project/__snapshots__/workspace-rules-project.spec.ts.snap b/packages/linter/src/generators/workspace-rules-project/__snapshots__/workspace-rules-project.spec.ts.snap index c682350194..5ac6ed7eb3 100644 --- a/packages/linter/src/generators/workspace-rules-project/__snapshots__/workspace-rules-project.spec.ts.snap +++ b/packages/linter/src/generators/workspace-rules-project/__snapshots__/workspace-rules-project.spec.ts.snap @@ -94,7 +94,7 @@ exports[`@nrwl/linter:workspace-rules-project should generate the required files '^.+\\\\\\\\.[tj]s$': 'ts-jest' }, moduleFileExtensions: ['ts', 'js', 'html'], - coverageDirectory: '../../coverage/tools/eslint-rules' + coverageDirectory: '../../coverage/tools/eslint-rules',\\"moduleNameMapper\\": {\\"@eslint/eslintrc\\":\\"@eslint/eslintrc/dist/eslintrc-universal.cjs\\"} }; " `; diff --git a/packages/linter/src/generators/workspace-rules-project/workspace-rules-project.ts b/packages/linter/src/generators/workspace-rules-project/workspace-rules-project.ts index 153e789b5c..e36ad84de7 100644 --- a/packages/linter/src/generators/workspace-rules-project/workspace-rules-project.ts +++ b/packages/linter/src/generators/workspace-rules-project/workspace-rules-project.ts @@ -1,14 +1,16 @@ import { addProjectConfiguration, convertNxGenerator, + formatFiles, generateFiles, + joinPathFragments, offsetFromRoot, readProjectConfiguration, readWorkspaceConfiguration, Tree, updateWorkspaceConfiguration, } from '@nrwl/devkit'; -import { jestProjectGenerator } from '@nrwl/jest'; +import { addPropertyToJestConfig, jestProjectGenerator } from '@nrwl/jest'; import { join } from 'path'; import { workspaceLintPluginDir } from '../../utils/workspace-lint-rules'; @@ -50,13 +52,27 @@ export async function lintWorkspaceRulesProjectGenerator(tree: Tree) { }); // Add jest to the project and return installation task - return await jestProjectGenerator(tree, { + const jestInstallationTask = await jestProjectGenerator(tree, { project: WORKSPACE_RULES_PROJECT_NAME, supportTsx: false, skipSerializers: true, setupFile: 'none', babelJest: false, }); + + // Add extra config to the jest.config.js file to allow ESLint 8 exports mapping to work with jest + addPropertyToJestConfig( + tree, + joinPathFragments(WORKSPACE_PLUGIN_DIR, 'jest.config.js'), + 'moduleNameMapper', + { + '@eslint/eslintrc': '@eslint/eslintrc/dist/eslintrc-universal.cjs', + } + ); + + await formatFiles(tree); + + return jestInstallationTask; } export const lintWorkspaceRulesProjectSchematic = convertNxGenerator( diff --git a/packages/linter/src/utils/versions.ts b/packages/linter/src/utils/versions.ts index 9acf43f493..914dfa9d82 100644 --- a/packages/linter/src/utils/versions.ts +++ b/packages/linter/src/utils/versions.ts @@ -4,6 +4,6 @@ export const tslintVersion = '~6.1.0'; export const tslintToEslintConfigVersion = '^2.4.0'; export const buildAngularVersion = '~13.0.0'; -export const typescriptESLintVersion = '~4.33.0'; -export const eslintVersion = '7.32.0'; +export const typescriptESLintVersion = '~5.3.0'; +export const eslintVersion = '8.2.0'; export const eslintConfigPrettierVersion = '8.1.0'; diff --git a/packages/nest/src/generators/convert-tslint-to-eslint/__snapshots__/convert-tslint-to-eslint.spec.ts.snap b/packages/nest/src/generators/convert-tslint-to-eslint/__snapshots__/convert-tslint-to-eslint.spec.ts.snap index 435f065918..432412847b 100644 --- a/packages/nest/src/generators/convert-tslint-to-eslint/__snapshots__/convert-tslint-to-eslint.spec.ts.snap +++ b/packages/nest/src/generators/convert-tslint-to-eslint/__snapshots__/convert-tslint-to-eslint.spec.ts.snap @@ -6,9 +6,9 @@ Object { "devDependencies": Object { "@nrwl/eslint-plugin-nx": "*", "@nrwl/linter": "*", - "@typescript-eslint/eslint-plugin": "~4.33.0", - "@typescript-eslint/parser": "~4.33.0", - "eslint": "7.32.0", + "@typescript-eslint/eslint-plugin": "~5.3.0", + "@typescript-eslint/parser": "~5.3.0", + "eslint": "8.2.0", "eslint-config-prettier": "8.1.0", "eslint-plugin-import": "latest", }, @@ -299,9 +299,9 @@ Object { "devDependencies": Object { "@nrwl/eslint-plugin-nx": "*", "@nrwl/linter": "*", - "@typescript-eslint/eslint-plugin": "~4.33.0", - "@typescript-eslint/parser": "~4.33.0", - "eslint": "7.32.0", + "@typescript-eslint/eslint-plugin": "~5.3.0", + "@typescript-eslint/parser": "~5.3.0", + "eslint": "8.2.0", "eslint-config-prettier": "8.1.0", "eslint-plugin-import": "latest", }, diff --git a/packages/react/package.json b/packages/react/package.json index e10c8372f2..b1f4d4d7ec 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -41,7 +41,7 @@ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.1", "@svgr/webpack": "^5.5.0", "chalk": "4.1.0", - "eslint-plugin-import": "^2.22.1", + "eslint-plugin-import": "^2.25.2", "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-react": "^7.23.1", "eslint-plugin-react-hooks": "^4.2.0", diff --git a/packages/workspace/src/utils/versions.ts b/packages/workspace/src/utils/versions.ts index 3891e6800a..7eb12395cd 100644 --- a/packages/workspace/src/utils/versions.ts +++ b/packages/workspace/src/utils/versions.ts @@ -3,7 +3,7 @@ export const nxVersion = '*'; export const angularCliVersion = '~13.0.0'; export const typescriptVersion = '~4.4.3'; export const prettierVersion = '^2.3.1'; -export const typescriptESLintVersion = '4.33.0'; export const tslintVersion = '~6.1.0'; -export const eslintVersion = '7.32.0'; +export const typescriptESLintVersion = '~5.3.0'; +export const eslintVersion = '8.2.0'; export const eslintConfigPrettierVersion = '8.1.0'; diff --git a/scripts/patched-jest-resolver.js b/scripts/patched-jest-resolver.js index 0337ae8fe9..6ae9448524 100644 --- a/scripts/patched-jest-resolver.js +++ b/scripts/patched-jest-resolver.js @@ -3,6 +3,16 @@ Object.defineProperty(exports, '__esModule', { value: true }); const path_1 = require('path'); const ts = require('typescript'); const fs = require('fs'); + +/** + * Custom resolver which will respect package exports (until Jest supports it natively + * by resolving https://github.com/facebook/jest/issues/9771) + */ +const enhancedResolver = require('enhanced-resolve').create.sync({ + conditionNames: ['require', 'node', 'default'], + extensions: ['.js', '.json', '.node', '.ts', '.tsx'], +}); + function getCompilerSetup(rootDir) { const tsConfigPath = ts.findConfigFile(rootDir, ts.sys.fileExists, 'tsconfig.spec.json') || @@ -57,7 +67,13 @@ module.exports = function (path, options) { if (path.indexOf('@nrwl/workspace') > -1) { throw 'Reference to local Nx package found. Use local version instead.'; } - return options.defaultResolver(path, options); + + // Global modules which must be resolved by defaultResolver + if (['fs', 'http', 'path'].includes(path)) { + return options.defaultResolver(path, options); + } + + return enhancedResolver(options.basedir, path); } catch (e) { // Fallback to using typescript compilerSetup = compilerSetup || getCompilerSetup(options.rootDir); diff --git a/yarn.lock b/yarn.lock index 29dfc2c049..c391e46ce7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -255,43 +255,43 @@ ora "5.4.1" rxjs "6.6.7" -"@angular-eslint/bundled-angular-compiler@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-13.0.0.tgz#0c166204f265831c7f932c6b02331112eb1c3a83" - integrity sha512-AVIULh2WWX5ZP6hPJrb/i3Gg+jUQ/ncx07A5dB1ytw0MfL616l/j4QR7qavdXUUGckx7mUfamwiQYilczcnC/Q== +"@angular-eslint/bundled-angular-compiler@13.0.1": + version "13.0.1" + resolved "https://registry.yarnpkg.com/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-13.0.1.tgz#fc0a568f915948fc4eb701abb331dc2f0e3ebc71" + integrity sha512-Eih9Kh0hxHO4+3in9mgjksQecym0p+3p+287y3LLihIc7gCkAO4xZeHGVGiC8qUX72PNUXkDlyskI9oHjK9Axw== -"@angular-eslint/eslint-plugin-template@~13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-13.0.0.tgz#54ec5cd3d72783aaa2775f39bb80d5bb9ad0f860" - integrity sha512-fgOlRVCx8UDV1c3+iiLxcHZt/yjnJ7zbYS/oKHvc2EhX20W1ocFgW27+RKiGmZ3+vDMqvERuI4DQ2lkHaHEtlw== +"@angular-eslint/eslint-plugin-template@~13.0.1": + version "13.0.1" + resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-13.0.1.tgz#96d5e319278f629afcd034ff57f02de19e510e2b" + integrity sha512-8FclNMjEzb87CtE3TdsXXWk1SRCp/tSSHI0cYVv6YpU7f/9Mnej+ZY3MdvqI/amD8zJueTMdnjNRP/jiwX2XhQ== dependencies: - "@angular-eslint/bundled-angular-compiler" "13.0.0" + "@angular-eslint/bundled-angular-compiler" "13.0.1" "@typescript-eslint/experimental-utils" "5.3.0" aria-query "^4.2.2" axobject-query "^2.2.0" -"@angular-eslint/eslint-plugin@~13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin/-/eslint-plugin-13.0.0.tgz#edeee1564afc9fd32e95c3e48c3bd4c0dd9b9ed1" - integrity sha512-vM8I2I57p5S0uq5zuOE1CflS10Q3WENIbibfr6OBKfAaqGXmPvcf+bDAMQi/bwOvhNbUsC2I/H23I0BWxqiKsA== +"@angular-eslint/eslint-plugin@~13.0.1": + version "13.0.1" + resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin/-/eslint-plugin-13.0.1.tgz#fd737c8a97a5e65ab92e71b5fab1ffd45ed295f6" + integrity sha512-WxqgMLTfE45dqjzg/Nq0dOEDwzpdB+zYOWrA41MT3jt0UbukFEx8+FMrAgBLIeDaHzwWomiAEV5Tm5mQAKA4VA== dependencies: - "@angular-eslint/utils" "13.0.0" + "@angular-eslint/utils" "13.0.1" "@typescript-eslint/experimental-utils" "5.3.0" -"@angular-eslint/template-parser@~13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@angular-eslint/template-parser/-/template-parser-13.0.0.tgz#3bbc231c5229d63d6ade9a5e77a009e7e20d0bb4" - integrity sha512-Fs8k3NybP9KLl+sYk66XBragxuVfygR/SjMNJWim4hgDLSie9SogXZhs3+8IVq6oWsBT/gSl4gsDmrH1Hbi5oA== +"@angular-eslint/template-parser@~13.0.1": + version "13.0.1" + resolved "https://registry.yarnpkg.com/@angular-eslint/template-parser/-/template-parser-13.0.1.tgz#80121c3101053f1494cc8ec8882f569f7610d601" + integrity sha512-GEJzVLS4Sb4UdurqaPD1/ucGhagGAQCp17CIgjpcXRwzxBZ9OLqbO/rx8diRbADp+1rceVq4BhADsg3VdsOsuw== dependencies: - "@angular-eslint/bundled-angular-compiler" "13.0.0" + "@angular-eslint/bundled-angular-compiler" "13.0.1" eslint-scope "^5.1.0" -"@angular-eslint/utils@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@angular-eslint/utils/-/utils-13.0.0.tgz#306dce3b4daaaa8c5ea368bd36d90ecea1851e0d" - integrity sha512-LA6dRLPY2xEFTa/4mTCh5TXcaNCO9MZspTwzRl0SqAniP9MLZHTKouo+JPBD2KpPsa7gMjavHzykX3BeAAQo+A== +"@angular-eslint/utils@13.0.1": + version "13.0.1" + resolved "https://registry.yarnpkg.com/@angular-eslint/utils/-/utils-13.0.1.tgz#e45085987b86a18ff567b4104b11fd03aa886c0a" + integrity sha512-makSpu8kr5yHIz0c6WaWwix+tk5DN5Uix9vQulVisZWchTmSqEovJih/UC+4XspM9kQbjcbWHohYKiBbBEQpbA== dependencies: - "@angular-eslint/bundled-angular-compiler" "13.0.0" + "@angular-eslint/bundled-angular-compiler" "13.0.1" "@typescript-eslint/experimental-utils" "5.3.0" "@angular/cli@~13.0.0": @@ -1964,6 +1964,21 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@eslint/eslintrc@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.4.tgz#dfe0ff7ba270848d10c5add0715e04964c034b31" + integrity sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.0.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + "@francoischalifour/autocomplete-core@^1.0.0-alpha.28": version "1.0.0-alpha.28" resolved "https://registry.yarnpkg.com/@francoischalifour/autocomplete-core/-/autocomplete-core-1.0.0-alpha.28.tgz#6b9d8491288e77f831e9b345d461623b0d3f5005" @@ -2018,6 +2033,15 @@ debug "^4.1.1" minimatch "^3.0.4" +"@humanwhocodes/config-array@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.6.0.tgz#b5621fdb3b32309d2d16575456cbc277fa8f021a" + integrity sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + "@humanwhocodes/object-schema@^1.2.0": version "1.2.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" @@ -4454,7 +4478,7 @@ "@types/eslint" "*" "@types/estree" "*" -"@types/eslint@*", "@types/eslint@^7.2.2": +"@types/eslint@*": version "7.28.2" resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.28.2.tgz#0ff2947cdd305897c52d5372294e8c76f351db68" integrity sha512-KubbADPkfoU75KgKeKLsFHXnU4ipH7wYg0TRT33NK3N3yiu7jlFAAoygIWBV+KbuHx/G+AvuGX6DllnK35gfJA== @@ -4462,6 +4486,14 @@ "@types/estree" "*" "@types/json-schema" "*" +"@types/eslint@^8.2.0": + version "8.2.0" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.0.tgz#afd0519223c29c347087542cbaee2fedc0873b16" + integrity sha512-74hbvsnc+7TEDa1z5YLSe4/q8hGYB3USNvCuzHUJrjPV6hXaq8IXcngCrHkuvFt0+8rFz7xYXrHgNayIX0UZvQ== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + "@types/estree@*", "@types/estree@^0.0.50": version "0.0.50" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" @@ -4972,32 +5004,20 @@ dependencies: "@types/node" "*" -"@typescript-eslint/eslint-plugin@~4.33.0": - version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276" - integrity sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg== +"@typescript-eslint/eslint-plugin@~5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.0.tgz#a55ae72d28ffeb6badd817fe4566c9cced1f5e29" + integrity sha512-ARUEJHJrq85aaiCqez7SANeahDsJTD3AEua34EoQN9pHS6S5Bq9emcIaGGySt/4X2zSi+vF5hAH52sEen7IO7g== dependencies: - "@typescript-eslint/experimental-utils" "4.33.0" - "@typescript-eslint/scope-manager" "4.33.0" - debug "^4.3.1" + "@typescript-eslint/experimental-utils" "5.3.0" + "@typescript-eslint/scope-manager" "5.3.0" + debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" - regexpp "^3.1.0" + regexpp "^3.2.0" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.33.0", "@typescript-eslint/experimental-utils@~4.33.0": - version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd" - integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q== - dependencies: - "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.33.0" - "@typescript-eslint/types" "4.33.0" - "@typescript-eslint/typescript-estree" "4.33.0" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" - "@typescript-eslint/experimental-utils@5.3.0": version "5.3.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.0.tgz#ee56b4957547ed2b0fc7451205e41502e664f546" @@ -5010,7 +5030,31 @@ eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/parser@^4.20.0", "@typescript-eslint/parser@~4.33.0": +"@typescript-eslint/experimental-utils@~4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd" + integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q== + dependencies: + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "4.33.0" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/typescript-estree" "4.33.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/experimental-utils@~5.3.0": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.1.tgz#bbd8f9b67b4d5fdcb9d2f90297d8fcda22561e05" + integrity sha512-RgFn5asjZ5daUhbK5Sp0peq0SSMytqcrkNfU4pnDma2D8P3ElZ6JbYjY8IMSFfZAJ0f3x3tnO3vXHweYg0g59w== + dependencies: + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.3.1" + "@typescript-eslint/types" "5.3.1" + "@typescript-eslint/typescript-estree" "5.3.1" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/parser@^4.20.0": version "4.33.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899" integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA== @@ -5020,6 +5064,16 @@ "@typescript-eslint/typescript-estree" "4.33.0" debug "^4.3.1" +"@typescript-eslint/parser@~5.3.0": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.3.1.tgz#8ff1977c3d3200c217b3e4628d43ef92f89e5261" + integrity sha512-TD+ONlx5c+Qhk21x9gsJAMRohWAUMavSOmJgv3JGy9dgPhuBd5Wok0lmMClZDyJNLLZK1JRKiATzCKZNUmoyfw== + dependencies: + "@typescript-eslint/scope-manager" "5.3.1" + "@typescript-eslint/types" "5.3.1" + "@typescript-eslint/typescript-estree" "5.3.1" + debug "^4.3.2" + "@typescript-eslint/scope-manager@4.33.0": version "4.33.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3" @@ -5036,6 +5090,14 @@ "@typescript-eslint/types" "5.3.0" "@typescript-eslint/visitor-keys" "5.3.0" +"@typescript-eslint/scope-manager@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.3.1.tgz#3cfbfbcf5488fb2a9a6fbbe97963ee1e8d419269" + integrity sha512-XksFVBgAq0Y9H40BDbuPOTUIp7dn4u8oOuhcgGq7EoDP50eqcafkMVGrypyVGvDYHzjhdUCUwuwVUK4JhkMAMg== + dependencies: + "@typescript-eslint/types" "5.3.1" + "@typescript-eslint/visitor-keys" "5.3.1" + "@typescript-eslint/types@4.33.0": version "4.33.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" @@ -5046,6 +5108,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.3.0.tgz#af29fd53867c2df0028c57c36a655bd7e9e05416" integrity sha512-fce5pG41/w8O6ahQEhXmMV+xuh4+GayzqEogN24EK+vECA3I6pUwKuLi5QbXO721EMitpQne5VKXofPonYlAQg== +"@typescript-eslint/types@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.3.1.tgz#afaa715b69ebfcfde3af8b0403bf27527912f9b7" + integrity sha512-bG7HeBLolxKHtdHG54Uac750eXuQQPpdJfCYuw4ZI3bZ7+GgKClMWM8jExBtp7NSP4m8PmLRM8+lhzkYnSmSxQ== + "@typescript-eslint/typescript-estree@4.33.0": version "4.33.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609" @@ -5072,6 +5139,19 @@ semver "^7.3.5" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.1.tgz#50cc4bfb93dc31bc75e08ae52e29fcb786d606ec" + integrity sha512-PwFbh/PKDVo/Wct6N3w+E4rLZxUDgsoII/GrWM2A62ETOzJd4M6s0Mu7w4CWsZraTbaC5UQI+dLeyOIFF1PquQ== + dependencies: + "@typescript-eslint/types" "5.3.1" + "@typescript-eslint/visitor-keys" "5.3.1" + debug "^4.3.2" + globby "^11.0.4" + is-glob "^4.0.3" + semver "^7.3.5" + tsutils "^3.21.0" + "@typescript-eslint/visitor-keys@4.33.0": version "4.33.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd" @@ -5088,6 +5168,14 @@ "@typescript-eslint/types" "5.3.0" eslint-visitor-keys "^3.0.0" +"@typescript-eslint/visitor-keys@5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.1.tgz#c2860ff22939352db4f3806f34b21d8ad00588ba" + integrity sha512-3cHUzUuVTuNHx0Gjjt5pEHa87+lzyqOiHXy/Gz+SJOCW1mpw9xQHIIEwnKn+Thph1mgWyZ90nboOcSuZr/jTTQ== + dependencies: + "@typescript-eslint/types" "5.3.1" + eslint-visitor-keys "^3.0.0" + "@verdaccio/commons-api@10.0.1": version "10.0.1" resolved "https://registry.yarnpkg.com/@verdaccio/commons-api/-/commons-api-10.0.1.tgz#7217a167e428a7603ff46685c4cc40bb1526e463" @@ -5573,7 +5661,7 @@ acorn@^7.0.0, acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.2.4, acorn@^8.4.1: +acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0: version "8.5.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== @@ -6029,7 +6117,7 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -array.prototype.flat@^1.2.1, array.prototype.flat@^1.2.3, array.prototype.flat@^1.2.5: +array.prototype.flat@^1.2.1, array.prototype.flat@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13" integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg== @@ -7893,11 +7981,6 @@ constants-browserify@1.0.0, constants-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= - content-disposition@0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" @@ -9286,14 +9369,6 @@ dns-txt@^2.0.2: dependencies: buffer-indexof "^1.0.0" -doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -9716,7 +9791,7 @@ errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: dependencies: prr "~1.0.1" -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== @@ -10194,7 +10269,7 @@ eslint-import-resolver-typescript@^2.4.0: resolve "^1.20.0" tsconfig-paths "^3.9.0" -eslint-module-utils@^2.6.0, eslint-module-utils@^2.7.1: +eslint-module-utils@^2.7.0, eslint-module-utils@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz#b435001c9f8dd4ab7f6d0efcae4b9696d4c24b7c" integrity sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ== @@ -10210,24 +10285,24 @@ eslint-plugin-cypress@^2.10.3: dependencies: globals "^11.12.0" -eslint-plugin-import@2.22.1: - version "2.22.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702" - integrity sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw== +eslint-plugin-import@2.25.2: + version "2.25.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz#b3b9160efddb702fc1636659e71ba1d10adbe9e9" + integrity sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g== dependencies: - array-includes "^3.1.1" - array.prototype.flat "^1.2.3" - contains-path "^0.1.0" + array-includes "^3.1.4" + array.prototype.flat "^1.2.5" debug "^2.6.9" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.4" - eslint-module-utils "^2.6.0" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.6" + eslint-module-utils "^2.7.0" has "^1.0.3" + is-core-module "^2.7.0" + is-glob "^4.0.3" minimatch "^3.0.4" - object.values "^1.1.1" - read-pkg-up "^2.0.0" - resolve "^1.17.0" - tsconfig-paths "^3.9.0" + object.values "^1.1.5" + resolve "^1.20.0" + tsconfig-paths "^3.11.0" eslint-plugin-import@^2.22.1: version "2.25.3" @@ -10329,6 +10404,14 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-6.0.0.tgz#9cf45b13c5ac8f3d4c50f46a5121f61b3e318978" + integrity sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" @@ -10404,6 +10487,50 @@ eslint@7.32.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" +eslint@8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.2.0.tgz#44d3fb506d0f866a506d97a0fc0e90ee6d06a815" + integrity sha512-erw7XmM+CLxTOickrimJ1SiF55jiNlVSp2qqm0NuBWPtHYQCegD5ZMaW0c3i5ytPqL+SSLaCxdvQXFPLJn+ABw== + dependencies: + "@eslint/eslintrc" "^1.0.4" + "@humanwhocodes/config-array" "^0.6.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^6.0.0" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.0.0" + espree "^9.0.0" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^6.0.1" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.2.0" + semver "^7.2.1" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + espree@^7.3.0, espree@^7.3.1: version "7.3.1" resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" @@ -10413,6 +10540,15 @@ espree@^7.3.0, espree@^7.3.1: acorn-jsx "^5.3.1" eslint-visitor-keys "^1.3.0" +espree@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.0.0.tgz#e90a2965698228502e771c7a58489b1a9d107090" + integrity sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ== + dependencies: + acorn "^8.5.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^3.0.0" + esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -12929,7 +13065,7 @@ is-color-stop@^1.1.0: rgb-regex "^1.0.1" rgba-regex "^1.0.0" -is-core-module@^2.2.0, is-core-module@^2.4.0, is-core-module@^2.5.0, is-core-module@^2.8.0: +is-core-module@^2.2.0, is-core-module@^2.4.0, is-core-module@^2.5.0, is-core-module@^2.7.0, is-core-module@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== @@ -14200,7 +14336,7 @@ js-string-escape@^1.0.1: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@4.1.0: +js-yaml@4.1.0, js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== @@ -14757,16 +14893,6 @@ listr2@^3.8.3: through "^2.3.8" wrap-ansi "^7.0.0" -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - load-json-file@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" @@ -16602,7 +16728,7 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -object.values@^1.1.0, object.values@^1.1.1, object.values@^1.1.3, object.values@^1.1.5: +object.values@^1.1.0, object.values@^1.1.3, object.values@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== @@ -17019,13 +17145,6 @@ parse-json@5.2.0, parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -17212,13 +17331,6 @@ path-to-regexp@^1.7.0: dependencies: isarray "0.0.1" -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - dependencies: - pify "^2.0.0" - path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -18971,14 +19083,6 @@ read-package-json-fast@^2.0.1: json-parse-even-better-errors "^2.3.0" npm-normalize-package-bin "^1.0.1" -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" @@ -18996,15 +19100,6 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" @@ -19197,7 +19292,7 @@ regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1: call-bind "^1.0.2" define-properties "^1.1.3" -regexpp@^3.1.0: +regexpp@^3.1.0, regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==