apollographql / eslint-plugin-graphql

:vertical_traffic_light: Check your GraphQL query strings against a schema.
https://www.npmjs.com/package/eslint-plugin-graphql
1.21k stars 103 forks source link

apollo-link-state #99

Open lifeiscontent opened 6 years ago

lifeiscontent commented 6 years ago

Now that apollo-link-state allows for local resolvers, this plugin throws errors on those local resolvers.

Can we get an update to pass the root resolver or something into the plugin to let eslint know about the extra information of the schema?

adampash commented 6 years ago

Alternately, even as a stop-gap if the plugin ignored fields with the @client directive, that'd be a nice start. (Though obviously supporting those would be nice in the long-run.)

jnwng commented 6 years ago

yea, i think having a client-side schema that can extend the schema provided would be interesting. let me poke around and see what people think about how that would work

in the meantime, @adampash's suggestion to provide an option to strip custom directives seems useful.

loicplaire commented 6 years ago

Does anyone have a work around until https://github.com/apollographql/eslint-plugin-graphql/pull/117 is merged?

loicplaire commented 6 years ago

If anyone else runs into that issue, my workaround until https://github.com/apollographql/eslint-plugin-graphql/pull/117 is merged is to redeclare the client directive in my apollo-link-state typeDefs e.g:

const typeDefs = /* GraphQL */ `
  directive @client on FIELD

  type User {
    isActive: Boolean
  }
`;

Another option is two provide the validators options and not include KnownDirectives.

I hope this helps!

cantino commented 5 years ago

@loicplaire, could you explain a bit more how to use this to prevent eslint-plugin-graphql from validating @client queries?

nether-cat commented 5 years ago

@cantino, as some time has passed and I am struggling with this, too, let me have a guess: What @loicplaire is suggesting, is to also make typeDefs for the client state (which as I know actually only requires defaults and resolvers). In these typeDefs we would redeclare the client directive and then build a combined pseudo-schema from both, the server and the client typeDefs to use with eslint-plugin-graphql. Making such redeclarations also fixed my linting issues I had in the past using custom directives that come with the Neo4j implementations for GraphQL.

donovanhiland commented 5 years ago

In the meantime this seems to work:

gql`
  fragment Example {
    clientField @client ${
      /* eslint-disable-line graphql/template-strings */ ''
    }
  }
`
nether-cat commented 5 years ago

I've also realized that GraphQL type extensions are not supported by the eslint plugin. No matter where I define e.g. extend type Payload { someFlag: Boolean } or even extend type Query { someField: String }, the eslint plugin builds the schema correctly (if I put in some typo, I get corresponding errors) but whereever I use these fields, they are not accepted by the linting rules. (So far I have tried using env: 'apollo' as well as env: 'literal' in my config).

jnwng commented 5 years ago

I've also realized that GraphQL type extensions are not supported by the eslint plugin. No matter where I define e.g. extend type Payload { someFlag: Boolean } or even extend type Query { someField: String }, the eslint plugin builds the schema correctly (if I put in some typo, I get corresponding errors) but whereever I use these fields, they are not accepted by the linting rules. (So far I have tried using env: 'apollo' as well as env: 'literal' in my config).

i dove deep on this and it has to do with the buildSchema function we're using from graphql-js. i think the resolution is likely to use the more extensive schema building functions in graphql-tools, and that sounds like it might be a solution here to extend the schema directives that are available instead of stripping them like #117.

somewhat relevant context, graphql-js doesn't support custom directives right now, which is a large limitation for eslint-plugin-graphql

sampsonjoliver commented 4 years ago

Is this resolved?

lifeiscontent commented 4 years ago

No

MrTibbles commented 4 years ago

To overcome this use the Apollo CLI download schema command to generate the schema file to validate against. When generating the schema pass the --includes argument with a value of the file path to wher your local GQL type defs are, the ones that define the local state. Then also pass the --endpoint argument with a value of the URL for your GQL service:

apollo client:download-schema --includes \"./some/filepath/toLocalTypeDefs.ts\" --endpoint http://somehost/graphql
damirbogd commented 4 years ago

To overcome this use the Apollo CLI download schema command to generate the schema file to validate against. When generating the schema pass the --includes argument with a value of the file path to wher your local GQL type defs are, the ones that define the local state. Then also pass the --endpoint argument with a value of the URL for your GQL service:

apollo client:download-schema --includes \"./some/filepath/toLocalTypeDefs.ts\" --endpoint http://somehost/graphql

@MrTibbles thank you so much, that's worked for me

apollo client:download-schema -c './apollo.config.js' --includes './src/typeDefs.ts' 'graphql/schema.json'

.eslintrc.js config

rules: {
        'graphql/template-strings': [
            'error',
            {
                env: 'literal',
                schemaJson: require('./graphql/schema.json'),
            },
        ],
    },

apollo.config.js

module.exports = {
    client: {
        includes: [
            'src/**/*.gql',
            'src/typeDefs.ts',
            'src/vue-apollo.js',
            'src/**/*.vue',
        ],
        clientSchemaDirectives: ['client'],
        service: {
            name: 'my-service-name',
            localSchemaFile: './graphql/schema.graphql',
        },
    },
}