buildASTSchema.js.flow 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // @flow strict
  2. import devAssert from '../jsutils/devAssert';
  3. import type { Source } from '../language/source';
  4. import type { DocumentNode } from '../language/ast';
  5. import type { ParseOptions } from '../language/parser';
  6. import { Kind } from '../language/kinds';
  7. import { parse } from '../language/parser';
  8. import { assertValidSDL } from '../validation/validate';
  9. import type { GraphQLSchemaValidationOptions } from '../type/schema';
  10. import { GraphQLSchema } from '../type/schema';
  11. import { specifiedDirectives } from '../type/directives';
  12. import { extendSchemaImpl } from './extendSchema';
  13. export type BuildSchemaOptions = {|
  14. ...GraphQLSchemaValidationOptions,
  15. /**
  16. * Descriptions are defined as preceding string literals, however an older
  17. * experimental version of the SDL supported preceding comments as
  18. * descriptions. Set to true to enable this deprecated behavior.
  19. * This option is provided to ease adoption and will be removed in v16.
  20. *
  21. * Default: false
  22. */
  23. commentDescriptions?: boolean,
  24. /**
  25. * Set to true to assume the SDL is valid.
  26. *
  27. * Default: false
  28. */
  29. assumeValidSDL?: boolean,
  30. |};
  31. /**
  32. * This takes the ast of a schema document produced by the parse function in
  33. * src/language/parser.js.
  34. *
  35. * If no schema definition is provided, then it will look for types named Query
  36. * and Mutation.
  37. *
  38. * Given that AST it constructs a GraphQLSchema. The resulting schema
  39. * has no resolve methods, so execution will use default resolvers.
  40. *
  41. * Accepts options as a second argument:
  42. *
  43. * - commentDescriptions:
  44. * Provide true to use preceding comments as the description.
  45. *
  46. */
  47. export function buildASTSchema(
  48. documentAST: DocumentNode,
  49. options?: BuildSchemaOptions,
  50. ): GraphQLSchema {
  51. devAssert(
  52. documentAST != null && documentAST.kind === Kind.DOCUMENT,
  53. 'Must provide valid Document AST.',
  54. );
  55. if (options?.assumeValid !== true && options?.assumeValidSDL !== true) {
  56. assertValidSDL(documentAST);
  57. }
  58. const emptySchemaConfig = {
  59. description: undefined,
  60. types: [],
  61. directives: [],
  62. extensions: undefined,
  63. extensionASTNodes: [],
  64. assumeValid: false,
  65. };
  66. const config = extendSchemaImpl(emptySchemaConfig, documentAST, options);
  67. if (config.astNode == null) {
  68. for (const type of config.types) {
  69. switch (type.name) {
  70. // Note: While this could make early assertions to get the correctly
  71. // typed values below, that would throw immediately while type system
  72. // validation with validateSchema() will produce more actionable results.
  73. case 'Query':
  74. config.query = (type: any);
  75. break;
  76. case 'Mutation':
  77. config.mutation = (type: any);
  78. break;
  79. case 'Subscription':
  80. config.subscription = (type: any);
  81. break;
  82. }
  83. }
  84. }
  85. const { directives } = config;
  86. // If specified directives were not explicitly declared, add them.
  87. for (const stdDirective of specifiedDirectives) {
  88. if (directives.every((directive) => directive.name !== stdDirective.name)) {
  89. directives.push(stdDirective);
  90. }
  91. }
  92. return new GraphQLSchema(config);
  93. }
  94. /**
  95. * A helper function to build a GraphQLSchema directly from a source
  96. * document.
  97. */
  98. export function buildSchema(
  99. source: string | Source,
  100. options?: {| ...BuildSchemaOptions, ...ParseOptions |},
  101. ): GraphQLSchema {
  102. const document = parse(source, {
  103. noLocation: options?.noLocation,
  104. allowLegacySDLEmptyFields: options?.allowLegacySDLEmptyFields,
  105. allowLegacySDLImplementsInterfaces:
  106. options?.allowLegacySDLImplementsInterfaces,
  107. experimentalFragmentVariables: options?.experimentalFragmentVariables,
  108. });
  109. return buildASTSchema(document, {
  110. commentDescriptions: options?.commentDescriptions,
  111. assumeValidSDL: options?.assumeValidSDL,
  112. assumeValid: options?.assumeValid,
  113. });
  114. }