0no-co / gql.tada

🪄 Magical GraphQL query engine for TypeScript
https://gql-tada.0no.co
MIT License
2.52k stars 41 forks source link

Support query fails to cover `includeDeprecated` arg #189

Closed hpohlmeyer closed 4 months ago

hpohlmeyer commented 4 months ago

Describe the bug

When generating a schema via the CLI, I get the error:

Something went wrong while trying to load the schema. CombinedError: [GraphQL] Field 'args' doesn't accept argument 'includeDeprecated'

I did a little bug-hunting and was on a similar route to #142. The support query is supposed to ensure that the introspection query does not use properties that are not supported by the schema. Unfortunately the support query does not cover this case.


Bug cause

I have recreated the IntrospectSupportQuery and tried it against my endpoint (provided by DatoCMS).

IntrospectSupportQuery ```gql query IntrospectSupportQuery { directive: __type(name: "__Field") { fields { name } } type: __type(name: "__Type") { fields { name } } inputValue: __type(name: "__InputValue") { fields { name } } } ```
IntrospectionSupportQuery Results ```json { "data": { "directive": { "fields": [ { "name": "args" }, { "name": "deprecationReason" }, { "name": "description" }, { "name": "isDeprecated" }, { "name": "name" }, { "name": "type" } ] }, "type": { "fields": [ { "name": "description" }, { "name": "enumValues" }, { "name": "fields" }, { "name": "inputFields" }, { "name": "interfaces" }, { "name": "kind" }, { "name": "name" }, { "name": "ofType" }, { "name": "possibleTypes" } ] }, "inputValue": { "fields": [ { "name": "defaultValue" }, { "name": "deprecationReason" }, { "name": "description" }, { "name": "isDeprecated" }, { "name": "name" }, { "name": "type" } ] } } } ```

As you can see it includes inputValue.fields.isDeprecated, which means inputValueDeprecation is marked as supported.

In the IntrospectionQuery, the args field is using the includeDeprecated argument, when inputValueDeprecation is marked as supported., which causes my schema generation to fail.

I am not very familiar with the GraphQL spec, so I don’t know if that is an error in the implementation of the spec, or a shortcoming of the IntrospectionSupportQuery. If the spec is implemented incorrectly, would it be possible to have a way to manually overwrite the results of the support query?

Reproduction

No response

gql.tada version

gql.tada v1.4.3

Validations

JoviDeCroock commented 4 months ago

When you run the following query, what __typename are you getting for your args?

query IntrospectSupportQuery {
  __schema {
    types {
      fields {
        name
        args {
          name
          __typename
          ## isDeprecated ## you can uncomment this to try if the field itself is supported
        }
      }
    }
  }
}

And when you run

query IntrospectSupportQuery {
  __schema {
    directives {
      name
      locations
    }
  }
}

What does deprecated give you here for locations?

hpohlmeyer commented 4 months ago

When you run the following query, what __typename are you getting for your args?

I am getting __InputValue for the args. The isDeprecated property seems to be supported.

First query result ```json { "data": { "__schema": { "types": [ { "fields": null }, { "fields": null }, { "fields": null }, { "fields": [ { "name": "count", "args": [] } ] }, { "fields": null }, { "fields": [ { "name": "alpha", "args": [] }, { "name": "blue", "args": [] }, { "name": "cssRgb", "args": [] }, { "name": "green", "args": [] }, { "name": "hex", "args": [] }, { "name": "red", "args": [] } ] }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": [ { "name": "_createdAt", "args": [] }, { "name": "_editingUrl", "args": [] }, { "name": "_updatedAt", "args": [] }, { "name": "alt", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "author", "args": [] }, { "name": "basename", "args": [] }, { "name": "blurUpThumb", "args": [ { "name": "punch", "__typename": "__InputValue", "isDeprecated": false }, { "name": "size", "__typename": "__InputValue", "isDeprecated": false }, { "name": "quality", "__typename": "__InputValue", "isDeprecated": false }, { "name": "imgixParams", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "blurhash", "args": [] }, { "name": "colors", "args": [] }, { "name": "copyright", "args": [] }, { "name": "customData", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "exifInfo", "args": [] }, { "name": "filename", "args": [] }, { "name": "focalPoint", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "format", "args": [] }, { "name": "height", "args": [] }, { "name": "id", "args": [] }, { "name": "md5", "args": [] }, { "name": "mimeType", "args": [] }, { "name": "notes", "args": [] }, { "name": "responsiveImage", "args": [ { "name": "imgixParams", "__typename": "__InputValue", "isDeprecated": false }, { "name": "sizes", "__typename": "__InputValue", "isDeprecated": false }, { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "size", "args": [] }, { "name": "smartTags", "args": [] }, { "name": "tags", "args": [] }, { "name": "thumbhash", "args": [] }, { "name": "title", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "url", "args": [ { "name": "imgixParams", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "video", "args": [] }, { "name": "width", "args": [] } ] }, { "fields": [ { "name": "_createdAt", "args": [] }, { "name": "_editingUrl", "args": [] }, { "name": "_updatedAt", "args": [] }, { "name": "alt", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "author", "args": [] }, { "name": "basename", "args": [] }, { "name": "blurUpThumb", "args": [ { "name": "punch", "__typename": "__InputValue", "isDeprecated": false }, { "name": "size", "__typename": "__InputValue", "isDeprecated": false }, { "name": "quality", "__typename": "__InputValue", "isDeprecated": false }, { "name": "imgixParams", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "blurhash", "args": [] }, { "name": "colors", "args": [] }, { "name": "copyright", "args": [] }, { "name": "customData", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "exifInfo", "args": [] }, { "name": "filename", "args": [] }, { "name": "focalPoint", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "format", "args": [] }, { "name": "height", "args": [] }, { "name": "id", "args": [] }, { "name": "md5", "args": [] }, { "name": "mimeType", "args": [] }, { "name": "notes", "args": [] }, { "name": "responsiveImage", "args": [ { "name": "imgixParams", "__typename": "__InputValue", "isDeprecated": false }, { "name": "sizes", "__typename": "__InputValue", "isDeprecated": false }, { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "size", "args": [] }, { "name": "smartTags", "args": [] }, { "name": "tags", "args": [] }, { "name": "thumbhash", "args": [] }, { "name": "title", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "url", "args": [ { "name": "imgixParams", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "video", "args": [] }, { "name": "width", "args": [] } ] }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": [ { "name": "facebookPageUrl", "args": [] }, { "name": "fallbackSeo", "args": [] }, { "name": "siteName", "args": [] }, { "name": "titleSuffix", "args": [] }, { "name": "twitterAccount", "args": [] } ] }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": [ { "name": "_createdAt", "args": [] }, { "name": "_editingUrl", "args": [] }, { "name": "_firstPublishedAt", "args": [] }, { "name": "_isValid", "args": [] }, { "name": "_modelApiKey", "args": [] }, { "name": "_publicationScheduledAt", "args": [] }, { "name": "_publishedAt", "args": [] }, { "name": "_seoMetaTags", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "_status", "args": [] }, { "name": "_unpublishingScheduledAt", "args": [] }, { "name": "_updatedAt", "args": [] }, { "name": "attendanceOptions", "args": [] }, { "name": "end", "args": [] }, { "name": "id", "args": [] }, { "name": "price", "args": [] }, { "name": "slug", "args": [] }, { "name": "start", "args": [] }, { "name": "title", "args": [] } ] }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": [ { "name": "_allMasterclassesMeta", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "filter", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "_allUploadsMeta", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "filter", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "_site", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "allMasterclasses", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false }, { "name": "skip", "__typename": "__InputValue", "isDeprecated": false }, { "name": "first", "__typename": "__InputValue", "isDeprecated": false }, { "name": "filter", "__typename": "__InputValue", "isDeprecated": false }, { "name": "orderBy", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "allUploads", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false }, { "name": "skip", "__typename": "__InputValue", "isDeprecated": false }, { "name": "first", "__typename": "__InputValue", "isDeprecated": false }, { "name": "filter", "__typename": "__InputValue", "isDeprecated": false }, { "name": "orderBy", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "masterclass", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false }, { "name": "filter", "__typename": "__InputValue", "isDeprecated": false }, { "name": "orderBy", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "upload", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false }, { "name": "filter", "__typename": "__InputValue", "isDeprecated": false }, { "name": "orderBy", "__typename": "__InputValue", "isDeprecated": false } ] } ] }, { "fields": [ { "name": "_createdAt", "args": [] }, { "name": "_editingUrl", "args": [] }, { "name": "_firstPublishedAt", "args": [] }, { "name": "_isValid", "args": [] }, { "name": "_modelApiKey", "args": [] }, { "name": "_publicationScheduledAt", "args": [] }, { "name": "_publishedAt", "args": [] }, { "name": "_seoMetaTags", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "_status", "args": [] }, { "name": "_unpublishingScheduledAt", "args": [] }, { "name": "_updatedAt", "args": [] }, { "name": "id", "args": [] } ] }, { "fields": null }, { "fields": null }, { "fields": [ { "name": "alt", "args": [] }, { "name": "aspectRatio", "args": [] }, { "name": "base64", "args": [] }, { "name": "bgColor", "args": [] }, { "name": "height", "args": [] }, { "name": "sizes", "args": [] }, { "name": "src", "args": [] }, { "name": "srcSet", "args": [] }, { "name": "title", "args": [] }, { "name": "webpSrcSet", "args": [] }, { "name": "width", "args": [] } ] }, { "fields": [ { "name": "description", "args": [] }, { "name": "image", "args": [] }, { "name": "noIndex", "args": [] }, { "name": "title", "args": [] }, { "name": "twitterCard", "args": [] } ] }, { "fields": [ { "name": "favicon", "args": [] }, { "name": "faviconMetaTags", "args": [ { "name": "variants", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "globalSeo", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "locales", "args": [] }, { "name": "noIndex", "args": [] } ] }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": [ { "name": "attributes", "args": [] }, { "name": "content", "args": [] }, { "name": "tag", "args": [] } ] }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": null }, { "fields": [ { "name": "alt", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "blurUpThumb", "args": [ { "name": "punch", "__typename": "__InputValue", "isDeprecated": false }, { "name": "size", "__typename": "__InputValue", "isDeprecated": false }, { "name": "quality", "__typename": "__InputValue", "isDeprecated": false }, { "name": "imgixParams", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "blurhash", "args": [] }, { "name": "duration", "args": [] }, { "name": "framerate", "args": [] }, { "name": "height", "args": [] }, { "name": "mp4Url", "args": [ { "name": "res", "__typename": "__InputValue", "isDeprecated": false }, { "name": "exactRes", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "muxAssetId", "args": [] }, { "name": "muxPlaybackId", "args": [] }, { "name": "streamingUrl", "args": [] }, { "name": "thumbhash", "args": [] }, { "name": "thumbnailUrl", "args": [ { "name": "format", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "title", "args": [ { "name": "locale", "__typename": "__InputValue", "isDeprecated": false }, { "name": "fallbackLocales", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "width", "args": [] } ] }, { "fields": null }, { "fields": null }, { "fields": [ { "name": "args", "args": [] }, { "name": "description", "args": [] }, { "name": "locations", "args": [] }, { "name": "name", "args": [] } ] }, { "fields": null }, { "fields": [ { "name": "deprecationReason", "args": [] }, { "name": "description", "args": [] }, { "name": "isDeprecated", "args": [] }, { "name": "name", "args": [] } ] }, { "fields": [ { "name": "args", "args": [ { "name": "includeDeprecated", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "deprecationReason", "args": [] }, { "name": "description", "args": [] }, { "name": "isDeprecated", "args": [] }, { "name": "name", "args": [] }, { "name": "type", "args": [] } ] }, { "fields": [ { "name": "defaultValue", "args": [] }, { "name": "deprecationReason", "args": [] }, { "name": "description", "args": [] }, { "name": "isDeprecated", "args": [] }, { "name": "name", "args": [] }, { "name": "type", "args": [] } ] }, { "fields": [ { "name": "directives", "args": [] }, { "name": "mutationType", "args": [] }, { "name": "queryType", "args": [] }, { "name": "subscriptionType", "args": [] }, { "name": "types", "args": [] } ] }, { "fields": [ { "name": "description", "args": [] }, { "name": "enumValues", "args": [ { "name": "includeDeprecated", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "fields", "args": [ { "name": "includeDeprecated", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "inputFields", "args": [ { "name": "includeDeprecated", "__typename": "__InputValue", "isDeprecated": false } ] }, { "name": "interfaces", "args": [] }, { "name": "kind", "args": [] }, { "name": "name", "args": [] }, { "name": "ofType", "args": [] }, { "name": "possibleTypes", "args": [] } ] }, { "fields": null }, { "fields": [ { "name": "x", "args": [] }, { "name": "y", "args": [] } ] } ] } } } ```

What does deprecated give you here for locations?

Second query result ```json { "data": { "__schema": { "directives": [ { "name": "include", "locations": [ "FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT" ] }, { "name": "skip", "locations": [ "FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT" ] }, { "name": "deprecated", "locations": [ "FIELD_DEFINITION", "ENUM_VALUE", "ARGUMENT_DEFINITION", "INPUT_FIELD_DEFINITION" ] } ] } } } ```
JoviDeCroock commented 4 months ago

That's really weird, they have the right type and support deprecationReason on args but don't support the includeDeprecated argument.

EDIT: wait... it is present

 "fields": [
            {
              "name": "args",
              "args": [
                {
                  "name": "includeDeprecated",
                  "__typename": "__InputValue",
                  "isDeprecated": false
                }
              ]
            },