@tanstack/eslint-config 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021-present Tanner Linsley
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@tanstack/eslint-config",
3
+ "version": "0.1.0",
4
+ "description": "Shared ESLint config used by TanStack projects.",
5
+ "author": "tannerlinsley",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/TanStack/config.git",
10
+ "directory": "packages/eslint-config"
11
+ },
12
+ "homepage": "https://tanstack.com/config",
13
+ "funding": {
14
+ "type": "github",
15
+ "url": "https://github.com/sponsors/tannerlinsley"
16
+ },
17
+ "type": "module",
18
+ "exports": {
19
+ ".": {
20
+ "import": {
21
+ "default": "./src/index.js"
22
+ }
23
+ },
24
+ "./package.json": "./package.json"
25
+ },
26
+ "preferGlobal": false,
27
+ "sideEffects": false,
28
+ "files": [
29
+ "src"
30
+ ],
31
+ "engines": {
32
+ "node": ">=18"
33
+ },
34
+ "dependencies": {
35
+ "@eslint/js": "^9.21.0",
36
+ "@stylistic/eslint-plugin-js": "^4.1.0",
37
+ "eslint-plugin-import-x": "^4.6.1",
38
+ "eslint-plugin-n": "^17.16.1",
39
+ "globals": "^16.0.0",
40
+ "typescript-eslint": "^8.25.0",
41
+ "vue-eslint-parser": "^9.4.3"
42
+ },
43
+ "devDependencies": {
44
+ "@types/eslint": "^9.6.1",
45
+ "eslint": "^9.21.0"
46
+ },
47
+ "scripts": {
48
+ "test:types": "tsc",
49
+ "test:eslint": "eslint ./src",
50
+ "test:build": "publint --strict"
51
+ }
52
+ }
package/src/import.js ADDED
@@ -0,0 +1,33 @@
1
+ // https://github.com/un-ts/eslint-plugin-import-x
2
+
3
+ /** @type {import('eslint').Linter.RulesRecord} */
4
+ export const importRules = {
5
+ /** Bans the use of inline type-only markers for named imports */
6
+ 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
7
+ /** Reports any imports that come after non-import statements */
8
+ 'import/first': 'error',
9
+ /** Stylistic preference */
10
+ 'import/newline-after-import': 'error',
11
+ /** No require() or module.exports */
12
+ 'import/no-commonjs': 'error',
13
+ /** No import loops */
14
+ 'import/no-cycle': 'error',
15
+ /** Reports if a resolved path is imported more than once */
16
+ 'import/no-duplicates': 'error',
17
+ /** Stylistic preference */
18
+ 'import/order': [
19
+ 'error',
20
+ {
21
+ groups: [
22
+ 'builtin',
23
+ 'external',
24
+ 'internal',
25
+ 'parent',
26
+ 'sibling',
27
+ 'index',
28
+ 'object',
29
+ 'type',
30
+ ],
31
+ },
32
+ ],
33
+ }
package/src/index.js ADDED
@@ -0,0 +1,87 @@
1
+ import tseslint from 'typescript-eslint'
2
+ import vueparser from 'vue-eslint-parser'
3
+ import stylisticJs from '@stylistic/eslint-plugin-js'
4
+ import pluginImport from 'eslint-plugin-import-x'
5
+ import pluginNode from 'eslint-plugin-n'
6
+ import globals from 'globals'
7
+ import { javascriptRules } from './javascript.js'
8
+ import { importRules } from './import.js'
9
+ import { typescriptRules } from './typescript.js'
10
+ import { nodeRules } from './node.js'
11
+ import { stylisticRules } from './stylistic.js'
12
+
13
+ const JS_GLOB_INCLUDE = ['**/*.{js,ts,tsx}']
14
+ const VUE_GLOB_INCLUDE = ['**/*.vue']
15
+
16
+ const GLOB_EXCLUDE = [
17
+ '**/.nx/**',
18
+ '**/.svelte-kit/**',
19
+ '**/build/**',
20
+ '**/coverage/**',
21
+ '**/dist/**',
22
+ '**/snap/**',
23
+ '**/vite.config.*.timestamp-*.*',
24
+ ]
25
+
26
+ const jsRules = {
27
+ ...javascriptRules,
28
+ ...typescriptRules,
29
+ ...importRules,
30
+ ...nodeRules,
31
+ ...stylisticRules,
32
+ }
33
+
34
+ const jsPlugins = {
35
+ '@stylistic/js': stylisticJs,
36
+ '@typescript-eslint': tseslint.plugin,
37
+ import: pluginImport,
38
+ node: pluginNode,
39
+ }
40
+
41
+ /** @type {import('eslint').Linter.Config[]} */
42
+ export const tanstackConfig = [
43
+ {
44
+ name: 'tanstack/ignores',
45
+ ignores: GLOB_EXCLUDE,
46
+ },
47
+ {
48
+ name: 'tanstack/setup',
49
+ files: JS_GLOB_INCLUDE,
50
+ languageOptions: {
51
+ sourceType: 'module',
52
+ ecmaVersion: 2020,
53
+ // @ts-expect-error
54
+ parser: tseslint.parser,
55
+ parserOptions: {
56
+ project: true,
57
+ parser: tseslint.parser,
58
+ },
59
+ globals: {
60
+ ...globals.browser,
61
+ },
62
+ },
63
+ // @ts-expect-error
64
+ plugins: jsPlugins,
65
+ rules: jsRules,
66
+ },
67
+ {
68
+ name: 'tanstack/vue',
69
+ files: VUE_GLOB_INCLUDE,
70
+ languageOptions: {
71
+ parser: vueparser,
72
+ parserOptions: {
73
+ sourceType: 'module',
74
+ ecmaVersion: 2020,
75
+ parser: tseslint.parser,
76
+ project: true,
77
+ extraFileExtensions: ['.vue'],
78
+ },
79
+ globals: {
80
+ ...globals.browser,
81
+ },
82
+ },
83
+ // @ts-expect-error
84
+ plugins: jsPlugins,
85
+ rules: jsRules,
86
+ },
87
+ ]
@@ -0,0 +1,56 @@
1
+ // https://eslint.org/docs/latest/rules/
2
+
3
+ /** @type {import('eslint').Linter.RulesRecord} */
4
+ export const javascriptRules = {
5
+ /** TODO */
6
+ 'for-direction': 'error',
7
+ 'no-async-promise-executor': 'error',
8
+ 'no-case-declarations': 'error',
9
+ 'no-class-assign': 'error',
10
+ 'no-compare-neg-zero': 'error',
11
+ 'no-cond-assign': 'error',
12
+ 'no-constant-binary-expression': 'error',
13
+ 'no-constant-condition': 'error',
14
+ 'no-control-regex': 'error',
15
+ 'no-debugger': 'error',
16
+ 'no-delete-var': 'error',
17
+ 'no-dupe-else-if': 'error',
18
+ 'no-duplicate-case': 'error',
19
+ 'no-empty-character-class': 'error',
20
+ 'no-empty-pattern': 'error',
21
+ 'no-empty-static-block': 'error',
22
+ 'no-ex-assign': 'error',
23
+ 'no-extra-boolean-cast': 'error',
24
+ 'no-fallthrough': 'error',
25
+ 'no-global-assign': 'error',
26
+ 'no-invalid-regexp': 'error',
27
+ 'no-irregular-whitespace': 'error',
28
+ 'no-loss-of-precision': 'error',
29
+ 'no-misleading-character-class': 'error',
30
+ 'no-nonoctal-decimal-escape': 'error',
31
+ 'no-octal': 'error',
32
+ 'no-regex-spaces': 'error',
33
+ 'no-self-assign': 'error',
34
+ /** Warn about variable with identical names in the outer scope */
35
+ 'no-shadow': 'warn',
36
+ 'no-shadow-restricted-names': 'error',
37
+ 'no-sparse-arrays': 'error',
38
+ 'no-unsafe-finally': 'error',
39
+ 'no-unsafe-optional-chaining': 'error',
40
+ 'no-unused-labels': 'error',
41
+ 'no-unused-private-class-members': 'error',
42
+ 'no-useless-backreference': 'error',
43
+ 'no-useless-catch': 'error',
44
+ 'no-useless-escape': 'error',
45
+ /** Prefer let and const */
46
+ 'no-var': 'error',
47
+ 'no-with': 'error',
48
+ /** Prefer const if never re-assigned */
49
+ 'prefer-const': 'error',
50
+ 'require-yield': 'error',
51
+ /** Stylistic consistency */
52
+ 'sort-imports': ['error', { ignoreDeclarationSort: true }],
53
+ 'use-isnan': 'error',
54
+ /** Enforce comparing typeof against valid strings */
55
+ 'valid-typeof': 'error',
56
+ }
package/src/node.js ADDED
@@ -0,0 +1,7 @@
1
+ // https://github.com/eslint-community/eslint-plugin-n
2
+
3
+ /** @type {import('eslint').Linter.RulesRecord} */
4
+ export const nodeRules = {
5
+ /** Enforce usage of the `node:` prefix for builtin imports */
6
+ 'node/prefer-node-protocol': 'error',
7
+ }
@@ -0,0 +1,7 @@
1
+ // https://eslint.style/packages/js
2
+
3
+ /** @type {import('eslint').Linter.RulesRecord} */
4
+ export const stylisticRules = {
5
+ /** Enforce consistency of spacing after the start of a comment */
6
+ '@stylistic/js/spaced-comment': 'error',
7
+ }
@@ -0,0 +1,72 @@
1
+ // https://typescript-eslint.io/rules/
2
+
3
+ /** @type {import('eslint').Linter.RulesRecord} */
4
+ export const typescriptRules = {
5
+ /** Prefer Array<T> format */
6
+ '@typescript-eslint/array-type': [
7
+ 'error',
8
+ { default: 'generic', readonly: 'generic' },
9
+ ],
10
+ /** Prevent @ts-ignore, allow @ts-expect-error */
11
+ '@typescript-eslint/ban-ts-comment': [
12
+ 'error',
13
+ {
14
+ 'ts-expect-error': false,
15
+ 'ts-ignore': 'allow-with-description',
16
+ },
17
+ ],
18
+ /** Enforce import type { T } */
19
+ '@typescript-eslint/consistent-type-imports': [
20
+ 'error',
21
+ { prefer: 'type-imports' },
22
+ ],
23
+ /** Shorthand method style is less strict */
24
+ '@typescript-eslint/method-signature-style': ['error', 'property'],
25
+ /** Enforces generic type convention */
26
+ '@typescript-eslint/naming-convention': [
27
+ 'error',
28
+ {
29
+ selector: 'typeParameter',
30
+ format: ['PascalCase'],
31
+ leadingUnderscore: 'forbid',
32
+ trailingUnderscore: 'forbid',
33
+ custom: {
34
+ regex: '^(T|T[A-Z][A-Za-z]+)$',
35
+ match: true,
36
+ },
37
+ },
38
+ ],
39
+ /** Duplicate values can lead to bugs that are hard to track down */
40
+ '@typescript-eslint/no-duplicate-enum-values': 'error',
41
+ /** Using the operator any more than once does nothing */
42
+ '@typescript-eslint/no-extra-non-null-assertion': 'error',
43
+ /** There are several potential bugs with this compared to other loops */
44
+ '@typescript-eslint/no-for-in-array': 'error',
45
+ /** Don't over-define types for simple things like strings */
46
+ '@typescript-eslint/no-inferrable-types': [
47
+ 'error',
48
+ { ignoreParameters: true },
49
+ ],
50
+ /** Enforce valid definition of new and constructor */
51
+ '@typescript-eslint/no-misused-new': 'error',
52
+ /** Disallow TypeScript namespaces */
53
+ '@typescript-eslint/no-namespace': 'error',
54
+ /** Disallow non-null assertions after an optional chain expression */
55
+ '@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
56
+ /** Detects conditionals which will always evaluate truthy or falsy */
57
+ '@typescript-eslint/no-unnecessary-condition': 'error',
58
+ /** Checks if the the explicit type is identical to the inferred type */
59
+ '@typescript-eslint/no-unnecessary-type-assertion': 'error',
60
+ /** Disallow using the unsafe built-in Function type */
61
+ '@typescript-eslint/no-unsafe-function-type': 'error',
62
+ /** Disallow using confusing built-in primitive class wrappers */
63
+ '@typescript-eslint/no-wrapper-object-types': 'error',
64
+ /** Enforce the use of as const over literal type */
65
+ '@typescript-eslint/prefer-as-const': 'error',
66
+ /** Prefer for-of loop over the standard for loop */
67
+ '@typescript-eslint/prefer-for-of': 'warn',
68
+ /** Warn about async functions which have no await expression */
69
+ '@typescript-eslint/require-await': 'warn',
70
+ /** Prefer of ES6-style import declarations */
71
+ '@typescript-eslint/triple-slash-reference': 'error',
72
+ }