🚦 Check your GraphQL query strings against a schema.
Installations
npm install eslint-plugin-graphql
Developer
Developer Guide
Module System
CommonJS
Min. Node Version
>=10.0
Typescript Support
No
Node Version
12.16.3
NPM Version
6.14.4
Statistics
1,213 Stars
332 Commits
103 Forks
71 Watching
31 Branches
56 Contributors
Updated on 27 Nov 2024
Languages
JavaScript (100%)
Total Downloads
Cumulative downloads
Total Downloads
146,465,433
Last day
8.8%
59,394
Compared to previous day
Last week
24.5%
330,920
Compared to previous week
Last month
18.1%
1,113,985
Compared to previous month
Last year
-36.1%
13,082,578
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
eslint-plugin-graphql
[2022-01-25] Note - Upcoming Deprecation Plans: We (Apollo) are working towards fully deprecating this repository. We suggest migrating to the community-supported graphql-eslint. We'll share detailed migration documentation when everything here is ready to be officially deprecated, but just a heads up in case you're planning on adopting anything here for a new project (which you still can of course if this project works for you - support for this project will be minimal however).
An ESLint plugin that checks tagged query strings inside JavaScript, or queries inside .graphql
files, against a GraphQL schema.
npm install eslint-plugin-graphql
eslint-plugin-graphql
has built-in settings for four GraphQL clients out of the box:
If you want to lint your GraphQL schema, rather than queries, check out cjoudrey/graphql-schema-linter.
Importing schema JSON
You'll need to import your introspection query result or the schema as a string in the Schema Language format. This can be done if you define your ESLint config in a JS file.
Retrieving a remote GraphQL schema
graphql-cli provides a get-schema
command (in conjunction with a .graphqlconfig
file) that makes retrieving remote schemas very simple.
apollo-codegen also provides an introspect-schema command that can get your remote schemas as well
Common options
All of the rules provided by this plugin have a few options in common. There are examples of how to use these with Apollo, Relay, Lokka, FraQL and literal files further down.
-
env
: Import default settings for your GraphQL client. Supported values:'apollo'
,'relay'
,'lokka'
,'fraql'
'literal'
. Defaults to'apollo'
. This is used for the slight parsing differences in the GraphQL syntax between Apollo, Relay, Lokka and FraQL as well as giving nice defaults to some other options. -
tagName
: The name of the template literal tag that this plugin should look for when searching for GraphQL queries. It has different defaults depending on theenv
option:'relay'
:'Relay.QL'
'internal'
: Special automatic value- others:
'gql'
,'graphql'
You also have to specify a schema. You can either do it using one of these options:
schemaJson
: Your schema as JSON.schemaJsonFilepath
: The absolute path to your schema as a .json file. (Warning: this variant is incompatible witheslint --cache
.)schemaString
: Your schema in the Schema Language format as a string.
Alternatively, you can use a .graphqlconfig file instead of the above three options. If you do there's one more option to know about:
projectName
: In case you specify multiple schemas in your.graphqlconfig
file, choose which one to use by providing the project name here as a string.
There's an example on how to use a .graphqlconfig
file further down.
Identity template literal tag
This plugin relies on GraphQL queries being prefixed with a special tag. In Relay and Apollo this is done often, but some other clients take query strings without a tag. In this case, fake-tag
can be used to define an identity tag that doesn't do anything except for tell the linter this is a GraphQL query:
1import gql from "fake-tag"; 2 3const QUERY_VIEWER_NAME = gql` 4 query ViewerName { 5 viewer { 6 name 7 } 8 } 9`;
Fake tags won’t be necessary once /* GraphQL */
comment tags are supported.
GraphQL literal files
This plugin also lints GraphQL literal files ending on .gql
or .graphql
.
In order to do so set env
to 'literal'
in your .eslintrc.js
and tell eslint to check these files as well.
1eslint . --ext .js --ext .gql --ext .graphql
Example config for Apollo
1// In a file called .eslintrc.js 2module.exports = { 3 parser: "babel-eslint", 4 rules: { 5 "graphql/template-strings": ['error', { 6 // Import default settings for your GraphQL client. Supported values: 7 // 'apollo', 'relay', 'lokka', 'fraql', 'literal' 8 env: 'apollo', 9 10 // Import your schema JSON here 11 schemaJson: require('./schema.json'), 12 13 // OR provide absolute path to your schema JSON (but not if using `eslint --cache`!) 14 // schemaJsonFilepath: path.resolve(__dirname, './schema.json'), 15 16 // OR provide the schema in the Schema Language format 17 // schemaString: printSchema(schema), 18 19 // tagName is gql by default 20 }] 21 }, 22 plugins: [ 23 'graphql' 24 ] 25}
Example config for Relay
1// In a file called .eslintrc.js 2module.exports = { 3 parser: "babel-eslint", 4 rules: { 5 "graphql/template-strings": ['error', { 6 // Import default settings for your GraphQL client. Supported values: 7 // 'apollo', 'relay', 'lokka', 'fraql', 'literal' 8 env: 'relay', 9 10 // Import your schema JSON here 11 schemaJson: require('./schema.json'), 12 13 // OR provide absolute path to your schema JSON (but not if using `eslint --cache`!) 14 // schemaJsonFilepath: path.resolve(__dirname, './schema.json'), 15 16 // OR provide the schema in the Schema Language format 17 // schemaString: printSchema(schema), 18 19 // tagName is set for you to Relay.QL 20 }] 21 }, 22 plugins: [ 23 'graphql' 24 ] 25}
Example config for Lokka
1// In a file called .eslintrc.js 2module.exports = { 3 parser: "babel-eslint", 4 rules: { 5 "graphql/template-strings": ['error', { 6 // Import default settings for your GraphQL client. Supported values: 7 // 'apollo', 'relay', 'lokka', 'fraql', 'literal' 8 env: 'lokka', 9 10 // Import your schema JSON here 11 schemaJson: require('./schema.json'), 12 13 // OR provide absolute path to your schema JSON (but not if using `eslint --cache`!) 14 // schemaJsonFilepath: path.resolve(__dirname, './schema.json'), 15 16 // OR provide the schema in the Schema Language format 17 // schemaString: printSchema(schema), 18 19 // Optional, the name of the template tag, defaults to 'gql' 20 tagName: 'gql' 21 }] 22 }, 23 plugins: [ 24 'graphql' 25 ] 26}
Example config for FraQL
1// In a file called .eslintrc.js 2module.exports = { 3 parser: "babel-eslint", 4 rules: { 5 "graphql/template-strings": ['error', { 6 // Import default settings for your GraphQL client. Supported values: 7 // 'apollo', 'relay', 'lokka', 'fraql', 'literal' 8 env: 'fraql', 9 10 // Import your schema JSON here 11 schemaJson: require('./schema.json'), 12 13 // OR provide absolute path to your schema JSON 14 // schemaJsonFilepath: path.resolve(__dirname, './schema.json'), 15 16 // OR provide the schema in the Schema Language format 17 // schemaString: printSchema(schema), 18 19 // Optional, the name of the template tag, defaults to 'gql' 20 tagName: 'gql' 21 }] 22 }, 23 plugins: [ 24 'graphql' 25 ] 26}
Example config for literal graphql files
1// In a file called .eslintrc.js 2module.exports = { 3 parser: "babel-eslint", 4 rules: { 5 "graphql/template-strings": ['error', { 6 // Import default settings for your GraphQL client. Supported values: 7 // 'apollo', 'relay', 'lokka', 'fraql', 'literal' 8 env: 'literal', 9 10 // Import your schema JSON here 11 schemaJson: require('./schema.json'), 12 13 // OR provide absolute path to your schema JSON (but not if using `eslint --cache`!) 14 // schemaJsonFilepath: path.resolve(__dirname, './schema.json'), 15 16 // OR provide the schema in the Schema Language format 17 // schemaString: printSchema(schema), 18 19 // tagName is set automatically 20 }] 21 }, 22 plugins: [ 23 'graphql' 24 ] 25}
Additional Schemas or Tags
This plugin can be used to validate against multiple schemas by identifying them with different tags. This is useful for applications interacting with multiple GraphQL systems. Additional schemas can simply be appended to the options list:
1module.exports = { 2 parser: "babel-eslint", 3 rules: { 4 "graphql/template-strings": ['error', { 5 env: 'apollo', 6 tagName: 'FirstGQL', 7 schemaJson: require('./schema-first.json') 8 }, { 9 env: 'relay', 10 tagName: 'SecondGQL', 11 schemaJson: require('./schema-second.json') 12 }] 13 }, 14 plugins: [ 15 'graphql' 16 ] 17}
Example config when using .graphqlconfig
If you have .graphqlconfig
file in the root of your repo you can omit schema-related
properties (schemaJson
, schemaJsonFilepath
and schemaString
) from rule config.
1// In a file called .eslintrc.js 2module.exports = { 3 parser: "babel-eslint", 4 rules: { 5 "graphql/template-strings": ['error', { 6 // Import default settings for your GraphQL client. Supported values: 7 // 'apollo', 'relay', 'lokka', 'fraql', 'literal' 8 env: 'literal' 9 // no need to specify schema here, it will be automatically determined using .graphqlconfig 10 }] 11 }, 12 plugins: [ 13 'graphql' 14 ] 15}
In case you use additional schemas, specify projectName
from .graphqlconfig
for each tagName
:
1module.exports = { 2 parser: "babel-eslint", 3 rules: { 4 "graphql/template-strings": ['error', { 5 env: 'apollo', 6 tagName: 'FirstGQL', 7 projectName: 'FirstGQLProject' 8 }, { 9 env: 'relay', 10 tagName: 'SecondGQL', 11 projectName: 'SecondGQLProject' 12 }] 13 }, 14 plugins: [ 15 'graphql' 16 ] 17}
Selecting Validation Rules
GraphQL validation rules can be configured in the eslint rule configuration using the validators
option. The default selection depends on the env
setting. If no env
is specified, all rules are enabled by default.
The validators
setting can be set either to a list of specific validator names or to the special value "all"
.
1module.exports = { 2 parser: "babel-eslint", 3 rules: { 4 "graphql/template-strings": ['error', { 5 env: 'apollo', 6 validators: 'all', 7 tagName: 'FirstGQL', 8 schemaJson: require('./schema-first.json') 9 }, { 10 validators: ['FieldsOnCorrectType'], 11 tagName: 'SecondGQL', 12 schemaJson: require('./schema-second.json') 13 }] 14 }, 15 plugins: [ 16 'graphql' 17 ] 18}
The full list of available validators is:
ExecutableDefinitions
FieldsOnCorrectType
FragmentsOnCompositeTypes
KnownArgumentNames
KnownDirectives
(disabled by default inrelay
)KnownFragmentNames
(disabled by default in all envs)KnownTypeNames
LoneAnonymousOperation
NoFragmentCycles
NoUndefinedVariables
(disabled by default inrelay
)NoUnusedFragments
(disabled by default in all envs)NoUnusedVariables
OverlappingFieldsCanBeMerged
PossibleFragmentSpreads
ProvidedRequiredArguments
(disabled by default inrelay
)ScalarLeafs
(disabled by default inrelay
)SingleFieldSubscriptions
UniqueArgumentNames
UniqueDirectivesPerLocation
UniqueFragmentNames
UniqueInputFieldNames
UniqueOperationNames
UniqueVariableNames
ValuesOfCorrectType
VariablesAreInputTypes
VariablesDefaultValueAllowed
VariablesInAllowedPosition
Named Operations Validation Rule
The Named Operation rule validates that all operations are named. Naming operations is valuable for including in server-side logs and debugging.
Pass
query FetchUsername {
viewer {
name
}
}
Fail
query {
viewer {
name
}
}
The rule is defined as graphql/named-operations
.
1// In a file called .eslintrc.js 2module.exports = { 3 parser: "babel-eslint", 4 rules: { 5 "graphql/template-strings": ['error', { 6 env: 'apollo', 7 schemaJson: require('./schema.json'), 8 }], 9 "graphql/named-operations": ['warn', { 10 schemaJson: require('./schema.json'), 11 }], 12 }, 13 plugins: [ 14 'graphql' 15 ] 16}
Required Fields Validation Rule
The Required Fields rule validates that any specified required field is part of the query, but only if that field is available in schema. This is useful to ensure that query results are cached properly in the client.
Pass
// 'uuid' required and present in the schema
schema {
query {
viewer {
name
uuid
}
}
}
query ViewerName {
viewer {
name
uuid
}
}
Pass
// 'uuid' usually required but not present in the schema here
schema {
query {
viewer {
name
}
}
}
query ViewerName {
viewer {
name
}
}
Fail
// 'uuid' required and present in the schema
schema {
query {
viewer {
uuid
name
}
}
}
query ViewerName {
viewer {
name
}
}
The rule is defined as graphql/required-fields
and requires the requiredFields
option.
1// In a file called .eslintrc.js 2module.exports = { 3 rules: { 4 'graphql/required-fields': [ 5 'error', 6 { 7 env: 'apollo', 8 schemaJsonFilepath: path.resolve(__dirname, './schema.json'), 9 requiredFields: ['uuid'], 10 }, 11 ], 12 }, 13 plugins: [ 14 'graphql' 15 ] 16}
Capitalization of a first letter of a Type name
This rule enforces that first letter of types is capitalized
Pass
query {
someUnion {
... on SomeType {
someField
}
}
}
Fail
query {
someUnion {
... on someType {
someField
}
}
}
The rule is defined as graphql/capitalized-type-name
.
1// In a file called .eslintrc.js 2module.exports = { 3 parser: "babel-eslint", 4 rules: { 5 "graphql/template-strings": ['error', { 6 env: 'apollo', 7 schemaJson: require('./schema.json'), 8 }], 9 "graphql/capitalized-type-name": ['warn', { 10 schemaJson: require('./schema.json'), 11 }], 12 }, 13 plugins: [ 14 'graphql' 15 ] 16}
No Deprecated Fields Validation Rule
The No Deprecated Fields rule validates that no deprecated fields are part of the query. This is useful to discover fields that have been marked as deprecated and shouldn't be used.
Fail
// 'id' requested and marked as deprecated in the schema
schema {
query {
viewer {
id: Int @deprecated(reason: "Use the 'uuid' field instead")
uuid: String
}
}
}
query ViewerName {
viewer {
id
}
}
The rule is defined as graphql/no-deprecated-fields
.
1// In a file called .eslintrc.js 2module.exports = { 3 rules: { 4 'graphql/no-deprecated-fields': [ 5 'error', 6 { 7 env: 'relay', 8 schemaJson: require('./schema.json') 9 }, 10 ], 11 }, 12 plugins: [ 13 'graphql' 14 ] 15}
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
security policy file detected
Details
- Info: security policy file detected: github.com/apollographql/.github/SECURITY.md:1
- Info: Found linked content: github.com/apollographql/.github/SECURITY.md:1
- Info: Found disclosure, vulnerability, and/or timelines in security policy: github.com/apollographql/.github/SECURITY.md:1
- Info: Found text in security policy: github.com/apollographql/.github/SECURITY.md:1
Reason
Found 6/15 approved changesets -- score normalized to 4
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/nodejs.yml:1
- Info: no jobLevel write permissions found
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/nodejs.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/apollographql/eslint-plugin-graphql/nodejs.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/nodejs.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/apollographql/eslint-plugin-graphql/nodejs.yml/master?enable=pin
- Warn: npmCommand not pinned by hash: .github/workflows/nodejs.yml:25
- Info: 0 out of 2 GitHub-owned GitHubAction dependencies pinned
- Info: 0 out of 1 npmCommand dependencies pinned
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
license file not detected
Details
- Warn: project does not have a license file
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 23 are checked with a SAST tool
Reason
24 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92
- Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw
- Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-w8qv-6jwh-64r5
- Warn: Project is vulnerable to: GHSA-7gc6-qh9x-w6h8
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c
- Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq
- Warn: Project is vulnerable to: GHSA-2j2x-2gpw-g8fm
- Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6
- Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h
- Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw
- Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9
- Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
- Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3
- Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m / GHSA-xvch-5gv4-984h
- Warn: Project is vulnerable to: GHSA-w7rc-rwvf-8q5r
- Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g
- Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
- Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7
- Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh
Score
3.2
/10
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More