diff --git a/src/index.js b/src/index.js index efc1bbb3de..301ac1486e 100644 --- a/src/index.js +++ b/src/index.js @@ -309,6 +309,8 @@ export { introspectionQuery, // Gets the target Operation from a Document getOperationAST, + // Convert a GraphQLSchema to an IntrospectionQuery + introspectionFromSchema, // Build a GraphQLSchema from an introspection result. buildClientSchema, // Build a GraphQLSchema from a parsed GraphQL Schema language AST. diff --git a/src/utilities/__tests__/introspectionFromSchema-test.js b/src/utilities/__tests__/introspectionFromSchema-test.js new file mode 100644 index 0000000000..ed93627606 --- /dev/null +++ b/src/utilities/__tests__/introspectionFromSchema-test.js @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { describe, it } from 'mocha'; +import { expect } from 'chai'; + +import dedent from '../../jsutils/dedent'; +import { GraphQLSchema, GraphQLObjectType, GraphQLString } from '../../type'; +import { printSchema } from '../schemaPrinter'; +import { buildClientSchema } from '../buildClientSchema'; +import { introspectionFromSchema } from '../introspectionFromSchema'; + +function introspectionToSDL(introspection) { + return printSchema(buildClientSchema(introspection)); +} + +describe('introspectionFromSchema', () => { + const schema = new GraphQLSchema({ + query: new GraphQLObjectType({ + name: 'Simple', + description: 'This is a simple type', + fields: { + string: { + type: GraphQLString, + description: 'This is a string field', + }, + }, + }), + }); + + it('converts a simple schema', () => { + const introspection = introspectionFromSchema(schema); + + expect(introspectionToSDL(introspection)).to.deep.equal(dedent` + schema { + query: Simple + } + + """This is a simple type""" + type Simple { + """This is a string field""" + string: String + } + `); + }); + + it('converts a simple schema without descriptions', () => { + const introspection = introspectionFromSchema(schema, { + descriptions: false, + }); + + expect(introspectionToSDL(introspection)).to.deep.equal(dedent` + schema { + query: Simple + } + + type Simple { + string: String + } + `); + }); +}); diff --git a/src/utilities/index.js b/src/utilities/index.js index 0d345c2750..90d0795fe4 100644 --- a/src/utilities/index.js +++ b/src/utilities/index.js @@ -41,6 +41,9 @@ export type { // Gets the target Operation from a Document export { getOperationAST } from './getOperationAST'; +// Convert a GraphQLSchema to an IntrospectionQuery +export { introspectionFromSchema } from './introspectionFromSchema'; + // Build a GraphQLSchema from an introspection result. export { buildClientSchema } from './buildClientSchema'; diff --git a/src/utilities/introspectionFromSchema.js b/src/utilities/introspectionFromSchema.js new file mode 100644 index 0000000000..c1797891d9 --- /dev/null +++ b/src/utilities/introspectionFromSchema.js @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +import invariant from '../jsutils/invariant'; +import { getIntrospectionQuery } from './introspectionQuery'; +import { GraphQLSchema } from '../type/schema'; +import { execute } from '../execution/execute'; +import { parse } from '../language/parser'; +import type { + IntrospectionQuery, + IntrospectionOptions, +} from './introspectionQuery'; + +/** + * Build an IntrospectionQuery from a GraphQLSchema + * + * IntrospectionQuery is useful for utilities that care about type and field + * relationships, but do not need to traverse through those relationships. + * + * This is the inverse of buildClientSchema. The primary use case is outside + * of the server context, for instance when doing schema comparisons. + */ +export function introspectionFromSchema( + schema: GraphQLSchema, + options: IntrospectionOptions, +): IntrospectionQuery { + const queryAST = parse(getIntrospectionQuery(options)); + const result = execute(schema, queryAST); + invariant(!result.then && !result.errors && result.data); + return (result.data: any); +}