Apollo-tooling: apollo client:codegen does not work with apollo client 2.5.0 local state

Created on 31 Jan 2019  ·  10Comments  ·  Source: apollographql/apollo-tooling

I'm using apollo-client 2.5.0, apollo 2.4.0 and I'm not able to generate typescript definitions for my local queries.

My Apollo Client init code:

const httpLink = new HttpLink({
  uri: 'http://localhost:3000/api/graphql',
  credentials: 'same-origin',
});

// Create a WebSocket link:
const wsLink = new WebSocketLink({
  uri: `ws://localhost:3000/api/subscriptions`,
  options: {
    reconnect: true,
    connectionParams: {
      authToken: getCookie('user'),
    }
  }
});

// using the ability to split links, you can send data to each link
// depending on what kind of operation is being sent
const link = split(
  // split based on operation type
  ({ query }) => {
    const { kind, operation } = getMainDefinition(query);
    return kind === 'OperationDefinition' && operation === 'subscription';
  },
  wsLink,
  httpLink,
);

const client = new ApolloClient(
  {
    link: ApolloLink.from(
      [
    onError(({ graphQLErrors, networkError }) => {
      if (graphQLErrors)
        graphQLErrors.map(({ message, locations, path }) =>
          console.log(
            `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
          ),
        );
      if (networkError) console.log(`[Network error]: ${networkError}`);
    }),
        link]),

    cache: new InMemoryCache(
      {

          dataIdFromObject: object => {
            // @ts-ignore
            if (object.uuid)
            {
              // @ts-ignore
              return `${object.__typename}:${object.uuid}`
            }
            else if (object.__typename === 'Interface')
            {
              return null; //Interfaces do not have unique ID's, we'd rather link them with their VMs
            }
            else {
              return defaultDataIdFromObject(object);
            }
          }
      }
    ),
    typeDefs : gql`
      type Mutation {
        selectVmTableItem(id: ID!): [ID!]
        deselectVmTableItem(id: ID!): [ID!]
      }
      type Query {
        vmTableSelection: [ID!]
      }
    `,
    resolvers: {
      Mutation: {
        selectVmTableItem: (_root, variables, context) => {
          const query = gql`
            query GetVmTableSelection {
              vmTableSelection @client
            }
          `;
          const previous = context.cache.readQuery({query});
          const data = [...previous, variables.id];
          context.cache.writeQuery({query, data});
          return data;
        }
      },
    }
  }
);

client.cache.writeData({
  data: {
    vmTableSelection : []
  }
});

Request in apollo-dev-tools:
image

Syntax error is due to Apollo Dev tools not knowing about @client but it works.

But apollo client:codegen fails:

apollo client:codegen __generated --target typescript --queries=app/app.tsx                                                                      ST 1   typescript-graphql 
  ⠼ Loading Apollo Project
    Generating query files
.../vmemperor/frontend/app/app.tsx: Cannot query field "vmTableSelection" on type "QueryRoot".
{ ToolError: Validation of GraphQL query document failed
    at Object.validateQueryDocument (/usr/lib/node_modules/apollo/node_modules/apollo-language-server/lib/errors/validation.js:32:19)
    at Object.generate [as default] (/usr/lib/node_modules/apollo/lib/generate.js:19:18)
    at write (/usr/lib/node_modules/apollo/lib/commands/client/codegen.js:64:54)
    at Task.task (/usr/lib/node_modules/apollo/lib/commands/client/codegen.js:83:46)
  ✔ Loading Apollo Project
  ✖ Generating query files with 'typescript' target
    → Validation of GraphQL query document failed
.../vmemperor/frontend/app/app.tsx: Cannot query field "vmTableSelection" on type "QueryRoot".
{ ToolError: Validation of GraphQL query document failed
    at Object.validateQueryDocument (/usr/lib/node_modules/apollo/node_modules/apollo-language-server/lib/errors/validation.js:32:19)
    at Object.generate [as default] (/usr/lib/node_modules/apollo/lib/generate.js:19:18)
    at write (/usr/lib/node_modules/apollo/lib/commands/client/codegen.js:64:54)
    at GraphQLClientProject.project.onDiagnostics [as _onDiagnostics] (/usr/lib/node_modules/apollo/lib/commands/client/codegen.js:81:29)
    at GraphQLClientProject.validate (/usr/lib/node_modules/apollo/node_modules/apollo-language-server/lib/project/client.js:122:18)
    at GraphQLClientProject.validateIfNeeded (/usr/lib/node_modules/apollo/node_modules/apollo-language-server/lib/project/base.js:131:14)
    at Timeout.setTimeout [as _onTimeout] (/usr/lib/node_modules/apollo/node_modules/apollo-language-server/lib/project/base.js:123:22)
    at ontimeout (timers.js:498:11)
    at tryOnTimeout (timers.js:323:5)
    at Timer.listOnTimeout (timers.js:290:5) name: 'ToolError' }
ToolError: Validation of GraphQL query document failed
    at Object.validateQueryDocument (/usr/lib/node_modules/apollo/node_modules/apollo-language-server/lib/errors/validation.js:32:19)
    at Object.generate [as default] (/usr/lib/node_modules/apollo/lib/generate.js:19:18)
    at write (/usr/lib/node_modules/apollo/lib/commands/client/codegen.js:64:54)
    at Task.task (/usr/lib/node_modules/apollo/lib/commands/client/codegen.js:83:46)
    at <anonymous>
(node:20140) UnhandledPromiseRejectionWarning: ToolError: Validation of GraphQL query document failed
    at Object.validateQueryDocument (/usr/lib/node_modules/apollo/node_modules/apollo-language-server/lib/errors/validation.js:32:19)
    at Object.generate [as default] (/usr/lib/node_modules/apollo/lib/generate.js:19:18)
    at write (/usr/lib/node_modules/apollo/lib/commands/client/codegen.js:64:54)
    at GraphQLClientProject.project.onDiagnostics [as _onDiagnostics] (/usr/lib/node_modules/apollo/lib/commands/client/codegen.js:81:29)
    at GraphQLClientProject.validate (/usr/lib/node_modules/apollo/node_modules/apollo-language-server/lib/project/client.js:122:18)
    at GraphQLClientProject.validateIfNeeded (/usr/lib/node_modules/apollo/node_modules/apollo-language-server/lib/project/base.js:131:14)
    at Timeout.setTimeout [as _onTimeout] (/usr/lib/node_modules/apollo/node_modules/apollo-language-server/lib/project/base.js:123:22)
    at ontimeout (timers.js:498:11)
    at tryOnTimeout (timers.js:323:5)
    at Timer.listOnTimeout (timers.js:290:5)
(node:20140) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 5)
(node:20140) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Most helpful comment

Thanks for taking the time to submit an issue @pashazz!

My initial thought is this. When codegen runs, it merges together your local schema _and_ your service's schema. What this means is, if you have type Query in both places, the resulting merged schema won't validate due to collision.

I just tested codegen against our fullstack tutorial and it works - I suspect due to the fact that we're _extending_ the root level types at the local schema. See here for the example I'm referring to:
https://github.com/apollographql/fullstack-tutorial/blob/master/final/client/src/resolvers.js#L4

Hope this solves your issue, but please let me know either way! ❤️

All 10 comments

Thanks for taking the time to submit an issue @pashazz!

My initial thought is this. When codegen runs, it merges together your local schema _and_ your service's schema. What this means is, if you have type Query in both places, the resulting merged schema won't validate due to collision.

I just tested codegen against our fullstack tutorial and it works - I suspect due to the fact that we're _extending_ the root level types at the local schema. See here for the example I'm referring to:
https://github.com/apollographql/fullstack-tutorial/blob/master/final/client/src/resolvers.js#L4

Hope this solves your issue, but please let me know either way! ❤️

Thank you for your response, it works!

Awesome, glad to hear it! Thanks for letting me know.

I'm having the same issue as this, though I _am_ using extend not re-declaring! 😖

Though the code itself all works fine, the TypeScript codegen goes nuts.

There's no known issues at the moment is there @trevor-scheer?

Error output:

yarn run v1.17.3
$ apollo client:codegen --target=typescript --watch
  ✔ Loading Apollo Project
  ✖ Generating query files with 'typescript' target
    → Cannot query field "alerts" on type "Query"
Press any key to stop.
(node:17999) UnhandledPromiseRejectionWarning: GraphQLError: Cannot query field "alerts" on type "Query"
    at Compiler.compileSelection (/Users/simon/Git/btg/client/node_modules/apollo-codegen-core/lib/compiler/index.js:119:27)
    at /Users/simon/Git/btg/client/node_modules/apollo-codegen-core/lib/compiler/index.js:106:76
    at Array.map (<anonymous>)
    at Compiler.compileSelectionSet (/Users/simon/Git/btg/client/node_modules/apollo-codegen-core/lib/compiler/index.js:106:18)
    at Compiler.compileOperation (/Users/simon/Git/btg/client/node_modules/apollo-codegen-core/lib/compiler/index.js:86:32)
    at Object.compileToIR (/Users/simon/Git/btg/client/node_modules/apollo-codegen-core/lib/compiler/index.js:15:44)
    at Object.generate [as default] (/Users/simon/Git/btg/client/node_modules/apollo/lib/generate.js:79:36)
    at write (/Users/simon/Git/btg/client/node_modules/apollo/lib/commands/client/codegen.js:67:54)
    at GraphQLClientProject._onDiagnostics (/Users/simon/Git/btg/client/node_modules/apollo/lib/commands/client/codegen.js:85:29)
    at GraphQLClientProject.validate (/Users/simon/Git/btg/client/node_modules/apollo-language-server/lib/project/client.js:186:18)
(node:17999) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:17999) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

client-schema.tsx

import gql from 'graphql-tag'
import { InMemoryCache } from 'apollo-cache-inmemory'

const typeDefs = gql`
  extend type Query {
    alerts: [Alert!]!
  }

  type Alert {
    level: AlertLevel!
    message: String!
  }

  enum AlertLevel {
    PRIMARY
    SECONDARY
    SUCCESS
    DANGER
    WARNING
    INFO
    LIGHT
    DARK
  }
`

const resolvers = {}

const cache = new InMemoryCache({
  freezeResults: true,
})

// Initialise the cache with default values
cache.writeData({
  data: {
    alerts: [
      { __typename: 'Alert', level: 'DANGER', message: 'THIS IS A TEST' },
    ],
  },
})

export { typeDefs, resolvers, cache }

Alerts.tsx

import * as React from 'react'
import gql from 'graphql-tag'
import { useQuery } from '@apollo/react-hooks'
import { GetAlertsToDisplay } from './__generated__/GetAlertsToDisplay'

const GET_ALERTS = gql`
  query GetAlertsToDisplay {
    alerts @client {
      level
      message
    }
  }
`

const Alerts: React.FC = () => {
  const { data } = useQuery<GetAlertsToDisplay>(GET_ALERTS)
  if (!data) return null

  return (
    <>
      {data.alerts.map((alert, index) => {
        return (
          <div
            key={index}
            className={`alert alert-${alert.level.toLowerCase()} alert-dismissible`}
          >
            {alert.message}
            <button type="button" className="close" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
        )
      })}
    </>
  )
}

export { Alerts }

@Siyfion this actually appears to be the same error I encountered when creating a reproduction for Ivan from the graphql-js project.
For reference: https://github.com/trevor-scheer/graphql-instanceof-reproduction

The root of the problem is how we have our graphql dependencies set up within the CLI and language server. If the project requires a graphql version that _doesn't fit the requirement of the CLI_, then we end up with multiple instances of graphql-js (and instanceof checks fail).

For now, a viable workaround is to make sure your project's version of graphql fits that of apollo's. You may need a fresh package-lock and install afterwards.

Hope this helps Simon, let me know if it doesn't and if you have any other questions!

cc @JakeDawkins - we have a couple things to experiment with in order to resolve this issue for good.

@trevor-scheer Ok, so I checked my package.json and it had the following:

Screenshot 2019-09-02 at 08 55 48

But, in the yarn.lock file I noticed that the graphql version being used was 14.5.3 in places. So I tried adding the following to my package.json:

"resolutions": {
  "graphql": "14.3.1"
},

Deleted my node_modules folder and re-installed... But unfortunately I still get the same issue:

yarn run v1.17.3
$ apollo client:codegen --target=typescript --watch
  ✔ Loading Apollo Project
  ✖ Generating query files with 'typescript' target
    → Cannot query field "alerts" on type "Query"
Press any key to stop.
(node:81198) UnhandledPromiseRejectionWarning: GraphQLError: Cannot query field "alerts" on type "Query"
    at Compiler.compileSelection (/Users/simon/Git/btg/client/node_modules/apollo-codegen-core/lib/compiler/index.js:119:27)
    at /Users/simon/Git/btg/client/node_modules/apollo-codegen-core/lib/compiler/index.js:106:76
    at Array.map (<anonymous>)
    at Compiler.compileSelectionSet (/Users/simon/Git/btg/client/node_modules/apollo-codegen-core/lib/compiler/index.js:106:18)
    at Compiler.compileOperation (/Users/simon/Git/btg/client/node_modules/apollo-codegen-core/lib/compiler/index.js:86:32)
    at Object.compileToIR (/Users/simon/Git/btg/client/node_modules/apollo-codegen-core/lib/compiler/index.js:15:44)
    at Object.generate [as default] (/Users/simon/Git/btg/client/node_modules/apollo/lib/generate.js:79:36)
    at write (/Users/simon/Git/btg/client/node_modules/apollo/lib/commands/client/codegen.js:67:54)
    at GraphQLClientProject._onDiagnostics (/Users/simon/Git/btg/client/node_modules/apollo/lib/commands/client/codegen.js:85:29)
    at GraphQLClientProject.validate (/Users/simon/Git/btg/client/node_modules/apollo-language-server/lib/project/client.js:186:18)
(node:81198) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:81198) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Are you sure this is a graphql version miss-match issue? It's true that I can't see anything wrong with the code and it works fine. Only the codeine fails, so it would make sense, but I thought the above would correct that issue?

Wow. So this was a pain in the royal *.

So this is the output I got from the command chain I was using initially, and then the output of specific versions afterwards!

TLDR; 2.18.0 doesn't work. 2.13.1 _does_ work. 2.16.1 _does_ work.

npx apollo --version
apollo/2.18.0 darwin-x64 node-v12.8.0
 ~/Git/btg/client   feature/TTU-163-Authentication-Confirmation ●  npx [email protected] client:codegen --target=typescript
 ›   Warning: apollo update available from 2.13.1 to 2.16.3.
  ✔ Loading Apollo Project
  ✔ Generating query files with 'typescript' target - wrote 3 files
 ~/Git/btg/client   feature/TTU-163-Authentication-Confirmation ●  npx [email protected] client:codegen --target=typescript
  ✔ Loading Apollo Project
  ✔ Generating query files with 'typescript' target - wrote 3 files

Also 2.17.1 works fine, so I think there has been a major regression in 2.18.0 @trevor-scheer

Ok, this is making me go nuts... If I change my codgen script to:

"codegen": "npx [email protected] client:codegen --target=typescript --globalTypesFile=./src/__generated__/globalTypes.ts"

Then it works!? However:

"npx apollo client:codegen --target=typescript --globalTypesFile=./src/__generated__/globalTypes.ts"

Fails with the error above. But you can see that the version it's running (shown in the last code snippet, is 2.18.0). What the hell is going on :/

UPDATE: So it turns out it basically works fine if I use an npx version that it _doesn't_ have locally in the project, which causes it to download all dependencies for the versions it requires. As soon as I add apollo as a dependency in my own project and then use that in the script, it fails.

2.25.0 but there is still a big problem with the generator. Does anyone know how to solve this problem? it's not working even if I use a different npx version (

Was this page helpful?
0 / 5 - 0 ratings