@lincy/eslint-config 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # @lincy/eslint-config
2
+
3
+ A set of opinionated ESLint (http://eslint.org) rules (all rules included) tailored for Vue.js projects
4
+
5
+ 如果依赖安装了 typescript, 则自动应用 ts 的规则
6
+ 如果依赖安装了 prettier, 则自动应用 prettier 的规则
7
+
8
+ Usage
9
+
10
+ - pnpm install -D eslint @lincy/eslint-config
11
+ - create a file named .eslintrc in your project:
12
+ ```
13
+ {
14
+ "extends": "@lincy"
15
+ // Your overrides...
16
+ }
17
+ ```
18
+
19
+ License
20
+
21
+ MIT
package/basic.js ADDED
@@ -0,0 +1,377 @@
1
+ module.exports = {
2
+ env: {
3
+ es6: true,
4
+ browser: true,
5
+ node: true,
6
+ },
7
+ reportUnusedDisableDirectives: true,
8
+ extends: [
9
+ './standard',
10
+ 'plugin:import/recommended',
11
+ 'plugin:eslint-comments/recommended',
12
+ 'plugin:jsonc/recommended-with-jsonc',
13
+ 'plugin:yml/standard',
14
+ 'plugin:markdown/recommended',
15
+ ],
16
+ ignorePatterns: [
17
+ '*.min.*',
18
+ '*.d.ts',
19
+ 'CHANGELOG.md',
20
+ 'dist',
21
+ 'LICENSE*',
22
+ 'output',
23
+ 'out',
24
+ 'coverage',
25
+ 'public',
26
+ 'temp',
27
+ 'package-lock.json',
28
+ 'pnpm-lock.yaml',
29
+ 'yarn.lock',
30
+ '__snapshots__',
31
+ // ignore for in lint-staged
32
+ '*.css',
33
+ '*.png',
34
+ '*.ico',
35
+ '*.toml',
36
+ '*.patch',
37
+ '*.txt',
38
+ '*.crt',
39
+ '*.key',
40
+ 'Dockerfile',
41
+ // force include
42
+ '!.github',
43
+ '!.vitepress',
44
+ '!.vscode',
45
+ ],
46
+ plugins: [
47
+ 'html',
48
+ 'unicorn',
49
+ 'antfu',
50
+ 'no-only-tests',
51
+ 'unused-imports',
52
+ ],
53
+ settings: {
54
+ 'import/resolver': {
55
+ node: { extensions: ['.js', '.mjs'] },
56
+ },
57
+ },
58
+ overrides: [
59
+ {
60
+ files: ['*.json', '*.json5'],
61
+ parser: 'jsonc-eslint-parser',
62
+ rules: {
63
+ 'jsonc/array-bracket-spacing': ['error', 'never'],
64
+ 'jsonc/comma-dangle': ['error', 'never'],
65
+ 'jsonc/comma-style': ['error', 'last'],
66
+ 'jsonc/indent': ['error', 2],
67
+ 'jsonc/key-spacing': ['error', { beforeColon: false, afterColon: true }],
68
+ 'jsonc/no-octal-escape': 'error',
69
+ 'jsonc/object-curly-newline': ['error', { multiline: true, consistent: true }],
70
+ 'jsonc/object-curly-spacing': ['error', 'always'],
71
+ 'jsonc/object-property-newline': ['error', { allowMultiplePropertiesPerLine: true }],
72
+ },
73
+ },
74
+ {
75
+ files: ['*.yaml', '*.yml'],
76
+ parser: 'yaml-eslint-parser',
77
+ rules: {
78
+ 'spaced-comment': 'off',
79
+ },
80
+ },
81
+ {
82
+ files: ['package.json'],
83
+ parser: 'jsonc-eslint-parser',
84
+ rules: {
85
+ 'jsonc/sort-keys': [
86
+ 'error',
87
+ {
88
+ pathPattern: '^$',
89
+ order: [
90
+ 'publisher',
91
+ 'name',
92
+ 'displayName',
93
+ 'type',
94
+ 'version',
95
+ 'private',
96
+ 'packageManager',
97
+ 'description',
98
+ 'author',
99
+ 'license',
100
+ 'funding',
101
+ 'homepage',
102
+ 'repository',
103
+ 'bugs',
104
+ 'keywords',
105
+ 'categories',
106
+ 'sideEffects',
107
+ 'exports',
108
+ 'main',
109
+ 'module',
110
+ 'unpkg',
111
+ 'jsdelivr',
112
+ 'types',
113
+ 'typesVersions',
114
+ 'bin',
115
+ 'icon',
116
+ 'files',
117
+ 'engines',
118
+ 'activationEvents',
119
+ 'contributes',
120
+ 'scripts',
121
+ 'peerDependencies',
122
+ 'peerDependenciesMeta',
123
+ 'dependencies',
124
+ 'optionalDependencies',
125
+ 'devDependencies',
126
+ 'pnpm',
127
+ 'overrides',
128
+ 'resolutions',
129
+ 'husky',
130
+ 'simple-git-hooks',
131
+ 'lint-staged',
132
+ 'eslintConfig',
133
+ ],
134
+ },
135
+ {
136
+ pathPattern: '^(?:dev|peer|optional|bundled)?[Dd]ependencies$',
137
+ order: { type: 'asc' },
138
+ },
139
+ {
140
+ pathPattern: '^exports.*$',
141
+ order: [
142
+ 'types',
143
+ 'require',
144
+ 'import',
145
+ ],
146
+ },
147
+ ],
148
+ },
149
+ },
150
+ {
151
+ files: ['*.d.ts'],
152
+ rules: {
153
+ 'import/no-duplicates': 'off',
154
+ },
155
+ },
156
+ {
157
+ files: ['*.js', '*.cjs', '*.jsx'],
158
+ rules: {
159
+ '@typescript-eslint/no-var-requires': 'off',
160
+ '@typescript-eslint/no-require-imports': 'off',
161
+ },
162
+ },
163
+ {
164
+ files: ['*.ts', '*.tsx', '*.mts', '*.cts'],
165
+ rules: {
166
+ 'no-void': ['error', { allowAsStatement: true }],
167
+ },
168
+ },
169
+ {
170
+ files: ['scripts/**/*.*', 'cli.*'],
171
+ rules: {
172
+ 'no-console': 'off',
173
+ },
174
+ },
175
+ {
176
+ files: ['*.test.ts', '*.test.js', '*.spec.ts', '*.spec.js'],
177
+ rules: {
178
+ 'no-unused-expressions': 'off',
179
+ 'no-only-tests/no-only-tests': 'error',
180
+ },
181
+ },
182
+ {
183
+ // Code blocks in markdown file
184
+ files: ['**/*.md/*.*'],
185
+ rules: {
186
+ '@typescript-eslint/no-redeclare': 'off',
187
+ '@typescript-eslint/no-unused-vars': 'off',
188
+ '@typescript-eslint/no-use-before-define': 'off',
189
+ '@typescript-eslint/no-var-requires': 'off',
190
+ '@typescript-eslint/comma-dangle': 'off',
191
+ '@typescript-eslint/consistent-type-imports': 'off',
192
+ 'import/no-unresolved': 'off',
193
+ 'unused-imports/no-unused-imports': 'off',
194
+ 'unused-imports/no-unused-vars': 'off',
195
+ 'no-alert': 'off',
196
+ 'no-console': 'off',
197
+ 'no-restricted-imports': 'off',
198
+ 'no-undef': 'off',
199
+ 'no-unused-expressions': 'off',
200
+ 'no-unused-vars': 'off',
201
+ },
202
+ },
203
+ ],
204
+ rules: {
205
+ // import
206
+ 'import/order': 'error',
207
+ 'import/first': 'error',
208
+ 'import/no-mutable-exports': 'error',
209
+ 'import/no-unresolved': 'off',
210
+ 'import/no-absolute-path': 'off',
211
+ 'import/newline-after-import': ['error', { count: 1, considerComments: true }],
212
+
213
+ // Common
214
+ 'semi': ['error', 'never'],
215
+ 'curly': ['error', 'multi-or-nest', 'consistent'],
216
+ 'quotes': ['error', 'single'],
217
+ 'quote-props': ['error', 'consistent-as-needed'],
218
+
219
+ 'unused-imports/no-unused-imports': 'error',
220
+ 'unused-imports/no-unused-vars': [
221
+ 'warn',
222
+ {
223
+ vars: 'all',
224
+ varsIgnorePattern: '^_',
225
+ args: 'after-used',
226
+ argsIgnorePattern: '^_',
227
+ },
228
+ ],
229
+
230
+ 'no-param-reassign': 'off',
231
+ 'array-bracket-spacing': ['error', 'never'],
232
+ 'brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
233
+ 'block-spacing': ['error', 'always'],
234
+ 'camelcase': 'off',
235
+ 'comma-spacing': ['error', { before: false, after: true }],
236
+ 'comma-style': ['error', 'last'],
237
+ 'comma-dangle': ['error', 'always-multiline'],
238
+ 'no-constant-condition': 'warn',
239
+ 'no-debugger': 'error',
240
+ // 'no-console': ['error', { allow: ['warn', 'error'] }],
241
+ 'no-console': 'off',
242
+ 'no-cond-assign': ['error', 'always'],
243
+ 'func-call-spacing': ['off', 'never'],
244
+ 'key-spacing': ['error', { beforeColon: false, afterColon: true }],
245
+ 'indent': ['error', 4, { SwitchCase: 1, VariableDeclarator: 1, outerIIFEBody: 1 }],
246
+ 'no-restricted-syntax': [
247
+ 'error',
248
+ 'DebuggerStatement',
249
+ 'LabeledStatement',
250
+ 'WithStatement',
251
+ ],
252
+ 'object-curly-spacing': ['error', 'always'],
253
+ 'no-return-await': 'off',
254
+ 'space-before-function-paren': [
255
+ 'error',
256
+ {
257
+ anonymous: 'always',
258
+ named: 'never',
259
+ asyncArrow: 'always',
260
+ },
261
+ ],
262
+
263
+ // es6
264
+ 'no-var': 'error',
265
+ 'prefer-const': [
266
+ 'error',
267
+ {
268
+ destructuring: 'all',
269
+ ignoreReadBeforeAssign: true,
270
+ },
271
+ ],
272
+ 'prefer-arrow-callback': [
273
+ 'error',
274
+ {
275
+ allowNamedFunctions: false,
276
+ allowUnboundThis: true,
277
+ },
278
+ ],
279
+ 'object-shorthand': [
280
+ 'error',
281
+ 'always',
282
+ {
283
+ ignoreConstructors: false,
284
+ avoidQuotes: true,
285
+ },
286
+ ],
287
+ 'prefer-exponentiation-operator': 'error',
288
+ 'prefer-rest-params': 'error',
289
+ 'prefer-spread': 'error',
290
+ 'prefer-template': 'error',
291
+ 'template-curly-spacing': 'error',
292
+ 'arrow-parens': ['error', 'as-needed', { requireForBlockBody: true }],
293
+ 'generator-star-spacing': 'off',
294
+ 'spaced-comment': ['error', 'always', {
295
+ line: {
296
+ markers: ['/'],
297
+ exceptions: ['/', '#'],
298
+ },
299
+ block: {
300
+ markers: ['!'],
301
+ exceptions: ['*'],
302
+ balanced: true,
303
+ },
304
+ }],
305
+
306
+ // best-practice
307
+ 'array-callback-return': 'error',
308
+ 'block-scoped-var': 'error',
309
+ 'consistent-return': 'off',
310
+ 'complexity': ['off', 11],
311
+ 'eqeqeq': ['error', 'smart'],
312
+ 'no-alert': 'warn',
313
+ 'no-case-declarations': 'error',
314
+ 'no-multi-spaces': 'error',
315
+ 'no-multi-str': 'error',
316
+ 'no-with': 'error',
317
+ 'no-void': 'error',
318
+ 'no-useless-escape': 'off',
319
+ 'vars-on-top': 'error',
320
+ 'require-await': 'off',
321
+ 'no-return-assign': 'off',
322
+ 'operator-linebreak': ['error', 'before'],
323
+ 'max-statements-per-line': ['error', { max: 1 }],
324
+
325
+ // unicorns
326
+ // Pass error message when throwing errors
327
+ 'unicorn/error-message': 'error',
328
+ // Uppercase regex escapes
329
+ 'unicorn/escape-case': 'error',
330
+ // Array.isArray instead of instanceof
331
+ 'unicorn/no-instanceof-array': 'error',
332
+ // Prevent deprecated `new Buffer()`
333
+ 'unicorn/no-new-buffer': 'error',
334
+ // Keep regex literals safe!
335
+ 'unicorn/no-unsafe-regex': 'off',
336
+ // Lowercase number formatting for octal, hex, binary (0x1'error' instead of 0X1'error')
337
+ 'unicorn/number-literal-case': 'error',
338
+ // includes over indexOf when checking for existence
339
+ 'unicorn/prefer-includes': 'error',
340
+ // String methods startsWith/endsWith instead of more complicated stuff
341
+ 'unicorn/prefer-string-starts-ends-with': 'error',
342
+ // textContent instead of innerText
343
+ 'unicorn/prefer-text-content': 'error',
344
+ // Enforce throwing type error when throwing error while checking typeof
345
+ 'unicorn/prefer-type-error': 'error',
346
+ // Use new when throwing error
347
+ 'unicorn/throw-new-error': 'error',
348
+ // Prefer using the node: protocol
349
+ 'unicorn/prefer-node-protocol': 'error',
350
+
351
+ 'no-use-before-define': ['error', { functions: false, classes: false, variables: true }],
352
+ 'eslint-comments/disable-enable-pair': 'off',
353
+ 'import/no-named-as-default-member': 'off',
354
+ 'import/no-named-as-default': 'off',
355
+ 'import/namespace': 'off',
356
+ 'n/no-callback-literal': 'off',
357
+
358
+ 'sort-imports': [
359
+ 'error',
360
+ {
361
+ ignoreCase: false,
362
+ ignoreDeclarationSort: true,
363
+ ignoreMemberSort: false,
364
+ memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
365
+ allowSeparatedGroups: false,
366
+ },
367
+ ],
368
+
369
+ // yml
370
+ 'yml/quotes': ['error', { prefer: 'single', avoidEscape: false }],
371
+ 'yml/no-empty-document': 'off',
372
+
373
+ 'antfu/if-newline': 'error',
374
+ 'antfu/import-dedupe': 'error',
375
+ 'antfu/top-level-function': 'error',
376
+ },
377
+ }
package/index.js ADDED
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ extends: ['./vue'],
3
+ }
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@lincy/eslint-config",
3
+ "version": "1.1.1",
4
+ "description": "LinCenYing's ESLint config",
5
+ "author": "LinCenYing <lincenying@gmail.com> (https://github.com/lincenying/)",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/lincenying/eslint-config-lcy",
8
+ "keywords": [
9
+ "eslint-config"
10
+ ],
11
+ "main": "index.js",
12
+ "files": [
13
+ "index.js",
14
+ "vue.js",
15
+ "ts.js",
16
+ "basic.js",
17
+ "standard.js"
18
+ ],
19
+ "peerDependencies": {
20
+ "eslint": ">=7.4.0"
21
+ },
22
+ "dependencies": {
23
+ "@typescript-eslint/eslint-plugin": "^5.59.0",
24
+ "@typescript-eslint/parser": "^5.59.0",
25
+ "eslint-config-prettier": "^8.6.0",
26
+ "eslint-plugin-antfu": "^0.38.5",
27
+ "eslint-plugin-eslint-comments": "^3.2.0",
28
+ "eslint-plugin-html": "^7.1.0",
29
+ "eslint-plugin-import": "^2.27.5",
30
+ "eslint-plugin-jest": "^27.2.1",
31
+ "eslint-plugin-jsonc": "^2.7.0",
32
+ "eslint-plugin-markdown": "^3.0.0",
33
+ "eslint-plugin-n": "^15.7.0",
34
+ "eslint-plugin-no-only-tests": "^3.1.0",
35
+ "eslint-plugin-prettier": "^4.2.1",
36
+ "eslint-plugin-promise": "^6.1.1",
37
+ "eslint-plugin-unicorn": "^46.0.0",
38
+ "eslint-plugin-unused-imports": "^2.0.0",
39
+ "eslint-plugin-vue": "^9.11.0",
40
+ "eslint-plugin-yml": "^1.5.0",
41
+ "jsonc-eslint-parser": "^2.2.0",
42
+ "local-pkg": "^0.4.3",
43
+ "yaml-eslint-parser": "^1.2.0"
44
+ },
45
+ "devDependencies": {
46
+ "eslint": "^8.38.0",
47
+ "typescript": "^5.0.4"
48
+ },
49
+ "publishConfig": {
50
+ "registry": "https://registry.npmjs.org/"
51
+ },
52
+ "pnpm": {
53
+ "peerDependencyRules": {
54
+ "ignoreMissing": [
55
+ "prettier"
56
+ ]
57
+ }
58
+ }
59
+ }
package/standard.js ADDED
@@ -0,0 +1,243 @@
1
+ // Inline from https://github.com/standard/eslint-config-standard/blob/master/.eslintrc.json
2
+ // Until it upgrades
3
+
4
+ module.exports = {
5
+ parserOptions: {
6
+ ecmaVersion: 2022,
7
+ ecmaFeatures: {
8
+ jsx: true,
9
+ },
10
+ sourceType: 'module',
11
+ },
12
+ env: {
13
+ es2021: true,
14
+ node: true,
15
+ },
16
+ plugins: ['import', 'n', 'promise'],
17
+ globals: {
18
+ document: 'readonly',
19
+ navigator: 'readonly',
20
+ window: 'readonly',
21
+ },
22
+ rules: {
23
+ 'no-var': 'warn',
24
+ 'object-shorthand': ['warn', 'properties'],
25
+
26
+ 'accessor-pairs': ['error', { setWithoutGet: true, enforceForClassMembers: true }],
27
+ 'array-bracket-spacing': ['error', 'never'],
28
+ 'array-callback-return': ['error', {
29
+ allowImplicit: false,
30
+ checkForEach: false,
31
+ }],
32
+ 'arrow-spacing': ['error', { before: true, after: true }],
33
+ 'block-spacing': ['error', 'always'],
34
+ 'brace-style': ['error', '1tbs', { allowSingleLine: true }],
35
+ 'camelcase': ['error', {
36
+ allow: ['^UNSAFE_'],
37
+ properties: 'never',
38
+ ignoreGlobals: true,
39
+ }],
40
+ 'comma-dangle': ['error', {
41
+ arrays: 'never',
42
+ objects: 'never',
43
+ imports: 'never',
44
+ exports: 'never',
45
+ functions: 'never',
46
+ }],
47
+ 'comma-spacing': ['error', { before: false, after: true }],
48
+ 'comma-style': ['error', 'last'],
49
+ 'computed-property-spacing': ['error', 'never', { enforceForClassMembers: true }],
50
+ 'constructor-super': 'error',
51
+ 'curly': ['error', 'multi-line'],
52
+ 'default-case-last': 'error',
53
+ 'dot-location': ['error', 'property'],
54
+ 'dot-notation': ['error', { allowKeywords: true }],
55
+ 'eol-last': 'error',
56
+ 'eqeqeq': ['error', 'always', { null: 'ignore' }],
57
+ 'func-call-spacing': ['error', 'never'],
58
+ 'generator-star-spacing': ['error', { before: true, after: true }],
59
+ 'indent': ['error', 4, {
60
+ SwitchCase: 1,
61
+ VariableDeclarator: 1,
62
+ outerIIFEBody: 1,
63
+ MemberExpression: 1,
64
+ FunctionDeclaration: { parameters: 1, body: 1 },
65
+ FunctionExpression: { parameters: 1, body: 1 },
66
+ CallExpression: { arguments: 1 },
67
+ ArrayExpression: 1,
68
+ ObjectExpression: 1,
69
+ ImportDeclaration: 1,
70
+ flatTernaryExpressions: false,
71
+ ignoreComments: false,
72
+ ignoredNodes: ['TemplateLiteral *', 'JSXElement', 'JSXElement > *', 'JSXAttribute', 'JSXIdentifier', 'JSXNamespacedName', 'JSXMemberExpression', 'JSXSpreadAttribute', 'JSXExpressionContainer', 'JSXOpeningElement', 'JSXClosingElement', 'JSXFragment', 'JSXOpeningFragment', 'JSXClosingFragment', 'JSXText', 'JSXEmptyExpression', 'JSXSpreadChild'],
73
+ offsetTernaryExpressions: true,
74
+ }],
75
+ 'key-spacing': ['error', { beforeColon: false, afterColon: true }],
76
+ 'keyword-spacing': ['error', { before: true, after: true }],
77
+ 'lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }],
78
+ 'multiline-ternary': ['error', 'always-multiline'],
79
+ 'new-cap': ['error', { newIsCap: true, capIsNew: false, properties: true }],
80
+ 'new-parens': 'error',
81
+ 'no-array-constructor': 'error',
82
+ 'no-async-promise-executor': 'error',
83
+ 'no-caller': 'error',
84
+ 'no-case-declarations': 'error',
85
+ 'no-class-assign': 'error',
86
+ 'no-compare-neg-zero': 'error',
87
+ 'no-cond-assign': 'error',
88
+ 'no-const-assign': 'error',
89
+ 'no-constant-condition': ['error', { checkLoops: false }],
90
+ 'no-control-regex': 'error',
91
+ 'no-debugger': 'error',
92
+ 'no-delete-var': 'error',
93
+ 'no-dupe-args': 'error',
94
+ 'no-dupe-class-members': 'error',
95
+ 'no-dupe-keys': 'error',
96
+ 'no-duplicate-case': 'error',
97
+ 'no-useless-backreference': 'error',
98
+ 'no-empty': ['error', { allowEmptyCatch: true }],
99
+ 'no-empty-character-class': 'error',
100
+ 'no-empty-pattern': 'error',
101
+ 'no-eval': 'error',
102
+ 'no-ex-assign': 'error',
103
+ 'no-extend-native': 'error',
104
+ 'no-extra-bind': 'error',
105
+ 'no-extra-boolean-cast': 'error',
106
+ 'no-extra-parens': ['error', 'functions'],
107
+ 'no-fallthrough': 'error',
108
+ 'no-floating-decimal': 'error',
109
+ 'no-func-assign': 'error',
110
+ 'no-global-assign': 'error',
111
+ 'no-implied-eval': 'error',
112
+ 'no-import-assign': 'error',
113
+ 'no-invalid-regexp': 'error',
114
+ 'no-irregular-whitespace': 'error',
115
+ 'no-iterator': 'error',
116
+ 'no-labels': ['error', { allowLoop: false, allowSwitch: false }],
117
+ 'no-lone-blocks': 'error',
118
+ 'no-loss-of-precision': 'error',
119
+ 'no-misleading-character-class': 'error',
120
+ 'no-prototype-builtins': 'error',
121
+ 'no-useless-catch': 'error',
122
+ 'no-mixed-operators': ['error', {
123
+ groups: [
124
+ ['==', '!=', '===', '!==', '>', '>=', '<', '<='],
125
+ ['&&', '||', '?:'],
126
+ ['in', 'instanceof'],
127
+ ],
128
+ allowSamePrecedence: true,
129
+ }],
130
+ 'no-mixed-spaces-and-tabs': 'error',
131
+ 'no-multi-spaces': 'error',
132
+ 'no-multi-str': 'error',
133
+ 'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 0 }],
134
+ 'no-new': 'error',
135
+ 'no-new-func': 'error',
136
+ 'no-new-object': 'error',
137
+ 'no-new-symbol': 'error',
138
+ 'no-new-wrappers': 'error',
139
+ 'no-obj-calls': 'error',
140
+ 'no-octal': 'error',
141
+ 'no-octal-escape': 'error',
142
+ 'no-proto': 'error',
143
+ 'no-redeclare': ['error', { builtinGlobals: false }],
144
+ 'no-regex-spaces': 'error',
145
+ 'no-return-assign': ['error', 'except-parens'],
146
+ 'no-self-assign': ['error', { props: true }],
147
+ 'no-self-compare': 'error',
148
+ 'no-sequences': 'error',
149
+ 'no-shadow-restricted-names': 'error',
150
+ 'no-sparse-arrays': 'error',
151
+ 'no-tabs': 'error',
152
+ 'no-template-curly-in-string': 'error',
153
+ 'no-this-before-super': 'error',
154
+ 'no-throw-literal': 'error',
155
+ 'no-trailing-spaces': 'error',
156
+ 'no-undef': 'error',
157
+ 'no-undef-init': 'error',
158
+ 'no-unexpected-multiline': 'error',
159
+ 'no-unmodified-loop-condition': 'error',
160
+ 'no-unneeded-ternary': ['error', { defaultAssignment: false }],
161
+ 'no-unreachable': 'error',
162
+ 'no-unreachable-loop': 'error',
163
+ 'no-unsafe-finally': 'error',
164
+ 'no-unsafe-negation': 'error',
165
+ 'no-unused-expressions': ['error', {
166
+ allowShortCircuit: true,
167
+ allowTernary: true,
168
+ allowTaggedTemplates: true,
169
+ }],
170
+ 'no-unused-vars': ['error', {
171
+ args: 'none',
172
+ caughtErrors: 'none',
173
+ ignoreRestSiblings: true,
174
+ vars: 'all',
175
+ }],
176
+ 'no-use-before-define': ['error', { functions: false, classes: false, variables: false }],
177
+ 'no-useless-call': 'error',
178
+ 'no-useless-computed-key': 'error',
179
+ 'no-useless-constructor': 'error',
180
+ 'no-useless-escape': 'error',
181
+ 'no-useless-rename': 'error',
182
+ 'no-useless-return': 'error',
183
+ 'no-void': 'error',
184
+ 'no-whitespace-before-property': 'error',
185
+ 'no-with': 'error',
186
+ 'object-curly-newline': ['error', { multiline: true, consistent: true }],
187
+ 'object-curly-spacing': ['error', 'always'],
188
+ 'object-property-newline': ['error', { allowMultiplePropertiesPerLine: true }],
189
+ 'one-var': ['error', { initialized: 'never' }],
190
+ 'operator-linebreak': ['error', 'after', { overrides: { '?': 'before', ':': 'before', '|>': 'before' } }],
191
+ 'padded-blocks': ['error', { blocks: 'never', switches: 'never', classes: 'never' }],
192
+ 'prefer-const': ['error', { destructuring: 'all' }],
193
+ 'prefer-promise-reject-errors': 'error',
194
+ 'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }],
195
+ 'quote-props': ['error', 'as-needed'],
196
+ 'quotes': ['error', 'single', { avoidEscape: true, allowTemplateLiterals: false }],
197
+ 'rest-spread-spacing': ['error', 'never'],
198
+ 'semi': ['error', 'never'],
199
+ 'semi-spacing': ['error', { before: false, after: true }],
200
+ 'space-before-blocks': ['error', 'always'],
201
+ 'space-before-function-paren': ['error', 'always'],
202
+ 'space-in-parens': ['error', 'never'],
203
+ 'space-infix-ops': 'error',
204
+ 'space-unary-ops': ['error', { words: true, nonwords: false }],
205
+ 'spaced-comment': ['error', 'always', {
206
+ line: { markers: ['*package', '!', '/', ',', '='] },
207
+ block: {
208
+ balanced: true,
209
+ markers: ['*package', '!', ',', ':', '::', 'flow-include'],
210
+ exceptions: ['*'],
211
+ },
212
+ }],
213
+ 'symbol-description': 'error',
214
+ 'template-curly-spacing': ['error', 'never'],
215
+ 'template-tag-spacing': ['error', 'never'],
216
+ 'unicode-bom': ['error', 'never'],
217
+ 'use-isnan': ['error', {
218
+ enforceForSwitchCase: true,
219
+ enforceForIndexOf: true,
220
+ }],
221
+ 'valid-typeof': ['error', { requireStringLiterals: true }],
222
+ 'wrap-iife': ['error', 'any', { functionPrototypeMethods: true }],
223
+ 'yield-star-spacing': ['error', 'both'],
224
+ 'yoda': ['error', 'never'],
225
+
226
+ 'import/export': 'error',
227
+ 'import/first': 'error',
228
+ 'import/no-absolute-path': ['error', { esmodule: true, commonjs: true, amd: false }],
229
+ 'import/no-duplicates': 'error',
230
+ 'import/no-named-default': 'error',
231
+ 'import/no-webpack-loader-syntax': 'error',
232
+
233
+ 'n/handle-callback-err': ['error', '^(err|error)$'],
234
+ 'n/no-callback-literal': 'error',
235
+ 'n/no-deprecated-api': 'error',
236
+ 'n/no-exports-assign': 'error',
237
+ 'n/no-new-require': 'error',
238
+ 'n/no-path-concat': 'error',
239
+ 'n/process-exit-as-throw': 'error',
240
+
241
+ 'promise/param-names': 'error',
242
+ },
243
+ }
package/ts.js ADDED
@@ -0,0 +1,184 @@
1
+ const fs = require('node:fs')
2
+ const { join } = require('node:path')
3
+ const basic = require('./basic')
4
+
5
+ const tsconfig = process.env.ESLINT_TSCONFIG || 'tsconfig.eslint.json'
6
+
7
+ module.exports = {
8
+ extends: [
9
+ './basic',
10
+ 'plugin:import/typescript',
11
+ 'plugin:@typescript-eslint/recommended',
12
+ ],
13
+ settings: {
14
+ 'import/resolver': {
15
+ node: {
16
+ extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx', '.d.ts'],
17
+ },
18
+ },
19
+ },
20
+ overrides: basic.overrides.concat(
21
+ !fs.existsSync(join(process.cwd(), tsconfig))
22
+ ? []
23
+ : [{
24
+ parserOptions: {
25
+ tsconfigRootDir: process.cwd(),
26
+ project: [tsconfig],
27
+ },
28
+ parser: '@typescript-eslint/parser',
29
+ excludedFiles: ['**/*.md/*.*'],
30
+ files: ['*.ts', '*.tsx', '*.mts', '*.cts'],
31
+ // https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/recommended-requiring-type-checking.ts
32
+ rules: {
33
+ 'no-throw-literal': 'off',
34
+ '@typescript-eslint/no-throw-literal': 'error',
35
+ 'no-implied-eval': 'off',
36
+ '@typescript-eslint/no-implied-eval': 'error',
37
+ 'dot-notation': 'off',
38
+ '@typescript-eslint/dot-notation': ['error', { allowKeywords: true }],
39
+ '@typescript-eslint/no-floating-promises': 'error',
40
+ '@typescript-eslint/no-misused-promises': 'error',
41
+ '@typescript-eslint/await-thenable': 'error',
42
+ '@typescript-eslint/no-for-in-array': 'error',
43
+ '@typescript-eslint/no-unnecessary-type-assertion': 'error',
44
+ '@typescript-eslint/no-unsafe-argument': 'error',
45
+ '@typescript-eslint/no-unsafe-assignment': 'error',
46
+ '@typescript-eslint/no-unsafe-call': 'error',
47
+ '@typescript-eslint/no-unsafe-member-access': 'error',
48
+ '@typescript-eslint/no-unsafe-return': 'error',
49
+ 'require-await': 'off',
50
+ '@typescript-eslint/require-await': 'error',
51
+ '@typescript-eslint/restrict-plus-operands': 'error',
52
+ '@typescript-eslint/restrict-template-expressions': 'error',
53
+ '@typescript-eslint/unbound-method': 'error',
54
+ },
55
+ },
56
+ {
57
+ // https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/unbound-method.md
58
+ files: [
59
+ '**/__tests__/**/*.ts',
60
+ '**/*.spec.ts',
61
+ '**/*.test.ts',
62
+ ],
63
+ plugins: ['jest'],
64
+ rules: {
65
+ // you should turn the original rule off *only* for test files
66
+ '@typescript-eslint/unbound-method': 'off',
67
+ 'jest/unbound-method': 'error',
68
+ },
69
+ }],
70
+ ),
71
+ rules: {
72
+ 'import/named': 'off',
73
+
74
+ // TS
75
+ '@typescript-eslint/ban-ts-comment': ['error', { 'ts-ignore': 'allow-with-description' }],
76
+ '@typescript-eslint/member-delimiter-style': ['error', { multiline: { delimiter: 'none' } }],
77
+ '@typescript-eslint/type-annotation-spacing': ['error', {}],
78
+ '@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports', disallowTypeAnnotations: false }],
79
+ '@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
80
+ '@typescript-eslint/prefer-ts-expect-error': 'error',
81
+ '@typescript-eslint/no-require-imports': 'error',
82
+
83
+ // Override JS
84
+ 'no-useless-constructor': 'off',
85
+ 'indent': 'off',
86
+ '@typescript-eslint/indent': ['error', 4, {
87
+ SwitchCase: 1,
88
+ VariableDeclarator: 1,
89
+ outerIIFEBody: 1,
90
+ MemberExpression: 1,
91
+ FunctionDeclaration: { parameters: 1, body: 1 },
92
+ FunctionExpression: { parameters: 1, body: 1 },
93
+ CallExpression: { arguments: 1 },
94
+ ArrayExpression: 1,
95
+ ObjectExpression: 1,
96
+ ImportDeclaration: 1,
97
+ flatTernaryExpressions: false,
98
+ ignoreComments: false,
99
+ ignoredNodes: [
100
+ 'TemplateLiteral *',
101
+ 'JSXElement',
102
+ 'JSXElement > *',
103
+ 'JSXAttribute',
104
+ 'JSXIdentifier',
105
+ 'JSXNamespacedName',
106
+ 'JSXMemberExpression',
107
+ 'JSXSpreadAttribute',
108
+ 'JSXExpressionContainer',
109
+ 'JSXOpeningElement',
110
+ 'JSXClosingElement',
111
+ 'JSXFragment',
112
+ 'JSXOpeningFragment',
113
+ 'JSXClosingFragment',
114
+ 'JSXText',
115
+ 'JSXEmptyExpression',
116
+ 'JSXSpreadChild',
117
+ 'TSTypeParameterInstantiation',
118
+ 'FunctionExpression > .params[decorators.length > 0]',
119
+ 'FunctionExpression > .params > :matches(Decorator, :not(:first-child))',
120
+ 'ClassBody.body > PropertyDefinition[decorators.length > 0] > .key',
121
+ ],
122
+ offsetTernaryExpressions: true,
123
+ }],
124
+ 'no-redeclare': 'off',
125
+ '@typescript-eslint/no-redeclare': 'error',
126
+ 'no-use-before-define': 'off',
127
+ '@typescript-eslint/no-use-before-define': ['error', { functions: false, classes: false, variables: true }],
128
+ 'brace-style': 'off',
129
+ '@typescript-eslint/brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
130
+ 'comma-dangle': 'off',
131
+ '@typescript-eslint/comma-dangle': ['error', 'always-multiline'],
132
+ 'object-curly-spacing': 'off',
133
+ '@typescript-eslint/object-curly-spacing': ['error', 'always'],
134
+ 'semi': 'off',
135
+ '@typescript-eslint/semi': ['error', 'never'],
136
+ 'quotes': 'off',
137
+ '@typescript-eslint/quotes': ['error', 'single'],
138
+ 'space-before-blocks': 'off',
139
+ '@typescript-eslint/space-before-blocks': ['error', 'always'],
140
+ 'space-before-function-paren': 'off',
141
+ '@typescript-eslint/space-before-function-paren': [
142
+ 'error',
143
+ {
144
+ anonymous: 'always',
145
+ named: 'never',
146
+ asyncArrow: 'always',
147
+ },
148
+ ],
149
+ 'space-infix-ops': 'off',
150
+ '@typescript-eslint/space-infix-ops': 'error',
151
+ 'keyword-spacing': 'off',
152
+ '@typescript-eslint/keyword-spacing': ['error', { before: true, after: true }],
153
+ 'comma-spacing': 'off',
154
+ '@typescript-eslint/comma-spacing': ['error', { before: false, after: true }],
155
+ 'no-extra-parens': 'off',
156
+ '@typescript-eslint/no-extra-parens': ['error', 'functions'],
157
+ 'no-dupe-class-members': 'off',
158
+ '@typescript-eslint/no-dupe-class-members': 'error',
159
+ 'no-loss-of-precision': 'off',
160
+ '@typescript-eslint/no-loss-of-precision': 'error',
161
+ 'lines-between-class-members': 'off',
162
+ '@typescript-eslint/lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }],
163
+
164
+ 'antfu/generic-spacing': 'error',
165
+
166
+ // off
167
+ '@typescript-eslint/consistent-indexed-object-style': 'off',
168
+ '@typescript-eslint/naming-convention': 'off',
169
+ '@typescript-eslint/explicit-function-return-type': 'off',
170
+ '@typescript-eslint/explicit-member-accessibility': 'off',
171
+ '@typescript-eslint/no-explicit-any': 'off',
172
+ '@typescript-eslint/parameter-properties': 'off',
173
+ '@typescript-eslint/no-empty-interface': 'off',
174
+ '@typescript-eslint/ban-ts-ignore': 'off',
175
+ '@typescript-eslint/no-empty-function': 'off',
176
+ '@typescript-eslint/no-non-null-assertion': 'off',
177
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
178
+ '@typescript-eslint/ban-types': 'off',
179
+ // '@typescript-eslint/no-namespace': 'off',
180
+ '@typescript-eslint/triple-slash-reference': 'off',
181
+ // handled by unused-imports/no-unused-imports
182
+ '@typescript-eslint/no-unused-vars': 'off',
183
+ },
184
+ }
package/vue.js ADDED
@@ -0,0 +1,121 @@
1
+ const { isPackageExists } = require('local-pkg')
2
+
3
+ const TS = isPackageExists('typescript')
4
+ const Prettier = isPackageExists('prettier')
5
+
6
+ if (!TS) {
7
+ console.warn(
8
+ '[@lincy/eslint-config] TypeScript is not installed, fallback to JS only.',
9
+ )
10
+ }
11
+
12
+ module.exports = {
13
+ overrides: [
14
+ {
15
+ files: ['*.vue'],
16
+ parser: 'vue-eslint-parser',
17
+ parserOptions: {
18
+ parser: '@typescript-eslint/parser',
19
+ },
20
+ rules: {
21
+ 'no-unused-vars': 'off',
22
+ 'no-undef': 'off',
23
+ ...(TS ? { '@typescript-eslint/no-unused-vars': 'off' } : null),
24
+ },
25
+ },
26
+ ],
27
+ extends: [
28
+ 'plugin:vue/vue3-recommended',
29
+ TS ? './ts' : './basic',
30
+ ...(Prettier ? ['prettier'] : []),
31
+ ],
32
+ plugins: [
33
+ ...(Prettier ? ['prettier'] : []),
34
+ ],
35
+ rules: {
36
+
37
+ 'vue/max-attributes-per-line': 'off',
38
+ 'vue/no-v-html': 'off',
39
+ 'vue/require-prop-types': 'off',
40
+ 'vue/require-default-prop': 'off',
41
+ 'vue/multi-word-component-names': 'off',
42
+ 'vue/prefer-import-from-vue': 'off',
43
+ 'vue/no-v-text-v-html-on-component': 'off',
44
+
45
+ // reactivity transform
46
+ 'vue/no-setup-props-destructure': 'off',
47
+
48
+ 'vue/component-tags-order': ['error', {
49
+ order: ['template', 'script', 'style'],
50
+ }],
51
+ 'vue/block-tag-newline': ['error', {
52
+ singleline: 'always',
53
+ multiline: 'always',
54
+ }],
55
+ 'vue/component-name-in-template-casing': ['error', 'PascalCase'],
56
+ 'vue/component-options-name-casing': ['error', 'PascalCase'],
57
+ 'vue/custom-event-name-casing': ['error', 'camelCase'],
58
+ 'vue/define-macros-order': ['error', {
59
+ order: ['defineProps', 'defineEmits'],
60
+ }],
61
+ 'vue/html-indent': ['error', 4, {
62
+ attribute: 1,
63
+ baseIndent: 1,
64
+ closeBracket: 0,
65
+ alignAttributesVertically: true,
66
+ ignores: [],
67
+ }],
68
+ 'vue/html-comment-content-spacing': ['error', 'always', {
69
+ exceptions: ['-'],
70
+ }],
71
+ 'vue/no-restricted-v-bind': ['error', '/^v-/'],
72
+ 'vue/no-useless-v-bind': 'error',
73
+ 'vue/no-unused-refs': 'error',
74
+ 'vue/padding-line-between-blocks': ['error', 'always'],
75
+ 'vue/prefer-separate-static-class': 'error',
76
+
77
+ // extensions
78
+ 'vue/array-bracket-spacing': ['error', 'never'],
79
+ 'vue/arrow-spacing': ['error', { before: true, after: true }],
80
+ 'vue/block-spacing': ['error', 'always'],
81
+ 'vue/brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
82
+ 'vue/comma-dangle': ['error', 'always-multiline'],
83
+ 'vue/comma-spacing': ['error', { before: false, after: true }],
84
+ 'vue/comma-style': ['error', 'last'],
85
+ 'vue/dot-location': ['error', 'property'],
86
+ 'vue/dot-notation': ['error', { allowKeywords: true }],
87
+ 'vue/eqeqeq': ['error', 'smart'],
88
+ // 'vue/func-call-spacing': ['off', 'never'],
89
+ 'vue/key-spacing': ['error', { beforeColon: false, afterColon: true }],
90
+ 'vue/keyword-spacing': ['error', { before: true, after: true }],
91
+ 'vue/no-constant-condition': 'warn',
92
+ 'vue/no-empty-pattern': 'error',
93
+ 'vue/no-extra-parens': ['error', 'functions'],
94
+ 'vue/no-irregular-whitespace': 'error',
95
+ 'vue/no-loss-of-precision': 'error',
96
+ 'vue/no-restricted-syntax': [
97
+ 'error',
98
+ 'DebuggerStatement',
99
+ 'LabeledStatement',
100
+ 'WithStatement',
101
+ ],
102
+ 'vue/no-sparse-arrays': 'error',
103
+ 'vue/object-curly-newline': ['error', { multiline: true, consistent: true }],
104
+ 'vue/object-curly-spacing': ['error', 'always'],
105
+ 'vue/object-property-newline': ['error', { allowMultiplePropertiesPerLine: true }],
106
+ 'vue/object-shorthand': ['error', 'always', {
107
+ ignoreConstructors: false,
108
+ avoidQuotes: true,
109
+ }],
110
+ 'vue/operator-linebreak': ['error', 'before'],
111
+ 'vue/prefer-template': 'error',
112
+ 'vue/quote-props': ['error', 'consistent-as-needed'],
113
+ 'vue/space-in-parens': ['error', 'never'],
114
+ 'vue/space-infix-ops': 'error',
115
+ 'vue/space-unary-ops': ['error', { words: true, nonwords: false }],
116
+ 'vue/template-curly-spacing': 'error',
117
+ 'vue/singleline-html-element-content-newline': 'off',
118
+
119
+ ...(Prettier ? { 'prettier/prettier': 'error' } : null),
120
+ },
121
+ }