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

Merged
merged 4 commits into from Aug 5, 2018

Conversation

Projects
None yet
3 participants
@IvanGoncharov
Collaborator

IvanGoncharov commented Jul 30, 2018

Discussed in #1389

@IvanGoncharov IvanGoncharov added this to the v14.0.0 milestone Jul 30, 2018

@IvanGoncharov IvanGoncharov changed the title from SDL validation to [RFC]SDL validation Jul 30, 2018

@IvanGoncharov

This comment has been minimized.

Show comment
Hide comment
@IvanGoncharov

IvanGoncharov Jul 30, 2018

Collaborator

@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 extendSchema.
I will try to finish it tomorrow.

Collaborator

IvanGoncharov commented Jul 30, 2018

@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 extendSchema.
I will try to finish it tomorrow.

@mjmahone

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,

This comment has been minimized.

@mjmahone

mjmahone Jul 31, 2018

Contributor

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.

@mjmahone

mjmahone Jul 31, 2018

Contributor

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.

This comment has been minimized.

@IvanGoncharov

IvanGoncharov Aug 3, 2018

Collaborator

@mjmahone Good catch 🔎 🐞
Fixed.

@IvanGoncharov

IvanGoncharov Aug 3, 2018

Collaborator

@mjmahone Good catch 🔎 🐞
Fixed.

);
if (!directiveDef) {
const name = node.name.value;
const locations = locationsMap[name];

This comment has been minimized.

@mjmahone

mjmahone Jul 31, 2018

Contributor

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.

@mjmahone

mjmahone Jul 31, 2018

Contributor

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.

This comment has been minimized.

@IvanGoncharov

IvanGoncharov Aug 5, 2018

Collaborator

@mjmahone It's unnecessary complication since you context has getDocument function. So I just removed Document and move this code on the top level.

@IvanGoncharov

IvanGoncharov Aug 5, 2018

Collaborator

@mjmahone It's unnecessary complication since you context has getDocument function. So I just removed Document and move this code on the top level.

Show outdated Hide outdated src/validation/validate.js Outdated
Show outdated Hide outdated src/validation/validate.js Outdated
Show outdated Hide outdated src/validation/ValidationContext.js Outdated
constructor(ast: DocumentNode, schema?: ?GraphQLSchema): void {
super(ast);
this._schema = schema;

This comment has been minimized.

@mjmahone

mjmahone Jul 31, 2018

Contributor

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".

@mjmahone

mjmahone Jul 31, 2018

Contributor

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".

This comment has been minimized.

@IvanGoncharov

IvanGoncharov Aug 5, 2018

Collaborator

@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.

@IvanGoncharov

IvanGoncharov Aug 5, 2018

Collaborator

@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.

This comment has been minimized.

@mjmahone

mjmahone Aug 5, 2018

Contributor

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.

@mjmahone

mjmahone Aug 5, 2018

Contributor

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.

IvanGoncharov added a commit to APIs-guru/graphql-js that referenced this pull request Jul 31, 2018

IvanGoncharov added a commit that referenced this pull request Jul 31, 2018

IvanGoncharov added a commit to APIs-guru/graphql-js that referenced this pull request Jul 31, 2018

IvanGoncharov added a commit that referenced this pull request Jul 31, 2018

IvanGoncharov added a commit to APIs-guru/graphql-js that referenced this pull request Jul 31, 2018

@mjmahone mjmahone referenced this pull request Jul 31, 2018

Closed

Validate SDL directives #1435

IvanGoncharov added a commit that referenced this pull request Aug 1, 2018

Allows to add schema definition missing in the original schema (#1441)
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);
```
@IvanGoncharov

This comment has been minimized.

Show comment
Hide comment
@IvanGoncharov

IvanGoncharov Aug 3, 2018

Collaborator

@mjmahone
Update: rebased on top of current master.

Collaborator

IvanGoncharov commented Aug 3, 2018

@mjmahone
Update: rebased on top of current master.

@@ -112,6 +120,10 @@ export function buildASTSchema(
throw new Error('Must provide a document ast.');
}
if (!options || !(options.assumeValid || options.assumeValidSDL)) {

This comment has been minimized.

@IvanGoncharov

IvanGoncharov Aug 3, 2018

Collaborator

@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 });
@IvanGoncharov

IvanGoncharov Aug 3, 2018

Collaborator

@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 });

This comment has been minimized.

@mjmahone

mjmahone Aug 3, 2018

Contributor

Ok this makes sense. A little bit annoying to add in that second key, but not the end of the world.

@mjmahone

mjmahone Aug 3, 2018

Contributor

Ok this makes sense. A little bit annoying to add in that second key, but not the end of the world.

This comment has been minimized.

@mjmahone

mjmahone Aug 3, 2018

Contributor

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.

@mjmahone

mjmahone Aug 3, 2018

Contributor

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.

This comment has been minimized.

@IvanGoncharov

IvanGoncharov Aug 3, 2018

Collaborator

@mjmahone My proposal:
{} => validateSDL + validateSchema
{ assumeValidSDL: true } => validateSchema
{assumeValid: true } => no checks

@IvanGoncharov

IvanGoncharov Aug 3, 2018

Collaborator

@mjmahone My proposal:
{} => validateSDL + validateSchema
{ assumeValidSDL: true } => validateSchema
{assumeValid: true } => no checks

IvanGoncharov added a commit that referenced this pull request Aug 3, 2018

@IvanGoncharov

This comment has been minimized.

Show comment
Hide comment
@IvanGoncharov

IvanGoncharov Aug 5, 2018

Collaborator

@mjmahone I updated this PR and answered all review comments.
Can you please take a look one more time?

This PR doesn't contain all necessary rules and tests, e.g. it rule that check duplications in extends:

type Query @test;

extend type Query @test;

If this PR is ok I will try to finish all other rules tomorrow as a separate PR.

Collaborator

IvanGoncharov commented Aug 5, 2018

@mjmahone I updated this PR and answered all review comments.
Can you please take a look one more time?

This PR doesn't contain all necessary rules and tests, e.g. it rule that check duplications in extends:

type Query @test;

extend type Query @test;

If this PR is ok I will try to finish all other rules tomorrow as a separate PR.

@mjmahone

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 ||

This comment has been minimized.

@mjmahone

mjmahone Aug 5, 2018

Contributor

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.

@mjmahone

mjmahone Aug 5, 2018

Contributor

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]),

This comment has been minimized.

@mjmahone

mjmahone Aug 5, 2018

Contributor

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),
@mjmahone

mjmahone Aug 5, 2018

Contributor

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),

This comment has been minimized.

@IvanGoncharov

IvanGoncharov Aug 5, 2018

Collaborator

@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 GraphQLErrors anyway. Plus such complex systems almost certainly using GraphQL*Type classes anyway.

@IvanGoncharov

IvanGoncharov Aug 5, 2018

Collaborator

@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 GraphQLErrors anyway. Plus such complex systems almost certainly using GraphQL*Type classes anyway.

Show outdated Hide outdated src/validation/validate.js Outdated
@mjmahone

This comment has been minimized.

Show comment
Hide comment
@mjmahone

mjmahone Aug 5, 2018

Contributor

@IvanGoncharov once we clear up the assertValid functions, I'm ready to get this merged. Everything else looks great!

Contributor

mjmahone commented Aug 5, 2018

@IvanGoncharov once we clear up the assertValid functions, I'm ready to get this merged. Everything else looks great!

IvanGoncharov added some commits Aug 2, 2018

@IvanGoncharov

This comment has been minimized.

Show comment
Hide comment
@IvanGoncharov

IvanGoncharov Aug 5, 2018

Collaborator

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.

@mjmahone graphql-js officially supports only two kinds of imports:

  1. e.g. import { /* ... */ } from 'graphql';
  2. e.g. import { /* ... */ } from 'graphql/language';

See here: https://github.com/graphql/graphql-js/blob/master/src/README.md
Importing from individual files are illegal and all such imports treated as part of private API, e.g. this disscussion: #1221

But I agree it could be confusing so I marked all added exports as @internal.

Collaborator

IvanGoncharov commented Aug 5, 2018

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.

@mjmahone graphql-js officially supports only two kinds of imports:

  1. e.g. import { /* ... */ } from 'graphql';
  2. e.g. import { /* ... */ } from 'graphql/language';

See here: https://github.com/graphql/graphql-js/blob/master/src/README.md
Importing from individual files are illegal and all such imports treated as part of private API, e.g. this disscussion: #1221

But I agree it could be confusing so I marked all added exports as @internal.

@mjmahone

Great! Thanks for going through all this work, @IvanGoncharov! This looks like it's in really good shape now.

@IvanGoncharov IvanGoncharov merged commit 38760a9 into graphql:master Aug 5, 2018

2 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
coverage/coveralls Coverage increased (+0.008%) to 98.762%
Details

@IvanGoncharov IvanGoncharov deleted the APIs-guru:sdlValidation branch Aug 6, 2018

matt-riley added a commit to matt-riley/gql_boilerplate that referenced this pull request Aug 31, 2018

Update graphql to the latest version 🚀 (#22)

## 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 🌴
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment