Compare commits
	
		
			16 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | a1e890844f | ||
|  | a2de527401 | ||
|  | 6080d3f74d | ||
|  | b996c58bac | ||
|  | b8fe1fabea | ||
|  | 0ab9f88603 | ||
|  | 17670e8e38 | ||
|  | 686f285a37 | ||
|  | 2d9efd4df6 | ||
|  | b8e6cdf047 | ||
|  | 50c962197b | ||
|  | bf19dc0adb | ||
|  | 38f64ae9af | ||
|  | 22527f61de | ||
|  | 1ff53f2f04 | ||
|  | 316bbd903b | 
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@antfu/eslint-config-monorepo", | ||||
|   "version": "0.20.3", | ||||
|   "version": "0.22.0", | ||||
|   "private": true, | ||||
|   "license": "MIT", | ||||
|   "author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)", | ||||
| @@ -12,7 +12,7 @@ | ||||
|   "devDependencies": { | ||||
|     "@antfu/eslint-config": "*", | ||||
|     "bumpp": "^7.1.1", | ||||
|     "eslint": "^8.12.0", | ||||
|     "eslint": "^8.14.0", | ||||
|     "eslint-plugin-antfu": "workspace:*", | ||||
|     "typescript": "^4.6.3" | ||||
|   } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@antfu/eslint-config", | ||||
|   "version": "0.20.3", | ||||
|   "version": "0.22.0", | ||||
|   "description": "", | ||||
|   "keywords": [], | ||||
|   "license": "MIT", | ||||
| @@ -15,22 +15,22 @@ | ||||
|   "dependencies": { | ||||
|     "@antfu/eslint-config-react": "workspace:*", | ||||
|     "@antfu/eslint-config-vue": "workspace:*", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.17.0", | ||||
|     "@typescript-eslint/parser": "^5.17.0", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.20.0", | ||||
|     "@typescript-eslint/parser": "^5.20.0", | ||||
|     "eslint-plugin-eslint-comments": "^3.2.0", | ||||
|     "eslint-plugin-html": "^6.2.0", | ||||
|     "eslint-plugin-import": "^2.25.4", | ||||
|     "eslint-plugin-import": "^2.26.0", | ||||
|     "eslint-plugin-jsonc": "^2.2.1", | ||||
|     "eslint-plugin-n": "^15.1.0", | ||||
|     "eslint-plugin-promise": "^6.0.0", | ||||
|     "eslint-plugin-unicorn": "^41.0.1", | ||||
|     "eslint-plugin-vue": "^8.5.0", | ||||
|     "eslint-plugin-unicorn": "^42.0.0", | ||||
|     "eslint-plugin-vue": "^8.7.1", | ||||
|     "eslint-plugin-yml": "^0.14.0", | ||||
|     "jsonc-eslint-parser": "^2.1.0", | ||||
|     "yaml-eslint-parser": "^0.5.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "eslint": "^8.12.0" | ||||
|     "eslint": "^8.14.0" | ||||
|   }, | ||||
|   "publishConfig": { | ||||
|     "access": "public" | ||||
|   | ||||
| @@ -44,9 +44,9 @@ module.exports = { | ||||
|       files: ['*.json', '*.json5'], | ||||
|       parser: 'jsonc-eslint-parser', | ||||
|       rules: { | ||||
|         'quotes': ['error', 'double'], | ||||
|         'quote-props': ['error', 'always'], | ||||
|         'comma-dangle': ['error', 'never'], | ||||
|         'jsonc/quotes': ['error', 'double'], | ||||
|         'jsonc/quote-props': ['error', 'always'], | ||||
|         'jsonc/comma-dangle': ['error', 'never'], | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
| @@ -183,7 +183,15 @@ module.exports = { | ||||
|     ], | ||||
|     'object-curly-spacing': ['error', 'always'], | ||||
|     'no-return-await': 'off', | ||||
|     'space-before-function-paren': ['error', 'never'], | ||||
|     'space-before-function-paren': [ | ||||
|       'error', | ||||
|       { | ||||
|         anonymous: 'always', | ||||
|         named: 'never', | ||||
|         asyncArrow: 'always', | ||||
|       }, | ||||
|     ], | ||||
|     'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 1 }], | ||||
|  | ||||
|     // es6 | ||||
|     'no-var': 'error', | ||||
| @@ -292,8 +300,8 @@ module.exports = { | ||||
|     'yml/no-empty-document': 'off', | ||||
|  | ||||
|     // antfu | ||||
|     'antfu/no-leading-newline': 'error', | ||||
|     'antfu/if-newline': 'error', | ||||
|     'antfu/import-dedupe': 'error', | ||||
|     // 'antfu/prefer-inline-type-import': 'error', | ||||
|   }, | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@antfu/eslint-config-basic", | ||||
|   "version": "0.20.3", | ||||
|   "version": "0.22.0", | ||||
|   "description": "", | ||||
|   "keywords": [], | ||||
|   "license": "MIT", | ||||
| @@ -19,18 +19,18 @@ | ||||
|     "eslint-plugin-antfu": "workspace:*", | ||||
|     "eslint-plugin-eslint-comments": "^3.2.0", | ||||
|     "eslint-plugin-html": "^6.2.0", | ||||
|     "eslint-plugin-import": "^2.25.4", | ||||
|     "eslint-plugin-import": "^2.26.0", | ||||
|     "eslint-plugin-jsonc": "^2.2.1", | ||||
|     "eslint-plugin-markdown": "^2.2.1", | ||||
|     "eslint-plugin-n": "^15.1.0", | ||||
|     "eslint-plugin-promise": "^6.0.0", | ||||
|     "eslint-plugin-unicorn": "^41.0.1", | ||||
|     "eslint-plugin-unicorn": "^42.0.0", | ||||
|     "eslint-plugin-yml": "^0.14.0", | ||||
|     "jsonc-eslint-parser": "^2.1.0", | ||||
|     "yaml-eslint-parser": "^0.5.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "eslint": "^8.12.0" | ||||
|     "eslint": "^8.14.0" | ||||
|   }, | ||||
|   "publishConfig": { | ||||
|     "access": "public" | ||||
|   | ||||
| @@ -202,7 +202,14 @@ module.exports = { | ||||
|     'semi': ['error', 'never'], | ||||
|     'semi-spacing': ['error', { before: false, after: true }], | ||||
|     'space-before-blocks': ['error', 'always'], | ||||
|     'space-before-function-paren': ['error', 'always'], | ||||
|     'space-before-function-paren': [ | ||||
|       'error', | ||||
|       { | ||||
|         anonymous: 'always', | ||||
|         named: 'never', | ||||
|         asyncArrow: 'always', | ||||
|       }, | ||||
|     ], | ||||
|     'space-in-parens': ['error', 'never'], | ||||
|     'space-infix-ops': 'error', | ||||
|     'space-unary-ops': ['error', { words: true, nonwords: false }], | ||||
|   | ||||
| @@ -2,8 +2,5 @@ | ||||
|   "extends": "@antfu", | ||||
|   "plugins": [ | ||||
|     "antfu" | ||||
|   ], | ||||
|   "rules": { | ||||
|     "antfu/no-leading-newline": "error" | ||||
|   } | ||||
|   ] | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "eslint-plugin-antfu", | ||||
|   "version": "0.20.3", | ||||
|   "version": "0.22.0", | ||||
|   "license": "MIT", | ||||
|   "main": "./dist/index.cjs", | ||||
|   "module": "./dist/index.mjs", | ||||
| @@ -22,10 +22,10 @@ | ||||
|     "prepublishOnly": "nr build" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@typescript-eslint/utils": "^5.17.0" | ||||
|     "@typescript-eslint/utils": "^5.20.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "unbuild": "^0.7.0", | ||||
|     "vitest": "^0.8.2" | ||||
|     "unbuild": "^0.7.4", | ||||
|     "vitest": "^0.9.4" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| import ifNewline from './rules/if-newline' | ||||
| import noLeadingNewline from './rules/no-leading-newline' | ||||
| import importDedupe from './rules/import-dedupe' | ||||
| import preferInlineTypeImport from './rules/prefer-inline-type-import' | ||||
|  | ||||
| export default { | ||||
|   rules: { | ||||
|     'no-leading-newline': noLeadingNewline, | ||||
|     'if-newline': ifNewline, | ||||
|     'import-dedupe': importDedupe, | ||||
|     'prefer-inline-type-import': preferInlineTypeImport, | ||||
|   }, | ||||
| } | ||||
|   | ||||
| @@ -1,14 +1,15 @@ | ||||
| import { RuleTester } from '@typescript-eslint/utils/dist/ts-eslint' | ||||
| import { it } from 'vitest' | ||||
| import rule, { RULE_NAME } from './no-leading-newline' | ||||
| import rule, { RULE_NAME } from './import-dedupe' | ||||
| 
 | ||||
| const valids = [ | ||||
|   'import {} from \'foo\'', | ||||
|   `// comment
 | ||||
| import {} from ''`,
 | ||||
|   'import { a } from \'foo\'', | ||||
| ] | ||||
| const invalids = [ | ||||
|   '\n\nimport {} from \'fo\'', | ||||
|   [ | ||||
|     'import { a, b, a, a, c, a } from \'foo\'', | ||||
|     'import { a, b,   c,  } from \'foo\'', | ||||
|   ], | ||||
| ] | ||||
| 
 | ||||
| it('runs', () => { | ||||
| @@ -19,9 +20,9 @@ it('runs', () => { | ||||
|   ruleTester.run(RULE_NAME, rule, { | ||||
|     valid: valids, | ||||
|     invalid: invalids.map(i => ({ | ||||
|       code: i, | ||||
|       output: i.trim(), | ||||
|       errors: [{ messageId: 'noLeadingNewline' }], | ||||
|       code: i[0], | ||||
|       output: i[1], | ||||
|       errors: [{ messageId: 'importDedupe' }, { messageId: 'importDedupe' }, { messageId: 'importDedupe' }], | ||||
|     })), | ||||
|   }) | ||||
| }) | ||||
							
								
								
									
										55
									
								
								packages/eslint-plugin-antfu/src/rules/import-dedupe.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								packages/eslint-plugin-antfu/src/rules/import-dedupe.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| import { createEslintRule } from '../utils' | ||||
|  | ||||
| export const RULE_NAME = 'import-dedupe' | ||||
| export type MessageIds = 'importDedupe' | ||||
| export type Options = [] | ||||
|  | ||||
| export default createEslintRule<Options, MessageIds>({ | ||||
|   name: RULE_NAME, | ||||
|   meta: { | ||||
|     type: 'problem', | ||||
|     docs: { | ||||
|       description: 'Fix duplication in imports', | ||||
|       recommended: 'error', | ||||
|     }, | ||||
|     fixable: 'code', | ||||
|     schema: [], | ||||
|     messages: { | ||||
|       importDedupe: 'Expect no duplication in imports', | ||||
|     }, | ||||
|   }, | ||||
|   defaultOptions: [], | ||||
|   create: (context) => { | ||||
|     return { | ||||
|       ImportDeclaration(node) { | ||||
|         if (node.specifiers.length <= 1) | ||||
|           return | ||||
|  | ||||
|         const names = new Set<string>() | ||||
|         node.specifiers.forEach((n) => { | ||||
|           const id = n.local.name | ||||
|           if (names.has(id)) { | ||||
|             context.report({ | ||||
|               node, | ||||
|               loc: { | ||||
|                 start: n.loc.end, | ||||
|                 end: n.loc.start, | ||||
|               }, | ||||
|               messageId: 'importDedupe', | ||||
|               fix(fixer) { | ||||
|                 const s = n.range[0] | ||||
|                 let e = n.range[1] | ||||
|                 if (context.getSourceCode().text[e] === ',') | ||||
|                   e += 1 | ||||
|                 return fixer.removeRange([s, e]) | ||||
|               }, | ||||
|             }) | ||||
|           } | ||||
|           names.add(id) | ||||
|         }) | ||||
|  | ||||
|         // console.log(node) | ||||
|       }, | ||||
|     } | ||||
|   }, | ||||
| }) | ||||
| @@ -1,44 +0,0 @@ | ||||
| import { createEslintRule } from '../utils' | ||||
|  | ||||
| export const RULE_NAME = 'no-leading-newline' | ||||
| export type MessageIds = 'noLeadingNewline' | ||||
| export type Options = [] | ||||
|  | ||||
| export default createEslintRule<Options, MessageIds>({ | ||||
|   name: RULE_NAME, | ||||
|   meta: { | ||||
|     type: 'problem', | ||||
|     docs: { | ||||
|       description: 'Do not allow leading newline', | ||||
|       recommended: 'error', | ||||
|     }, | ||||
|     fixable: 'whitespace', | ||||
|     schema: [], | ||||
|     messages: { | ||||
|       noLeadingNewline: 'No leading newline allowed', | ||||
|     }, | ||||
|   }, | ||||
|   defaultOptions: [], | ||||
|   create: (context) => { | ||||
|     return { | ||||
|       Program(node) { | ||||
|         const code = context.getSourceCode() | ||||
|         const match = code.text.match(/^[\s]+/)?.[0] || '' | ||||
|         if (match.includes('\n')) { | ||||
|           const line = match.split('\n') | ||||
|           context.report({ | ||||
|             node, | ||||
|             loc: { | ||||
|               start: { line: 0, column: 0 }, | ||||
|               end: { line: line.length - 1, column: line[line.length - 1].length }, | ||||
|             }, | ||||
|             messageId: 'noLeadingNewline', | ||||
|             fix(fixer) { | ||||
|               return fixer.replaceTextRange([0, match.length], '') | ||||
|             }, | ||||
|           }) | ||||
|         } | ||||
|       }, | ||||
|     } | ||||
|   }, | ||||
| }) | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@antfu/eslint-config-react", | ||||
|   "version": "0.20.3", | ||||
|   "version": "0.22.0", | ||||
|   "description": "", | ||||
|   "keywords": [], | ||||
|   "license": "MIT", | ||||
| @@ -23,7 +23,7 @@ | ||||
|     "eslint-plugin-react": "^7.29.4" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "eslint": "^8.12.0", | ||||
|     "eslint": "^8.14.0", | ||||
|     "react": "^18.0.0", | ||||
|     "typescript": "^4.6.3" | ||||
|   } | ||||
|   | ||||
| @@ -17,7 +17,6 @@ module.exports = { | ||||
|     'import/named': 'off', | ||||
|  | ||||
|     // TS | ||||
|     '@typescript-eslint/semi': ['error', 'never'], | ||||
|     '@typescript-eslint/ban-ts-comment': ['error', { 'ts-ignore': 'allow-with-description' }], | ||||
|     '@typescript-eslint/member-delimiter-style': ['error', { multiline: { delimiter: 'none' } }], | ||||
|     '@typescript-eslint/type-annotation-spacing': ['error', {}], | ||||
| @@ -29,7 +28,41 @@ module.exports = { | ||||
|     // Override JS | ||||
|     'no-useless-constructor': 'off', | ||||
|     'indent': 'off', | ||||
|     '@typescript-eslint/indent': ['error', 2], | ||||
|     '@typescript-eslint/indent': ['error', 2, { | ||||
|       SwitchCase: 1, | ||||
|       VariableDeclarator: 1, | ||||
|       outerIIFEBody: 1, | ||||
|       MemberExpression: 1, | ||||
|       FunctionDeclaration: { parameters: 1, body: 1 }, | ||||
|       FunctionExpression: { parameters: 1, body: 1 }, | ||||
|       CallExpression: { arguments: 1 }, | ||||
|       ArrayExpression: 1, | ||||
|       ObjectExpression: 1, | ||||
|       ImportDeclaration: 1, | ||||
|       flatTernaryExpressions: false, | ||||
|       ignoreComments: false, | ||||
|       ignoredNodes: [ | ||||
|         'TemplateLiteral *', | ||||
|         'JSXElement', | ||||
|         'JSXElement > *', | ||||
|         'JSXAttribute', | ||||
|         'JSXIdentifier', | ||||
|         'JSXNamespacedName', | ||||
|         'JSXMemberExpression', | ||||
|         'JSXSpreadAttribute', | ||||
|         'JSXExpressionContainer', | ||||
|         'JSXOpeningElement', | ||||
|         'JSXClosingElement', | ||||
|         'JSXFragment', | ||||
|         'JSXOpeningFragment', | ||||
|         'JSXClosingFragment', | ||||
|         'JSXText', | ||||
|         'JSXEmptyExpression', | ||||
|         'JSXSpreadChild', | ||||
|         'TSTypeParameterInstantiation', | ||||
|       ], | ||||
|       offsetTernaryExpressions: true, | ||||
|     }], | ||||
|     'no-unused-vars': 'off', | ||||
|     '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], | ||||
|     'no-redeclare': 'off', | ||||
| @@ -42,6 +75,43 @@ module.exports = { | ||||
|     '@typescript-eslint/comma-dangle': ['error', 'always-multiline'], | ||||
|     'object-curly-spacing': 'off', | ||||
|     '@typescript-eslint/object-curly-spacing': ['error', 'always'], | ||||
|     'semi': 'off', | ||||
|     '@typescript-eslint/semi': ['error', 'never'], | ||||
|     'quotes': 'off', | ||||
|     '@typescript-eslint/quotes': ['error', 'single'], | ||||
|     'space-before-blocks': 'off', | ||||
|     '@typescript-eslint/space-before-blocks': ['error', 'always'], | ||||
|     'space-before-function-paren': 'off', | ||||
|     '@typescript-eslint/space-before-function-paren': [ | ||||
|       'error', | ||||
|       { | ||||
|         anonymous: 'always', | ||||
|         named: 'never', | ||||
|         asyncArrow: 'always', | ||||
|       }, | ||||
|     ], | ||||
|     'space-infix-ops': 'off', | ||||
|     '@typescript-eslint/space-infix-ops': 'error', | ||||
|     'keyword-spacing': 'off', | ||||
|     '@typescript-eslint/keyword-spacing': ['error', { before: true, after: true }], | ||||
|     'comma-spacing': 'off', | ||||
|     '@typescript-eslint/comma-spacing': ['error', { before: false, after: true }], | ||||
|     'no-extra-parens': 'off', | ||||
|     '@typescript-eslint/no-extra-parens': ['error', 'functions'], | ||||
|     'no-dupe-class-members': 'off', | ||||
|     '@typescript-eslint/no-dupe-class-members': 'error', | ||||
|     'no-loss-of-precision': 'off', | ||||
|     '@typescript-eslint/no-loss-of-precision': 'error', | ||||
|     'lines-between-class-members': 'off', | ||||
|     '@typescript-eslint/lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }], | ||||
|     // The following rule overrides require a parser service, aka. require a `typescript.json` path. | ||||
|     // This needs to be done individually for each project, and it slows down linting significantly. | ||||
|     // 'no-throw-literal': 'off', | ||||
|     // '@typescript-eslint/no-throw-literal': 'error', | ||||
|     // 'no-implied-eval': 'off', | ||||
|     // '@typescript-eslint/no-implied-eval': 'error', | ||||
|     // 'dot-notation': 'off', | ||||
|     // '@typescript-eslint/dot-notation': ['error', { allowKeywords: true }], | ||||
|  | ||||
|     // off | ||||
|     '@typescript-eslint/camelcase': 'off', | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@antfu/eslint-config-ts", | ||||
|   "version": "0.20.3", | ||||
|   "version": "0.22.0", | ||||
|   "description": "", | ||||
|   "keywords": [], | ||||
|   "license": "MIT", | ||||
| @@ -18,10 +18,10 @@ | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@antfu/eslint-config-basic": "workspace:*", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.17.0", | ||||
|     "@typescript-eslint/parser": "^5.17.0" | ||||
|     "@typescript-eslint/eslint-plugin": "^5.20.0", | ||||
|     "@typescript-eslint/parser": "^5.20.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "eslint": "^8.12.0" | ||||
|     "eslint": "^8.14.0" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@antfu/eslint-config-vue", | ||||
|   "version": "0.20.3", | ||||
|   "version": "0.22.0", | ||||
|   "description": "", | ||||
|   "keywords": [], | ||||
|   "license": "MIT", | ||||
| @@ -17,9 +17,9 @@ | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@antfu/eslint-config-ts": "workspace:*", | ||||
|     "eslint-plugin-vue": "^8.5.0" | ||||
|     "eslint-plugin-vue": "^8.7.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "eslint": "^8.12.0" | ||||
|     "eslint": "^8.14.0" | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										586
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										586
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user