-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC]SDL validation #1438
[RFC]SDL validation #1438
Conversation
schema = extendSchema(schema, ast); | ||
const queryType = schema.getQueryType(); | ||
expect(queryType).to.have.property('name', 'Foo'); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mjmahone This is a proposed solution for a situation where library/tools want to add its directives to user-provided SDL.
Alternatively, you can just prefix user-provided SDL but it will screw line offsets in errors.
Another alternative is to use concatAST
but there no method to convert GraphQLDirective
to AST.
This is a pretty big change but in addition to injecting directives it also allows to implement buildASTSchema
as follows:
function buildASTSchema(ast, options) {
return extendSchema(new GraphQLSchema({}), ast, options);
}
To make review easier tomorrow I will extract this change into separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks pretty cool! I think we might need to provide a method to convert GraphQLDirective
to AST.
@mjmahone This is working code but it needs more tests and I also want to split out a two PRs: all refactorings and allows to define a schema using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very exciting! It is a huge improvement over #1435. My two concerns: making sure the assumeValid
API is correct, and trying to avoid using a GraphQLSchema
at all inside our SDL validation.
* | ||
* Default: false | ||
*/ | ||
assumeValidSDL?: boolean, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should just piggyback on the GraphQLSchemaValidationOptions
's assumeValid
key.
If I set assumeValid
and then get an error thrown when building the AST schema, that would be surprising. Especially as buildASTSchema
's sole job is to build a schema.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mjmahone Good catch 🔎 🐞
Fixed.
); | ||
if (!directiveDef) { | ||
const name = node.name.value; | ||
const locations = locationsMap[name]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow this looks like it will not work, until you read the visitInParallel
documentation:
Each visitor will be visited for each node before moving on.
So this only works because we are guaranteed to visit every single Document
prior to visiting any definition. That is very clever.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mjmahone It's unnecessary complication since you context
has getDocument
function. So I just removed Document
and move this code on the top level.
src/validation/validate.js
Outdated
|
||
export function validateSDL( | ||
documentAST: DocumentNode, | ||
schemaToExtend?: ?GraphQLSchema, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this a lot, and would in fact be a fan of moving all existing schema validation rules into validateSDL
. Not sure if we want to do that prior to 14.0
, but it might be nice to add them as optional rules for 14.1
, and then have those be the specified rules for 15.0
(6 months down the line? Not sure what our release cadence is supposed to be).
I am very tempted to fix buildASTSchema(ast, {assumeValid: true})
to not throw on errors that would normally be considered SDL-type errors (i.e. errors that do not prevent us from building a schema, it just would likely fail once built).
src/validation/validate.js
Outdated
export function validateSDL( | ||
documentAST: DocumentNode, | ||
schemaToExtend?: ?GraphQLSchema, | ||
rules?: $ReadOnlyArray<any> = specifiedSDLRules, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmm, I'm not 100% certain whether or not we should allow people to pass in a TypeInfo
here. I know internally we have a special TypeInfo
(centered around dealing with pre-open-source GraphQL oddities) that we always pass into validate
, but I don't believe it's required for the SDL at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mjmahone Are you referring to the rules
field?
To be more explicit I created SDLValidationRule
and used it here so now this line looks like:
rules?: $ReadOnlyArray<SDLValidationRule> = specifiedSDLRules,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I'm OK with the rules field. For validate
there is an extra optional argument, typeInfo?: TypeInfo
which I do not believe is required.
src/validation/ValidationContext.js
Outdated
@@ -42,11 +42,44 @@ type VariableUsage = {| | |||
* allowing access to commonly useful contextual information from within a | |||
* validation rule. | |||
*/ | |||
export default class ValidationContext { | |||
_schema: GraphQLSchema; | |||
export class BaseValidationContext { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this split, as there's so many rules that don't need a schema at all.
However, I am beginning to think there are three pieces:
- a pure "ErrorReporter". Has no AST knowledge.
- an AST-only context. This is
SDLValidationContext
as it stands. Everything that is a purevisitor
can use this context. It may need two documents, Schema and Executable ASTs. - a Schema-aware context. Much like
visitor
can take in avisitWithTypeInfo
, this would hold aASTValidationContext
, and delegate to that one for the ast functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in #1446
|
||
constructor(ast: DocumentNode, schema?: ?GraphQLSchema): void { | ||
super(ast); | ||
this._schema = schema; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should even allow access to a GraphQLSchema
here: instead, if you pass in an existing schema, we can convert that schema to AST nodes (a very rough way to do this would be to parse(printSchema(schema))
).
Ideally, the current GraphQLSchema
would only be a runtime thing: you need it to validate queries you're trying to persist, but you don't need it to validate or transform itself.
I like the idea that there's a split between "validation that needs a schema" and "validation that does not", and "validation that does not need a schema" is a superset of "SDL validation".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mjmahone Problem is that conversion from SDL to GraphQLSchema
is lossless, but not vice versa. For example, you lose all directives which prevent from enforcing the rule that forbids directive duplication in extends.
Also after parse(printSchema(schema)))
you loose ability to print errors with original locations and formating of nodes.
And there are others many potential scenarious where we loose something by such converion especially if schema that we trying to extend was build from GraphQL*Types
not from SDL. For example, developer can create custom class derived GraphQLObjectType
with some additional data and require this additional data inside his custom SDL rules.
And it's not a technical problem, since GraphQLSchema
is intended to be most complete represenation of schema.
and "validation that does not need a schema" is a superset of "SDL validation".
"validation that does not need a schema" => ASTValidationContext
And this context suffisient for all rules that scoped to particular defintion.
If rule should check conflicts/dependencies beetween definitions it should handle case when you extending existing schema and use SDLValidationContext
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should fix it so it's lossless, but that would be a different PR, and we could probably target 14.1 for that.
Also after parse(printSchema(schema))) you loose ability to print errors with original locations and formating of nodes.
I think there's a way around this, where we'd do buildSchemaDocuments(schema): Array<DocumentNode>
, where each DocumentNode
would contain all definitions from a specific source. That's obviously more complex of a change than what we want to do here, but I think would be worth having. For GraphQL*Types
we'd have to have some form of "default" or "non-Source" document. But for truly custom classes, you're right we can't make lossless conversions.
If rule should check conflicts/dependencies beetween definitions it should handle case when you extending existing schema and use SDLValidationContext.
Makes sense, so let's push this forward as-is. But I'd like to switch our mental model to being AST-validation first, and then only using the schema when it's truly necessary. You've mostly accomplished this, but I envision a bunch of people creating validation rules that silently fail if no schema is present (because they assume they always have a schema present). That would be an unfortunate future.
Split out from graphql#1438
Split out from #1438 Allows to inject directives and types into SDL-based schema: ```js import { GrapQLDateTime } from 'somepackage'; let schema = new GraphQLSchema({ types: [GrapQLDateTime], }); const ast = parse(` type Query { timestamp: DateTime } `); schema = extendSchema(schema, ast); ``` ```js let schema = new GraphQLSchema({ directives: [ new GraphQLDirective({ name: 'onSchema', locations: ['SCHEMA'], }), ], }); const ast = parse(` schema @onSchema { query: Foo } type Foo { bar: String } `); schema = extendSchema(schema, ast); ```
fe27d28
to
33a71bd
Compare
@mjmahone |
@@ -112,6 +120,10 @@ export function buildASTSchema( | |||
throw new Error('Must provide a document ast.'); | |||
} | |||
|
|||
if (!options || !(options.assumeValid || options.assumeValidSDL)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mjmahone We need separate assumeValidSDL
check so developers are able to change set of validation rules(add or delete).
const errors = validateSDL(ast, null, customSetOfRules);
if (errors.length !== 0) {
// ...
}
const schema = buildASTSchema(ast, { assumeValidSDL: true });
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok this makes sense. A little bit annoying to add in that second key, but not the end of the world.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait: are you thinking assumeValid
is a superset of assumeValidSDL
or disjoint? I would still ideally have it be a superset. We could add assumeValidExecutableAST
or something that is disjoint with assumeValidSDL
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mjmahone My proposal:
{}
=> validateSDL
+ validateSchema
{ assumeValidSDL: true }
=> validateSchema
{assumeValid: true }
=> no checks
1b33f44
to
1da0376
Compare
@mjmahone I updated this PR and answered all review comments. This PR doesn't contain all necessary rules and tests, e.g. it rule that check duplications in extends:
If this PR is ok I will try to finish all other rules tomorrow as a separate PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just want to make sure it makes sense to make assertValidSDL
and assertValidSDLExtension
functions public with this release. If you really think it's important to, I'm OK with it, but I'd prefer waiting for a future release to play it safe. We also aren't even using them in our test harness, so I don't think it's required just yet.
const oldSchema = context.getSchema(); | ||
const alreadyDefined = | ||
oldSchema && | ||
(oldSchema.astNode || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels weird to check the astNode
here, but I guess it's needed in case your original schema definition is invalid (for instance, if it has no query
): we still would want to report this error upon re-defining, too. So this does make sense.
SchemaDefinition(node) { | ||
if (alreadyDefined) { | ||
context.reportError( | ||
new GraphQLError(canNotDefineSchemaWithinExtension(), [node]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be nice to point back to the originally defined schema if provided. But I could be wrong here and that would just be noise.
Also a very small nit provided you're only going to use this node in the error, not sure it's worth changing:
new GraphQLError(canNotDefineSchemaWithinExtension(), node),
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mjmahone I was thinking that in some systems (e.g. GraphQL is very popular for CMS) clients can provide their own extension SDL. So I was concern that we can leak some internal data in printed errors.
Thinking more about this I think I'm too paranoid since validateSchema
already leaking this info so if someone decides he doesn't want origin node to be printed he needs to sanitize GraphQLError
s anyway. Plus such complex systems almost certainly using GraphQL*Type
classes anyway.
src/validation/validate.js
Outdated
* Utility function which asserts a SDL document is valid by throwing an error | ||
* if it is invalid. | ||
*/ | ||
export function assertValidSDL(documentAST: DocumentNode): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we make this API public yet? We don't have a corresponding assertValidAST
yet, nor assertValid
(for both SDL and AST). Internally, we do the exact same thing you're doing here internally, but we should probably offer all the functionality (maybe with a single assertValid
function for now). I'm also not 100% sure the assertValid
functions belongs here vs. a utility file, and I am not sure we should offer them without offering the ability to pass in your own set of rules.
@IvanGoncharov once we clear up the |
1da0376
to
1e24f87
Compare
@mjmahone
See here: https://github.com/graphql/graphql-js/blob/master/src/README.md But I agree it could be confusing so I marked all added exports as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! Thanks for going through all this work, @IvanGoncharov! This looks like it's in really good shape now.
## Version **14.0.0** of **graphql** was just published. <table> <tr> <th align=left> Dependency </th> <td> <a target=_blank href=https://github.com/graphql/graphql-js>graphql</a> </td> </tr> <tr> <th align=left> Current Version </th> <td> 0.13.2 </td> </tr> <tr> <th align=left> Type </th> <td> dependency </td> </tr> </table> The version **14.0.0** is **not covered** by your **current version range**. If you don’t accept this pull request, your project will work just like it did before. However, you might be missing out on a bunch of new features, fixes and/or performance improvements from the dependency update. It might be worth looking into these changes and trying to get this project onto the latest version of graphql. If you have a solid test suite and good coverage, a passing build is a strong indicator that you can take advantage of these changes directly by merging the proposed change into your project. If the build fails or you don’t have such unconditional trust in your tests, this branch is a great starting point for you to work on the update. --- <details> <summary>Release Notes</summary> <strong>v14.0.0</strong> <p><strong>Breaking:</strong></p> <ul> <li>Drops support for node v4 and v9, makes sure node v10 is supported (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="320331530" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1338" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1338">#1338</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="347064508" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1445" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1445">#1445</a>)</li> <li>Reject invalid scalar value coercion (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="329203491" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1365" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1365">#1365</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="320302933" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1336" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1336">#1336</a>)</li> <li>Removes <code>VariablesDefaultValueAllowed</code> validation rule, and <code>ProvidedNonNullArguments</code> became <code>ProvidedRequiredArguments</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="302567815" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1274" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1274">#1274</a>)</li> <li>Stricter coercion of Scalar Types (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331077407" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1382" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1382">#1382</a>)</li> <li>Removes deprecated Introspection fields <code>onOperation</code>, <code>onFragment</code>, and <code>onField</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331430870" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1385" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1385">#1385</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="343635964" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1429" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1429">#1429</a>)</li> <li><code>GraphQL*Config</code> are now exact types (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331763019" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1391" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1391">#1391</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="347050549" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1443" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1443">#1443</a>)</li> <li>"Schema Change" keys in <code>BreakingChangeType</code> and <code>DangerousChangeType</code> for detecting adding args and input fields changed name (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="355220055" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1492" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1492">#1492</a>)</li> <li><code>formatError</code> API changed for error message extensions. To upgrade without changing existing server responses, wrap <code>graphql</code>'s <code>formatError</code>:</li> </ul> <pre><code>import { formatError as baseFormatError, /* ... */ } from 'graphql'; { // other options formatError(error) { const { extensions, ...rest } = baseFormatError(error); return { ...extensions, ...rest }; }, } </code></pre> <p><strong>New:</strong></p> <ul> <li>Parse new schema extensions (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="315664664" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1314" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1314">#1314</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="317012679" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1323" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1323">#1323</a>)</li> <li>Export SDL AST types (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="315694355" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1315" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1315">#1315</a>)</li> <li><code>extendSchema</code> extended with spec-compliant SDL extensions (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="330426164" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1373" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1373">#1373</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331961053" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1392" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1392">#1392</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="346266873" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1441" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1441">#1441</a>)</li> <li><code>symbol.toStringTag</code> support (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="307864327" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1297" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1297">#1297</a>)</li> <li>Expose <code>getOperationRootType(schema, operationAST)</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="322058451" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1345" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1345">#1345</a>)</li> <li>Package is marked as side-effect free (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="314458450" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1312" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1312">#1312</a>)</li> <li><code>validateSchema</code> works with Schema extensions (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="337240645" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1410" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1410">#1410</a>)</li> <li><code>validate</code> works on SDL definitions (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="345971682" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1438" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1438">#1438</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331081195" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1383" href="https://urls.greenkeeper.io/graphql/graphql-js/issues/1383">#1383</a>)</li> <li>directives can be added to variable definitions, behind <code>experimentalVariableDefinitionDirectives</code> flag (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="345484247" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1437" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1437">#1437</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="348424943" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1454" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1454">#1454</a>)</li> <li>ASTNode predicates, like <code>isDefinitionNode</code> and <code>isTypeSystemDefinitionNode</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="349160476" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1459" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1459">#1459</a>)</li> <li><code>isRequiredArgument</code> and <code>isRequiredInputField</code> predicates (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="349831716" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1463" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1463">#1463</a>)</li> </ul> <p><strong>Fixed:</strong></p> <ul> <li>Fixes for custom enum types</li> <li>Prettier, Flow and eslint upgrades (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="310208412" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1304" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1304">#1304</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="316500173" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1319" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1319">#1319</a>)</li> <li>Babel 7 upgrade (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="323277037" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1350" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1350">#1350</a>)</li> <li>Introspection query perf improved (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="318663971" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1329" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1329">#1329</a>)</li> <li><code>introspectionFromSchema</code> has default options (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="336268824" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1408" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1408">#1408</a>)</li> <li><code>buildSchema</code> memory leaks and infinite recursion fixed (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="341094161" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1417" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1417">#1417</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="343182956" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1427" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1427">#1427</a>)</li> <li><code>watch</code> command fixed (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="347719430" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1449" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1449">#1449</a>)</li> <li>Benchmarking for <code>validation</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="350893741" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1471" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1471">#1471</a>)</li> </ul> <p><strong>Deprecated:</strong></p> <p>These will be removed in v15</p> <ul> <li><code>introspectionQuery</code>, use <code>getIntrospectionQuery</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331432132" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1386" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1386">#1386</a>)</li> <li><code>getDescription</code>, use the schema AST node to get descriptions (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="333742859" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1396" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1396">#1396</a>)</li> <li><code>isValidJSValue</code>, use <code>coerceValue</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331432132" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1386" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1386">#1386</a>)</li> <li><code>isValidLiteralValue</code>, use validation (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331432132" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1386" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1386">#1386</a>)</li> </ul> </details> <details> <summary>FAQ and help</summary> There is a collection of [frequently asked questions](https://greenkeeper.io/faq.html). If those don’t help, you can always [ask the humans behind Greenkeeper](https://github.com/greenkeeperio/greenkeeper/issues/new). </details> --- Your [Greenkeeper](https://greenkeeper.io) bot 🌴
## Version **14.0.0** of **graphql** was just published. <table> <tr> <th align=left> Dependency </th> <td> <a target=_blank href=https://github.com/graphql/graphql-js>graphql</a> </td> </tr> <tr> <th align=left> Current Version </th> <td> 0.13.2 </td> </tr> <tr> <th align=left> Type </th> <td> dependency </td> </tr> </table> The version **14.0.0** is **not covered** by your **current version range**. If you don’t accept this pull request, your project will work just like it did before. However, you might be missing out on a bunch of new features, fixes and/or performance improvements from the dependency update. It might be worth looking into these changes and trying to get this project onto the latest version of graphql. If you have a solid test suite and good coverage, a passing build is a strong indicator that you can take advantage of these changes directly by merging the proposed change into your project. If the build fails or you don’t have such unconditional trust in your tests, this branch is a great starting point for you to work on the update. --- <details> <summary>Release Notes</summary> <strong>v14.0.0</strong> <p><strong>Breaking:</strong></p> <ul> <li>Drops support for node v4 and v9, makes sure node v10 is supported (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="320331530" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1338" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1338">#1338</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="347064508" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1445" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1445">#1445</a>)</li> <li>Reject invalid scalar value coercion (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="329203491" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1365" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1365">#1365</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="320302933" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1336" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1336">#1336</a>)</li> <li>Removes <code>VariablesDefaultValueAllowed</code> validation rule, and <code>ProvidedNonNullArguments</code> became <code>ProvidedRequiredArguments</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="302567815" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1274" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1274">#1274</a>)</li> <li>Stricter coercion of Scalar Types (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331077407" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1382" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1382">#1382</a>)</li> <li>Removes deprecated Introspection fields <code>onOperation</code>, <code>onFragment</code>, and <code>onField</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331430870" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1385" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1385">#1385</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="343635964" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1429" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1429">#1429</a>)</li> <li><code>GraphQL*Config</code> are now exact types (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331763019" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1391" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1391">#1391</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="347050549" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1443" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1443">#1443</a>)</li> <li>"Schema Change" keys in <code>BreakingChangeType</code> and <code>DangerousChangeType</code> for detecting adding args and input fields changed name (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="355220055" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1492" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1492">#1492</a>)</li> <li><code>formatError</code> API changed for error message extensions. To upgrade without changing existing server responses, wrap <code>graphql</code>'s <code>formatError</code>:</li> </ul> <pre><code>import { formatError as baseFormatError, /* ... */ } from 'graphql'; { // other options formatError(error) { const { extensions, ...rest } = baseFormatError(error); return { ...extensions, ...rest }; }, } </code></pre> <p><strong>New:</strong></p> <ul> <li>Parse new schema extensions (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="315664664" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1314" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1314">#1314</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="317012679" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1323" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1323">#1323</a>)</li> <li>Export SDL AST types (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="315694355" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1315" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1315">#1315</a>)</li> <li><code>extendSchema</code> extended with spec-compliant SDL extensions (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="330426164" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1373" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1373">#1373</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331961053" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1392" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1392">#1392</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="346266873" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1441" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1441">#1441</a>)</li> <li><code>symbol.toStringTag</code> support (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="307864327" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1297" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1297">#1297</a>)</li> <li>Expose <code>getOperationRootType(schema, operationAST)</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="322058451" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1345" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1345">#1345</a>)</li> <li>Package is marked as side-effect free (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="314458450" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1312" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1312">#1312</a>)</li> <li><code>validateSchema</code> works with Schema extensions (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="337240645" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1410" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1410">#1410</a>)</li> <li><code>validate</code> works on SDL definitions (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="345971682" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1438" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1438">#1438</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331081195" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1383" href="https://urls.greenkeeper.io/graphql/graphql-js/issues/1383">#1383</a>)</li> <li>directives can be added to variable definitions, behind <code>experimentalVariableDefinitionDirectives</code> flag (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="345484247" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1437" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1437">#1437</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="348424943" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1454" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1454">#1454</a>)</li> <li>ASTNode predicates, like <code>isDefinitionNode</code> and <code>isTypeSystemDefinitionNode</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="349160476" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1459" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1459">#1459</a>)</li> <li><code>isRequiredArgument</code> and <code>isRequiredInputField</code> predicates (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="349831716" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1463" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1463">#1463</a>)</li> </ul> <p><strong>Fixed:</strong></p> <ul> <li>Fixes for custom enum types</li> <li>Prettier, Flow and eslint upgrades (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="310208412" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1304" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1304">#1304</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="316500173" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1319" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1319">#1319</a>)</li> <li>Babel 7 upgrade (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="323277037" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1350" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1350">#1350</a>)</li> <li>Introspection query perf improved (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="318663971" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1329" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1329">#1329</a>)</li> <li><code>introspectionFromSchema</code> has default options (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="336268824" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1408" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1408">#1408</a>)</li> <li><code>buildSchema</code> memory leaks and infinite recursion fixed (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="341094161" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1417" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1417">#1417</a>, <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="343182956" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1427" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1427">#1427</a>)</li> <li><code>watch</code> command fixed (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="347719430" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1449" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1449">#1449</a>)</li> <li>Benchmarking for <code>validation</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="350893741" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1471" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1471">#1471</a>)</li> </ul> <p><strong>Deprecated:</strong></p> <p>These will be removed in v15</p> <ul> <li><code>introspectionQuery</code>, use <code>getIntrospectionQuery</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331432132" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1386" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1386">#1386</a>)</li> <li><code>getDescription</code>, use the schema AST node to get descriptions (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="333742859" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1396" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1396">#1396</a>)</li> <li><code>isValidJSValue</code>, use <code>coerceValue</code> (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331432132" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1386" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1386">#1386</a>)</li> <li><code>isValidLiteralValue</code>, use validation (<a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="331432132" data-permission-text="Issue title is private" data-url="graphql/graphql-js#1386" href="https://urls.greenkeeper.io/graphql/graphql-js/pull/1386">#1386</a>)</li> </ul> </details> <details> <summary>FAQ and help</summary> There is a collection of [frequently asked questions](https://greenkeeper.io/faq.html). If those don’t help, you can always [ask the humans behind Greenkeeper](https://github.com/greenkeeperio/greenkeeper/issues/new). </details> --- Your [Greenkeeper](https://greenkeeper.io) bot 🌴
Discussed in #1389