Skip to content
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

Unknown argument "includeDeprecated" on field "__Directive.args" #2895

Closed
Betree opened this issue Jan 27, 2021 · 5 comments · Fixed by #3273
Closed

Unknown argument "includeDeprecated" on field "__Directive.args" #2895

Betree opened this issue Jan 27, 2021 · 5 comments · Fixed by #3273
Assignees
Labels

Comments

@Betree
Copy link

Betree commented Jan 27, 2021

With the update to 15.5.0, we need to implement our own script to fetch the GraphQL schema (get-graphql-schema that we were using doesn't seem to be maintained anymore).

I'm using the following script to achieve that:

npm run script scripts/update-graphql-schemas.ts http://localhost:3060/graphql/v1
// scripts/update-graphql-schemas.ts

import * as fs from 'fs';
import * as path from 'path';

import { buildClientSchema } from 'graphql/utilities/buildClientSchema';
import { getIntrospectionQuery } from 'graphql/utilities/getIntrospectionQuery';
import { printSchema } from 'graphql/utilities/printSchema';
import fetch from 'node-fetch';

interface Options {
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
  headers?: { [key: string]: string };
  json?: boolean;
}

/**
 *
 * Fetch remote schema and turn it into string
 *
 * @param endpoint
 * @param options
 */
export async function getRemoteSchema(
  endpoint: string,
  options: Options,
): Promise<{ status: 'ok'; schema: string } | { status: 'err'; message: string }> {
  try {
    const introspectionQuery = getIntrospectionQuery({ inputValueDeprecation: true });
    const { data, errors } = await fetch(endpoint, {
      method: options.method,
      headers: options.headers,
      body: JSON.stringify({ query: introspectionQuery }),
    }).then(res => res.json());

    if (errors) {
      return { status: 'err', message: JSON.stringify(errors, null, 2) };
    }

    if (options.json) {
      return {
        status: 'ok',
        schema: JSON.stringify(data, null, 2),
      };
    } else {
      const schema = buildClientSchema(data);
      return {
        status: 'ok',
        schema: printSchema(schema),
      };
    }
  } catch (err) {
    return { status: 'err', message: err.message };
  }
}

/**
 *
 * Prints schema to file.
 *
 * @param dist
 * @param schema
 */
export function printToFile(
  dist: string,
  schema: string,
): { status: 'ok'; path: string } | { status: 'err'; message: string } {
  try {
    const output = path.resolve(process.cwd(), dist);

    if (!fs.existsSync(output)) {
      console.error(`${output} does not exists`);
      process.exit(1);
    }
    fs.writeFileSync(output, schema);

    return { status: 'ok', path: output };
  } catch (err) {
    return { status: 'err', message: err.message };
  }
}

export async function main(endpoint): Promise<void> {
  /* Headers */
  const defaultHeaders = {
    'Content-Type': 'application/json',
  };

  /* Fetch schema */
  const schema = await getRemoteSchema(endpoint, {
    method: 'POST',
    headers: defaultHeaders,
    json: false,
  });

  if (schema.status === 'err') {
    console.error(schema.message);
  } else {
    console.log(schema.schema);
  }
}

main(process.argv[2]);

This script works fine without inputValueDeprecation: true passed to getIntrospectionQuery, but whenever I try to add this option the script fails with the following message:

[
  {
    "message": "Unknown argument \"includeDeprecated\" on field \"__Directive.args\".",
    "locations": [
      {
        "line": 16,
        "column": 16
      }
    ],
    "extensions": {
      "code": "GRAPHQL_VALIDATION_FAILED",
      "exception": {
        "stacktrace": [
          "GraphQLError: Unknown argument \"includeDeprecated\" on field \"__Directive.args\".",
          "    at Object.Argument (/home/user/Workspace/Projects/opencollective/opencollective-api/node_modules/graphql/validation/rules/KnownArgumentNamesRule.js:46:29)",
          "    at Object.enter (/home/user/Workspace/Projects/opencollective/opencollective-api/node_modules/graphql/language/visitor.js:323:29)",
          "    at Object.enter (/home/user/Workspace/Projects/opencollective/opencollective-api/node_modules/graphql/utilities/TypeInfo.js:370:25)",
          "    at visit (/home/user/Workspace/Projects/opencollective/opencollective-api/node_modules/graphql/language/visitor.js:243:26)",
          "    at Object.validate (/home/user/Workspace/Projects/opencollective/opencollective-api/node_modules/graphql/validation/validate.js:69:24)",
          "    at validate (/home/user/Workspace/Projects/opencollective/opencollective-api/node_modules/apollo-server-core/src/requestPipeline.ts:510:14)",
          "    at Object.<anonymous> (/home/user/Workspace/Projects/opencollective/opencollective-api/node_modules/apollo-server-core/src/requestPipeline.ts:296:32)",
          "    at Generator.next (<anonymous>)",
          "    at fulfilled (/home/user/Workspace/Projects/opencollective/opencollective-api/node_modules/apollo-server-core/dist/requestPipeline.js:5:58)",
          "    at processTicksAndRejections (internal/process/task_queues.js:93:5)"
        ]
      }
    }
  }
]

Context

Followup on #2834

@IvanGoncharov
Copy link
Member

@Betree What version of graphql-js do you use on your backend?

@Betree
Copy link
Author

Betree commented Jan 31, 2021

@Betree What version of graphql-js do you use on your backend?

It's the 15.5.0, the script above was implemented directly in the backend project

@Betree
Copy link
Author

Betree commented Feb 4, 2021

Running the query below on the API with graphql-js 15.5.0 works properly, so it does not seems to be a mismatch between versions:

{
  __schema {
    types {
      name
      fields(includeDeprecated: true) {
        isDeprecated
      }
    }
  }
}

@MichalLytek
Copy link

MichalLytek commented Feb 28, 2021

@IvanGoncharov I can confirm this bug on v15.5.0, as soon when I enable inputValueDeprecation: true in getIntrospectionQuery.

GraphQLError: Unknown argument "includeDeprecated" on field "__Directive.args".

Looks like that function generates that (includeDeprecated: true) on a wrong node.

@IvanGoncharov IvanGoncharov self-assigned this Mar 31, 2021
davidgovea added a commit to davidgovea/graphql-js that referenced this issue Apr 21, 2021
davidgovea added a commit to davidgovea/graphql-js that referenced this issue Apr 21, 2021
@davidgovea
Copy link

davidgovea commented Apr 27, 2021

Added a PR #3046 with a test that reproduces this issue.
Also attempted a fix, but I don't think I used the correct approach (removed includeDeprecated from __schema->directives->args). I am new to the GraphQL spec, so I need to dig in more.

Could #3048 be related as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants