Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cjoudrey/graphql-schema-linter
Validate GraphQL schema definitions against a set of rules
https://github.com/cjoudrey/graphql-schema-linter
graphql linter
Last synced: 3 days ago
JSON representation
Validate GraphQL schema definitions against a set of rules
- Host: GitHub
- URL: https://github.com/cjoudrey/graphql-schema-linter
- Owner: cjoudrey
- License: mit
- Created: 2017-08-03T04:44:30.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2024-12-15T12:57:13.000Z (28 days ago)
- Last Synced: 2024-12-18T22:02:15.069Z (25 days ago)
- Topics: graphql, linter
- Language: JavaScript
- Homepage:
- Size: 2.04 MB
- Stars: 694
- Watchers: 10
- Forks: 62
- Open Issues: 68
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.txt
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
- awesome - graphql-schema-linter - Validate GraphQL schema definitions against a set of rules (JavaScript)
- awesome-list - graphql-schema-linter
- awesome-linters - graphql-schema-linter - (Linters / GraphQL)
README
# graphql-schema-linter [![Travis CI](https://travis-ci.org/cjoudrey/graphql-schema-linter.svg?branch=master)](https://travis-ci.org/cjoudrey/graphql-schema-linter) [![npm version](https://badge.fury.io/js/graphql-schema-linter.svg)](https://yarnpkg.com/en/package/graphql-schema-linter)
This package provides a command line tool to validate GraphQL schema definitions against a set of rules.
![Screenshot](https://raw.githubusercontent.com/cjoudrey/graphql-schema-linter/master/screenshot-v0.0.24.png)
If you're looking to lint your GraphQL queries, check out this ESLint plugin: [apollographql/eslint-plugin-graphql](https://github.com/apollographql/eslint-plugin-graphql).
## Install
`graphql-schema-linter` depends on `graphql` as a peer dependency.
In order to use `graphql-schema-linter`, you can either add it to an existing project that uses the `graphql` package:
```
# Using yarn
yarn add graphql-schema-linter# Using npm
npm install --save graphql-schema-linter
```Or, you may install it globally along side `graphql`:
```
# Using yarn
yarn global add graphql-schema-linter graphql# Using npm
npm install -g graphql-schema-linter graphql
```## Usage
```
Usage: graphql-schema-linter [options] [schema.graphql ...]Options:
-r, --rules
only the rules specified will be used to validate the schema
example: --rules fields-have-descriptions,types-have-descriptions
-o, --rules-options
configure the specified rules with the passed in configuration options
example: --rules-options '{"enum-values-sorted-alphabetically":{"sortOrder":"lexicographical"}}'
-i, --ignore
ignore errors for specific schema members (see "Inline rule overrides" for an alternative way to do this)
example: --ignore '{"fields-have-descriptions":["Obvious","Query.obvious","Query.something.obvious"]}'
-f, --format
choose the output format of the report
possible values: compact, json, text
-s, --stdin
schema definition will be read from STDIN instead of specified file
-c, --config-directory
path to begin searching for config files
-p, --custom-rule-paths
path to additional custom rules to be loaded. Example: rules/*.js
--comment-descriptions
use old way of defining descriptions in GraphQL SDL
--old-implements-syntax
use old way of defining implemented interfaces in GraphQL SDL
--version
output the version number
-h, --help
output usage information
```### Usage with pre-commit Hooks
Using [lint-staged](https://github.com/okonet/lint-staged) and [husky](https://github.com/typicode/husky), you can lint
your staged GraphQL schema file before you commit. First, install these packages:```bash
yarn add --dev lint-staged husky
```Then add a `precommit` script and a `lint-staged` key to your `package.json` like so:
```json
{
"scripts": {
"precommit": "lint-staged"
},
"lint-staged": {
"*.graphql": ["graphql-schema-linter path/to/*.graphql"]
}
}
```The above configuration assumes that you have either one `schema.graphql` file or multiple `.graphql` files that should
be concatenated together and linted as a whole.If your project has `.graphql` query files and `.graphql` schema files, you'll likely need multiple entries in the
`lint-staged` object - one for queries and one for schema. For example:```json
{
"scripts": {
"precommit": "lint-staged"
},
"lint-staged": {
"client/*.graphql": ["eslint . --ext .js --ext .gql --ext .graphql"],
"server/*.graphql": ["graphql-schema-linter server/*.graphql"]
}
}
```If you have multiple schemas in the same folder, your `lint-staged` configuration will need to be more specific, otherwise
`graphql-schema-linter` will assume they are all parts of one schema. For example:**Correct:**
```json
{
"scripts": {
"precommit": "lint-staged"
},
"lint-staged": {
"server/schema.public.graphql": ["graphql-schema-linter"],
"server/schema.private.graphql": ["graphql-schema-linter"]
}
}
```**Incorrect (if you have multiple schemas):**
```json
{
"scripts": {
"precommit": "lint-staged"
},
"lint-staged": {
"server/*.graphql": ["graphql-schema-linter"]
}
}
```## Configuration file
In addition to being able to configure `graphql-schema-linter` via command line options, it can also be configured via
one of the following configuration files.For now, only `rules`, `schemaPaths`, `customRulePaths`, and `rulesOptions` can be configured in a configuration file, but more options may be added in the future.
### In `package.json`
```json
{
"graphql-schema-linter": {
"rules": ["enum-values-sorted-alphabetically"],
"schemaPaths": ["path/to/my/schema/files/**.graphql"],
"customRulePaths": ["path/to/my/custom/rules/*.js"],
"rulesOptions": {
"enum-values-sorted-alphabetically": { "sortOrder": "lexicographical" }
}
}
}
```### In `.graphql-schema-linterrc`
```json
{
"rules": ["enum-values-sorted-alphabetically"],
"schemaPaths": ["path/to/my/schema/files/**.graphql"],
"customRulePaths": ["path/to/my/custom/rules/*.js"],
"rulesOptions": {
"enum-values-sorted-alphabetically": { "sortOrder": "lexicographical" }
}
}
```### In `graphql-schema-linter.config.js`
```js
module.exports = {
rules: ['enum-values-sorted-alphabetically'],
schemaPaths: ['path/to/my/schema/files/**.graphql'],
customRulePaths: ['path/to/my/custom/rules/*.js'],
rulesOptions: {
'enum-values-sorted-alphabetically': { sortOrder: 'lexicographical' }
}
};
```## Inline rule overrides
There could be cases where a linter rule is undesirable for a specific part of a GraphQL schema.
Rather than disable the rule for the entire schema, it is possible to disable it for that specific part of the schema using an inline configuration.
There are 4 different inline configurations:
- `lint-disable rule1, rule2, ..., ruleN` will disable the specified rules, starting at the line it is defined, and until the end of the file or until the rule is re-enabled by an inline configuration.
- `lint-enable rule1, rule2, ..., ruleN` will enable the specified rules, starting at the line it is defined, and until the end of the file or until the rule is disabled by an inline configuration.
- `lint-disable-line rule1, rule2, ..., ruleN` will disable the specified rules for the given line.
- `lint-enable-line rule1, rule2, ..., ruleN` will enable the specified rules for the given line.
One can use these inline configurations by adding them directly to the GraphQL schema as comments.
```graphql
# lint-disable types-have-descriptions, fields-have-descriptions
type Query {
field: String
}
# lint-enable types-have-descriptions, fields-have-descriptions"""
Mutation root
"""
type Mutation {
"""
Field description
"""
field: Stringfield2: String # lint-disable-line fields-have-descriptions
}
```**Note:** If you are authoring your GraphQL schema using a tool that prevents you from adding comments, you may use the `--ignore` to obtain the same functionality.
## Built-in rules
### `arguments-have-descriptions`
This rule will validate that all field arguments have a description.
### `defined-types-are-used`
This rule will validate that all defined types are used at least once in the schema.
### `deprecations-have-a-reason`
This rule will validate that all deprecations have a reason.
### `descriptions-are-capitalized`
This rule will validate that all descriptions, if present, start with a capital letter.
### `enum-values-all-caps`
This rule will validate that all enum values are capitalized.
### `enum-values-have-descriptions`
This rule will validate that all enum values have a description.
### `enum-values-sorted-alphabetically`
This rule will validate that all enum values are sorted alphabetically.
Accepts following rule options:
- `sortOrder`: `` - either `alphabetical` or `lexicographical`, defaults: `alphabetical`
### `fields-are-camel-cased`
This rule will validate that object type field and interface type field names are camel cased.
### `fields-have-descriptions`
This rule will validate that object type fields and interface type fields have a description.
### `input-object-fields-sorted-alphabetically`
This rule will validate that all input object fields are sorted alphabetically.
Accepts following rule options:
- `sortOrder`: `` - either `alphabetical` or `lexicographical`, defaults: `alphabetical`
### `input-object-values-are-camel-cased`
This rule will validate that input object value names are camel cased.
### `input-object-values-have-descriptions`
This rule will validate that input object values have a description.
### `interface-fields-sorted-alphabetically`
This rule will validate that all interface object fields are sorted alphabetically.
Accepts following rule options:
- `sortOrder`: `` - either `alphabetical` or `lexicographical`, defaults: `alphabetical`
### `relay-connection-types-spec`
This rule will validate the schema adheres to [section 2 (Connection Types)](https://facebook.github.io/relay/graphql/connections.htm#sec-Connection-Types) of the [Relay Cursor Connections Specification](https://facebook.github.io/relay/graphql/connections.htm).
More specifically:
- Only object type names may end in `Connection`. These object types are considered connection types.
- Connection types must have a `edges` field that returns a list type.
- Connection types must have a `pageInfo` field that returns a non-null `PageInfo` object.### `relay-connection-arguments-spec`
This rule will validate the schema adheres to [section 4 (Arguments)](https://facebook.github.io/relay/graphql/connections.htm#sec-Arguments) of the [Relay Cursor Connections Specification](https://facebook.github.io/relay/graphql/connections.htm).
More specifically:
- A field that returns a `Connection` must include forward pagination arguments, backward pagination arguments, or both.
- To enable forward pagination, two arguments are required: `first: Int` and `after: *`.
- To enable backward pagination, two arguments are required: `last: Int` and `before: *`.Note: If only forward pagination is enabled, the `first` argument can be specified as non-nullable (i.e., `Int!` instead of `Int`). Similarly, if only backward pagination is enabled, the `last` argument can be specified as non-nullable.
This rule will validate the schema adheres to [section 5 (PageInfo)](https://facebook.github.io/relay/graphql/connections.htm#sec-undefined.PageInfo) of the [Relay Cursor Connections Specification](https://facebook.github.io/relay/graphql/connections.htm).
More specifically:
- A GraphQL schema must have a `PageInfo` object type.
- `PageInfo` type must have a `hasNextPage: Boolean!` field.
- `PageInfo` type must have a `hasPreviousPage: Boolean!` field.### `type-fields-sorted-alphabetically`
This rule will validate that all type object fields are sorted alphabetically.
Accepts following rule options:
- `sortOrder`: `` - either `alphabetical` or `lexicographical`, defaults: `alphabetical`
### `types-are-capitalized`
This rule will validate that interface types and object types have capitalized names.
### `types-have-descriptions`
This will will validate that interface types, object types, union types, scalar types, enum types and input types have descriptions.
## Output formatters
The format of the output can be controlled via the `--format` option.
The following formatters are currently available: `text`, `compact`, `json`.
### Text (default)
Sample output:
```
app/schema.graphql
5:1 The object type `QueryRoot` is missing a description. types-have-descriptions
6:3 The field `QueryRoot.songs` is missing a description. fields-have-descriptionsapp/songs.graphql
1:1 The object type `Song` is missing a description. types-have-descriptions3 errors detected
```Each error is prefixed with the line number and column the error occurred on.
### Compact
Sample output:
```
app/schema.graphql:5:1 The object type `QueryRoot` is missing a description. (types-have-descriptions)
app/schema.graphql:6:3 The field `QueryRoot.a` is missing a description. (fields-have-descriptions)
app/songs.graphql:1:1 The object type `Song` is missing a description. (types-have-descriptions)
```Each error is prefixed with the path, the line number and column the error occurred on.
### JSON
Sample output:
```json
{
"errors": [
{
"message": "The object type `QueryRoot` is missing a description.",
"location": {
"line": 5,
"column": 1,
"file": "schema.graphql"
},
"rule": "types-have-descriptions"
},
{
"message": "The field `QueryRoot.a` is missing a description.",
"location": {
"line": 6,
"column": 3,
"file": "schema.graphql"
},
"rule": "fields-have-descriptions"
}
]
}
```## Exit codes
Verifying the exit code of the `graphql-schema-lint` process is a good way of programmatically knowing the
result of the validation.If the process exits with `0` it means all rules passed.
If the process exits with `1` it means one or many rules failed. Information about these failures can be obtained by
reading the `stdout` and using the appropriate output formatter.If the process exits with `2` it means an invalid configuration was provided. Information about this can be obtained by
reading the `stderr`.If the process exits with `3` it means an uncaught error happened. This most likely means you found a bug.
## Customizing rules
`graphql-schema-linter` comes with a set of rules, but it's possible that it doesn't exactly match your expectations.
The `--rules ` allows you pick and choose what rules you want to use to validate your schema.
In some cases, you may want to write your own rules. `graphql-schema-linter` leverages [GraphQL.js' visitor.js](https://github.com/graphql/graphql-js/blob/6f151233defaaed93fe8a9b38fa809f22e0f5928/src/language/visitor.js#L138)
in order to validate a schema.You may define custom rules by following the usage of [visitor.js](https://github.com/graphql/graphql-js/blob/6f151233defaaed93fe8a9b38fa809f22e0f5928/src/language/visitor.js#L138) and saving your newly created rule as a `.js` file.
You can then instruct `graphql-schema-linter` to include this rule using the `--custom-rule-paths ` option flag.
For sample rules, see the [`src/rules`](https://github.com/cjoudrey/graphql-schema-linter/tree/master/src/rules) folder of this repository or
GraphQL.js' [`src/validation/rules`](https://github.com/graphql/graphql-js/tree/6f151233defaaed93fe8a9b38fa809f22e0f5928/src/validation/rules) folder.