From d3dca9229265178025a97aa148e073e8a1e1ccd9 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 8 Jan 2024 14:48:45 +0800 Subject: [PATCH] Switch to the new ESLint config (#15869) --- .eslintignore | 26 +- .eslintrc.cjs | 442 ----------------- eslint.config.js | 455 ++++++++++++++++++ package.json | 6 +- scripts/bundle-eslint-config.cjs | 117 ----- scripts/bundle-eslint-config.js | 114 +++++ .../prefer-create-type-check-function.js | 4 +- yarn.lock | 51 +- 8 files changed, 628 insertions(+), 587 deletions(-) delete mode 100644 .eslintrc.cjs create mode 100644 eslint.config.js delete mode 100644 scripts/bundle-eslint-config.cjs create mode 100644 scripts/bundle-eslint-config.js diff --git a/.eslintignore b/.eslintignore index 180e998cb..545df7e0a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,17 +1,17 @@ .tmp -!/*.js -/tests/format/**/*.js -/tests/integration/cli/ -!/tests/format/**/jsfmt.spec.js -!/**/.eslintrc.js -/test*.* -/scripts/release/node_modules -/coverage/ -/dist*/ +# Do not use `tests/format/**/*`, since it will ignore directories +# https://github.com/eslint/eslint/issues/17964#issuecomment-1879772142 +tests/format/**/*.* +!tests/format/**/jsfmt.spec.js +tests/integration/cli/ +test*.* +scripts/release/node_modules +coverage/ +dist*/ **/node_modules/** -/website/build/ -/website/static/playground.js -/website/static/lib/ -/scripts/benchmark/*/ +website/build/ +website/static/playground.js +website/static/lib/ +scripts/benchmark/*/ **/.yarn/** **/.pnp.* diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index db02c16a7..000000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,442 +0,0 @@ -"use strict"; -const path = require("node:path"); -const { isCI } = require("ci-info"); - -module.exports = { - root: true, - env: { - es2022: true, - node: true, - }, - parserOptions: { - ecmaVersion: "latest", - sourceType: "module", - }, - extends: [ - "eslint:recommended", - "prettier", - "plugin:regexp/recommended", - "plugin:unicorn/recommended", - ], - plugins: [ - "@stylistic/js", - "@typescript-eslint", - "import", - "n", - "prettier-internal-rules", - "regexp", - "simple-import-sort", - "unicorn", - ], - rules: { - "arrow-body-style": ["error", "as-needed"], - curly: "error", - "dot-notation": "error", - eqeqeq: "error", - "logical-assignment-operators": "error", - "no-console": isCI ? "error" : "warn", - "no-constant-binary-expression": "error", - "no-duplicate-imports": "error", - "no-else-return": [ - "error", - { - allowElseIf: false, - }, - ], - "no-implicit-coercion": "error", - "no-inner-declarations": "error", - "no-lonely-if": "error", - "no-restricted-syntax": [ - "error", - // `!foo === bar` and `!foo !== bar` - 'BinaryExpression[operator=/^[!=]==$/] > UnaryExpression.left[operator="!"]', - ], - "no-unneeded-ternary": "error", - "no-useless-return": "error", - "no-unused-expressions": [ - "error", - { - allowShortCircuit: true, - allowTernary: true, - }, - ], - "no-unused-vars": [ - "error", - { - ignoreRestSiblings: true, - }, - ], - "no-var": "error", - "object-shorthand": [ - "error", - "always", - { - avoidExplicitReturnArrows: true, - }, - ], - "one-var": ["error", "never"], - "prefer-arrow-callback": "error", - "prefer-const": [ - "error", - { - destructuring: "all", - }, - ], - "prefer-destructuring": [ - "error", - { - VariableDeclarator: { - array: false, - object: true, - }, - AssignmentExpression: { - array: false, - object: false, - }, - }, - { - enforceForRenamedProperties: false, - }, - ], - "prefer-object-has-own": "error", - "prefer-object-spread": "error", - "prefer-rest-params": "error", - "prefer-spread": "error", - "require-await": "error", - "symbol-description": "error", - yoda: [ - "error", - "never", - { - exceptRange: true, - }, - ], - - // Internal rules - "prettier-internal-rules/jsx-identifier-case": "error", - "prettier-internal-rules/no-identifier-n": "error", - "prettier-internal-rules/prefer-fs-promises-submodule": "error", - - // @typescript-eslint/eslint-plugin - "@typescript-eslint/prefer-ts-expect-error": "error", - - "@stylistic/js/quotes": [ - "error", - "double", - { - avoidEscape: true, - }, - ], - - // eslint-plugin-import - "import/extensions": ["error", "ignorePackages"], - "import/no-extraneous-dependencies": [ - "error", - { - devDependencies: [ - "jest.config.js", - "tests/**", - "scripts/**", - "website/**/*", - ], - }, - ], - "import/no-anonymous-default-export": [ - "error", - { - allowArray: true, - allowArrowFunction: true, - allowAnonymousClass: false, - allowAnonymousFunction: false, - allowCallExpression: true, - allowNew: true, - allowLiteral: true, - allowObject: true, - }, - ], - - // eslint-plugin-n - "n/no-path-concat": "error", - - // eslint-plugin-regexp - "regexp/match-any": [ - "error", - { - allows: ["dotAll"], - }, - ], - /* cspell:disable-next-line */ - "regexp/no-extra-lookaround-assertions": "error", - "regexp/no-missing-g-flag": "error", - "regexp/no-useless-flag": [ - "error", - { - strictTypes: false, - }, - ], - /* cspell:disable-next-line */ - "regexp/prefer-lookaround": [ - "error", - { - strictTypes: false, - }, - ], - // Conflicting with `unicorn/better-regex` - "regexp/strict": "off", - // Hard to fix - "regexp/no-empty-alternative": "off", - "regexp/no-super-linear-backtracking": "off", - - "simple-import-sort/imports": "error", - "simple-import-sort/exports": "error", - - // eslint-plugin-unicorn - "unicorn/escape-case": "off", - "unicorn/catch-error-name": "off", - "unicorn/consistent-destructuring": "off", - "unicorn/consistent-function-scoping": "off", - "unicorn/import-style": "off", - "unicorn/no-array-callback-reference": "off", - "unicorn/no-array-method-this-argument": "off", - "unicorn/no-array-reduce": "off", - "unicorn/no-await-expression-member": "off", - "unicorn/no-for-loop": "off", - "unicorn/no-hex-escape": "off", - "unicorn/no-negated-condition": "off", - "unicorn/no-nested-ternary": "off", - "unicorn/no-null": "off", - "unicorn/no-process-exit": "off", - "unicorn/no-thenable": "off", - "unicorn/no-unreadable-array-destructuring": "off", - "unicorn/no-useless-switch-case": "off", - "unicorn/no-useless-undefined": [ - "error", - { - checkArrowFunctionBody: false, - }, - ], - "unicorn/number-literal-case": "off", - "unicorn/numeric-separators-style": "off", - "unicorn/prefer-array-flat": [ - "error", - { - functions: ["flat", "flatten"], - }, - ], - "unicorn/prefer-add-event-listener": "off", - "unicorn/prefer-at": [ - "error", - { - getLastElementFunctions: ["getLast"], - }, - ], - "unicorn/prefer-code-point": "off", - "unicorn/prefer-dom-node-append": "off", - "unicorn/prefer-dom-node-remove": "off", - "unicorn/prefer-export-from": [ - "error", - { - ignoreUsedVariables: true, - }, - ], - "unicorn/prefer-query-selector": "off", - "unicorn/prefer-ternary": "off", - "unicorn/prevent-abbreviations": "off", - "unicorn/relative-url-style": "off", - "unicorn/switch-case-braces": ["error", "avoid"], - }, - overrides: [ - // CommonJS modules - { - files: [ - "**/*.cjs", - "scripts/tools/eslint-plugin-prettier-internal-rules/**/*.js", - "website/**/*.js", - ], - parserOptions: { - sourceType: "script", - }, - rules: { - strict: "error", - "unicorn/prefer-module": "off", - "unicorn/prefer-node-protocol": "off", - }, - }, - { - files: ["scripts/**/*", "tests/config/install-prettier.js"], - rules: { - "no-console": "off", - }, - }, - { - files: ["scripts/**/*.js"], - rules: { - "unicorn/prefer-top-level-await": "error", - }, - }, - { - files: [ - "tests/config/**/*.js", - "tests/format/**/jsfmt.spec.js", - "tests/integration/**/*.js", - "tests/unit/**/*.js", - "tests/dts/unit/**/*.js", - "scripts/release/__tests__/**/*.spec.js", - ], - env: { - jest: true, - }, - plugins: ["jest"], - rules: { - "@stylistic/js/quotes": [ - "error", - "double", - { - avoidEscape: true, - allowTemplateLiterals: true, - }, - ], - - "jest/valid-expect": [ - "error", - { - alwaysAwait: true, - }, - ], - "jest/prefer-to-be": "error", - }, - }, - { - files: ["tests/format/**/*.js"], - rules: { - "prettier-internal-rules/no-legacy-format-test-fixtures": "error", - }, - }, - { - files: ["tests/integration/**/*.js"], - rules: { - "prettier-internal-rules/await-cli-tests": "error", - }, - }, - { - files: ["tests/**/*.js"], - rules: { - // TODO: Enable this when we drop support for Node.js v14 - "logical-assignment-operators": "off", - "unicorn/prefer-array-flat": "off", - "unicorn/prefer-array-flat-map": "off", - "unicorn/prefer-string-replace-all": "off", - }, - globals: { - run_spec: "readonly", - runCli: "readonly", - }, - }, - { - files: ["src/cli/**/*.js"], - rules: { - "n/no-restricted-import": [ - "error", - [ - { - name: [ - path.resolve(__dirname, "src/**"), - `!${path.resolve(__dirname, "src/cli/**")}`, - `!${path.resolve(__dirname, "src/index.js")}`, - ], - message: "Don't use code from other directory.", - }, - ], - ], - }, - }, - { - files: "src/language-js/needs-parens.js", - rules: { - "prettier-internal-rules/better-parent-property-check-in-needs-parens": - "error", - }, - }, - { - files: "src/**/*.js", - rules: { - "prettier-internal-rules/flat-ast-path-call": "error", - "prettier-internal-rules/no-conflicting-comment-check-flags": "error", - "prettier-internal-rules/no-doc-public-import": "error", - "prettier-internal-rules/no-empty-flat-contents-for-if-break": "error", - "prettier-internal-rules/no-unnecessary-ast-path-call": "error", - "prettier-internal-rules/prefer-ast-path-each": "error", - "prettier-internal-rules/prefer-indent-if-break": "error", - "prettier-internal-rules/prefer-is-non-empty-array": "error", - "prettier-internal-rules/prefer-ast-path-getters": "error", - }, - }, - { - files: ["src/language-*/**/*.js"], - rules: { - "prettier-internal-rules/directly-loc-start-end": "error", - }, - }, - { - files: ["src/language-js/**/*.js"], - excludedFiles: ["src/language-js/parse/postprocess/*.js"], - rules: { - "prettier-internal-rules/no-node-comments": [ - "error", - { - file: "src/language-js/utils/index.js", - functions: ["hasComment", "getComments"], - }, - "src/language-js/pragma.js", - "src/language-js/parse/babel.js", - "src/language-js/parse/meriyah.js", - "src/language-js/parse/json.js", - "src/language-js/parse/acorn.js", - "src/language-js/parse/utils/wrap-babel-expression.js", - ], - "prettier-internal-rules/prefer-create-type-check-function": [ - "error", - { - ignoreSingleType: true, - onlyTopLevelFunctions: true, - }, - ], - }, - }, - { - files: ["website/**/*"], - env: { - browser: true, - worker: true, - }, - extends: ["plugin:react/recommended"], - settings: { - react: { - version: "18", - }, - }, - rules: { - "react/display-name": "off", - "react/no-deprecated": "off", - "react/prop-types": "off", - "unicorn/filename-case": "off", - }, - }, - { - files: ["website/playground/**/*"], - parserOptions: { - sourceType: "module", - }, - }, - { - files: ["bin/prettier.cjs"], - parserOptions: { - ecmaVersion: 5, - }, - rules: { - "no-var": "off", - "prefer-arrow-callback": "off", - }, - }, - ], -}; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 000000000..b0fefe490 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,455 @@ +import fs from "node:fs/promises"; +import url from "node:url"; + +import { FlatCompat } from "@eslint/eslintrc"; +import eslintPluginJs from "@eslint/js"; +import eslintPluginStylisticJs from "@stylistic/eslint-plugin-js"; +import eslintPluginTypescriptEslint from "@typescript-eslint/eslint-plugin"; +import { isCI } from "ci-info"; +import eslintConfigPrettier from "eslint-config-prettier"; +import eslintPluginImport from "eslint-plugin-import"; +import eslintPluginJest from "eslint-plugin-jest"; +import eslintPluginN from "eslint-plugin-n"; +import eslintPluginReactConfigRecommended from "eslint-plugin-react/configs/recommended.js"; +import eslintPluginRegexp from "eslint-plugin-regexp"; +import eslintPluginSimpleImportSort from "eslint-plugin-simple-import-sort"; +import eslintPluginUnicorn from "eslint-plugin-unicorn"; + +import eslintPluginPrettierInternalRules from "./scripts/tools/eslint-plugin-prettier-internal-rules/index.js"; + +const toPath = (file) => url.fileURLToPath(new URL(file, import.meta.url)); +const compat = new FlatCompat({ baseDirectory: toPath("./") }); + +export default [ + eslintPluginJs.configs.recommended, + ...compat.config(eslintPluginRegexp.configs.recommended), + eslintPluginUnicorn.configs["flat/recommended"], + eslintConfigPrettier, + ...compat.env({ es2024: true, node: true }), + { + plugins: { + "@stylistic/js": eslintPluginStylisticJs, + "@typescript-eslint": eslintPluginTypescriptEslint, + import: eslintPluginImport, + n: eslintPluginN, + "prettier-internal-rules": eslintPluginPrettierInternalRules, + "simple-import-sort": eslintPluginSimpleImportSort, + }, + + rules: { + "arrow-body-style": ["error", "as-needed"], + curly: "error", + "dot-notation": "error", + eqeqeq: "error", + "logical-assignment-operators": "error", + "no-console": isCI ? "error" : "warn", + "no-constant-binary-expression": "error", + "no-duplicate-imports": "error", + "no-else-return": [ + "error", + { + allowElseIf: false, + }, + ], + "no-implicit-coercion": "error", + "no-inner-declarations": "error", + "no-lonely-if": "error", + "no-restricted-syntax": [ + "error", + // `!foo === bar` and `!foo !== bar` + 'BinaryExpression[operator=/^[!=]==$/] > UnaryExpression.left[operator="!"]', + ], + "no-unneeded-ternary": "error", + "no-useless-return": "error", + "no-unused-expressions": [ + "error", + { + allowShortCircuit: true, + allowTernary: true, + }, + ], + "no-unused-vars": [ + "error", + { + ignoreRestSiblings: true, + }, + ], + "no-var": "error", + "object-shorthand": [ + "error", + "always", + { + avoidExplicitReturnArrows: true, + }, + ], + "one-var": ["error", "never"], + "prefer-arrow-callback": "error", + "prefer-const": [ + "error", + { + destructuring: "all", + }, + ], + "prefer-destructuring": [ + "error", + { + VariableDeclarator: { + array: false, + object: true, + }, + AssignmentExpression: { + array: false, + object: false, + }, + }, + { + enforceForRenamedProperties: false, + }, + ], + "prefer-object-has-own": "error", + "prefer-object-spread": "error", + "prefer-rest-params": "error", + "prefer-spread": "error", + "require-await": "error", + "symbol-description": "error", + yoda: [ + "error", + "never", + { + exceptRange: true, + }, + ], + + // Internal rules + "prettier-internal-rules/jsx-identifier-case": "error", + "prettier-internal-rules/no-identifier-n": "error", + "prettier-internal-rules/prefer-fs-promises-submodule": "error", + + // @typescript-eslint/eslint-plugin + "@typescript-eslint/prefer-ts-expect-error": "error", + + "@stylistic/js/quotes": [ + "error", + "double", + { + avoidEscape: true, + }, + ], + + // eslint-plugin-import + "import/extensions": ["error", "ignorePackages"], + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: [ + "jest.config.js", + "tests/**", + "scripts/**", + "website/**/*", + "eslint.config.js", + ], + }, + ], + "import/no-anonymous-default-export": [ + "error", + { + allowArray: true, + allowArrowFunction: true, + allowAnonymousClass: false, + allowAnonymousFunction: false, + allowCallExpression: true, + allowNew: true, + allowLiteral: true, + allowObject: true, + }, + ], + + // eslint-plugin-n + "n/no-path-concat": "error", + + // eslint-plugin-regexp + "regexp/match-any": [ + "error", + { + allows: ["dotAll"], + }, + ], + /* cspell:disable-next-line */ + "regexp/no-extra-lookaround-assertions": "error", + "regexp/no-missing-g-flag": "error", + "regexp/no-useless-flag": [ + "error", + { + strictTypes: false, + }, + ], + /* cspell:disable-next-line */ + "regexp/prefer-lookaround": [ + "error", + { + strictTypes: false, + }, + ], + // Conflicting with `unicorn/better-regex` + "regexp/strict": "off", + // Hard to fix + "regexp/no-empty-alternative": "off", + "regexp/no-super-linear-backtracking": "off", + + "simple-import-sort/imports": "error", + "simple-import-sort/exports": "error", + + // eslint-plugin-unicorn + "unicorn/escape-case": "off", + "unicorn/catch-error-name": "off", + "unicorn/consistent-destructuring": "off", + "unicorn/consistent-function-scoping": "off", + "unicorn/import-style": "off", + "unicorn/no-array-callback-reference": "off", + "unicorn/no-array-method-this-argument": "off", + "unicorn/no-array-reduce": "off", + "unicorn/no-await-expression-member": "off", + "unicorn/no-for-loop": "off", + "unicorn/no-hex-escape": "off", + "unicorn/no-negated-condition": "off", + "unicorn/no-nested-ternary": "off", + "unicorn/no-null": "off", + "unicorn/no-process-exit": "off", + "unicorn/no-thenable": "off", + "unicorn/no-unreadable-array-destructuring": "off", + "unicorn/no-useless-switch-case": "off", + "unicorn/no-useless-undefined": [ + "error", + { + checkArrowFunctionBody: false, + }, + ], + "unicorn/number-literal-case": "off", + "unicorn/numeric-separators-style": "off", + "unicorn/prefer-array-flat": [ + "error", + { + functions: ["flat", "flatten"], + }, + ], + "unicorn/prefer-add-event-listener": "off", + "unicorn/prefer-at": [ + "error", + { + getLastElementFunctions: ["getLast"], + }, + ], + "unicorn/prefer-code-point": "off", + "unicorn/prefer-dom-node-append": "off", + "unicorn/prefer-dom-node-remove": "off", + "unicorn/prefer-export-from": [ + "error", + { + ignoreUsedVariables: true, + }, + ], + "unicorn/prefer-query-selector": "off", + "unicorn/prefer-ternary": "off", + "unicorn/prevent-abbreviations": "off", + "unicorn/relative-url-style": "off", + "unicorn/switch-case-braces": ["error", "avoid"], + }, + }, + { + ignores: (await fs.readFile("./.eslintignore", "utf8")) + .split("\n") + .filter((pattern) => pattern && !pattern.startsWith("#")), + }, + // CommonJS modules + { + files: [ + "**/*.cjs", + "scripts/tools/eslint-plugin-prettier-internal-rules/**/*.js", + "website/**/*.js", + ], + languageOptions: { + sourceType: "script", + }, + rules: { + strict: "error", + "unicorn/prefer-module": "off", + "unicorn/prefer-node-protocol": "off", + }, + }, + { + files: ["scripts/**/*", "tests/config/install-prettier.js"], + rules: { + "no-console": "off", + }, + }, + { + files: ["scripts/**/*.js"], + rules: { + "unicorn/prefer-top-level-await": "error", + }, + }, + ...compat.env({ jest: true }).map((config) => ({ + ...config, + files: [ + "tests/config/**/*.js", + "tests/format/**/jsfmt.spec.js", + "tests/integration/**/*.js", + "tests/unit/**/*.js", + "tests/dts/unit/**/*.js", + "scripts/release/__tests__/**/*.spec.js", + ], + plugins: { jest: eslintPluginJest }, + rules: { + "@stylistic/js/quotes": [ + "error", + "double", + { + avoidEscape: true, + allowTemplateLiterals: true, + }, + ], + "jest/valid-expect": [ + "error", + { + alwaysAwait: true, + }, + ], + "jest/prefer-to-be": "error", + }, + })), + { + files: ["tests/format/**/*.js"], + rules: { + "prettier-internal-rules/no-legacy-format-test-fixtures": "error", + }, + }, + { + files: ["tests/integration/**/*.js"], + rules: { + "prettier-internal-rules/await-cli-tests": "error", + }, + }, + { + files: ["tests/**/*.js"], + rules: { + // TODO: Enable this when we drop support for Node.js v14 + "logical-assignment-operators": "off", + "unicorn/prefer-array-flat": "off", + "unicorn/prefer-array-flat-map": "off", + "unicorn/prefer-string-replace-all": "off", + }, + languageOptions: { + globals: { + run_spec: "readonly", + runCli: "readonly", + }, + }, + }, + { + files: ["src/cli/**/*.js"], + rules: { + "n/no-restricted-import": [ + "error", + [ + { + name: [ + toPath("src/**"), + `!${toPath("src/cli/**")}`, + `!${toPath("src/index.js")}`, + ], + message: "Don't use code from other directory.", + }, + ], + ], + }, + }, + { + files: ["src/language-js/needs-parens.js"], + rules: { + "prettier-internal-rules/better-parent-property-check-in-needs-parens": + "error", + }, + }, + { + files: ["src/**/*.js"], + rules: { + "prettier-internal-rules/flat-ast-path-call": "error", + "prettier-internal-rules/no-conflicting-comment-check-flags": "error", + "prettier-internal-rules/no-doc-public-import": "error", + "prettier-internal-rules/no-empty-flat-contents-for-if-break": "error", + "prettier-internal-rules/no-unnecessary-ast-path-call": "error", + "prettier-internal-rules/prefer-ast-path-each": "error", + "prettier-internal-rules/prefer-indent-if-break": "error", + "prettier-internal-rules/prefer-is-non-empty-array": "error", + "prettier-internal-rules/prefer-ast-path-getters": "error", + }, + }, + { + files: ["src/language-*/**/*.js"], + rules: { + "prettier-internal-rules/directly-loc-start-end": "error", + }, + }, + { + files: ["src/language-js/**/*.js"], + ignores: ["src/language-js/parse/postprocess/*.js"], + rules: { + "prettier-internal-rules/no-node-comments": [ + "error", + { + file: "src/language-js/utils/index.js", + functions: ["hasComment", "getComments"], + }, + "src/language-js/pragma.js", + "src/language-js/parse/babel.js", + "src/language-js/parse/meriyah.js", + "src/language-js/parse/json.js", + "src/language-js/parse/acorn.js", + "src/language-js/parse/utils/wrap-babel-expression.js", + ], + "prettier-internal-rules/prefer-create-type-check-function": [ + "error", + { + ignoreSingleType: true, + onlyTopLevelFunctions: true, + }, + ], + }, + }, + ...compat + .env({ browser: true, worker: true }) + .map((config) => ({ ...config, files: ["website/**/*"] })), + Object.assign(eslintPluginReactConfigRecommended, { + files: ["website/**/*"], + settings: { + react: { + version: "18", + }, + }, + }), + { + files: ["website/**/*"], + rules: { + "react/display-name": "off", + "react/no-deprecated": "off", + "react/prop-types": "off", + "unicorn/filename-case": "off", + }, + }, + { + files: ["website/playground/**/*"], + languageOptions: { + sourceType: "module", + }, + }, + { + files: ["bin/prettier.cjs"], + languageOptions: { + ecmaVersion: 5, + }, + rules: { + "no-var": "off", + "prefer-arrow-callback": "off", + }, + }, +]; diff --git a/package.json b/package.json index 95a147703..b2c3dfc4e 100644 --- a/package.json +++ b/package.json @@ -107,8 +107,11 @@ }, "devDependencies": { "@babel/generator": "7.23.6", + "@eslint/eslintrc": "3.0.0", + "@eslint/js": "8.56.0", "@glimmer/reference": "0.87.1", "@stylistic/eslint-plugin-js": "1.5.3", + "@types/eslint__js": "8.42.3", "@types/estree": "1.0.5", "@types/file-entry-cache": "5.0.4", "@types/find-cache-dir": "3.2.1", @@ -131,7 +134,6 @@ "eslint-plugin-import": "2.29.1", "eslint-plugin-jest": "27.6.1", "eslint-plugin-n": "16.6.1", - "eslint-plugin-prettier-internal-rules": "2.0.1", "eslint-plugin-react": "7.33.2", "eslint-plugin-regexp": "2.1.2", "eslint-plugin-simple-import-sort": "10.0.0", @@ -163,7 +165,7 @@ "test:dev-package": "cross-env INSTALL_PACKAGE=1 yarn test", "test:dist": "cross-env NODE_ENV=production yarn test", "test:dist-standalone": "cross-env TEST_STANDALONE=1 yarn test:dist", - "test:dist-lint": "eslint --no-eslintrc --no-ignore --no-inline-config --config=./scripts/bundle-eslint-config.cjs \"dist/**/*.{js,cjs,mjs}\"", + "test:dist-lint": "eslint --no-ignore --no-inline-config --config=./scripts/bundle-eslint-config.js dist", "perf": "yarn && yarn build && cross-env NODE_ENV=production node ./dist/bin/prettier.cjs", "perf:inspect": "yarn && yarn build && cross-env NODE_ENV=production node --inspect-brk ./dist/bin/prettier.cjs", "perf:benchmark": "yarn perf --debug-benchmark", diff --git a/scripts/bundle-eslint-config.cjs b/scripts/bundle-eslint-config.cjs deleted file mode 100644 index 14ec8dfea..000000000 --- a/scripts/bundle-eslint-config.cjs +++ /dev/null @@ -1,117 +0,0 @@ -"use strict"; - -const targets = require("../package.json").browserslist; - -/* TODO[@fisker]: Fix `no-restricted-syntax` */ - -module.exports = { - root: true, - parserOptions: { - ecmaVersion: "latest", - }, - settings: { - targets, - lintAllEsApis: true, - polyfills: [ - // These are not really polyfilled, but seems safe to use in target browsers - "BigInt", - "Symbol.asyncIterator", - ], - }, - plugins: ["compat"], - overrides: [ - { - files: ["**/*"], - rules: { - "no-restricted-syntax": [ - "error", - // Forbid `require()` .mjs file - { - selector: - 'CallExpression[callee.name="require"][arguments.0.value=/^\\..*?\\.mjs$/]', - message: ".mjs file can't be `require()`d", - }, - ], - }, - }, - { - files: ["**/*.mjs"], - parserOptions: { - sourceType: "module", - }, - }, - { - files: [ - "doc.js", - "doc.mjs", - "standalone.js", - "standalone.mjs", - "plugins/*", - ], - env: { - browser: true, - }, - rules: { - "compat/compat": "error", - // "no-restricted-syntax": [ - // "error", - // // Forbid `require()` - // { - // selector: 'CallExpression[callee.name="require"]', - // message: - // "Universal bundles should not include any `require()` call.", - // }, - // { - // selector: "ImportDeclaration", - // message: - // "Universal bundles should not include any `import` declaration.", - // }, - // { - // selector: - // ":matches(ExportAllDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration)[source]", - // message: "Universal bundles should not `export` from other files.", - // }, - // { - // selector: "ImportExpression", - // message: "Universal bundles should not include any `import()`.", - // }, - // ], - }, - }, - { - files: ["index.cjs", "index.mjs", "bin/*", "internal/*"], - rules: { - // "no-restricted-syntax": [ - // "error", - // // Forbid top level `require()` parsers - // { - // selector: - // 'CallExpression:not(:function *)[callee.name="require"][arguments.0.value=/plugins/]', - // message: "Parsers should be inline `require()`d.", - // }, - // // Forbid top level `import()` parsers - // { - // selector: - // "ImportExpression:not(:function *)[source.value=/plugins/]", - // message: "Parsers should be inline `import()`ed.", - // }, - // // Forbid `import`/`export` parsers - // { - // selector: - // ":matches(ImportDeclaration, ExportAllDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration)[source.value=/plugins/]", - // message: "Parsers should be inline `import()`ed.", - // }, - // ], - }, - }, - { - files: ["bin/prettier.cjs"], - parserOptions: { - ecmaVersion: 5, - }, - rules: { - "compat/compat": "error", - }, - }, - ], -}; diff --git a/scripts/bundle-eslint-config.js b/scripts/bundle-eslint-config.js new file mode 100644 index 000000000..f4a204328 --- /dev/null +++ b/scripts/bundle-eslint-config.js @@ -0,0 +1,114 @@ +import fs from "node:fs/promises"; +import url from "node:url"; + +import { FlatCompat } from "@eslint/eslintrc"; +import eslintPluginCompat from "eslint-plugin-compat"; + +const { browserslist: targets } = JSON.parse( + await fs.readFile(new URL("../package.json", import.meta.url)), +); + +const toPath = (file) => url.fileURLToPath(new URL(file, import.meta.url)); +const compat = new FlatCompat({ baseDirectory: toPath("./") }); + +/* TODO[@fisker]: Fix `no-restricted-syntax` */ + +export default [ + { + plugins: { + compat: eslintPluginCompat, + }, + settings: { + targets, + lintAllEsApis: true, + polyfills: [ + // These are not really polyfilled, but seems safe to use in target browsers + "BigInt", + "Symbol.asyncIterator", + ], + }, + rules: { + "no-restricted-syntax": [ + "error", + // Forbid `require()` .mjs file + { + selector: + 'CallExpression[callee.name="require"][arguments.0.value=/^\\..*?\\.mjs$/]', + message: ".mjs file can't be `require()`d", + }, + ], + }, + }, + + { + files: [ + "doc.js", + "doc.mjs", + "standalone.js", + "standalone.mjs", + "plugins/*", + ], + ...compat.env({ browser: true }), + rules: { + "compat/compat": "error", + // "no-restricted-syntax": [ + // "error", + // // Forbid `require()` + // { + // selector: 'CallExpression[callee.name="require"]', + // message: + // "Universal bundles should not include any `require()` call.", + // }, + // { + // selector: "ImportDeclaration", + // message: + // "Universal bundles should not include any `import` declaration.", + // }, + // { + // selector: + // ":matches(ExportAllDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration)[source]", + // message: "Universal bundles should not `export` from other files.", + // }, + // { + // selector: "ImportExpression", + // message: "Universal bundles should not include any `import()`.", + // }, + // ], + }, + }, + { + files: ["index.cjs", "index.mjs", "bin/*", "internal/*"], + rules: { + // "no-restricted-syntax": [ + // "error", + // // Forbid top level `require()` parsers + // { + // selector: + // 'CallExpression:not(:function *)[callee.name="require"][arguments.0.value=/plugins/]', + // message: "Parsers should be inline `require()`d.", + // }, + // // Forbid top level `import()` parsers + // { + // selector: + // "ImportExpression:not(:function *)[source.value=/plugins/]", + // message: "Parsers should be inline `import()`ed.", + // }, + // // Forbid `import`/`export` parsers + // { + // selector: + // ":matches(ImportDeclaration, ExportAllDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration)[source.value=/plugins/]", + // message: "Parsers should be inline `import()`ed.", + // }, + // ], + }, + }, + { + files: ["bin/prettier.cjs"], + languageOptions: { + ecmaVersion: 5, + }, + rules: { + "compat/compat": "error", + }, + }, +]; diff --git a/scripts/tools/eslint-plugin-prettier-internal-rules/prefer-create-type-check-function.js b/scripts/tools/eslint-plugin-prettier-internal-rules/prefer-create-type-check-function.js index 65eb0aa99..d99341ff7 100644 --- a/scripts/tools/eslint-plugin-prettier-internal-rules/prefer-create-type-check-function.js +++ b/scripts/tools/eslint-plugin-prettier-internal-rules/prefer-create-type-check-function.js @@ -164,9 +164,7 @@ module.exports = { fixable: "code", }, create(context) { - const { ignoreSingleType, onlyTopLevelFunctions } = { - ignoreSingleType: false, - onlyTopLevelFunctions: false, + const { ignoreSingleType = false, onlyTopLevelFunctions = false } = { ...context.options[0], }; const sourceCode = context.getSourceCode(); diff --git a/yarn.lock b/yarn.lock index ca34bc2ed..7b1eb7a1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1073,6 +1073,23 @@ __metadata: languageName: node linkType: hard +"@eslint/eslintrc@npm:3.0.0": + version: 3.0.0 + resolution: "@eslint/eslintrc@npm:3.0.0" + dependencies: + ajv: "npm:^6.12.4" + debug: "npm:^4.3.2" + espree: "npm:^9.6.0" + globals: "npm:^13.19.0" + ignore: "npm:^5.2.0" + import-fresh: "npm:^3.2.1" + js-yaml: "npm:^4.1.0" + minimatch: "npm:^3.1.2" + strip-json-comments: "npm:^3.1.1" + checksum: 329060fa3f63049aa66272b9c713acf73123dcd5d2eba5eebedd196cae6db7000d2e4c6107f826cbd60579916be1bf0601e0551872f2015ad14490e803aded87 + languageName: node + linkType: hard + "@eslint/eslintrc@npm:^2.1.4": version: 2.1.4 resolution: "@eslint/eslintrc@npm:2.1.4" @@ -1796,7 +1813,26 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:1.0.5": +"@types/eslint@npm:*": + version: 8.56.1 + resolution: "@types/eslint@npm:8.56.1" + dependencies: + "@types/estree": "npm:*" + "@types/json-schema": "npm:*" + checksum: 985fd0293e454c459e672e73857920d0746f2eaae8b9aa13a4078c6d3d8fd0d2272f07f67b7fd9078a52d8fe7e1e61a498944129c0f4bc4c29c9cfa968168f5e + languageName: node + linkType: hard + +"@types/eslint__js@npm:8.42.3": + version: 8.42.3 + resolution: "@types/eslint__js@npm:8.42.3" + dependencies: + "@types/eslint": "npm:*" + checksum: e31f19de642d35a664695d0cab873ce6de19b8a3506755835b91f8a49a8c41099dcace449df49f1a486de6fa6565d21ceb1fa33be6004fc7adef9226e5d256a1 + languageName: node + linkType: hard + +"@types/estree@npm:*, @types/estree@npm:1.0.5": version: 1.0.5 resolution: "@types/estree@npm:1.0.5" checksum: 7de6d928dd4010b0e20c6919e1a6c27b61f8d4567befa89252055fad503d587ecb9a1e3eab1b1901f923964d7019796db810b7fd6430acb26c32866d126fd408 @@ -1863,7 +1899,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 1a3c3e06236e4c4aab89499c428d585527ce50c24fe8259e8b3926d3df4cfbbbcf306cfc73ddfb66cbafc973116efd15967020b0f738f63e09e64c7d260519e7 @@ -3857,13 +3893,6 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-prettier-internal-rules@npm:2.0.1": - version: 2.0.1 - resolution: "eslint-plugin-prettier-internal-rules@npm:2.0.1" - checksum: 9c30e4db037014a355f9a9c553f48b30384f8b8245584143062c186ae66fe7ff3b7e1a9ad7c85701a6f178cb1424b90c3abb51e686943c6821d777cdfab4ed81 - languageName: node - linkType: hard - "eslint-plugin-react@npm:7.33.2": version: 7.33.2 resolution: "eslint-plugin-react@npm:7.33.2" @@ -7306,12 +7335,15 @@ __metadata: "@babel/generator": "npm:7.23.6" "@babel/parser": "npm:7.23.6" "@babel/types": "npm:7.23.6" + "@eslint/eslintrc": "npm:3.0.0" + "@eslint/js": "npm:8.56.0" "@glimmer/reference": "npm:0.87.1" "@glimmer/syntax": "npm:0.87.1" "@iarna/toml": "npm:2.2.5" "@prettier/is-es5-identifier-name": "npm:0.2.0" "@prettier/parse-srcset": "npm:3.1.0" "@stylistic/eslint-plugin-js": "npm:1.5.3" + "@types/eslint__js": "npm:8.42.3" "@types/estree": "npm:1.0.5" "@types/file-entry-cache": "npm:5.0.4" "@types/find-cache-dir": "npm:3.2.1" @@ -7351,7 +7383,6 @@ __metadata: eslint-plugin-import: "npm:2.29.1" eslint-plugin-jest: "npm:27.6.1" eslint-plugin-n: "npm:16.6.1" - eslint-plugin-prettier-internal-rules: "npm:2.0.1" eslint-plugin-react: "npm:7.33.2" eslint-plugin-regexp: "npm:2.1.2" eslint-plugin-simple-import-sort: "npm:10.0.0"