graphql.js.flow 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // @flow strict
  2. import isPromise from './jsutils/isPromise';
  3. import { type PromiseOrValue } from './jsutils/PromiseOrValue';
  4. import { parse } from './language/parser';
  5. import { type Source } from './language/source';
  6. import { validate } from './validation/validate';
  7. import { validateSchema } from './type/validate';
  8. import { type GraphQLSchema } from './type/schema';
  9. import {
  10. type GraphQLFieldResolver,
  11. type GraphQLTypeResolver,
  12. } from './type/definition';
  13. import { type ExecutionResult, execute } from './execution/execute';
  14. /**
  15. * This is the primary entry point function for fulfilling GraphQL operations
  16. * by parsing, validating, and executing a GraphQL document along side a
  17. * GraphQL schema.
  18. *
  19. * More sophisticated GraphQL servers, such as those which persist queries,
  20. * may wish to separate the validation and execution phases to a static time
  21. * tooling step, and a server runtime step.
  22. *
  23. * Accepts either an object with named arguments, or individual arguments:
  24. *
  25. * schema:
  26. * The GraphQL type system to use when validating and executing a query.
  27. * source:
  28. * A GraphQL language formatted string representing the requested operation.
  29. * rootValue:
  30. * The value provided as the first argument to resolver functions on the top
  31. * level type (e.g. the query object type).
  32. * contextValue:
  33. * The context value is provided as an argument to resolver functions after
  34. * field arguments. It is used to pass shared information useful at any point
  35. * during executing this query, for example the currently logged in user and
  36. * connections to databases or other services.
  37. * variableValues:
  38. * A mapping of variable name to runtime value to use for all variables
  39. * defined in the requestString.
  40. * operationName:
  41. * The name of the operation to use if requestString contains multiple
  42. * possible operations. Can be omitted if requestString contains only
  43. * one operation.
  44. * fieldResolver:
  45. * A resolver function to use when one is not provided by the schema.
  46. * If not provided, the default field resolver is used (which looks for a
  47. * value or method on the source value with the field's name).
  48. * typeResolver:
  49. * A type resolver function to use when none is provided by the schema.
  50. * If not provided, the default type resolver is used (which looks for a
  51. * `__typename` field or alternatively calls the `isTypeOf` method).
  52. */
  53. export type GraphQLArgs = {|
  54. schema: GraphQLSchema,
  55. source: string | Source,
  56. rootValue?: mixed,
  57. contextValue?: mixed,
  58. variableValues?: ?{ +[variable: string]: mixed, ... },
  59. operationName?: ?string,
  60. fieldResolver?: ?GraphQLFieldResolver<any, any>,
  61. typeResolver?: ?GraphQLTypeResolver<any, any>,
  62. |};
  63. declare function graphql(GraphQLArgs, ..._: []): Promise<ExecutionResult>;
  64. /* eslint-disable no-redeclare */
  65. declare function graphql(
  66. schema: GraphQLSchema,
  67. source: Source | string,
  68. rootValue?: mixed,
  69. contextValue?: mixed,
  70. variableValues?: ?{ +[variable: string]: mixed, ... },
  71. operationName?: ?string,
  72. fieldResolver?: ?GraphQLFieldResolver<any, any>,
  73. typeResolver?: ?GraphQLTypeResolver<any, any>,
  74. ): Promise<ExecutionResult>;
  75. export function graphql(
  76. argsOrSchema,
  77. source,
  78. rootValue,
  79. contextValue,
  80. variableValues,
  81. operationName,
  82. fieldResolver,
  83. typeResolver,
  84. ) {
  85. /* eslint-enable no-redeclare */
  86. // Always return a Promise for a consistent API.
  87. return new Promise(resolve =>
  88. resolve(
  89. // Extract arguments from object args if provided.
  90. arguments.length === 1
  91. ? graphqlImpl(argsOrSchema)
  92. : graphqlImpl({
  93. schema: argsOrSchema,
  94. source,
  95. rootValue,
  96. contextValue,
  97. variableValues,
  98. operationName,
  99. fieldResolver,
  100. typeResolver,
  101. }),
  102. ),
  103. );
  104. }
  105. /**
  106. * The graphqlSync function also fulfills GraphQL operations by parsing,
  107. * validating, and executing a GraphQL document along side a GraphQL schema.
  108. * However, it guarantees to complete synchronously (or throw an error) assuming
  109. * that all field resolvers are also synchronous.
  110. */
  111. declare function graphqlSync(GraphQLArgs, ..._: []): ExecutionResult;
  112. /* eslint-disable no-redeclare */
  113. declare function graphqlSync(
  114. schema: GraphQLSchema,
  115. source: Source | string,
  116. rootValue?: mixed,
  117. contextValue?: mixed,
  118. variableValues?: ?{ +[variable: string]: mixed, ... },
  119. operationName?: ?string,
  120. fieldResolver?: ?GraphQLFieldResolver<any, any>,
  121. typeResolver?: ?GraphQLTypeResolver<any, any>,
  122. ): ExecutionResult;
  123. export function graphqlSync(
  124. argsOrSchema,
  125. source,
  126. rootValue,
  127. contextValue,
  128. variableValues,
  129. operationName,
  130. fieldResolver,
  131. typeResolver,
  132. ) {
  133. /* eslint-enable no-redeclare */
  134. // Extract arguments from object args if provided.
  135. const result =
  136. arguments.length === 1
  137. ? graphqlImpl(argsOrSchema)
  138. : graphqlImpl({
  139. schema: argsOrSchema,
  140. source,
  141. rootValue,
  142. contextValue,
  143. variableValues,
  144. operationName,
  145. fieldResolver,
  146. typeResolver,
  147. });
  148. // Assert that the execution was synchronous.
  149. if (isPromise(result)) {
  150. throw new Error('GraphQL execution failed to complete synchronously.');
  151. }
  152. return result;
  153. }
  154. function graphqlImpl(args: GraphQLArgs): PromiseOrValue<ExecutionResult> {
  155. const {
  156. schema,
  157. source,
  158. rootValue,
  159. contextValue,
  160. variableValues,
  161. operationName,
  162. fieldResolver,
  163. typeResolver,
  164. } = args;
  165. // Validate Schema
  166. const schemaValidationErrors = validateSchema(schema);
  167. if (schemaValidationErrors.length > 0) {
  168. return { errors: schemaValidationErrors };
  169. }
  170. // Parse
  171. let document;
  172. try {
  173. document = parse(source);
  174. } catch (syntaxError) {
  175. return { errors: [syntaxError] };
  176. }
  177. // Validate
  178. const validationErrors = validate(schema, document);
  179. if (validationErrors.length > 0) {
  180. return { errors: validationErrors };
  181. }
  182. // Execute
  183. return execute({
  184. schema,
  185. document,
  186. rootValue,
  187. contextValue,
  188. variableValues,
  189. operationName,
  190. fieldResolver,
  191. typeResolver,
  192. });
  193. }