@fullstacksjs/eslint-config 8.1.1 → 8.4.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/README.md CHANGED
@@ -58,6 +58,16 @@ Just extend from `@fullstacksjs`:
58
58
 
59
59
  It reads your root `package.json` dependencies and includes necessary rules.
60
60
 
61
+ ## NextJS
62
+
63
+ [NextJS](https://nextjs.org/) config is subset of base config which is compatible with builtin NextJS eslint config.
64
+
65
+ ```json
66
+ {
67
+ "extends": ["@fullstacksjs/eslint-config/nextjs"]
68
+ }
69
+ ```
70
+
61
71
  ## Advanced Usage
62
72
 
63
73
  ```jsonc
@@ -70,6 +80,7 @@ It reads your root `package.json` dependencies and includes necessary rules.
70
80
  "@fullstacksjs/eslint-config/strict",
71
81
  "@fullstacksjs/eslint-config/cypress",
72
82
  "@fullstacksjs/eslint-config/storybook",
83
+ "@fullstacksjs/eslint-config/graphql", // Need extra config
73
84
  "@fullstacksjs/eslint-config/esm", // for native ESM modules
74
85
  "@fullstacksjs/eslint-config/typecheck" // ⚠️ Needs configurations (not included in default config)
75
86
  ]
@@ -92,6 +103,30 @@ If you need more advanced `typescript-eslint` rules, then you can extend from `"
92
103
  }
93
104
  ```
94
105
 
106
+ ## Graphql
107
+
108
+ To enable graphql module you need to extends from `@fullstacksjs/eslint-config/graphql` and configure schema and operations in you eslint config or graphql config. for more information checkout [here](https://github.com/B2o5T/graphql-eslint#configuration).
109
+
110
+ Here is an example:
111
+
112
+ ```jsonc
113
+ // eslintrc
114
+
115
+ {
116
+ "extends": [
117
+ ...
118
+ "@fullstacksjs/eslint-config/eslint"
119
+ ],
120
+ }
121
+ ```
122
+
123
+ ```yaml
124
+ # .graphqlrc.yml
125
+
126
+ schema: 'path/to/schema'
127
+ ```
128
+
129
+
95
130
  ## What's included?
96
131
 
97
132
  * @typescript-eslint/eslint-plugin
@@ -108,6 +143,7 @@ If you need more advanced `typescript-eslint` rules, then you can extend from `"
108
143
  * eslint-plugin-node
109
144
  * eslint-plugin-promise
110
145
  * eslint-plugin-storybook
146
+ * eslint-plugin-graphql
111
147
 
112
148
  That's all. Feel free to use 💛
113
149
 
package/base.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @type { import('eslint').Linter.Config } */
1
2
  module.exports = {
2
3
  plugins: ['prettier', 'import', 'simple-import-sort', 'promise', 'node', 'fp'],
3
4
  parserOptions: {
package/cypress.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @type { import('eslint').Linter.Config } */
1
2
  module.exports = {
2
3
  overrides: [
3
4
  {
package/esm.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @type { import('eslint').Linter.Config } */
1
2
  module.exports = {
2
3
  rules: {
3
4
  'import/extensions': 'off',
package/graphql.js ADDED
@@ -0,0 +1,11 @@
1
+ /** @type { import('eslint').Linter.Config } */
2
+ module.exports = {
3
+ overrides: [
4
+ {
5
+ files: ['*.graphql', '*.gql'],
6
+ parser: '@graphql-eslint/eslint-plugin',
7
+ plugins: ['@graphql-eslint'],
8
+ extends: './rules/graphql.js',
9
+ },
10
+ ],
11
+ };
package/index.js CHANGED
@@ -8,9 +8,11 @@ const { packageJson: pkg } = readPkgUp.sync({
8
8
 
9
9
  const packages = Packages(pkg);
10
10
 
11
+ /** @type { import('eslint').Linter.Config } */
11
12
  module.exports = {
12
13
  extends: [
13
14
  require.resolve('./base'),
15
+ require.resolve('./storybook'),
14
16
  packages.ifAnyDep('jest', () => require.resolve('./jest')),
15
17
  packages.ifAnyDep('react', () => require.resolve('./react')),
16
18
  packages.ifAnyDep('typescript', () => require.resolve('./typescript')),
package/jest.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const exts = '(js|jsx|ts|tsx)';
2
2
  const dirs = '(test|tests|__test__|__tests__|spec|specs)';
3
3
 
4
+ /** @type { import('eslint').Linter.Config } */
4
5
  module.exports = {
5
6
  overrides: [
6
7
  {
package/nextjs.js ADDED
@@ -0,0 +1,25 @@
1
+ /** @type { import('eslint').Linter.Config } */
2
+ module.exports = {
3
+ plugins: ['prettier', 'simple-import-sort', 'promise', 'node', 'fp'],
4
+ parserOptions: {
5
+ ecmaVersion: 2020,
6
+ sourceType: 'module',
7
+ requireConfigFile: false,
8
+ },
9
+ env: {
10
+ browser: true,
11
+ es6: true,
12
+ node: true,
13
+ },
14
+ extends: [
15
+ './rules/base',
16
+ './rules/es2015',
17
+ './rules/forbidden',
18
+ './rules/style',
19
+ './rules/variables',
20
+ './rules/fp',
21
+ './rules/promise',
22
+ './rules/node',
23
+ 'prettier',
24
+ ],
25
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fullstacksjs/eslint-config",
3
- "version": "8.1.1",
3
+ "version": "8.4.0",
4
4
  "license": "MIT",
5
5
  "author": "fullstacks <fullstacksjs@gmail.com>",
6
6
  "description": "fullstacks eslint config",
@@ -20,8 +20,10 @@
20
20
  "base.js",
21
21
  "index.js",
22
22
  "jest.js",
23
+ "nextjs.js",
23
24
  "cypress.js",
24
25
  "storybook.js",
26
+ "graphql.js",
25
27
  "react.js",
26
28
  "typescript.js",
27
29
  "typecheck.js",
@@ -34,7 +36,10 @@
34
36
  "check-rules:react": "eslint-find-rules --no-core --unused ./tests/react.js",
35
37
  "check-rules:typescript": "eslint-find-rules --no-core --unused ./tests/typescript.js",
36
38
  "check-rules:cypress": "eslint-find-rules --no-core --unused ./tests/cypress.js",
37
- "test": "npm-run-all --parallel check-rules:*",
39
+ "check-rules:graphql": "eslint-find-rules --no-core --unused ./tests/graphql.js",
40
+ "check-rules:storybook": "eslint-find-rules --no-core --unused ./tests/storybook.js",
41
+ "spell": "cspell ./* --no-progress",
42
+ "test": "npm-run-all --parallel check-rules:* && npm run spell",
38
43
  "prepublishOnly": "pinst --disable",
39
44
  "postpublish": "pinst --enable",
40
45
  "pre-commit": "npm run test && lint-staged"
@@ -42,43 +47,42 @@
42
47
  "main": "index.js",
43
48
  "dependencies": {
44
49
  "@frontendmonster/utils": "0.3.11",
45
- "@typescript-eslint/eslint-plugin": "5.10.2",
46
- "@typescript-eslint/parser": "5.10.2",
47
- "eslint-config-prettier": "8.3.0",
48
- "eslint-import-resolver-typescript": "2.5.0",
50
+ "@graphql-eslint/eslint-plugin": "3.10.1",
51
+ "@typescript-eslint/eslint-plugin": "5.17.0",
52
+ "@typescript-eslint/parser": "5.17.0",
53
+ "eslint-config-prettier": "8.5.0",
54
+ "eslint-import-resolver-typescript": "2.7.0",
49
55
  "eslint-plugin-cypress": "2.12.1",
50
56
  "eslint-plugin-fp": "2.3.0",
51
57
  "eslint-plugin-import": "2.25.4",
52
- "eslint-plugin-jest": "26.1.0",
58
+ "eslint-plugin-jest": "26.1.3",
53
59
  "eslint-plugin-jest-formatting": "3.1.0",
54
60
  "eslint-plugin-jsx-a11y": "6.5.1",
55
61
  "eslint-plugin-node": "11.1.0",
56
62
  "eslint-plugin-prettier": "4.0.0",
57
63
  "eslint-plugin-promise": "6.0.0",
58
- "eslint-plugin-react": "7.28.0",
59
- "eslint-plugin-react-hooks": "4.3.0",
64
+ "eslint-plugin-react": "7.29.4",
65
+ "eslint-plugin-react-hooks": "4.4.0",
60
66
  "eslint-plugin-simple-import-sort": "7.0.0",
61
- "eslint-plugin-storybook": "0.5.6",
62
- "inquirer": "8.2.0",
63
- "listr": "0.14.3",
64
- "lodash.has": "4.5.2",
65
- "read-pkg-up": "7.0.1",
66
- "yargs": "17.3.1"
67
+ "eslint-plugin-storybook": "0.5.7",
68
+ "read-pkg-up": "7.0.1"
67
69
  },
68
70
  "devDependencies": {
69
- "eslint": "8.8.0",
71
+ "cspell": "5.19.7",
72
+ "eslint": "8.12.0",
70
73
  "eslint-find-rules": "4.1.0",
71
74
  "husky": "7.0.4",
72
- "lint-staged": "12.3.3",
73
- "np": "7.6.0",
75
+ "lint-staged": "12.3.7",
76
+ "np": "7.6.1",
74
77
  "npm-run-all": "4.1.5",
75
- "pinst": "2.1.6",
76
- "prettier": "2.5.1",
77
- "typescript": "4.5.5"
78
+ "pinst": "3.0.0",
79
+ "prettier": "2.6.1",
80
+ "typescript": "4.6.3"
78
81
  },
79
82
  "peerDependencies": {
80
83
  "cypress": ">=8",
81
84
  "eslint": ">=7",
85
+ "graphql": ">=15",
82
86
  "prettier": "2",
83
87
  "react": ">=16",
84
88
  "typescript": "4"
@@ -95,6 +99,9 @@
95
99
  },
96
100
  "jest": {
97
101
  "optional": true
102
+ },
103
+ "graphql": {
104
+ "optional": true
98
105
  }
99
106
  }
100
107
  }
package/react.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @type { import('eslint').Linter.Config } */
1
2
  module.exports = {
2
3
  plugins: ['react', 'react-hooks', 'jsx-a11y'],
3
4
  parserOptions: {
@@ -0,0 +1,66 @@
1
+ /** @type { import('eslint').Linter.Config } */
2
+ module.exports = {
3
+ rules: {
4
+ '@graphql-eslint/alphabetize': ['warn', { fields: ['ObjectTypeDefinition'] }],
5
+ '@graphql-eslint/description-style': 'warn',
6
+ '@graphql-eslint/executable-definitions': 'off',
7
+ '@graphql-eslint/fields-on-correct-type': 'warn',
8
+ '@graphql-eslint/fragments-on-composite-type': 'warn',
9
+ '@graphql-eslint/input-name': 'warn',
10
+ '@graphql-eslint/known-argument-names': 'warn',
11
+ '@graphql-eslint/known-directives': 'warn',
12
+ '@graphql-eslint/known-fragment-names': 'warn',
13
+ '@graphql-eslint/known-type-names': 'warn',
14
+ '@graphql-eslint/lone-anonymous-operation': 'warn',
15
+ '@graphql-eslint/lone-schema-definition': 'warn',
16
+ '@graphql-eslint/match-document-filename': ['warn', { query: 'camelCase', mutation: 'camelCase', subscription: 'camelCase' }],
17
+ '@graphql-eslint/naming-convention': 'warn',
18
+ '@graphql-eslint/no-anonymous-operations': 'warn',
19
+ '@graphql-eslint/no-case-insensitive-enum-values-duplicates': 'warn',
20
+ '@graphql-eslint/no-deprecated': 'warn',
21
+ '@graphql-eslint/no-duplicate-fields': 'warn',
22
+ '@graphql-eslint/no-fragment-cycles': 'warn',
23
+ '@graphql-eslint/no-hashtag-description': 'warn',
24
+ '@graphql-eslint/no-root-type': 'off',
25
+ '@graphql-eslint/no-scalar-result-type-on-mutation': 'warn',
26
+ '@graphql-eslint/no-typename-prefix': 'warn',
27
+ '@graphql-eslint/no-undefined-variables': 'warn',
28
+ '@graphql-eslint/no-unreachable-types': 'warn',
29
+ '@graphql-eslint/no-unused-fields': 'warn',
30
+ '@graphql-eslint/no-unused-fragments': 'warn',
31
+ '@graphql-eslint/no-unused-variables': 'warn',
32
+ '@graphql-eslint/one-field-subscriptions': 'warn',
33
+ '@graphql-eslint/overlapping-fields-can-be-merged': 'warn',
34
+ '@graphql-eslint/possible-fragment-spread': 'warn',
35
+ '@graphql-eslint/possible-type-extension': 'warn',
36
+ '@graphql-eslint/provided-required-arguments': 'warn',
37
+ '@graphql-eslint/relay-arguments': 'warn',
38
+ '@graphql-eslint/relay-connection-types': 'warn',
39
+ '@graphql-eslint/relay-edge-types': 'warn',
40
+ '@graphql-eslint/relay-page-info': 'warn',
41
+ '@graphql-eslint/require-deprecation-date': 'warn',
42
+ '@graphql-eslint/require-deprecation-reason': 'warn',
43
+ '@graphql-eslint/require-description': 'off',
44
+ '@graphql-eslint/require-field-of-type-query-in-mutation-result': 'warn',
45
+ '@graphql-eslint/require-id-when-available': 'warn',
46
+ '@graphql-eslint/scalar-leafs': 'warn',
47
+ '@graphql-eslint/selection-set-depth': 'off',
48
+ '@graphql-eslint/strict-id-in-types': 'warn',
49
+ '@graphql-eslint/unique-argument-names': 'warn',
50
+ '@graphql-eslint/unique-directive-names': 'warn',
51
+ '@graphql-eslint/unique-directive-names-per-location': 'warn',
52
+ '@graphql-eslint/unique-enum-value-names': 'warn',
53
+ '@graphql-eslint/unique-field-definition-names': 'warn',
54
+ '@graphql-eslint/unique-fragment-name': 'warn',
55
+ '@graphql-eslint/unique-input-field-names': 'warn',
56
+ '@graphql-eslint/unique-operation-name': 'warn',
57
+ '@graphql-eslint/unique-operation-types': 'warn',
58
+ '@graphql-eslint/unique-type-names': 'warn',
59
+ '@graphql-eslint/unique-variable-names': 'warn',
60
+ '@graphql-eslint/value-literals-of-correct-type': 'warn',
61
+ '@graphql-eslint/variables-are-input-types': 'warn',
62
+ '@graphql-eslint/variables-in-allowed-position': 'warn',
63
+
64
+ 'spaced-comment': 'off',
65
+ },
66
+ };
package/rules/react.js CHANGED
@@ -11,10 +11,12 @@ module.exports = {
11
11
  'react/forbid-foreign-prop-types': 'error',
12
12
  'react/forbid-prop-types': 'off',
13
13
  'react/function-component-definition': ['warn', { namedComponents: 'arrow-function', unnamedComponents: 'arrow-function' }],
14
+ 'react/hook-use-state': 'warn',
15
+ 'react/iframe-missing-sandbox': 'error',
14
16
  'react/jsx-boolean-value': 'off',
15
17
  'react/jsx-child-element-spacing': 'warn',
16
18
  'react/jsx-curly-brace-presence': ['warn', { props: 'never', children: 'ignore' }],
17
- 'react/jsx-filename-extension': ['error', { extensions: ['.js', '.jsx', '.ts', '.tsx'] }],
19
+ 'react/jsx-filename-extension': ['error', { extensions: ['.jsx', '.tsx'] }],
18
20
  'react/jsx-fragments': 'off',
19
21
  'react/jsx-handler-names': 'off',
20
22
  'react/jsx-key': 'error',
@@ -42,8 +44,8 @@ module.exports = {
42
44
  'react/no-array-index-key': 'warn',
43
45
  'react/no-arrow-function-lifecycle': 'error',
44
46
  'react/no-children-prop': 'off',
45
- 'react/no-danger-with-children': 'error',
46
47
  'react/no-danger': 'off',
48
+ 'react/no-danger-with-children': 'error',
47
49
  'react/no-deprecated': 'error',
48
50
  'react/no-did-mount-set-state': 'error',
49
51
  'react/no-did-update-set-state': 'error',
@@ -13,5 +13,6 @@ module.exports = {
13
13
  'storybook/csf-component': 'warn',
14
14
  'storybook/no-stories-of': 'warn',
15
15
  'storybook/no-title-property-in-meta': 'warn',
16
+ 'storybook/meta-inline-properties': 'off',
16
17
  },
17
18
  };
@@ -6,11 +6,12 @@ module.exports = {
6
6
  'warn',
7
7
  { allowPrivateClassPropertyAccess: false, allowProtectedClassPropertyAccess: false, allowIndexSignaturePropertyAccess: true },
8
8
  ],
9
- '@typescript-eslint/no-meaningless-void-operator': ['warn', { checkNever: false }],
10
9
  '@typescript-eslint/no-confusing-void-expression': ['warn', { ignoreArrowShorthand: true, ignoreVoidOperator: true }],
11
10
  '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }],
12
11
  '@typescript-eslint/no-implied-eval': 'error',
12
+ '@typescript-eslint/no-meaningless-void-operator': ['warn', { checkNever: false }],
13
13
  '@typescript-eslint/no-misused-promises': 'error',
14
+ '@typescript-eslint/no-redundant-type-constituents': 'warn',
14
15
  '@typescript-eslint/no-throw-literal': 'error',
15
16
  '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
16
17
  '@typescript-eslint/no-unnecessary-qualifier': 'error',
@@ -129,6 +129,7 @@ module.exports = {
129
129
  ],
130
130
  '@typescript-eslint/no-use-before-define': ['error', { functions: false, classes: true }],
131
131
  '@typescript-eslint/no-useless-constructor': 'error',
132
+ '@typescript-eslint/no-useless-empty-export': 'warn',
132
133
  '@typescript-eslint/no-var-requires': 'error',
133
134
  '@typescript-eslint/object-curly-spacing': 'warn',
134
135
  '@typescript-eslint/padding-line-between-statements': ['warn', { blankLine: 'always', prev: ['return'], next: ['export'] }],
@@ -175,6 +176,7 @@ module.exports = {
175
176
  },
176
177
  ],
177
178
  '@typescript-eslint/strict-boolean-expressions': 'off', // Annoying
179
+ '@typescript-eslint/space-before-blocks': 'off',
178
180
 
179
181
  '@typescript-eslint/triple-slash-reference': 'error',
180
182
  '@typescript-eslint/typedef': ['error', { parameter: false, arrowParameter: false, variableDeclaration: false }],
@@ -196,6 +198,7 @@ module.exports = {
196
198
  'no-useless-constructor': 'off',
197
199
  'object-curly-spacing': 'off',
198
200
  'padding-line-between-statements': 'off',
201
+ 'space-before-blocks': 'off',
199
202
 
200
203
  // open issues
201
204
  'react/jsx-no-useless-fragment': 'off', // Need useless-fragment for JSX return type
package/storybook.js CHANGED
@@ -1,7 +1,8 @@
1
+ /** @type { import('eslint').Linter.Config } */
1
2
  module.exports = {
2
3
  overrides: [
3
4
  {
4
- plugin: ['storybook'],
5
+ plugins: ['storybook'],
5
6
  files: ['*.stories.@(ts|tsx|js|jsx|mjs|cjs)', '*.story.@(ts|tsx|js|jsx|mjs|cjs)'],
6
7
  extends: ['./rules/storybook.js'],
7
8
  },
package/typecheck.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @type { import('eslint').Linter.Config } */
1
2
  module.exports = {
2
3
  overrides: [
3
4
  {
package/typescript.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @type { import('eslint').Linter.Config } */
1
2
  module.exports = {
2
3
  parser: '@typescript-eslint/parser',
3
4
  plugins: ['@typescript-eslint/eslint-plugin'],