Compare commits
	
		
			43 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | c22a36bbec | ||
|  | 71e8f0c3b2 | ||
|  | e0071450be | ||
|  | bfa0e2bb80 | ||
|  | 49b9b7f7db | ||
|  | 3a2c549110 | ||
|  | 59308e8e36 | ||
|  | cf1240c847 | ||
|  | 0ff5e45fdd | ||
|  | effc708692 | ||
|  | ea307c91e5 | ||
|  | b7ce1614d8 | ||
|  | bf390b0693 | ||
|  | 500fe9df8d | ||
|  | 5be2b3fd39 | ||
|  | 5821926148 | ||
|  | 3ef955d56f | ||
|  | 1b25322bf5 | ||
|  | 2ed8536b85 | ||
|  | 4edff9cd15 | ||
|  | f245939bfa | ||
|  | be5bc8009c | ||
|  | d4a9ebcc17 | ||
|  | c1355234c0 | ||
|  | 6dfc773b05 | ||
|  | 2bf0c8d727 | ||
|  | 504de8392a | ||
|  | 6cf4794985 | ||
|  | bbed70b969 | ||
|  | f553c519f6 | ||
|  | 4e77637da4 | ||
|  | abf5c27385 | ||
|  | 7b48da27dc | ||
|  | 0947ddb151 | ||
|  | 0a9c9b0384 | ||
|  | 84ae087ea0 | ||
|  | 5d908028ca | ||
|  | 610d886afd | ||
|  | aefa76e48a | ||
|  | e787e9a647 | ||
|  | a3598d36d2 | ||
|  | 7b399a63db | ||
|  | bb09e1d6b4 | 
							
								
								
									
										46
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| # @antfu/eslint-config | ||||
|  | ||||
| [](https://npmjs.com/package/@antfu/eslint-config) | ||||
| [](https://npmjs.com/package/@antfu/eslint-config) [](https://github.com/antfu/eslint-config) | ||||
|  | ||||
| - Single quotes, no semi | ||||
| - Auto fix for formatting (aimed to be used standalone **without** Prettier) | ||||
| @@ -41,26 +41,48 @@ For example: | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ### Config VS Code auto fix | ||||
| ### VS Code support (auto fix) | ||||
|  | ||||
| Install [VS Code ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and create `.vscode/settings.json` | ||||
| Install [VS Code ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) | ||||
|  | ||||
| ```json | ||||
| Add the following settings to your `settings.json`: | ||||
|  | ||||
| ```jsonc | ||||
| { | ||||
|   "prettier.enable": false, | ||||
|   "editor.formatOnSave": false, | ||||
|   "editor.codeActionsOnSave": { | ||||
|     "source.fixAll.eslint": true | ||||
|   } | ||||
|     "source.fixAll.eslint": true, | ||||
|     "source.organizeImports": false | ||||
|   }, | ||||
|  | ||||
|   // The following is optional. | ||||
|   // It's better to put under project setting `.vscode/settings.json` | ||||
|   // to avoid conflicts with working with different eslint configs | ||||
|   // that does not support all formats. | ||||
|   "eslint.validate": [ | ||||
|     "javascript", | ||||
|     "javascriptreact", | ||||
|     "typescript", | ||||
|     "typescriptreact", | ||||
|     "vue", | ||||
|     "html", | ||||
|     "markdown", | ||||
|     "json", | ||||
|     "jsonc", | ||||
|     "yaml" | ||||
|   ] | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ### TypeScript Aware Rules | ||||
|  | ||||
| Type aware rules are enabled when a `tsconfig.eslint.json` is found in the project root, which will introduce some stricter rules into your project. If you want to enable it while have no `tsconfig.eslint.json` in the project root, you can change tsconfig name by modifying `ESLINT_TSCONFIG` env.  | ||||
| Type aware rules are enabled when a `tsconfig.eslint.json` is found in the project root, which will introduce some stricter rules into your project. If you want to enable it while have no `tsconfig.eslint.json` in the project root, you can change tsconfig name by modifying `ESLINT_TSCONFIG` env. | ||||
|  | ||||
| ```js | ||||
| // .eslintrc.js | ||||
| const process = require('node:process') | ||||
|  | ||||
| process.env.ESLINT_TSCONFIG = 'tsconfig.json' | ||||
|  | ||||
| module.exports = { | ||||
| @@ -89,6 +111,16 @@ and then | ||||
| npm i -D lint-staged simple-git-hooks | ||||
| ``` | ||||
|  | ||||
| ## Badge | ||||
|  | ||||
| If you enjoy this code style, and would like to mention it in your project, here is the badge you can use: | ||||
|  | ||||
| ```md | ||||
| [](https://github.com/antfu/eslint-config) | ||||
| ``` | ||||
|  | ||||
| [](https://github.com/antfu/eslint-config) | ||||
|  | ||||
| ## FAQ | ||||
|  | ||||
| ### Prettier? | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| { | ||||
|   "type": "module", | ||||
|   "private": true, | ||||
|   "packageManager": "pnpm@8.5.1", | ||||
|   "packageManager": "pnpm@8.6.12", | ||||
|   "scripts": { | ||||
|     "build": "vite-ssg build", | ||||
|     "dev": "vite --port 3333 --open", | ||||
| @@ -15,48 +15,48 @@ | ||||
|     "up": "taze major -I" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@unocss/reset": "^0.52.1", | ||||
|     "@vueuse/core": "^10.1.2", | ||||
|     "@unocss/reset": "^0.54.2", | ||||
|     "@vueuse/core": "^10.3.0", | ||||
|     "@vueuse/head": "^1.1.26", | ||||
|     "nprogress": "^0.2.0", | ||||
|     "pinia": "^2.1.3", | ||||
|     "pinia": "^2.1.6", | ||||
|     "vue": "^3.3.4", | ||||
|     "vue-demi": "^0.14.5", | ||||
|     "vue-i18n": "^9.2.2", | ||||
|     "vue-router": "^4.2.1" | ||||
|     "vue-router": "^4.2.4" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@antfu/eslint-config": "^0.39.1", | ||||
|     "@iconify-json/carbon": "^1.1.16", | ||||
|     "@antfu/eslint-config": "^0.40.0", | ||||
|     "@iconify-json/carbon": "^1.1.19", | ||||
|     "@intlify/vite-plugin-vue-i18n": "^7.0.0", | ||||
|     "@types/markdown-it-link-attributes": "^3.0.1", | ||||
|     "@types/nprogress": "^0.2.0", | ||||
|     "@vitejs/plugin-vue": "^4.2.3", | ||||
|     "@vue/test-utils": "^2.3.2", | ||||
|     "critters": "^0.0.16", | ||||
|     "@vue/test-utils": "^2.4.1", | ||||
|     "critters": "^0.0.20", | ||||
|     "cross-env": "^7.0.3", | ||||
|     "cypress": "^12.12.0", | ||||
|     "eslint": "^8.41.0", | ||||
|     "cypress": "^12.17.3", | ||||
|     "eslint": "^8.46.0", | ||||
|     "eslint-plugin-cypress": "^2.13.3", | ||||
|     "https-localhost": "^4.7.1", | ||||
|     "markdown-it-link-attributes": "^4.0.1", | ||||
|     "markdown-it-shiki": "^0.9.0", | ||||
|     "pnpm": "^8.5.1", | ||||
|     "shiki": "^0.14.2", | ||||
|     "taze": "^0.10.1", | ||||
|     "typescript": "^5.0.4", | ||||
|     "unocss": "^0.52.1", | ||||
|     "unplugin-auto-import": "^0.16.2", | ||||
|     "unplugin-vue-components": "^0.24.1", | ||||
|     "vite": "^4.3.8", | ||||
|     "vite-plugin-inspect": "^0.7.26", | ||||
|     "vite-plugin-pages": "^0.30.1", | ||||
|     "vite-plugin-pwa": "^0.15.0", | ||||
|     "pnpm": "^8.6.12", | ||||
|     "shiki": "^0.14.3", | ||||
|     "taze": "^0.11.2", | ||||
|     "typescript": "^5.1.6", | ||||
|     "unocss": "^0.54.2", | ||||
|     "unplugin-auto-import": "^0.16.6", | ||||
|     "unplugin-vue-components": "^0.25.1", | ||||
|     "vite": "^4.4.9", | ||||
|     "vite-plugin-inspect": "^0.7.35", | ||||
|     "vite-plugin-pages": "^0.31.0", | ||||
|     "vite-plugin-pwa": "^0.16.4", | ||||
|     "vite-plugin-vue-layouts": "^0.8.0", | ||||
|     "vite-plugin-vue-markdown": "^0.23.5", | ||||
|     "vite-ssg": "^0.22.2", | ||||
|     "vite-plugin-vue-markdown": "^0.23.7", | ||||
|     "vite-ssg": "^0.23.1", | ||||
|     "vite-ssg-sitemap": "^0.5.1", | ||||
|     "vitest": "^0.31.1", | ||||
|     "vue-tsc": "^1.6.5" | ||||
|     "vitest": "^0.34.1", | ||||
|     "vue-tsc": "^1.8.8" | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,8 +1,8 @@ | ||||
| { | ||||
|   "name": "@antfu/eslint-config-monorepo", | ||||
|   "version": "0.39.2", | ||||
|   "version": "0.40.2", | ||||
|   "private": true, | ||||
|   "packageManager": "pnpm@8.5.1", | ||||
|   "packageManager": "pnpm@8.6.12", | ||||
|   "author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)", | ||||
|   "license": "MIT", | ||||
|   "scripts": { | ||||
| @@ -14,10 +14,10 @@ | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@antfu/eslint-config": "workspace:*", | ||||
|     "bumpp": "^9.1.0", | ||||
|     "eslint": "^8.41.0", | ||||
|     "bumpp": "^9.1.1", | ||||
|     "eslint": "^8.46.0", | ||||
|     "eslint-plugin-antfu": "link:./packages/eslint-plugin-antfu", | ||||
|     "rimraf": "^5.0.1", | ||||
|     "typescript": "^5.0.4" | ||||
|     "typescript": "^5.1.6" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -142,8 +142,9 @@ module.exports = { | ||||
|             pathPattern: '^exports.*$', | ||||
|             order: [ | ||||
|               'types', | ||||
|               'require', | ||||
|               'import', | ||||
|               'require', | ||||
|               'default', | ||||
|             ], | ||||
|           }, | ||||
|         ], | ||||
| @@ -204,6 +205,7 @@ module.exports = { | ||||
|         'no-unused-vars': 'off', | ||||
|         'antfu/no-cjs-exports': 'off', | ||||
|         'antfu/no-ts-export-equal': 'off', | ||||
|         'n/prefer-global/process': 'off', | ||||
|       }, | ||||
|     }, | ||||
|   ], | ||||
| @@ -215,6 +217,7 @@ module.exports = { | ||||
|     'import/no-unresolved': 'off', | ||||
|     'import/no-absolute-path': 'off', | ||||
|     'import/newline-after-import': ['error', { count: 1, considerComments: true }], | ||||
|     'import/no-self-import': 'error', | ||||
|  | ||||
|     // Common | ||||
|     'semi': ['error', 'never'], | ||||
| @@ -240,7 +243,7 @@ module.exports = { | ||||
|     'no-debugger': 'error', | ||||
|     'no-console': ['error', { allow: ['warn', 'error'] }], | ||||
|     'no-cond-assign': ['error', 'always'], | ||||
|     'func-call-spacing': ['off', 'never'], | ||||
|     'func-call-spacing': 'off', | ||||
|     'key-spacing': ['error', { beforeColon: false, afterColon: true }], | ||||
|     'indent': ['error', 2, { SwitchCase: 1, VariableDeclarator: 1, outerIIFEBody: 1 }], | ||||
|     'no-restricted-syntax': [ | ||||
| @@ -259,6 +262,19 @@ module.exports = { | ||||
|         asyncArrow: 'always', | ||||
|       }, | ||||
|     ], | ||||
|     'no-restricted-globals': [ | ||||
|       'error', | ||||
|       { name: 'global', message: 'Use `globalThis` instead.' }, | ||||
|       { name: 'self', message: 'Use `globalThis` instead.' }, | ||||
|     ], | ||||
|     'no-restricted-properties': [ | ||||
|       'error', | ||||
|       { property: '__proto__', message: 'Use `Object.getPrototypeOf` or `Object.setPrototypeOf` instead.' }, | ||||
|       { property: '__defineGetter__', message: 'Use `Object.defineProperty` instead.' }, | ||||
|       { property: '__defineSetter__', message: 'Use `Object.defineProperty` instead.' }, | ||||
|       { property: '__lookupGetter__', message: 'Use `Object.getOwnPropertyDescriptor` instead.' }, | ||||
|       { property: '__lookupSetter__', message: 'Use `Object.getOwnPropertyDescriptor` instead.' }, | ||||
|     ], | ||||
|  | ||||
|     // es6 | ||||
|     'no-var': 'error', | ||||
| @@ -307,7 +323,7 @@ module.exports = { | ||||
|     'array-callback-return': 'error', | ||||
|     'block-scoped-var': 'error', | ||||
|     'consistent-return': 'off', | ||||
|     'complexity': ['off', 11], | ||||
|     'complexity': 'off', | ||||
|     'eqeqeq': ['error', 'smart'], | ||||
|     'no-alert': 'warn', | ||||
|     'no-case-declarations': 'error', | ||||
| @@ -324,7 +340,7 @@ module.exports = { | ||||
|     'max-statements-per-line': ['error', { max: 1 }], | ||||
|  | ||||
|     // node | ||||
|     // 'n/prefer-global/process': ['error', 'never'], // Not sure if we need it as we are using `process.env.NODE_ENV` a lot in front-end. | ||||
|     'n/prefer-global/process': ['error', 'never'], | ||||
|     'n/prefer-global/buffer': ['error', 'never'], | ||||
|     'n/no-callback-literal': 'off', | ||||
|  | ||||
| @@ -353,6 +369,10 @@ module.exports = { | ||||
|     'unicorn/throw-new-error': 'error', | ||||
|     // Prefer using the node: protocol | ||||
|     'unicorn/prefer-node-protocol': 'error', | ||||
|     // Prefer using number properties like `Number.isNaN` rather than `isNaN` | ||||
|     'unicorn/prefer-number-properties': 'error', | ||||
|     // Ban `new Array` as `Array` constructor's params are ambiguous | ||||
|     'unicorn/no-new-array': 'error', | ||||
|  | ||||
|     'no-use-before-define': ['error', { functions: false, classes: false, variables: true }], | ||||
|     'eslint-comments/disable-enable-pair': 'off', | ||||
| @@ -376,6 +396,7 @@ module.exports = { | ||||
|     'yml/no-empty-document': 'off', | ||||
|  | ||||
|     // antfu | ||||
|     'antfu/no-import-node-modules-by-path': 'error', | ||||
|     'antfu/if-newline': 'error', | ||||
|     'antfu/import-dedupe': 'error', | ||||
|     'antfu/top-level-function': 'error', | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@antfu/eslint-config-basic", | ||||
|   "version": "0.39.2", | ||||
|   "version": "0.40.2", | ||||
|   "description": "", | ||||
|   "author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)", | ||||
|   "license": "MIT", | ||||
| @@ -22,19 +22,19 @@ | ||||
|     "eslint-plugin-antfu": "workspace:*", | ||||
|     "eslint-plugin-eslint-comments": "^3.2.0", | ||||
|     "eslint-plugin-html": "^7.1.0", | ||||
|     "eslint-plugin-import": "^2.27.5", | ||||
|     "eslint-plugin-jsonc": "^2.8.0", | ||||
|     "eslint-plugin-markdown": "^3.0.0", | ||||
|     "eslint-plugin-n": "^16.0.0", | ||||
|     "eslint-plugin-import": "npm:eslint-plugin-i@2.28.0-2", | ||||
|     "eslint-plugin-jsonc": "^2.9.0", | ||||
|     "eslint-plugin-markdown": "^3.0.1", | ||||
|     "eslint-plugin-n": "^16.0.1", | ||||
|     "eslint-plugin-no-only-tests": "^3.1.0", | ||||
|     "eslint-plugin-promise": "^6.1.1", | ||||
|     "eslint-plugin-unicorn": "^47.0.0", | ||||
|     "eslint-plugin-unused-imports": "^2.0.0", | ||||
|     "eslint-plugin-yml": "^1.7.0", | ||||
|     "eslint-plugin-unicorn": "^48.0.1", | ||||
|     "eslint-plugin-unused-imports": "^3.0.0", | ||||
|     "eslint-plugin-yml": "^1.8.0", | ||||
|     "jsonc-eslint-parser": "^2.3.0", | ||||
|     "yaml-eslint-parser": "^1.2.2" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "eslint": "^8.41.0" | ||||
|     "eslint": "^8.46.0" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -9,20 +9,24 @@ module.exports = { | ||||
|     }, | ||||
|     sourceType: 'module', | ||||
|   }, | ||||
|  | ||||
|   env: { | ||||
|     es2021: true, | ||||
|     node: true, | ||||
|   }, | ||||
|  | ||||
|   plugins: [ | ||||
|     'import', | ||||
|     'n', | ||||
|     'promise', | ||||
|   ], | ||||
|  | ||||
|   globals: { | ||||
|     document: 'readonly', | ||||
|     navigator: 'readonly', | ||||
|     window: 'readonly', | ||||
|   }, | ||||
|  | ||||
|   rules: { | ||||
|     'no-var': 'warn', | ||||
|     'object-shorthand': ['warn', 'properties'], | ||||
| @@ -126,7 +130,7 @@ module.exports = { | ||||
|     'no-mixed-operators': ['error', { | ||||
|       groups: [ | ||||
|         ['==', '!=', '===', '!==', '>', '>=', '<', '<='], | ||||
|         ['&&', '||', '?:'], | ||||
|         ['&&', '||'], | ||||
|         ['in', 'instanceof'], | ||||
|       ], | ||||
|       allowSamePrecedence: true, | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@antfu/eslint-config-react", | ||||
|   "version": "0.39.2", | ||||
|   "version": "0.40.2", | ||||
|   "description": "", | ||||
|   "author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)", | ||||
|   "license": "MIT", | ||||
| @@ -20,12 +20,12 @@ | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@antfu/eslint-config-ts": "workspace:*", | ||||
|     "eslint-plugin-react": "^7.32.2", | ||||
|     "eslint-plugin-react": "^7.33.1", | ||||
|     "eslint-plugin-react-hooks": "^4.6.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "eslint": "^8.41.0", | ||||
|     "eslint": "^8.46.0", | ||||
|     "react": "^18.2.0", | ||||
|     "typescript": "^5.0.4" | ||||
|     "typescript": "^5.1.6" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| const fs = require('node:fs') | ||||
| const { join } = require('node:path') | ||||
| const process = require('node:process') | ||||
| const basic = require('@antfu/eslint-config-basic') | ||||
|  | ||||
| const tsconfig = process.env.ESLINT_TSCONFIG || 'tsconfig.eslint.json' | ||||
| @@ -72,7 +73,6 @@ module.exports = { | ||||
|     '@typescript-eslint/consistent-type-definitions': ['error', 'interface'], | ||||
|     '@typescript-eslint/prefer-ts-expect-error': 'error', | ||||
|     '@typescript-eslint/no-require-imports': 'error', | ||||
|  | ||||
|     // Override JS | ||||
|     'no-useless-constructor': 'off', | ||||
|     'indent': 'off', | ||||
| @@ -160,6 +160,8 @@ module.exports = { | ||||
|     'antfu/generic-spacing': 'error', | ||||
|     'antfu/no-cjs-exports': 'error', | ||||
|     'antfu/no-ts-export-equal': 'error', | ||||
|     'antfu/no-const-enum': 'error', | ||||
|     'antfu/named-tuple-spacing': 'error', | ||||
|  | ||||
|     // off | ||||
|     '@typescript-eslint/consistent-indexed-object-style': 'off', | ||||
| @@ -173,7 +175,6 @@ module.exports = { | ||||
|     '@typescript-eslint/no-empty-function': 'off', | ||||
|     '@typescript-eslint/no-non-null-assertion': 'off', | ||||
|     '@typescript-eslint/explicit-module-boundary-types': 'off', | ||||
|     '@typescript-eslint/ban-types': 'off', | ||||
|     '@typescript-eslint/triple-slash-reference': 'off', | ||||
|     // handled by unused-imports/no-unused-imports | ||||
|     '@typescript-eslint/no-unused-vars': 'off', | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@antfu/eslint-config-ts", | ||||
|   "version": "0.39.2", | ||||
|   "version": "0.40.2", | ||||
|   "description": "", | ||||
|   "author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)", | ||||
|   "license": "MIT", | ||||
| @@ -18,11 +18,11 @@ | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@antfu/eslint-config-basic": "workspace:*", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.59.7", | ||||
|     "@typescript-eslint/parser": "^5.59.7", | ||||
|     "eslint-plugin-jest": "^27.2.1" | ||||
|     "@typescript-eslint/eslint-plugin": "^6.2.1", | ||||
|     "@typescript-eslint/parser": "^6.2.1", | ||||
|     "eslint-plugin-jest": "^27.2.3" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "eslint": "^8.41.0" | ||||
|     "eslint": "^8.46.0" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -36,6 +36,7 @@ module.exports = { | ||||
|     'vue/multi-word-component-names': 'off', | ||||
|     'vue/prefer-import-from-vue': 'off', | ||||
|     'vue/no-v-text-v-html-on-component': 'off', | ||||
|     'vue/no-dupe-keys': 'off', | ||||
|  | ||||
|     // reactivity transform | ||||
|     'vue/no-setup-props-destructure': 'off', | ||||
| @@ -51,7 +52,7 @@ module.exports = { | ||||
|     'vue/component-options-name-casing': ['error', 'PascalCase'], | ||||
|     'vue/custom-event-name-casing': ['error', 'camelCase'], | ||||
|     'vue/define-macros-order': ['error', { | ||||
|       order: ['defineProps', 'defineEmits'], | ||||
|       order: ['defineOptions', 'defineProps', 'defineEmits', 'defineSlots'], | ||||
|     }], | ||||
|     'vue/html-comment-content-spacing': ['error', 'always', { | ||||
|       exceptions: ['-'], | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@antfu/eslint-config-vue", | ||||
|   "version": "0.39.2", | ||||
|   "version": "0.40.2", | ||||
|   "description": "", | ||||
|   "author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)", | ||||
|   "license": "MIT", | ||||
| @@ -17,10 +17,10 @@ | ||||
|   "dependencies": { | ||||
|     "@antfu/eslint-config-basic": "workspace:*", | ||||
|     "@antfu/eslint-config-ts": "workspace:*", | ||||
|     "eslint-plugin-vue": "^9.14.0", | ||||
|     "eslint-plugin-vue": "^9.16.1", | ||||
|     "local-pkg": "^0.4.3" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "eslint": "^8.41.0" | ||||
|     "eslint": "^8.46.0" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@antfu/eslint-config", | ||||
|   "version": "0.39.2", | ||||
|   "version": "0.40.2", | ||||
|   "description": "Anthony's ESLint config", | ||||
|   "author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)", | ||||
|   "license": "MIT", | ||||
| @@ -17,21 +17,21 @@ | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@antfu/eslint-config-vue": "workspace:*", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.59.7", | ||||
|     "@typescript-eslint/parser": "^5.59.7", | ||||
|     "@typescript-eslint/eslint-plugin": "^6.2.1", | ||||
|     "@typescript-eslint/parser": "^6.2.1", | ||||
|     "eslint-plugin-eslint-comments": "^3.2.0", | ||||
|     "eslint-plugin-html": "^7.1.0", | ||||
|     "eslint-plugin-import": "^2.27.5", | ||||
|     "eslint-plugin-jsonc": "^2.8.0", | ||||
|     "eslint-plugin-n": "^16.0.0", | ||||
|     "eslint-plugin-import": "npm:eslint-plugin-i@2.28.0-2", | ||||
|     "eslint-plugin-jsonc": "^2.9.0", | ||||
|     "eslint-plugin-n": "^16.0.1", | ||||
|     "eslint-plugin-promise": "^6.1.1", | ||||
|     "eslint-plugin-unicorn": "^47.0.0", | ||||
|     "eslint-plugin-vue": "^9.14.0", | ||||
|     "eslint-plugin-yml": "^1.7.0", | ||||
|     "eslint-plugin-unicorn": "^48.0.1", | ||||
|     "eslint-plugin-vue": "^9.16.1", | ||||
|     "eslint-plugin-yml": "^1.8.0", | ||||
|     "jsonc-eslint-parser": "^2.3.0", | ||||
|     "yaml-eslint-parser": "^1.2.2" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "eslint": "^8.41.0" | ||||
|     "eslint": "^8.46.0" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -4,7 +4,7 @@ export default defineBuildConfig({ | ||||
|   entries: [ | ||||
|     'src/index', | ||||
|   ], | ||||
|   declaration: true, | ||||
|   declaration: false, | ||||
|   clean: true, | ||||
|   rollup: { | ||||
|     emitCJS: true, | ||||
|   | ||||
| @@ -1,11 +1,10 @@ | ||||
| { | ||||
|   "name": "eslint-plugin-antfu", | ||||
|   "version": "0.39.2", | ||||
|   "version": "0.40.2", | ||||
|   "license": "MIT", | ||||
|   "homepage": "https://github.com/antfu/eslint-config", | ||||
|   "main": "./dist/index.cjs", | ||||
|   "module": "./dist/index.mjs", | ||||
|   "types": "./dist/index.d.ts", | ||||
|   "files": [ | ||||
|     "dist" | ||||
|   ], | ||||
| @@ -16,11 +15,12 @@ | ||||
|     "prepublishOnly": "nr build" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@typescript-eslint/utils": "^5.59.7" | ||||
|     "@typescript-eslint/utils": "^6.2.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/node": "^20.2.3", | ||||
|     "@types/node": "^20.4.8", | ||||
|     "@typescript-eslint/rule-tester": "^6.2.1", | ||||
|     "unbuild": "^1.2.1", | ||||
|     "vitest": "^0.31.1" | ||||
|     "vitest": "^0.34.1" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -3,8 +3,11 @@ import ifNewline from './rules/if-newline' | ||||
| import importDedupe from './rules/import-dedupe' | ||||
| import preferInlineTypeImport from './rules/prefer-inline-type-import' | ||||
| import topLevelFunction from './rules/top-level-function' | ||||
| import noImportNodeModulesByPath from './rules/no-import-node-modules-by-path' | ||||
| import noTsExportEqual from './rules/no-ts-export-equal' | ||||
| import noCjsExports from './rules/no-cjs-exports' | ||||
| import noConstEnum from './rules/no-const-enum' | ||||
| import namedTupleSpacing from './rules/named-tuple-spacing' | ||||
|  | ||||
| export default { | ||||
|   rules: { | ||||
| @@ -13,7 +16,10 @@ export default { | ||||
|     'prefer-inline-type-import': preferInlineTypeImport, | ||||
|     'generic-spacing': genericSpacing, | ||||
|     'top-level-function': topLevelFunction, | ||||
|     'no-import-node-modules-by-path': noImportNodeModulesByPath, | ||||
|     'no-cjs-exports': noCjsExports, | ||||
|     'no-ts-export-equal': noTsExportEqual, | ||||
|     'no-const-enum': noConstEnum, | ||||
|     'named-tuple-spacing': namedTupleSpacing, | ||||
|   }, | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| import { RuleTester } from '@typescript-eslint/utils/dist/ts-eslint' | ||||
| import { it } from 'vitest' | ||||
| import { RuleTester } from '@typescript-eslint/rule-tester' | ||||
| import rule, { RULE_NAME } from './generic-spacing' | ||||
|  | ||||
| const valids = [ | ||||
| @@ -36,17 +35,15 @@ const invalids = [ | ||||
| }`], | ||||
| ] as const | ||||
|  | ||||
| it('runs', () => { | ||||
|   const ruleTester: RuleTester = new RuleTester({ | ||||
|     parser: require.resolve('@typescript-eslint/parser'), | ||||
|   }) | ||||
|  | ||||
|   ruleTester.run(RULE_NAME, rule, { | ||||
|     valid: valids, | ||||
|     invalid: invalids.map(i => ({ | ||||
|       code: i[0], | ||||
|       output: i[1].trim(), | ||||
|       errors: Array.from({ length: i[2] || 1 }, () => ({ messageId: 'genericSpacingMismatch' })), | ||||
|     })), | ||||
|   }) | ||||
| const ruleTester: RuleTester = new RuleTester({ | ||||
|   parser: require.resolve('@typescript-eslint/parser'), | ||||
| }) | ||||
|  | ||||
| ruleTester.run(RULE_NAME, rule as any, { | ||||
|   valid: valids, | ||||
|   invalid: invalids.map(i => ({ | ||||
|     code: i[0], | ||||
|     output: i[1].trim(), | ||||
|     errors: Array.from({ length: i[2] || 1 }, () => ({ messageId: 'genericSpacingMismatch' })), | ||||
|   })), | ||||
| }) | ||||
|   | ||||
| @@ -10,7 +10,7 @@ export default createEslintRule<Options, MessageIds>({ | ||||
|     type: 'suggestion', | ||||
|     docs: { | ||||
|       description: 'Spaces around generic type parameters', | ||||
|       recommended: 'error', | ||||
|       recommended: 'stylistic', | ||||
|     }, | ||||
|     fixable: 'code', | ||||
|     schema: [], | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| import { RuleTester } from '@typescript-eslint/utils/dist/ts-eslint' | ||||
| import { it } from 'vitest' | ||||
| import { RuleTester } from '@typescript-eslint/rule-tester' | ||||
| import rule, { RULE_NAME } from './if-newline' | ||||
|  | ||||
| const valids = [ | ||||
| @@ -14,17 +13,15 @@ const invalids = [ | ||||
|   ['if (true) console.log(\'hello\')', 'if (true) \nconsole.log(\'hello\')'], | ||||
| ] | ||||
|  | ||||
| it('runs', () => { | ||||
|   const ruleTester: RuleTester = new RuleTester({ | ||||
|     parser: require.resolve('@typescript-eslint/parser'), | ||||
|   }) | ||||
|  | ||||
|   ruleTester.run(RULE_NAME, rule, { | ||||
|     valid: valids, | ||||
|     invalid: invalids.map(i => ({ | ||||
|       code: i[0], | ||||
|       output: i[1], | ||||
|       errors: [{ messageId: 'missingIfNewline' }], | ||||
|     })), | ||||
|   }) | ||||
| const ruleTester: RuleTester = new RuleTester({ | ||||
|   parser: require.resolve('@typescript-eslint/parser'), | ||||
| }) | ||||
|  | ||||
| ruleTester.run(RULE_NAME, rule as any, { | ||||
|   valid: valids, | ||||
|   invalid: invalids.map(i => ({ | ||||
|     code: i[0], | ||||
|     output: i[1], | ||||
|     errors: [{ messageId: 'missingIfNewline' }], | ||||
|   })), | ||||
| }) | ||||
|   | ||||
| @@ -10,7 +10,7 @@ export default createEslintRule<Options, MessageIds>({ | ||||
|     type: 'problem', | ||||
|     docs: { | ||||
|       description: 'Newline after if', | ||||
|       recommended: 'error', | ||||
|       recommended: 'stylistic', | ||||
|     }, | ||||
|     fixable: 'code', | ||||
|     schema: [], | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| import { RuleTester } from '@typescript-eslint/utils/dist/ts-eslint' | ||||
| import { it } from 'vitest' | ||||
| import { RuleTester } from '@typescript-eslint/rule-tester' | ||||
| import rule, { RULE_NAME } from './import-dedupe' | ||||
|  | ||||
| const valids = [ | ||||
| @@ -12,17 +11,15 @@ const invalids = [ | ||||
|   ], | ||||
| ] | ||||
|  | ||||
| it('runs', () => { | ||||
|   const ruleTester: RuleTester = new RuleTester({ | ||||
|     parser: require.resolve('@typescript-eslint/parser'), | ||||
|   }) | ||||
|  | ||||
|   ruleTester.run(RULE_NAME, rule, { | ||||
|     valid: valids, | ||||
|     invalid: invalids.map(i => ({ | ||||
|       code: i[0], | ||||
|       output: i[1], | ||||
|       errors: [{ messageId: 'importDedupe' }, { messageId: 'importDedupe' }, { messageId: 'importDedupe' }], | ||||
|     })), | ||||
|   }) | ||||
| const ruleTester: RuleTester = new RuleTester({ | ||||
|   parser: require.resolve('@typescript-eslint/parser'), | ||||
| }) | ||||
|  | ||||
| ruleTester.run(RULE_NAME, rule as any, { | ||||
|   valid: valids, | ||||
|   invalid: invalids.map(i => ({ | ||||
|     code: i[0], | ||||
|     output: i[1], | ||||
|     errors: [{ messageId: 'importDedupe' }, { messageId: 'importDedupe' }, { messageId: 'importDedupe' }], | ||||
|   })), | ||||
| }) | ||||
|   | ||||
| @@ -10,7 +10,7 @@ export default createEslintRule<Options, MessageIds>({ | ||||
|     type: 'problem', | ||||
|     docs: { | ||||
|       description: 'Fix duplication in imports', | ||||
|       recommended: 'error', | ||||
|       recommended: 'strict', | ||||
|     }, | ||||
|     fixable: 'code', | ||||
|     schema: [], | ||||
|   | ||||
| @@ -0,0 +1,98 @@ | ||||
| import { RuleTester } from '@typescript-eslint/rule-tester' | ||||
| import rule, { RULE_NAME } from './named-tuple-spacing' | ||||
|  | ||||
| const valids = [ | ||||
|   'type T = [i: number]', | ||||
|   'type T = [i?: number]', | ||||
|   'type T = [i: number, j: number]', | ||||
|   'type T = [i: number, j: () => string]', | ||||
|   `const emit = defineEmits<{ | ||||
|     change: [id: number] | ||||
|     update: [value: string] | ||||
|   }>()`, | ||||
| ] | ||||
|  | ||||
| const ruleTester: RuleTester = new RuleTester({ | ||||
|   parser: require.resolve('@typescript-eslint/parser'), | ||||
| }) | ||||
|  | ||||
| ruleTester.run(RULE_NAME, rule as any, { | ||||
|   valid: valids, | ||||
|   invalid: [ | ||||
|     { | ||||
|       code: 'type T = [i:number]', | ||||
|       output: 'type T = [i: number]', | ||||
|       errors: [{ messageId: 'expectedSpaceAfter' }], | ||||
|     }, | ||||
|     { | ||||
|       code: 'type T = [i:  number]', | ||||
|       output: 'type T = [i: number]', | ||||
|       errors: [{ messageId: 'expectedSpaceAfter' }], | ||||
|     }, | ||||
|     { | ||||
|       code: 'type T = [i?:number]', | ||||
|       output: 'type T = [i?: number]', | ||||
|       errors: [{ messageId: 'expectedSpaceAfter' }], | ||||
|     }, | ||||
|     { | ||||
|       code: 'type T = [i?   :number]', | ||||
|       output: 'type T = [i?: number]', | ||||
|       errors: [{ messageId: 'unexpectedSpaceBetween' }, { messageId: 'expectedSpaceAfter' }], | ||||
|     }, | ||||
|     { | ||||
|       code: 'type T = [i : number]', | ||||
|       output: 'type T = [i: number]', | ||||
|       errors: [{ messageId: 'unexpectedSpaceBefore' }], | ||||
|     }, | ||||
|     { | ||||
|       code: 'type T = [i  : number]', | ||||
|       output: 'type T = [i: number]', | ||||
|       errors: [{ messageId: 'unexpectedSpaceBefore' }], | ||||
|     }, | ||||
|     { | ||||
|       code: 'type T = [i  ?  : number]', | ||||
|       output: 'type T = [i?: number]', | ||||
|       errors: [{ messageId: 'unexpectedSpaceBetween' }, { messageId: 'unexpectedSpaceBefore' }], | ||||
|     }, | ||||
|     { | ||||
|       code: 'type T = [i:number, j:number]', | ||||
|       output: 'type T = [i: number, j: number]', | ||||
|       errors: [{ messageId: 'expectedSpaceAfter' }, { messageId: 'expectedSpaceAfter' }], | ||||
|     }, | ||||
|     { | ||||
|       code: 'type T = [i:()=>void, j:number]', | ||||
|       output: 'type T = [i: ()=>void, j: number]', | ||||
|       errors: [{ messageId: 'expectedSpaceAfter' }, { messageId: 'expectedSpaceAfter' }], | ||||
|     }, | ||||
|     { | ||||
|       code: ` | ||||
|         const emit = defineEmits<{ | ||||
|           change: [id:number] | ||||
|           update: [value:string] | ||||
|         }>() | ||||
|         `, | ||||
|       output: ` | ||||
|         const emit = defineEmits<{ | ||||
|           change: [id: number] | ||||
|           update: [value: string] | ||||
|         }>() | ||||
|         `, | ||||
|       errors: [{ messageId: 'expectedSpaceAfter' }, { messageId: 'expectedSpaceAfter' }], | ||||
|     }, | ||||
|     { | ||||
|       code: ` | ||||
|         const emit = defineEmits<{ | ||||
|           change: [id? :number] | ||||
|           update: [value:string] | ||||
|         }>() | ||||
|         `, | ||||
|       output: ` | ||||
|         const emit = defineEmits<{ | ||||
|           change: [id?: number] | ||||
|           update: [value: string] | ||||
|         }>() | ||||
|         `, | ||||
|       errors: [{ messageId: 'unexpectedSpaceBetween' }, { messageId: 'expectedSpaceAfter' }, { messageId: 'expectedSpaceAfter' }], | ||||
|     }, | ||||
|   ], | ||||
| }) | ||||
| @@ -0,0 +1,83 @@ | ||||
| import { createEslintRule } from '../utils' | ||||
|  | ||||
| export const RULE_NAME = 'named-tuple-spacing' | ||||
| export type MessageIds = 'expectedSpaceAfter' | 'unexpectedSpaceBetween' | 'unexpectedSpaceBefore' | ||||
| export type Options = [] | ||||
|  | ||||
| const RE = /^([\w_$]+)(\s*)(\?\s*)?:(\s*)(.*)$/ | ||||
|  | ||||
| export default createEslintRule<Options, MessageIds>({ | ||||
|   name: RULE_NAME, | ||||
|   meta: { | ||||
|     type: 'suggestion', | ||||
|     docs: { | ||||
|       description: 'Expect space before type declaration in named tuple', | ||||
|       recommended: 'stylistic', | ||||
|     }, | ||||
|     fixable: 'code', | ||||
|     schema: [], | ||||
|     messages: { | ||||
|       expectedSpaceAfter: 'Expected a space after the \':\'.', | ||||
|       unexpectedSpaceBetween: 'Unexpected space between \'?\' and the \':\'.', | ||||
|       unexpectedSpaceBefore: 'Unexpected space before the \':\'.', | ||||
|     }, | ||||
|   }, | ||||
|   defaultOptions: [], | ||||
|   create: (context) => { | ||||
|     const sourceCode = context.getSourceCode() | ||||
|     return { | ||||
|       TSNamedTupleMember: (node: any) => { | ||||
|         const code = sourceCode.text.slice(node.range[0], node.range[1]) | ||||
|  | ||||
|         const match = code.match(RE) | ||||
|         if (!match) | ||||
|           return | ||||
|  | ||||
|         const labelName = node.label.name | ||||
|         const spaceBeforeColon = match[2] | ||||
|         const optionalMark = match[3] | ||||
|         const spacesAfterColon = match[4] | ||||
|         const elementType = match[5] | ||||
|  | ||||
|         function getReplaceValue() { | ||||
|           let ret = labelName | ||||
|           if (node.optional) | ||||
|             ret += '?' | ||||
|           ret += ': ' | ||||
|           ret += elementType | ||||
|           return ret | ||||
|         } | ||||
|  | ||||
|         if (optionalMark?.length > 1) { | ||||
|           context.report({ | ||||
|             node, | ||||
|             messageId: 'unexpectedSpaceBetween', | ||||
|             *fix(fixer) { | ||||
|               yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue())) | ||||
|             }, | ||||
|           }) | ||||
|         } | ||||
|  | ||||
|         if (spaceBeforeColon?.length) { | ||||
|           context.report({ | ||||
|             node, | ||||
|             messageId: 'unexpectedSpaceBefore', | ||||
|             *fix(fixer) { | ||||
|               yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue())) | ||||
|             }, | ||||
|           }) | ||||
|         } | ||||
|  | ||||
|         if (spacesAfterColon != null && spacesAfterColon.length !== 1) { | ||||
|           context.report({ | ||||
|             node, | ||||
|             messageId: 'expectedSpaceAfter', | ||||
|             *fix(fixer) { | ||||
|               yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue())) | ||||
|             }, | ||||
|           }) | ||||
|         } | ||||
|       }, | ||||
|     } | ||||
|   }, | ||||
| }) | ||||
| @@ -1,5 +1,4 @@ | ||||
| import { RuleTester } from '@typescript-eslint/utils/dist/ts-eslint' | ||||
| import { it } from 'vitest' | ||||
| import { RuleTester } from '@typescript-eslint/rule-tester' | ||||
| import rule, { RULE_NAME } from './no-cjs-exports' | ||||
|  | ||||
| const valids = [ | ||||
| @@ -13,16 +12,14 @@ const invalids = [ | ||||
|   { code: 'module.exports.a = {}', filename: 'test.ts' }, | ||||
| ] | ||||
|  | ||||
| it('runs', () => { | ||||
|   const ruleTester: RuleTester = new RuleTester({ | ||||
|     parser: require.resolve('@typescript-eslint/parser'), | ||||
|   }) | ||||
|  | ||||
|   ruleTester.run(RULE_NAME, rule, { | ||||
|     valid: valids, | ||||
|     invalid: invalids.map(i => ({ | ||||
|       ...i, | ||||
|       errors: [{ messageId: 'noCjsExports' }], | ||||
|     })), | ||||
|   }) | ||||
| const ruleTester: RuleTester = new RuleTester({ | ||||
|   parser: require.resolve('@typescript-eslint/parser'), | ||||
| }) | ||||
|  | ||||
| ruleTester.run(RULE_NAME, rule as any, { | ||||
|   valid: valids, | ||||
|   invalid: invalids.map(i => ({ | ||||
|     ...i, | ||||
|     errors: [{ messageId: 'noCjsExports' }], | ||||
|   })), | ||||
| }) | ||||
|   | ||||
| @@ -10,7 +10,6 @@ export default createEslintRule<Options, MessageIds>({ | ||||
|     type: 'problem', | ||||
|     docs: { | ||||
|       description: 'Do not use CJS exports', | ||||
|       recommended: false, | ||||
|     }, | ||||
|     schema: [], | ||||
|     messages: { | ||||
|   | ||||
							
								
								
									
										22
									
								
								packages/eslint-plugin-antfu/src/rules/no-const-enum.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								packages/eslint-plugin-antfu/src/rules/no-const-enum.test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| import { RuleTester } from '@typescript-eslint/rule-tester' | ||||
| import rule, { RULE_NAME } from './no-const-enum' | ||||
|  | ||||
| const valids = [ | ||||
|   'enum E {}', | ||||
| ] | ||||
|  | ||||
| const invalids = [ | ||||
|   'const enum E {}', | ||||
| ] | ||||
|  | ||||
| const ruleTester: RuleTester = new RuleTester({ | ||||
|   parser: require.resolve('@typescript-eslint/parser'), | ||||
| }) | ||||
|  | ||||
| ruleTester.run(RULE_NAME, rule as any, { | ||||
|   valid: valids, | ||||
|   invalid: invalids.map(i => ({ | ||||
|     code: i, | ||||
|     errors: [{ messageId: 'noConstEnum' }], | ||||
|   })), | ||||
| }) | ||||
							
								
								
									
										33
									
								
								packages/eslint-plugin-antfu/src/rules/no-const-enum.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								packages/eslint-plugin-antfu/src/rules/no-const-enum.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| import { createEslintRule } from '../utils' | ||||
|  | ||||
| export const RULE_NAME = 'no-const-enum' | ||||
| export type MessageIds = 'noConstEnum' | ||||
| export type Options = [] | ||||
|  | ||||
| export default createEslintRule<Options, MessageIds>({ | ||||
|   name: RULE_NAME, | ||||
|   meta: { | ||||
|     type: 'problem', | ||||
|     docs: { | ||||
|       description: 'Disallow using `const enum` expression', | ||||
|       recommended: 'recommended', | ||||
|     }, | ||||
|     schema: [], | ||||
|     messages: { | ||||
|       noConstEnum: 'Do not use `const enum` expression', | ||||
|     }, | ||||
|   }, | ||||
|   defaultOptions: [], | ||||
|   create: (context) => { | ||||
|     return { | ||||
|       TSEnumDeclaration: (node) => { | ||||
|         if (node.const) { | ||||
|           context.report({ | ||||
|             node, | ||||
|             messageId: 'noConstEnum', | ||||
|           }) | ||||
|         } | ||||
|       }, | ||||
|     } | ||||
|   }, | ||||
| }) | ||||
| @@ -0,0 +1,28 @@ | ||||
| import { RuleTester } from '@typescript-eslint/rule-tester' | ||||
| import rule, { RULE_NAME } from './no-import-node-modules-by-path' | ||||
|  | ||||
| const valids = [ | ||||
|   'import xxx from "a"', | ||||
|   'import "b"', | ||||
|   'const c = require("c")', | ||||
|   'require("d")', | ||||
| ] | ||||
|  | ||||
| const invalids = [ | ||||
|   'import a from "../node_modules/a"', | ||||
|   'import "../node_modules/b"', | ||||
|   'const c = require("../node_modules/c")', | ||||
|   'require("../node_modules/d")', | ||||
| ] | ||||
|  | ||||
| const ruleTester: RuleTester = new RuleTester({ | ||||
|   parser: require.resolve('@typescript-eslint/parser'), | ||||
| }) | ||||
|  | ||||
| ruleTester.run(RULE_NAME, rule as any, { | ||||
|   valid: valids, | ||||
|   invalid: invalids.map(i => ({ | ||||
|     code: i, | ||||
|     errors: [{ messageId: 'noImportNodeModulesByPath' }], | ||||
|   })), | ||||
| }) | ||||
| @@ -0,0 +1,42 @@ | ||||
| import { createEslintRule } from '../utils' | ||||
|  | ||||
| export const RULE_NAME = 'no-import-node-modules-by-path' | ||||
| export type MessageIds = 'noImportNodeModulesByPath' | ||||
| export type Options = [] | ||||
|  | ||||
| export default createEslintRule<Options, MessageIds>({ | ||||
|   name: RULE_NAME, | ||||
|   meta: { | ||||
|     type: 'problem', | ||||
|     docs: { | ||||
|       description: 'Prevent importing modules in `node_modules` folder by relative or absolute path', | ||||
|       recommended: 'recommended', | ||||
|     }, | ||||
|     schema: [], | ||||
|     messages: { | ||||
|       noImportNodeModulesByPath: 'Do not import modules in `node_modules` folder by path', | ||||
|     }, | ||||
|   }, | ||||
|   defaultOptions: [], | ||||
|   create: (context) => { | ||||
|     return { | ||||
|       'ImportDeclaration': (node) => { | ||||
|         if (node.source.value.includes('/node_modules/')) { | ||||
|           context.report({ | ||||
|             node, | ||||
|             messageId: 'noImportNodeModulesByPath', | ||||
|           }) | ||||
|         } | ||||
|       }, | ||||
|       'CallExpression[callee.name="require"]': (node: any) => { | ||||
|         const value = node.arguments[0]?.value | ||||
|         if (typeof value === 'string' && value.includes('/node_modules/')) { | ||||
|           context.report({ | ||||
|             node, | ||||
|             messageId: 'noImportNodeModulesByPath', | ||||
|           }) | ||||
|         } | ||||
|       }, | ||||
|     } | ||||
|   }, | ||||
| }) | ||||
| @@ -1,5 +1,4 @@ | ||||
| import { RuleTester } from '@typescript-eslint/utils/dist/ts-eslint' | ||||
| import { it } from 'vitest' | ||||
| import { RuleTester } from '@typescript-eslint/rule-tester' | ||||
| import rule, { RULE_NAME } from './no-ts-export-equal' | ||||
|  | ||||
| const valids = [ | ||||
| @@ -11,16 +10,14 @@ const invalids = [ | ||||
|   { code: 'export = {}', filename: 'test.ts' }, | ||||
| ] | ||||
|  | ||||
| it('runs', () => { | ||||
|   const ruleTester: RuleTester = new RuleTester({ | ||||
|     parser: require.resolve('@typescript-eslint/parser'), | ||||
|   }) | ||||
|  | ||||
|   ruleTester.run(RULE_NAME, rule, { | ||||
|     valid: valids, | ||||
|     invalid: invalids.map(i => ({ | ||||
|       ...i, | ||||
|       errors: [{ messageId: 'noTsExportEqual' }], | ||||
|     })), | ||||
|   }) | ||||
| const ruleTester: RuleTester = new RuleTester({ | ||||
|   parser: require.resolve('@typescript-eslint/parser'), | ||||
| }) | ||||
|  | ||||
| ruleTester.run(RULE_NAME, rule as any, { | ||||
|   valid: valids, | ||||
|   invalid: invalids.map(i => ({ | ||||
|     ...i, | ||||
|     errors: [{ messageId: 'noTsExportEqual' }], | ||||
|   })), | ||||
| }) | ||||
|   | ||||
| @@ -10,7 +10,7 @@ export default createEslintRule<Options, MessageIds>({ | ||||
|     type: 'problem', | ||||
|     docs: { | ||||
|       description: 'Do not use `exports =`', | ||||
|       recommended: false, | ||||
|       recommended: 'recommended', | ||||
|     }, | ||||
|     schema: [], | ||||
|     messages: { | ||||
|   | ||||
| @@ -1,27 +1,25 @@ | ||||
| import { RuleTester } from '@typescript-eslint/utils/dist/ts-eslint' | ||||
| import { it } from 'vitest' | ||||
| import { RuleTester } from '@typescript-eslint/rule-tester' | ||||
| import rule, { RULE_NAME } from './prefer-inline-type-import' | ||||
|  | ||||
| const valids = [ | ||||
|   'import { type Foo } from \'foo\'', | ||||
|   'import type Foo from \'foo\'', | ||||
|   'import type * as Foo from \'foo\'', | ||||
|   'import type {} from \'foo\'', | ||||
| ] | ||||
| const invalids = [ | ||||
|   ['import type { Foo } from \'foo\'', 'import { type Foo } from \'foo\''], | ||||
| ] | ||||
|  | ||||
| it('runs', () => { | ||||
|   const ruleTester: RuleTester = new RuleTester({ | ||||
|     parser: require.resolve('@typescript-eslint/parser'), | ||||
|   }) | ||||
|  | ||||
|   ruleTester.run(RULE_NAME, rule, { | ||||
|     valid: valids, | ||||
|     invalid: invalids.map(i => ({ | ||||
|       code: i[0], | ||||
|       output: i[1].trim(), | ||||
|       errors: [{ messageId: 'preferInlineTypeImport' }], | ||||
|     })), | ||||
|   }) | ||||
| const ruleTester: RuleTester = new RuleTester({ | ||||
|   parser: require.resolve('@typescript-eslint/parser'), | ||||
| }) | ||||
|  | ||||
| ruleTester.run(RULE_NAME, rule as any, { | ||||
|   valid: valids, | ||||
|   invalid: invalids.map(i => ({ | ||||
|     code: i[0], | ||||
|     output: i[1].trim(), | ||||
|     errors: [{ messageId: 'preferInlineTypeImport' }], | ||||
|   })), | ||||
| }) | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| // Ported from https://github.com/gajus/eslint-plugin-canonical/blob/master/src/rules/preferInlineTypeImport.js | ||||
| // by Gajus Kuizinas https://github.com/gajus | ||||
| import type { TSESTree } from '@typescript-eslint/utils' | ||||
| import type { RuleFixer, SourceCode } from '@typescript-eslint/utils/dist/ts-eslint' | ||||
| import type { RuleFixer, SourceCode } from '@typescript-eslint/utils/ts-eslint' | ||||
| import { createEslintRule } from '../utils' | ||||
|  | ||||
| export const RULE_NAME = 'prefer-inline-type-import' | ||||
| @@ -14,7 +14,6 @@ export default createEslintRule<Options, MessageIds>({ | ||||
|     type: 'suggestion', | ||||
|     docs: { | ||||
|       description: 'Inline type import', | ||||
|       recommended: 'error', | ||||
|     }, | ||||
|     fixable: 'code', | ||||
|     schema: [], | ||||
| @@ -30,7 +29,7 @@ export default createEslintRule<Options, MessageIds>({ | ||||
|         // ignore bare type imports | ||||
|         if (node.specifiers.length === 1 && ['ImportNamespaceSpecifier', 'ImportDefaultSpecifier'].includes(node.specifiers[0].type)) | ||||
|           return | ||||
|         if (node.importKind === 'type') { | ||||
|         if (node.importKind === 'type' && node.specifiers.length > 0) { | ||||
|           context.report({ | ||||
|             *fix(fixer) { | ||||
|               yield * removeTypeSpecifier(fixer, sourceCode, node) | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| import { RuleTester } from '@typescript-eslint/utils/dist/ts-eslint' | ||||
| import { it } from 'vitest' | ||||
| import { RuleTester } from '@typescript-eslint/rule-tester' | ||||
| import rule, { RULE_NAME } from './top-level-function' | ||||
|  | ||||
| const valids = [ | ||||
| @@ -51,17 +50,15 @@ const invalids = [ | ||||
|   ], | ||||
| ] | ||||
|  | ||||
| it('runs', () => { | ||||
|   const ruleTester: RuleTester = new RuleTester({ | ||||
|     parser: require.resolve('@typescript-eslint/parser'), | ||||
|   }) | ||||
|  | ||||
|   ruleTester.run(RULE_NAME, rule, { | ||||
|     valid: valids, | ||||
|     invalid: invalids.map(i => ({ | ||||
|       code: i[0], | ||||
|       output: i[1], | ||||
|       errors: [{ messageId: 'topLevelFunctionDeclaration' }], | ||||
|     })), | ||||
|   }) | ||||
| const ruleTester: RuleTester = new RuleTester({ | ||||
|   parser: require.resolve('@typescript-eslint/parser'), | ||||
| }) | ||||
|  | ||||
| ruleTester.run(RULE_NAME, rule as any, { | ||||
|   valid: valids, | ||||
|   invalid: invalids.map(i => ({ | ||||
|     code: i[0], | ||||
|     output: i[1], | ||||
|     errors: [{ messageId: 'topLevelFunctionDeclaration' }], | ||||
|   })), | ||||
| }) | ||||
|   | ||||
| @@ -10,7 +10,7 @@ export default createEslintRule<Options, MessageIds>({ | ||||
|     type: 'problem', | ||||
|     docs: { | ||||
|       description: 'Enforce top-level functions to be declared with function keyword', | ||||
|       recommended: 'error', | ||||
|       recommended: 'stylistic', | ||||
|     }, | ||||
|     fixable: 'code', | ||||
|     schema: [], | ||||
|   | ||||
							
								
								
									
										7
									
								
								packages/eslint-plugin-antfu/vitest.config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/eslint-plugin-antfu/vitest.config.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| import { defineConfig } from 'vitest/config' | ||||
|  | ||||
| export default defineConfig({ | ||||
|   test: { | ||||
|     globals: true, | ||||
|   }, | ||||
| }) | ||||
							
								
								
									
										1305
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1305
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -3,7 +3,8 @@ | ||||
|     "baseUrl": ".", | ||||
|     "target": "es2020", | ||||
|     "module": "es2020", | ||||
|     "moduleResolution": "node" | ||||
|     "moduleResolution": "Bundler", | ||||
|     "esModuleInterop": true | ||||
|   }, | ||||
|   "include": [ | ||||
|     "./packages/**/*.ts" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user