@graphql-eslint/eslint-plugin 3.14.0-alpha-20221221133443-5be7fc6 → 3.14.0-alpha-20221222012949-5caade4
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +309 -0
- package/cjs/cache.js +30 -0
- package/cjs/configs/base.js +7 -0
- package/cjs/configs/index.js +16 -0
- package/cjs/configs/operations-all.js +31 -0
- package/cjs/configs/operations-recommended.js +56 -0
- package/cjs/configs/relay.js +12 -0
- package/cjs/configs/schema-all.js +23 -0
- package/cjs/configs/schema-recommended.js +52 -0
- package/cjs/documents.js +149 -0
- package/cjs/estree-converter/converter.js +62 -0
- package/cjs/estree-converter/index.js +6 -0
- package/cjs/estree-converter/types.js +2 -0
- package/cjs/estree-converter/utils.js +109 -0
- package/cjs/graphql-config.js +55 -0
- package/cjs/index.js +17 -0
- package/cjs/parser.js +61 -0
- package/cjs/processor.js +78 -0
- package/cjs/rules/alphabetize.js +348 -0
- package/cjs/rules/description-style.js +78 -0
- package/cjs/rules/graphql-js-validation.js +499 -0
- package/cjs/rules/index.js +68 -0
- package/cjs/rules/input-name.js +136 -0
- package/cjs/rules/lone-executable-definition.js +88 -0
- package/cjs/rules/match-document-filename.js +235 -0
- package/cjs/rules/naming-convention.js +310 -0
- package/cjs/rules/no-anonymous-operations.js +67 -0
- package/cjs/rules/no-case-insensitive-enum-values-duplicates.js +61 -0
- package/cjs/rules/no-deprecated.js +124 -0
- package/cjs/rules/no-duplicate-fields.js +112 -0
- package/cjs/rules/no-hashtag-description.js +89 -0
- package/cjs/rules/no-root-type.js +86 -0
- package/cjs/rules/no-scalar-result-type-on-mutation.js +66 -0
- package/cjs/rules/no-typename-prefix.js +65 -0
- package/cjs/rules/no-unreachable-types.js +158 -0
- package/cjs/rules/no-unused-fields.js +130 -0
- package/cjs/rules/relay-arguments.js +121 -0
- package/cjs/rules/relay-connection-types.js +107 -0
- package/cjs/rules/relay-edge-types.js +189 -0
- package/cjs/rules/relay-page-info.js +100 -0
- package/cjs/rules/require-deprecation-date.js +123 -0
- package/cjs/rules/require-deprecation-reason.js +56 -0
- package/cjs/rules/require-description.js +193 -0
- package/cjs/rules/require-field-of-type-query-in-mutation-result.js +72 -0
- package/cjs/rules/require-id-when-available.js +199 -0
- package/cjs/rules/selection-set-depth.js +135 -0
- package/cjs/rules/strict-id-in-types.js +162 -0
- package/cjs/rules/unique-fragment-name.js +90 -0
- package/cjs/rules/unique-operation-name.js +65 -0
- package/cjs/schema.js +42 -0
- package/cjs/testkit.js +183 -0
- package/cjs/types.js +2 -0
- package/cjs/utils.js +96 -0
- package/docs/README.md +82 -0
- package/docs/custom-rules.md +184 -0
- package/docs/deprecated-rules.md +24 -0
- package/docs/parser-options.md +95 -0
- package/docs/parser.md +67 -0
- package/docs/rules/alphabetize.md +194 -0
- package/docs/rules/description-style.md +57 -0
- package/docs/rules/executable-definitions.md +20 -0
- package/docs/rules/fields-on-correct-type.md +23 -0
- package/docs/rules/fragments-on-composite-type.md +20 -0
- package/docs/rules/input-name.md +80 -0
- package/docs/rules/known-argument-names.md +23 -0
- package/docs/rules/known-directives.md +48 -0
- package/docs/rules/known-fragment-names.md +72 -0
- package/docs/rules/known-type-names.md +24 -0
- package/docs/rules/lone-anonymous-operation.md +20 -0
- package/docs/rules/lone-executable-definition.md +59 -0
- package/docs/rules/lone-schema-definition.md +19 -0
- package/docs/rules/match-document-filename.md +181 -0
- package/docs/rules/naming-convention.md +320 -0
- package/docs/rules/no-anonymous-operations.md +43 -0
- package/docs/rules/no-case-insensitive-enum-values-duplicates.md +46 -0
- package/docs/rules/no-deprecated.md +88 -0
- package/docs/rules/no-duplicate-fields.md +69 -0
- package/docs/rules/no-fragment-cycles.md +19 -0
- package/docs/rules/no-hashtag-description.md +62 -0
- package/docs/rules/no-root-type.md +55 -0
- package/docs/rules/no-scalar-result-type-on-mutation.md +39 -0
- package/docs/rules/no-typename-prefix.md +42 -0
- package/docs/rules/no-undefined-variables.md +20 -0
- package/docs/rules/no-unreachable-types.md +52 -0
- package/docs/rules/no-unused-fields.md +64 -0
- package/docs/rules/no-unused-fragments.md +20 -0
- package/docs/rules/no-unused-variables.md +20 -0
- package/docs/rules/one-field-subscriptions.md +19 -0
- package/docs/rules/overlapping-fields-can-be-merged.md +20 -0
- package/docs/rules/possible-fragment-spread.md +21 -0
- package/docs/rules/possible-type-extension.md +19 -0
- package/docs/rules/provided-required-arguments.md +21 -0
- package/docs/rules/relay-arguments.md +59 -0
- package/docs/rules/relay-connection-types.md +43 -0
- package/docs/rules/relay-edge-types.md +60 -0
- package/docs/rules/relay-page-info.md +34 -0
- package/docs/rules/require-deprecation-date.md +59 -0
- package/docs/rules/require-deprecation-reason.md +49 -0
- package/docs/rules/require-description.md +147 -0
- package/docs/rules/require-field-of-type-query-in-mutation-result.md +50 -0
- package/docs/rules/require-id-when-available.md +91 -0
- package/docs/rules/scalar-leafs.md +23 -0
- package/docs/rules/selection-set-depth.md +86 -0
- package/docs/rules/strict-id-in-types.md +129 -0
- package/docs/rules/unique-argument-names.md +19 -0
- package/docs/rules/unique-directive-names-per-location.md +21 -0
- package/docs/rules/unique-directive-names.md +19 -0
- package/docs/rules/unique-enum-value-names.md +16 -0
- package/docs/rules/unique-field-definition-names.md +19 -0
- package/docs/rules/unique-fragment-name.md +52 -0
- package/docs/rules/unique-input-field-names.md +19 -0
- package/docs/rules/unique-operation-name.md +56 -0
- package/docs/rules/unique-operation-types.md +19 -0
- package/docs/rules/unique-type-names.md +19 -0
- package/docs/rules/unique-variable-names.md +19 -0
- package/docs/rules/value-literals-of-correct-type.md +22 -0
- package/docs/rules/variables-are-input-types.md +20 -0
- package/docs/rules/variables-in-allowed-position.md +19 -0
- package/package.json +8 -11
- package/{cache.d.ts → typings/cache.d.cts} +0 -0
- package/typings/cache.d.ts +10 -0
- package/typings/configs/base.d.cts +5 -0
- package/typings/configs/base.d.ts +5 -0
- package/typings/configs/index.d.cts +139 -0
- package/typings/configs/index.d.ts +139 -0
- package/typings/configs/operations-all.d.cts +20 -0
- package/typings/configs/operations-all.d.ts +20 -0
- package/typings/configs/operations-recommended.d.cts +50 -0
- package/typings/configs/operations-recommended.d.ts +50 -0
- package/typings/configs/relay.d.cts +10 -0
- package/typings/configs/relay.d.ts +10 -0
- package/typings/configs/schema-all.d.cts +15 -0
- package/typings/configs/schema-all.d.ts +15 -0
- package/typings/configs/schema-recommended.d.cts +47 -0
- package/typings/configs/schema-recommended.d.ts +47 -0
- package/{documents.d.ts → typings/documents.d.cts} +0 -0
- package/typings/documents.d.ts +21 -0
- package/{estree-converter/converter.d.ts → typings/estree-converter/converter.d.cts} +0 -0
- package/typings/estree-converter/converter.d.ts +3 -0
- package/{estree-converter/index.d.ts → typings/estree-converter/index.d.cts} +0 -0
- package/typings/estree-converter/index.d.ts +3 -0
- package/{estree-converter/types.d.ts → typings/estree-converter/types.d.cts} +0 -0
- package/typings/estree-converter/types.d.ts +40 -0
- package/{estree-converter/utils.d.ts → typings/estree-converter/utils.d.cts} +0 -0
- package/typings/estree-converter/utils.d.ts +13 -0
- package/{graphql-config.d.ts → typings/graphql-config.d.cts} +0 -0
- package/typings/graphql-config.d.ts +4 -0
- package/typings/index.d.cts +9 -0
- package/{index.d.ts → typings/index.d.ts} +1 -5
- package/{parser.d.ts → typings/parser.d.cts} +0 -0
- package/typings/parser.d.ts +2 -0
- package/{processor.d.ts → typings/processor.d.cts} +0 -0
- package/typings/processor.d.ts +6 -0
- package/{rules/alphabetize.d.ts → typings/rules/alphabetize.d.cts} +0 -0
- package/typings/rules/alphabetize.d.ts +76 -0
- package/{rules/description-style.d.ts → typings/rules/description-style.d.cts} +0 -0
- package/typings/rules/description-style.d.ts +20 -0
- package/{rules/graphql-js-validation.d.ts → typings/rules/graphql-js-validation.d.cts} +0 -0
- package/typings/rules/graphql-js-validation.d.ts +2 -0
- package/{rules/index.d.ts → typings/rules/index.d.cts} +0 -0
- package/typings/rules/index.d.ts +104 -0
- package/{rules/input-name.d.ts → typings/rules/input-name.d.cts} +0 -0
- package/typings/rules/input-name.d.ts +35 -0
- package/{rules/lone-executable-definition.d.ts → typings/rules/lone-executable-definition.d.cts} +0 -0
- package/typings/rules/lone-executable-definition.d.ts +26 -0
- package/{rules/match-document-filename.d.ts → typings/rules/match-document-filename.d.cts} +0 -0
- package/typings/rules/match-document-filename.d.ts +72 -0
- package/{rules/naming-convention.d.ts → typings/rules/naming-convention.d.cts} +0 -0
- package/typings/rules/naming-convention.d.ts +83 -0
- package/{rules/no-anonymous-operations.d.ts → typings/rules/no-anonymous-operations.d.cts} +0 -0
- package/{rules/no-case-insensitive-enum-values-duplicates.d.ts → typings/rules/no-anonymous-operations.d.ts} +0 -0
- package/{rules/no-hashtag-description.d.ts → typings/rules/no-case-insensitive-enum-values-duplicates.d.cts} +0 -0
- package/{rules/no-scalar-result-type-on-mutation.d.ts → typings/rules/no-case-insensitive-enum-values-duplicates.d.ts} +0 -0
- package/{rules/no-deprecated.d.ts → typings/rules/no-deprecated.d.cts} +0 -0
- package/typings/rules/no-deprecated.d.ts +2 -0
- package/{rules/no-duplicate-fields.d.ts → typings/rules/no-duplicate-fields.d.cts} +0 -0
- package/{rules/relay-page-info.d.ts → typings/rules/no-duplicate-fields.d.ts} +0 -0
- package/{rules/no-typename-prefix.d.ts → typings/rules/no-hashtag-description.d.cts} +0 -0
- package/{rules/no-unreachable-types.d.ts → typings/rules/no-hashtag-description.d.ts} +0 -0
- package/{rules/no-root-type.d.ts → typings/rules/no-root-type.d.cts} +0 -0
- package/typings/rules/no-root-type.d.ts +25 -0
- package/{rules/no-unused-fields.d.ts → typings/rules/no-scalar-result-type-on-mutation.d.cts} +0 -0
- package/{rules/unique-operation-name.d.ts → typings/rules/no-scalar-result-type-on-mutation.d.ts} +0 -0
- package/typings/rules/no-typename-prefix.d.cts +2 -0
- package/typings/rules/no-typename-prefix.d.ts +2 -0
- package/typings/rules/no-unreachable-types.d.cts +2 -0
- package/typings/rules/no-unreachable-types.d.ts +2 -0
- package/typings/rules/no-unused-fields.d.cts +2 -0
- package/typings/rules/no-unused-fields.d.ts +2 -0
- package/{rules/relay-arguments.d.ts → typings/rules/relay-arguments.d.cts} +0 -0
- package/typings/rules/relay-arguments.d.ts +21 -0
- package/{rules/relay-connection-types.d.ts → typings/rules/relay-connection-types.d.cts} +0 -0
- package/typings/rules/relay-connection-types.d.ts +4 -0
- package/{rules/relay-edge-types.d.ts → typings/rules/relay-edge-types.d.cts} +0 -0
- package/typings/rules/relay-edge-types.d.ts +31 -0
- package/{rules/require-deprecation-reason.d.ts → typings/rules/relay-page-info.d.cts} +0 -0
- package/{rules/require-field-of-type-query-in-mutation-result.d.ts → typings/rules/relay-page-info.d.ts} +0 -0
- package/{rules/require-deprecation-date.d.ts → typings/rules/require-deprecation-date.d.cts} +0 -0
- package/typings/rules/require-deprecation-date.d.ts +18 -0
- package/typings/rules/require-deprecation-reason.d.cts +2 -0
- package/typings/rules/require-deprecation-reason.d.ts +2 -0
- package/{rules/require-description.d.ts → typings/rules/require-description.d.cts} +0 -0
- package/typings/rules/require-description.d.ts +14 -0
- package/typings/rules/require-field-of-type-query-in-mutation-result.d.cts +2 -0
- package/typings/rules/require-field-of-type-query-in-mutation-result.d.ts +2 -0
- package/{rules/require-id-when-available.d.ts → typings/rules/require-id-when-available.d.cts} +0 -0
- package/typings/rules/require-id-when-available.d.ts +36 -0
- package/{rules/selection-set-depth.d.ts → typings/rules/selection-set-depth.d.cts} +0 -0
- package/typings/rules/selection-set-depth.d.ts +28 -0
- package/{rules/strict-id-in-types.d.ts → typings/rules/strict-id-in-types.d.cts} +0 -0
- package/typings/rules/strict-id-in-types.d.ts +57 -0
- package/{rules/unique-fragment-name.d.ts → typings/rules/unique-fragment-name.d.cts} +0 -0
- package/typings/rules/unique-fragment-name.d.ts +5 -0
- package/typings/rules/unique-operation-name.d.cts +2 -0
- package/typings/rules/unique-operation-name.d.ts +2 -0
- package/{schema.d.ts → typings/schema.d.cts} +0 -0
- package/typings/schema.d.ts +3 -0
- package/{testkit.d.ts → typings/testkit.d.cts} +0 -0
- package/typings/testkit.d.ts +27 -0
- package/{types.d.ts → typings/types.d.cts} +0 -0
- package/typings/types.d.ts +81 -0
- package/{utils.d.ts → typings/utils.d.cts} +0 -0
- package/typings/utils.d.ts +34 -0
- package/configs/base.json +0 -4
- package/configs/operations-all.json +0 -25
- package/configs/operations-recommended.json +0 -50
- package/configs/relay.json +0 -9
- package/configs/schema-all.json +0 -17
- package/configs/schema-recommended.json +0 -49
- package/index.js +0 -4995
- package/index.mjs +0 -4983
package/README.md
ADDED
@@ -0,0 +1,309 @@
|
|
1
|
+
This project integrates GraphQL and ESLint, for a better developer experience.
|
2
|
+
|
3
|
+
<img height="150" src="./logo.png">
|
4
|
+
|
5
|
+
[![npm version](https://badge.fury.io/js/%40graphql-eslint%2Feslint-plugin.svg)](https://badge.fury.io/js/%40graphql-eslint%2Feslint-plugin)
|
6
|
+
|
7
|
+
> Created and maintained by [The Guild](https://the-guild.dev)
|
8
|
+
|
9
|
+
## Key Features
|
10
|
+
|
11
|
+
- 🚀 Integrates with ESLint core (as a ESTree parser)
|
12
|
+
- 🚀 Works on `.graphql` files, `gql` usages and `/* GraphQL */` magic comments
|
13
|
+
- 🚀 Lints both GraphQL schema and GraphQL operations
|
14
|
+
- 🚀 Extended type info for more advanced usages
|
15
|
+
- 🚀 Supports ESLint directives (for example: `eslint-disable-next-line`)
|
16
|
+
- 🚀 Easily extendable - supports custom rules based on GraphQL's AST and ESLint API
|
17
|
+
- 🚀 Validates, lints, prettifies and checks for best practices across GraphQL schema and GraphQL
|
18
|
+
operations
|
19
|
+
- 🚀 Integrates with [`graphql-config`](https://graphql-config.com)
|
20
|
+
- 🚀 Integrates and visualizes lint issues in popular IDEs (VSCode / WebStorm)
|
21
|
+
|
22
|
+
> Special thanks to [ilyavolodin](https://github.com/ilyavolodin) for his work on a similar project!
|
23
|
+
|
24
|
+
<img src="https://thumbs.gfycat.com/ActualTerrificDog-size_restricted.gif" />
|
25
|
+
|
26
|
+
## Getting Started
|
27
|
+
|
28
|
+
- [Introducing GraphQL-ESLint!](https://the-guild.dev/blog/introducing-graphql-eslint) @
|
29
|
+
`the-guild.dev`
|
30
|
+
|
31
|
+
### Installation
|
32
|
+
|
33
|
+
Start by installing the plugin package, which includes everything you need:
|
34
|
+
|
35
|
+
```sh
|
36
|
+
yarn add -D @graphql-eslint/eslint-plugin
|
37
|
+
```
|
38
|
+
|
39
|
+
Or, with NPM:
|
40
|
+
|
41
|
+
```sh
|
42
|
+
npm install --save-dev @graphql-eslint/eslint-plugin
|
43
|
+
```
|
44
|
+
|
45
|
+
> Make sure you have `graphql` dependency in your project.
|
46
|
+
|
47
|
+
## Configuration
|
48
|
+
|
49
|
+
To get started, define an override in your ESLint config to apply this plugin to `.graphql` files.
|
50
|
+
Add the [rules](docs/README.md) you want applied.
|
51
|
+
|
52
|
+
> 🚨 Important! This step is necessary even if you are declaring operations and/or schema in code
|
53
|
+
> files.
|
54
|
+
|
55
|
+
```json
|
56
|
+
{
|
57
|
+
"overrides": [
|
58
|
+
{
|
59
|
+
"files": ["*.graphql"],
|
60
|
+
"parser": "@graphql-eslint/eslint-plugin",
|
61
|
+
"plugins": ["@graphql-eslint"],
|
62
|
+
"rules": {
|
63
|
+
"@graphql-eslint/known-type-names": "error"
|
64
|
+
}
|
65
|
+
}
|
66
|
+
]
|
67
|
+
}
|
68
|
+
```
|
69
|
+
|
70
|
+
If your GraphQL definitions are defined only in `.graphql` files, and you're only using rules that
|
71
|
+
apply to individual files, you should be good to go 👍. If you would like use a remote schema or use
|
72
|
+
rules that apply across the entire collection of definitions at once, see
|
73
|
+
[here](#extended-linting-rules-with-graphql-schema).
|
74
|
+
|
75
|
+
### Apply this plugin to GraphQL definitions defined in code files
|
76
|
+
|
77
|
+
If you are defining GraphQL schema or GraphQL operations in code files, you'll want to define an
|
78
|
+
additional override to extend the functionality of this plugin to the schema and operations in those
|
79
|
+
files.
|
80
|
+
|
81
|
+
```diff
|
82
|
+
{
|
83
|
+
"overrides": [
|
84
|
+
+ {
|
85
|
+
+ "files": ["*.js"],
|
86
|
+
+ "processor": "@graphql-eslint/graphql"
|
87
|
+
+ },
|
88
|
+
{
|
89
|
+
"files": ["*.graphql"],
|
90
|
+
"parser": "@graphql-eslint/eslint-plugin",
|
91
|
+
"plugins": ["@graphql-eslint"],
|
92
|
+
"rules": {
|
93
|
+
"@graphql-eslint/known-type-names": "error"
|
94
|
+
}
|
95
|
+
}
|
96
|
+
]
|
97
|
+
}
|
98
|
+
```
|
99
|
+
|
100
|
+
Under the hood, specifying the `@graphql-eslint/graphql` processor for code files will cause
|
101
|
+
`graphql-eslint/graphql` to extract the schema and operation definitions from these files into
|
102
|
+
virtual GraphQL documents with `.graphql` extensions. This will allow the overrides you've defined
|
103
|
+
for `.graphql` files, via `"files": ["*.graphql"]`, to get applied to the definitions defined in
|
104
|
+
your code files.
|
105
|
+
|
106
|
+
### Extended linting rules with GraphQL Schema
|
107
|
+
|
108
|
+
Some rules require an understanding of the entire schema at once. For example,
|
109
|
+
[no-unreachable-types](https://github.com/B2o5T/graphql-eslint/blob/master/docs/rules/no-unreachable-types.md#no-unreachable-types)
|
110
|
+
checks that all types are reachable by root-level fields.
|
111
|
+
|
112
|
+
To use these rules, you'll need to tell ESLint how to identify the entire set of schema definitions.
|
113
|
+
|
114
|
+
If you are using [`graphql-config`](https://graphql-config.com), you are good to go.
|
115
|
+
`graphql-eslint` integrates with it automatically and will use it to load your schema!
|
116
|
+
|
117
|
+
Alternatively, you can define `parserOptions.schema` in the `*.graphql` override in your ESLint
|
118
|
+
config.
|
119
|
+
|
120
|
+
The parser allows you to specify a json file / graphql files(s) / url / raw string to locate your
|
121
|
+
schema (We are using `graphql-tools` to do that). Just add `parserOptions.schema` to your
|
122
|
+
configuration file:
|
123
|
+
|
124
|
+
```diff
|
125
|
+
{
|
126
|
+
"files": ["*.graphql"],
|
127
|
+
"parser": "@graphql-eslint/eslint-plugin",
|
128
|
+
"plugins": ["@graphql-eslint"],
|
129
|
+
"rules": {
|
130
|
+
"@graphql-eslint/no-unreachable-types": "error"
|
131
|
+
},
|
132
|
+
+ "parserOptions": {
|
133
|
+
+ "schema": "./schema.graphql"
|
134
|
+
+ }
|
135
|
+
}
|
136
|
+
```
|
137
|
+
|
138
|
+
> You can find a complete [documentation of the `parserOptions` here](docs/parser-options.md).
|
139
|
+
|
140
|
+
> Some rules require type information to operate, it's marked in the docs for each rule!
|
141
|
+
|
142
|
+
### Extended linting rules with siblings operations
|
143
|
+
|
144
|
+
While implementing this tool, we had to find solutions for a better integration of the GraphQL
|
145
|
+
ecosystem and ESLint core.
|
146
|
+
|
147
|
+
GraphQL's operations can be distributed across many files, while ESLint operates on one file at a
|
148
|
+
time. If you are using GraphQL fragments in separate files, some rules might yield incorrect
|
149
|
+
results, due the missing information.
|
150
|
+
|
151
|
+
To workaround that, we allow you to provide additional information on your GraphQL operations,
|
152
|
+
making it available for rules while doing the actual linting.
|
153
|
+
|
154
|
+
To provide that, we are using `graphql-tools` loaders to load your sibling operations and fragments,
|
155
|
+
just specify a glob expression(s) that points to your code/`.graphql` files:
|
156
|
+
|
157
|
+
```diff
|
158
|
+
{
|
159
|
+
"files": ["*.graphql"],
|
160
|
+
"parser": "@graphql-eslint/eslint-plugin",
|
161
|
+
"plugins": ["@graphql-eslint"],
|
162
|
+
"rules": {
|
163
|
+
"@graphql-eslint/unique-operation-name": "error"
|
164
|
+
},
|
165
|
+
"parserOptions": {
|
166
|
+
+ "operations": "./src/**/*.graphql",
|
167
|
+
"schema": "./schema.graphql"
|
168
|
+
}
|
169
|
+
}
|
170
|
+
```
|
171
|
+
|
172
|
+
### VSCode Integration
|
173
|
+
|
174
|
+
Use
|
175
|
+
[ESLint VSCode extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
|
176
|
+
to integrate ESLint into VSCode.
|
177
|
+
|
178
|
+
For syntax highlighting you need a GraphQL extension (which may potentially have its own linting),
|
179
|
+
for example
|
180
|
+
[GraphQL (by GraphQL Foundation)](https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql).
|
181
|
+
|
182
|
+
### Disabling Rules
|
183
|
+
|
184
|
+
The `graphql-eslint` parser looks for GraphQL comments syntax (marked with `#`) and will send it to
|
185
|
+
ESLint as directives. That means, you can use ESLint directives syntax to hint ESLint, just like in
|
186
|
+
any other type of files.
|
187
|
+
|
188
|
+
To disable ESLint for a specific line, you can do:
|
189
|
+
|
190
|
+
```graphql
|
191
|
+
# eslint-disable-next-line
|
192
|
+
type Query {
|
193
|
+
foo: String!
|
194
|
+
}
|
195
|
+
```
|
196
|
+
|
197
|
+
You can also specify specific rules to disable, apply it over the entire file,
|
198
|
+
`eslint-disable-next-line` or current `eslint-disable-line`.
|
199
|
+
|
200
|
+
You can find a list of
|
201
|
+
[ESLint directives here](https://eslint.org/docs/2.13.1/user-guide/configuring#disabling-rules-with-inline-comments).
|
202
|
+
|
203
|
+
## Available Rules
|
204
|
+
|
205
|
+
You can find a complete list of [all available rules here](docs/README.md).
|
206
|
+
|
207
|
+
### Deprecated Rules
|
208
|
+
|
209
|
+
See [docs/deprecated-rules.md](docs/deprecated-rules.md).
|
210
|
+
|
211
|
+
## Available Configs
|
212
|
+
|
213
|
+
<!-- prettier-ignore-start -->
|
214
|
+
|Name|Description|
|
215
|
+
|:-:|-|
|
216
|
+
|[`schema-recommended`](packages/plugin/src/configs/schema-recommended.json)|enables recommended rules for schema (SDL) development|
|
217
|
+
|[`schema-all`](packages/plugin/src/configs/schema-all.json)|enables all rules for schema (SDL) development, except for those that require `parserOptions.operations` option|
|
218
|
+
|[`operations-recommended`](packages/plugin/src/configs/operations-recommended.json) |enables recommended rules for consuming GraphQL (operations) development|
|
219
|
+
|[`operations-all`](packages/plugin/src/configs/operations-all.json)|enables all rules for consuming GraphQL (operations) development|
|
220
|
+
|[`relay`](packages/plugin/src/configs/relay.json)|enables rules from Relay specification for schema (SDL) development|
|
221
|
+
<!-- prettier-ignore-end -->
|
222
|
+
|
223
|
+
> If you are in a project that develops the GraphQL schema, you'll need `schema` rules.
|
224
|
+
|
225
|
+
> If you are in a project that develops GraphQL operations (query/mutation/subscription), you'll
|
226
|
+
> need `operations` rules.
|
227
|
+
|
228
|
+
> If you are in a monorepo project, you probably need both sets of rules, see
|
229
|
+
> [example of configuration](examples/monorepo/.eslintrc.cjs).
|
230
|
+
|
231
|
+
### Config usage
|
232
|
+
|
233
|
+
For example, to enable the `schema-recommended` config, enable it in your `.eslintrc` file with the
|
234
|
+
`extends` option:
|
235
|
+
|
236
|
+
> All configs under the hood set `parser` as `@graphql-eslint/eslint-plugin` and add
|
237
|
+
> `@graphql-eslint` to `plugins` array, so you don't need to specify them.
|
238
|
+
|
239
|
+
```diff
|
240
|
+
{
|
241
|
+
"overrides": [
|
242
|
+
{
|
243
|
+
"files": ["*.js"],
|
244
|
+
"processor": "@graphql-eslint/graphql"
|
245
|
+
},
|
246
|
+
{
|
247
|
+
"files": ["*.graphql"],
|
248
|
+
- "parser": "@graphql-eslint/eslint-plugin",
|
249
|
+
- "plugins": ["@graphql-eslint"],
|
250
|
+
+ "extends": "plugin:@graphql-eslint/schema-recommended"
|
251
|
+
}
|
252
|
+
]
|
253
|
+
}
|
254
|
+
```
|
255
|
+
|
256
|
+
### `prettier` rule
|
257
|
+
|
258
|
+
`eslint-plugin-prettier` supports `.graphql` files, and `v4.1.0` supports `graphql` blocks even
|
259
|
+
better. You need to do the following:
|
260
|
+
|
261
|
+
```js
|
262
|
+
module.exports = {
|
263
|
+
overrides: [
|
264
|
+
{
|
265
|
+
files: ['*.js'],
|
266
|
+
processor: '@graphql-eslint/graphql',
|
267
|
+
extends: ['plugin:prettier/recommended']
|
268
|
+
},
|
269
|
+
{
|
270
|
+
files: ['*.graphql'],
|
271
|
+
parser: '@graphql-eslint/eslint-plugin',
|
272
|
+
plugins: ['@graphql-eslint'],
|
273
|
+
rules: {
|
274
|
+
'prettier/prettier': 'error'
|
275
|
+
}
|
276
|
+
}
|
277
|
+
]
|
278
|
+
}
|
279
|
+
```
|
280
|
+
|
281
|
+
You can take [`examples/prettier`](examples/prettier/.eslintrc.cjs) as example.
|
282
|
+
|
283
|
+
## Further Reading
|
284
|
+
|
285
|
+
If you wish to learn more about this project, how the parser works, how to add custom rules and more
|
286
|
+
please refer to the below links:
|
287
|
+
|
288
|
+
- [Writing Custom Rules](docs/custom-rules.md)
|
289
|
+
- [How the parser works?](docs/parser.md)
|
290
|
+
- [`parserOptions`](docs/parser-options.md)
|
291
|
+
|
292
|
+
## Contributions
|
293
|
+
|
294
|
+
Contributions, issues and feature requests are very welcome. If you are using this package and fixed
|
295
|
+
a bug for yourself, please consider submitting a PR!
|
296
|
+
|
297
|
+
And if this is your first time contributing to this project, please do read our
|
298
|
+
[Contributor Workflow Guide](https://github.com/the-guild-org/Stack/blob/master/CONTRIBUTING.md)
|
299
|
+
before you get started off.
|
300
|
+
|
301
|
+
### Code of Conduct
|
302
|
+
|
303
|
+
Help us keep GraphQL ESLint open and inclusive. Please read and follow our
|
304
|
+
[Code of Conduct](https://github.com/the-guild-org/Stack/blob/master/CODE_OF_CONDUCT.md) as adopted
|
305
|
+
from [Contributor Covenant](https://contributor-covenant.org).
|
306
|
+
|
307
|
+
## License
|
308
|
+
|
309
|
+
Released under the [MIT license](LICENSE).
|
package/cjs/cache.js
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.ModuleCache = void 0;
|
4
|
+
const tslib_1 = require("tslib");
|
5
|
+
// Based on the `eslint-plugin-import`'s cache
|
6
|
+
// https://github.com/import-js/eslint-plugin-import/blob/main/utils/ModuleCache.js
|
7
|
+
const debug_1 = tslib_1.__importDefault(require("debug"));
|
8
|
+
const log = (0, debug_1.default)('graphql-eslint:ModuleCache');
|
9
|
+
class ModuleCache {
|
10
|
+
constructor() {
|
11
|
+
this.map = new Map();
|
12
|
+
}
|
13
|
+
set(cacheKey, result) {
|
14
|
+
this.map.set(cacheKey, { lastSeen: process.hrtime(), result });
|
15
|
+
log('setting entry for', cacheKey);
|
16
|
+
}
|
17
|
+
get(cacheKey, settings = { lifetime: 10 /* seconds */ }) {
|
18
|
+
if (!this.map.has(cacheKey)) {
|
19
|
+
log('cache miss for', cacheKey);
|
20
|
+
return;
|
21
|
+
}
|
22
|
+
const { lastSeen, result } = this.map.get(cacheKey);
|
23
|
+
// check freshness
|
24
|
+
if (process.env.NODE /* don't check for ESLint CLI */ ||
|
25
|
+
process.hrtime(lastSeen)[0] < settings.lifetime) {
|
26
|
+
return result;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
exports.ModuleCache = ModuleCache;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.configs = void 0;
|
4
|
+
const tslib_1 = require("tslib");
|
5
|
+
const schema_recommended_1 = tslib_1.__importDefault(require("./schema-recommended"));
|
6
|
+
const schema_all_1 = tslib_1.__importDefault(require("./schema-all"));
|
7
|
+
const operations_recommended_1 = tslib_1.__importDefault(require("./operations-recommended"));
|
8
|
+
const operations_all_1 = tslib_1.__importDefault(require("./operations-all"));
|
9
|
+
const relay_1 = tslib_1.__importDefault(require("./relay"));
|
10
|
+
exports.configs = {
|
11
|
+
'schema-recommended': schema_recommended_1.default,
|
12
|
+
'schema-all': schema_all_1.default,
|
13
|
+
'operations-recommended': operations_recommended_1.default,
|
14
|
+
'operations-all': operations_all_1.default,
|
15
|
+
relay: relay_1.default,
|
16
|
+
};
|
@@ -0,0 +1,31 @@
|
|
1
|
+
"use strict";
|
2
|
+
/*
|
3
|
+
* 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
|
4
|
+
*/
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.default = {
|
7
|
+
extends: ['./configs/base', './configs/operations-recommended'],
|
8
|
+
rules: {
|
9
|
+
'@graphql-eslint/alphabetize': [
|
10
|
+
'error',
|
11
|
+
{
|
12
|
+
selections: ['OperationDefinition', 'FragmentDefinition'],
|
13
|
+
variables: ['OperationDefinition'],
|
14
|
+
arguments: ['Field', 'Directive'],
|
15
|
+
},
|
16
|
+
],
|
17
|
+
'@graphql-eslint/lone-executable-definition': 'error',
|
18
|
+
'@graphql-eslint/match-document-filename': [
|
19
|
+
'error',
|
20
|
+
{
|
21
|
+
query: 'kebab-case',
|
22
|
+
mutation: 'kebab-case',
|
23
|
+
subscription: 'kebab-case',
|
24
|
+
fragment: 'kebab-case',
|
25
|
+
},
|
26
|
+
],
|
27
|
+
'@graphql-eslint/unique-fragment-name': 'error',
|
28
|
+
'@graphql-eslint/unique-operation-name': 'error',
|
29
|
+
},
|
30
|
+
};
|
31
|
+
module.exports = exports.default;
|
@@ -0,0 +1,56 @@
|
|
1
|
+
"use strict";
|
2
|
+
/*
|
3
|
+
* 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
|
4
|
+
*/
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.default = {
|
7
|
+
extends: './configs/base',
|
8
|
+
rules: {
|
9
|
+
'@graphql-eslint/executable-definitions': 'error',
|
10
|
+
'@graphql-eslint/fields-on-correct-type': 'error',
|
11
|
+
'@graphql-eslint/fragments-on-composite-type': 'error',
|
12
|
+
'@graphql-eslint/known-argument-names': 'error',
|
13
|
+
'@graphql-eslint/known-directives': 'error',
|
14
|
+
'@graphql-eslint/known-fragment-names': 'error',
|
15
|
+
'@graphql-eslint/known-type-names': 'error',
|
16
|
+
'@graphql-eslint/lone-anonymous-operation': 'error',
|
17
|
+
'@graphql-eslint/naming-convention': [
|
18
|
+
'error',
|
19
|
+
{
|
20
|
+
VariableDefinition: 'camelCase',
|
21
|
+
OperationDefinition: {
|
22
|
+
style: 'PascalCase',
|
23
|
+
forbiddenPrefixes: ['Query', 'Mutation', 'Subscription', 'Get'],
|
24
|
+
forbiddenSuffixes: ['Query', 'Mutation', 'Subscription'],
|
25
|
+
},
|
26
|
+
FragmentDefinition: {
|
27
|
+
style: 'PascalCase',
|
28
|
+
forbiddenPrefixes: ['Fragment'],
|
29
|
+
forbiddenSuffixes: ['Fragment'],
|
30
|
+
},
|
31
|
+
},
|
32
|
+
],
|
33
|
+
'@graphql-eslint/no-anonymous-operations': 'error',
|
34
|
+
'@graphql-eslint/no-deprecated': 'error',
|
35
|
+
'@graphql-eslint/no-duplicate-fields': 'error',
|
36
|
+
'@graphql-eslint/no-fragment-cycles': 'error',
|
37
|
+
'@graphql-eslint/no-undefined-variables': 'error',
|
38
|
+
'@graphql-eslint/no-unused-fragments': 'error',
|
39
|
+
'@graphql-eslint/no-unused-variables': 'error',
|
40
|
+
'@graphql-eslint/one-field-subscriptions': 'error',
|
41
|
+
'@graphql-eslint/overlapping-fields-can-be-merged': 'error',
|
42
|
+
'@graphql-eslint/possible-fragment-spread': 'error',
|
43
|
+
'@graphql-eslint/provided-required-arguments': 'error',
|
44
|
+
'@graphql-eslint/require-id-when-available': 'error',
|
45
|
+
'@graphql-eslint/scalar-leafs': 'error',
|
46
|
+
'@graphql-eslint/selection-set-depth': ['error', { maxDepth: 7 }],
|
47
|
+
'@graphql-eslint/unique-argument-names': 'error',
|
48
|
+
'@graphql-eslint/unique-directive-names-per-location': 'error',
|
49
|
+
'@graphql-eslint/unique-input-field-names': 'error',
|
50
|
+
'@graphql-eslint/unique-variable-names': 'error',
|
51
|
+
'@graphql-eslint/value-literals-of-correct-type': 'error',
|
52
|
+
'@graphql-eslint/variables-are-input-types': 'error',
|
53
|
+
'@graphql-eslint/variables-in-allowed-position': 'error',
|
54
|
+
},
|
55
|
+
};
|
56
|
+
module.exports = exports.default;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.default = {
|
4
|
+
extends: './configs/base',
|
5
|
+
rules: {
|
6
|
+
'@graphql-eslint/relay-arguments': 'error',
|
7
|
+
'@graphql-eslint/relay-connection-types': 'error',
|
8
|
+
'@graphql-eslint/relay-edge-types': 'error',
|
9
|
+
'@graphql-eslint/relay-page-info': 'error',
|
10
|
+
},
|
11
|
+
};
|
12
|
+
module.exports = exports.default;
|
@@ -0,0 +1,23 @@
|
|
1
|
+
"use strict";
|
2
|
+
/*
|
3
|
+
* 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
|
4
|
+
*/
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.default = {
|
7
|
+
extends: ['./configs/base', './configs/schema-recommended'],
|
8
|
+
rules: {
|
9
|
+
'@graphql-eslint/alphabetize': [
|
10
|
+
'error',
|
11
|
+
{
|
12
|
+
fields: ['ObjectTypeDefinition', 'InterfaceTypeDefinition', 'InputObjectTypeDefinition'],
|
13
|
+
values: ['EnumTypeDefinition'],
|
14
|
+
arguments: ['FieldDefinition', 'Field', 'DirectiveDefinition', 'Directive'],
|
15
|
+
},
|
16
|
+
],
|
17
|
+
'@graphql-eslint/input-name': 'error',
|
18
|
+
'@graphql-eslint/no-scalar-result-type-on-mutation': 'error',
|
19
|
+
'@graphql-eslint/require-deprecation-date': 'error',
|
20
|
+
'@graphql-eslint/require-field-of-type-query-in-mutation-result': 'error',
|
21
|
+
},
|
22
|
+
};
|
23
|
+
module.exports = exports.default;
|
@@ -0,0 +1,52 @@
|
|
1
|
+
"use strict";
|
2
|
+
/*
|
3
|
+
* 🚨 IMPORTANT! Do not manually modify this file. Run: `yarn generate-configs`
|
4
|
+
*/
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.default = {
|
7
|
+
extends: './configs/base',
|
8
|
+
rules: {
|
9
|
+
'@graphql-eslint/description-style': 'error',
|
10
|
+
'@graphql-eslint/known-argument-names': 'error',
|
11
|
+
'@graphql-eslint/known-directives': 'error',
|
12
|
+
'@graphql-eslint/known-type-names': 'error',
|
13
|
+
'@graphql-eslint/lone-schema-definition': 'error',
|
14
|
+
'@graphql-eslint/naming-convention': [
|
15
|
+
'error',
|
16
|
+
{
|
17
|
+
types: 'PascalCase',
|
18
|
+
FieldDefinition: 'camelCase',
|
19
|
+
InputValueDefinition: 'camelCase',
|
20
|
+
Argument: 'camelCase',
|
21
|
+
DirectiveDefinition: 'camelCase',
|
22
|
+
EnumValueDefinition: 'UPPER_CASE',
|
23
|
+
'FieldDefinition[parent.name.value=Query]': {
|
24
|
+
forbiddenPrefixes: ['query', 'get'],
|
25
|
+
forbiddenSuffixes: ['Query'],
|
26
|
+
},
|
27
|
+
'FieldDefinition[parent.name.value=Mutation]': {
|
28
|
+
forbiddenPrefixes: ['mutation'],
|
29
|
+
forbiddenSuffixes: ['Mutation'],
|
30
|
+
},
|
31
|
+
'FieldDefinition[parent.name.value=Subscription]': {
|
32
|
+
forbiddenPrefixes: ['subscription'],
|
33
|
+
forbiddenSuffixes: ['Subscription'],
|
34
|
+
},
|
35
|
+
},
|
36
|
+
],
|
37
|
+
'@graphql-eslint/no-case-insensitive-enum-values-duplicates': 'error',
|
38
|
+
'@graphql-eslint/no-hashtag-description': 'error',
|
39
|
+
'@graphql-eslint/no-typename-prefix': 'error',
|
40
|
+
'@graphql-eslint/no-unreachable-types': 'error',
|
41
|
+
'@graphql-eslint/provided-required-arguments': 'error',
|
42
|
+
'@graphql-eslint/require-deprecation-reason': 'error',
|
43
|
+
'@graphql-eslint/require-description': ['error', { types: true, DirectiveDefinition: true }],
|
44
|
+
'@graphql-eslint/strict-id-in-types': 'error',
|
45
|
+
'@graphql-eslint/unique-directive-names': 'error',
|
46
|
+
'@graphql-eslint/unique-directive-names-per-location': 'error',
|
47
|
+
'@graphql-eslint/unique-field-definition-names': 'error',
|
48
|
+
'@graphql-eslint/unique-operation-types': 'error',
|
49
|
+
'@graphql-eslint/unique-type-names': 'error',
|
50
|
+
},
|
51
|
+
};
|
52
|
+
module.exports = exports.default;
|