cjoudrey / graphql-schema-linter Goto Github PK
View Code? Open in Web Editor NEWValidate GraphQL schema definitions against a set of rules
License: MIT License
Validate GraphQL schema definitions against a set of rules
License: MIT License
In order to ensure old types get removed when they are no longer used, we could have a rule that verifies that all types in the schema are referenced at least once.
For example, the rule would warn about the type User
not being used in the following schema:
type QueryRoot {
a: String!
}
type User {
email: String!
}
Although we aren't defining the rules the way ESLint expects, we might be able to add a module that makes the linter work with ESLint.
For example: https://github.com/azeemba/eslint-plugin-json/blob/d2d48e30e17d9d4e7c62455ceffbd8338cd5b083/lib/index.js#L25
Another example: https://github.com/apollographql/eslint-plugin-graphql
This could be done by allowing the user to pass the filename to their formatter and it would be included when CLI runs.
It would be great if people could simply pass the path of a custom rule when running graphql-schema-linter
and the file would be required and the rule would be included in the default set of rules.
Some other linters (specifically for me, tslint
) have the ability to output results in the JUnit test result format. This gives instant integration with a wide variety of CI and testing tools.
As reported in #55 (comment), there is currently no rule to ensure input object type values have a description.
Example:
input User {
username: String
# Description
withDescription: String
}
Rather than add this to the existing fields-have-descriptions
rule, I think we might want to roll this out as a new rule such that users can opt in to it.
cc @mscharley
re: #36 and modularizing the schema
file
key to JSON returned by to JSONFormatter
TextFormatter
into multiple blocks. Prefix each block with the name of the filename.We should add a plugin to graphql-cli to expose the schema linter as graphql lint schema
or something of that nature.
At the moment this causes a crash:
$ graphql-schema-linter
It looks like you may have hit a bug in graphql-schema-linter.
It would be super helpful if you could report this here: https://github.com/cjoudrey/graphql-schema-linter/issues/new
TypeError: Must provide Source. Received: null
at parse (/Users/cjoudrey/.config/yarn/global/node_modules/graphql/language/parser.js:43:11)
at validateSchemaDefinition (/Users/cjoudrey/.config/yarn/global/node_modules/graphql-schema-linter/lib/validator.js:21:30)
at run (/Users/cjoudrey/.config/yarn/global/node_modules/graphql-schema-linter/lib/runner.js:46:56)
at Object.<anonymous> (/Users/cjoudrey/.config/yarn/global/node_modules/graphql-schema-linter/lib/cli.js:15:32)
at Module._compile (module.js:635:30)
at Object.Module._extensions..js (module.js:646:10)
at Module.load (module.js:554:32)
at tryModuleLoad (module.js:497:12)
at Function.Module._load (module.js:489:3)
at Function.Module.runMain (module.js:676:10)
The official spec recommends this, so we should put in a rule for it.
The current tests for rules are a bit verbose. We might be able to simplify them by writing a few helpers.
We could inspire ourselves from graphql-js
: https://github.com/graphql/graphql-js/blob/d3fd6c3fd3369b354e79499c07f94e1d62fb5f79/src/validation/__tests__/OverlappingFieldsCanBeMerged-test.js#L89-L115
Object.values
doesn't seem to be supported in the LTS version of Node. We should use a workaround like this so that we support Node 6.
# schema.gql
union Foo = String | Int
The above should fail linting as it has no documentation.
I've set this up in a few projects and it's awesome - then you don't need to worry about folks running yarn run fmt
before checking code in.
Output:
$ graphql-schema-linter $(bin/find-schemas graphql)
It looks like you may have hit a bug in graphql-schema-linter.
It would be super helpful if you could report this here: https://github.com/cjoudrey/graphql-schema-linter/issues/new
TypeError: Cannot read property 'length' of null
at /usr/src/app/node_modules/graphql-schema-linter/lib/source_map.js:30:57
at Array.reduce (native)
at SourceMap._computeOffsets (/usr/src/app/node_modules/graphql-schema-linter/lib/source_map.js:28:20)
at new SourceMap (/usr/src/app/node_modules/graphql-schema-linter/lib/source_map.js:16:25)
at Configuration.getSchema (/usr/src/app/node_modules/graphql-schema-linter/lib/configuration.js:92:26)
at run (/usr/src/app/node_modules/graphql-schema-linter/lib/runner.js:43:30)
at Object.<anonymous> (/usr/src/app/node_modules/graphql-schema-linter/lib/cli.js:15:32)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
I'm not sure what exactly leads to this, this is while I'm trying to clean up after a massive brainstorming session with the rest of my team. When I dig up more information I'll report back with what I find.
...so that all of our editors are using the same settings. Blocked by: prettier/prettier#2589
In reviewing #39, I realized we should put a usage recommendation in the readme for using lint-staged
Also, the popular lint-staged project (linting only files that have changed in your current git commit) passes multiple files in via command line args. Typically, the assumption is that the files are linted in isolating, but it seems like for GraphQL schema, there will either be:
In which case, the instructions for lint-staged would be:
Just run graphql-schema-linter
since it will take the single file in as a command line arg
"lint-staged": {
"*.graphql": ["graphql-schema-linter"]
},
No matter how many files have changed (one or more), run the linter on all of your GraphQL files
"lint-staged": {
"*.graphql": ["graphql-schema-linter './**/*.graphql'"]
},
We'd need to play with this to see if we can overwrite the standard args getting passed to graphql-schema-linter
from lint-staged
It looks like you may have hit a bugin graphql-schema-linter.
It would be super helpful if you could report this here: https://github.com/cjoudrey/graphql-schema-linter/issues/new
Error: Expected Interface type.
at invariant (/usr/src/app/node_modules/graphql-schema-linter/node_modules/graphql/jsutils/invariant.js:19:11)
at produceInterfaceType (/usr/src/app/node_modules/graphql-schema-linter/node_modules/graphql/utilities/buildASTSchema.js:260:83)
at /usr/src/app/node_modules/graphql-schema-linter/node_modules/graphql/utilities/buildASTSchema.js:334:14
at Array.map (native)
at makeImplementedInterfaces (/usr/src/app/node_modules/graphql-schema-linter/node_modules/graphql/utilities/buildASTSchema.js:333:45)
at interfaces (/usr/src/app/node_modules/graphql-schema-linter/node_modules/graphql/utilities/buildASTSchema.js:312:16)
at resolveThunk (/usr/src/app/node_modules/graphql-schema-linter/node_modules/graphql/type/definition.js:169:40)
at defineInterfaces (/usr/src/app/node_modules/graphql-schema-linter/node_modules/graphql/type/definition.js:331:20)
at GraphQLObjectType.getInterfaces (/usr/src/app/node_modules/graphql-schema-linter/node_modules/graphql/type/definition.js:315:52)
at typeMapReducer (/usr/src/app/node_modules/graphql-schema-linter/node_modules/graphql/type/schema.js:205:23)
# test.schema
schema {
viewer: Viewer
}
type Person {
email: String
}
# Error triggered because of this.
type Viewer implements Person {
email: String
}
Hi, I've tried running graphql-schema-linter on multiple files with the latest version of graphql but the linting breaks with this error:
It looks like you may have hit a bug in graphql-schema-linter.
It would be super helpful if you could report this here: https://github.com/cjoudrey/graphql-schema-linter/issues/new
Error: Query root type must be provided.
at assertValidSchema (/Users/patrick/Documents/Github/graphql-mock/node_modules/graphql/type/validate.js:78:11)
at validate (/Users/patrick/Documents/Github/graphql-mock/node_modules/graphql/validation/validate.js:61:35)
at validateSchemaDefinition (/Users/patrick/Documents/Github/graphql-mock/node_modules/graphql-schema-linter/lib/validator.js:30:41)
at run (/Users/patrick/Documents/Github/graphql-mock/node_modules/graphql-schema-linter/lib/runner.js:64:56)
at Object.<anonymous> (/Users/patrick/Documents/Github/graphql-mock/node_modules/graphql-schema-linter/lib/cli.js:15:32)
at Module._compile (module.js:660:30)
at Object.Module._extensions..js (module.js:671:10)
at Module.load (module.js:573:32)
at tryModuleLoad (module.js:513:12)
at Function.Module._load (module.js:505:3)
Which seems to be caused by this: graphql/graphql-js#1124
My workaround was to merge all the files with AWK and lint the merged schema,
awk 'FNR==1{print ""}1' ../api/**/*.graphql | graphql-schema-linter .graphql -s
I'm not sure what the best solution to fix this will be, I know there is no official syntax for imports, but there are two "proposal":
I think add some kind of imports support would be great, the only issue is that we still have the error from above, since now the GraphQL library needs a root type. Another solution would be do merge (like I did with the awk) all the files and run the validation on it. Then we need to a mapping between the merged file and the original ones, but shouldn't be difficult :)
What do you think? I might have some time to help this or the next week
Example:
type Query {
helloWorld(
# Invalid
invalid_argument: String
# Valid
validArgument: String
): String
}
Is it possible to add a rule that detects if there is a trailing comma and errors if not?
(Like the comma-dangle rule in eslint)
0
means there are no errors in the schema
1
means there are errors
2
means there was an internal error (i.e. uncaught exception, bad usage, etc..)
$ yarn
yarn install v0.27.5
[1/4] Resolving packages...
error Couldn't find match for "3.0" in "master,revert-2.2.0,10/head,13/head,14/head,15/head,16/head,17/head,19/head,22/head,23/head,24/head,24/merge,27/head,29/head,29/merge,31/head,33/head,34/head,34/merge,36/head,37/head,37/merge,42/head,42/merge,44/head,44/merge,47/head,51/head,52/head,52/merge,54/head,55/head,60/head,60/merge,61/head,61/merge,64/head,66/head,67/head,68/head,70/head,73/head,74/head,75/head,76/head,78/head,0.1.0,0.2.0,1.0.0,1.0.1,1.0.2,1.1.0,2.0.0,2.0.1,2.0.2,2.1.0,2.1.1,2.1.2,2.1.3,2.2.0,2.2.1,2.2.2" for "https://github.com/davidtheclark/cosmiconfig.git".
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
Refs: #26 (comment)
Apparently the 3.0
branch has been merged 2 days ago and deleted. Please use a normal version thanks.
Most tools make you explicitly whitelist params. This is nice because then you avoid the possibility of your project automatically picking up a new rule and starting to fail. Also, technically each release that adds a new rule would likely be a "breaking change" requiring a major release. Thoughts?
Hi there,
I have a folder hierarchy that's roughly src/api/graphql/[graphql_files].graphql
... when I run graphql-schema-linter ./**/*.graphql
the linter works fine, however, if I include
"lint-staged": {
"*.graphql": ["graphql-schema-linter"]
}
in the package.json, or run graphql-schema-linter ./api/**/*.graphql
, or graphql-schema-linter ./api/graphql/**/*.graphql
, I get
It looks like you may have hit a bug in graphql-schema-linter.
It would be super helpful if you could report this here: https://github.com/cjoudrey/graphql-schema-linter/issues/new
Error: Type "ContentArea" not found in document.
the ContentArea type is of course defined in the path and works fine when I run the initially aforementioned command. Any ideas?
In some error cases, the linter can programmatically know what the schema should have been.
It would be awesome to provide a --fix
option that would automatically resolve these errors.
Some example rules that could be fixed by the linter this way:
EnumValuesAllCaps
EnumValuesSortedAlphabetically
FieldsAreCamelCased
InputObjectValuesAreCamelCased
TypesAreCapitalized
Rather than have to always configure the linter via command line options, it could be useful to have a dot file at the root of a project to configure what rules should be used.
I can't even get a version number out of it:
# graphql-schema-linter --version
module.js:471
throw err;
^
Error: Cannot find module '../../src/rules/input_object_values_have_descriptions'
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/usr/src/app/node_modules/graphql-schema-linter/lib/rules/index.js:15:46)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js(module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
Reported by @goldcaddy77
At the moment this happens:
{ Error: EAGAIN: resource temporarily unavailable, read
at fs.readSync (fs.js:680:18)
We should probably return a more legible error message for this.
The types-have-descriptions
rule currently validates enum types have a description, but there is no rule that validates enum values have a description.
We might want to roll this out as a new rule such that users can opt in to it.
This would allow the command line tool to run by fetching the schema from the .graphqlconfig
file.
Some examples:
The goal of this rule is:
There will be times where users want a rule 95% of the time, but want to disable it in certain situations like eslint disable.
I guess the mechanism would need to be in a comment?
Ensure that the schema doesn't violate any of the constraints outlined in the relay connection specification.
At the moment the DeprecationsHaveAReason
rule will use the line
and column
of the FieldDefinition
node rather than the affected @directive
node.
This means if someone were to highlight the error it would lead to highlighting the wrong part of the line.
Example
Current:
11:3 The field `user.firstName` is deprecated but has no deprecation reason.
firstName: String @deprecated
^^^^^^^^^
What we actually want:
11:21 The field `user.firstName` is deprecated but has no deprecation reason.
firstName: String @deprecated
^^^^^^^^^^^
At the moment this causes a crash:
$ graphql-schema-linter invalid.graphql
It looks like you may have hit a bug in graphql-schema-linter.
It would be super helpful if you could report this here: https://github.com/cjoudrey/graphql-schema-linter/issues/new
Error: ENOENT: no such file or directory, open 'invalid.graphql'
at Object.fs.openSync (fs.js:646:18)
at fs.readFileSync (fs.js:551:33)
at getSchemaFromFile (/Users/cjoudrey/.config/yarn/global/node_modules/graphql-schema-linter/lib/configuration.js:191:31)
at /Users/cjoudrey/.config/yarn/global/node_modules/graphql-schema-linter/lib/configuration.js:196:22
at Array.reduce (<anonymous>)
at getSchemaSegmentsFromFiles (/Users/cjoudrey/.config/yarn/global/node_modules/graphql-schema-linter/lib/configuration.js:195:16)
at Configuration.getSchema (/Users/cjoudrey/.config/yarn/global/node_modules/graphql-schema-linter/lib/configuration.js:90:24)
at run (/Users/cjoudrey/.config/yarn/global/node_modules/graphql-schema-linter/lib/runner.js:41:30)
at Object.<anonymous> (/Users/cjoudrey/.config/yarn/global/node_modules/graphql-schema-linter/lib/cli.js:15:32)
at Module._compile (module.js:635:30)
Similar to #13, at the moment the TypesAreCapitalized
rule will use the line
and column
of the ObjectTypeDefinition
node rather than the affected Name
node.
This means if someone were to highlight the error it would lead to highlighting the wrong part of the line.
Example
Current:
type user {
^^^^
What we actually want:
type user {
^^^^
We could add a ValidationError
class that extends GraphQLError
so that we can include a ruleName
property that formatters can use.
# schema.gql
input Foo {
hello: String
}
The above should fail linting as it has no documentation.
As per graphql/graphql-js#927, descriptions are now strings instead of comments in the SDL.
In order to provide a graceful upgrade path, we could bump graphql-js
and add a new configuration option called --comments-as-descriptions
that would toggle buildASTSchema
's {commentDescriptions: true}
.
Hey there,
I've been trying this library for linting a SDL, however I'm getting this error:
Error: Must provide schema definition with query type or a type named Query.
at buildASTSchema (/Users/emmenko/dev/src/xxx/node_modules/graphql-schema-linter/node_modules/graphql/utilities/buildASTSchema.js:167:11)
at validateSchemaDefinition (/Users/emmenko/dev/src/xxx/node_modules/graphql-schema-linter/lib/validator.js:18:51)
at run (/Users/emmenko/dev/src/xxx/node_modules/graphql-schema-linter/lib/runner.js:47:56)
at Object.<anonymous> (/Users/emmenko/dev/src/xxx/node_modules/graphql-schema-linter/lib/cli.js:15:32)
at Module._compile (module.js:569:30)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
at Function.Module.runMain (module.js:605:10)
The reason is most likely that I have the schema spread out to different files (see modularizing schema) and I'm using the extend
keyword for extending the Query
type.
// schema.js
const SchemaDefinition = `
type Query {
version: String
# See each individual schema for specific queries
}
schema {
query: Query
}
`;
module.exports = makeExecutableSchema({
typeDefs: [
SchemaDefinition,
user.schema,
// ...
],
resolvers: {...}
});
// user/schema.gql
type User {...}
extend type Query {
me: User
}
// foo/schema.gql
type Foo {...}
extend type Query {
foo: Foo
}
Any idea if this might work?
Many thanks!
At the moment the command line crashes when you don't give it a schema or if the schema is invalid.
There should be a way to display usage via the command line.
We could add a way for the user to define a blacklist and whitelist of rules to use when validating a schema.
This could be defined both as command line options and in the config file.
Example:
type Query {
# Invalid
invalid_name: String
# Valid
thisIsValid: String
}
This rule should verify both interface fields and object type fields.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.