graphql 0.12.3 → 0.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/error/GraphQLError.js +2 -3
- package/error/GraphQLError.js.flow +3 -4
- package/{module/error/GraphQLError.js → error/GraphQLError.mjs} +2 -3
- package/error/formatError.js +1 -1
- package/error/formatError.js.flow +1 -1
- package/{module/error/formatError.js → error/formatError.mjs} +1 -1
- package/error/index.js.flow +1 -1
- package/{module/error/index.js → error/index.mjs} +1 -1
- package/error/locatedError.js +2 -1
- package/error/locatedError.js.flow +2 -1
- package/{module/error/locatedError.js → error/locatedError.mjs} +2 -1
- package/error/printError.js +1 -1
- package/error/printError.js.flow +1 -1
- package/{module/error/printError.js → error/printError.mjs} +1 -1
- package/error/syntaxError.js +1 -1
- package/error/syntaxError.js.flow +1 -1
- package/{module/error/syntaxError.js → error/syntaxError.mjs} +1 -1
- package/execution/execute.js +70 -90
- package/execution/execute.js.flow +83 -106
- package/{module/execution/execute.js → execution/execute.mjs} +53 -81
- package/execution/index.js.flow +1 -1
- package/{module/execution/index.js → execution/index.mjs} +1 -1
- package/execution/values.js +2 -6
- package/execution/values.js.flow +6 -7
- package/{module/execution/values.js → execution/values.mjs} +2 -2
- package/graphql.js +1 -1
- package/graphql.js.flow +3 -2
- package/{module/graphql.js → graphql.mjs} +1 -1
- package/index.js +24 -6
- package/index.js.flow +16 -2
- package/{module/index.js → index.mjs} +10 -2
- package/jsutils/MaybePromise.js +1 -0
- package/{module/jsutils/ObjMap.js.flow → jsutils/MaybePromise.js.flow} +2 -2
- package/{module/jsutils/ObjMap.js → jsutils/MaybePromise.mjs} +0 -0
- package/jsutils/ObjMap.js.flow +1 -1
- package/{module/language/ast.js → jsutils/ObjMap.mjs} +0 -0
- package/jsutils/dedent.js +23 -18
- package/jsutils/dedent.js.flow +21 -20
- package/jsutils/dedent.mjs +50 -0
- package/jsutils/find.js +1 -1
- package/jsutils/find.js.flow +1 -1
- package/{module/jsutils/find.js → jsutils/find.mjs} +1 -1
- package/jsutils/instanceOf.js +17 -16
- package/jsutils/instanceOf.js.flow +21 -15
- package/jsutils/instanceOf.mjs +31 -0
- package/jsutils/invariant.js +1 -1
- package/jsutils/invariant.js.flow +1 -1
- package/{module/jsutils/invariant.js → jsutils/invariant.mjs} +1 -1
- package/jsutils/isInvalid.js +1 -1
- package/jsutils/isInvalid.js.flow +1 -1
- package/{module/jsutils/isInvalid.js → jsutils/isInvalid.mjs} +1 -1
- package/jsutils/isNullish.js +1 -1
- package/jsutils/isNullish.js.flow +1 -1
- package/{module/jsutils/isNullish.js → jsutils/isNullish.mjs} +1 -1
- package/jsutils/isPromise.js +24 -0
- package/jsutils/isPromise.js.flow +20 -0
- package/jsutils/isPromise.mjs +18 -0
- package/jsutils/keyMap.js +1 -1
- package/jsutils/keyMap.js.flow +1 -1
- package/{module/jsutils/keyMap.js → jsutils/keyMap.mjs} +1 -1
- package/jsutils/keyValMap.js +1 -1
- package/jsutils/keyValMap.js.flow +1 -1
- package/{module/jsutils/keyValMap.js → jsutils/keyValMap.mjs} +1 -1
- package/jsutils/memoize3.js +48 -0
- package/jsutils/memoize3.js.flow +44 -0
- package/jsutils/memoize3.mjs +42 -0
- package/jsutils/objectValues.js +24 -0
- package/jsutils/objectValues.js.flow +18 -0
- package/jsutils/objectValues.mjs +19 -0
- package/jsutils/orList.js +1 -1
- package/jsutils/orList.js.flow +1 -1
- package/{module/jsutils/orList.js → jsutils/orList.mjs} +1 -1
- package/jsutils/promiseForObject.js +34 -0
- package/jsutils/promiseForObject.js.flow +30 -0
- package/jsutils/promiseForObject.mjs +28 -0
- package/jsutils/promiseReduce.js +34 -0
- package/jsutils/promiseReduce.js.flow +32 -0
- package/jsutils/promiseReduce.mjs +26 -0
- package/jsutils/quotedOrList.js +1 -1
- package/jsutils/quotedOrList.js.flow +1 -1
- package/{module/jsutils/quotedOrList.js → jsutils/quotedOrList.mjs} +1 -1
- package/jsutils/suggestionList.js +1 -1
- package/jsutils/suggestionList.js.flow +1 -1
- package/{module/jsutils/suggestionList.js → jsutils/suggestionList.mjs} +1 -1
- package/language/ast.js.flow +3 -30
- package/language/ast.mjs +0 -0
- package/language/blockStringValue.js +1 -1
- package/language/blockStringValue.js.flow +1 -1
- package/{module/language/blockStringValue.js → language/blockStringValue.mjs} +1 -1
- package/language/directiveLocation.js +3 -3
- package/language/directiveLocation.js.flow +4 -4
- package/{module/language/directiveLocation.js → language/directiveLocation.mjs} +3 -3
- package/language/index.js +10 -10
- package/language/index.js.flow +5 -4
- package/{module/language/index.js → language/index.mjs} +3 -3
- package/language/kinds.js +70 -71
- package/language/kinds.js.flow +71 -71
- package/language/kinds.mjs +79 -0
- package/language/lexer.js +73 -87
- package/language/lexer.js.flow +87 -93
- package/{module/language/lexer.js → language/lexer.mjs} +73 -87
- package/language/location.js +1 -1
- package/language/location.js.flow +1 -1
- package/{module/language/location.js → language/location.mjs} +1 -1
- package/language/parser.js +68 -58
- package/language/parser.js.flow +104 -110
- package/{module/language/parser.js → language/parser.mjs} +69 -59
- package/language/printer.js +52 -55
- package/language/printer.js.flow +74 -120
- package/{module/language/printer.js → language/printer.mjs} +52 -55
- package/language/source.js +1 -1
- package/language/source.js.flow +1 -1
- package/{module/language/source.js → language/source.mjs} +1 -1
- package/language/visitor.js +1 -1
- package/language/visitor.js.flow +1 -1
- package/{module/language/visitor.js → language/visitor.mjs} +1 -1
- package/package.json +4 -9
- package/subscription/asyncIteratorReject.js +1 -1
- package/subscription/asyncIteratorReject.js.flow +1 -1
- package/{module/subscription/asyncIteratorReject.js → subscription/asyncIteratorReject.mjs} +1 -1
- package/subscription/index.js.flow +1 -1
- package/{module/subscription/index.js → subscription/index.mjs} +1 -1
- package/subscription/mapAsyncIterator.js +3 -1
- package/subscription/mapAsyncIterator.js.flow +7 -4
- package/{module/subscription/mapAsyncIterator.js → subscription/mapAsyncIterator.mjs} +4 -1
- package/subscription/subscribe.js +1 -1
- package/subscription/subscribe.js.flow +1 -1
- package/{module/subscription/subscribe.js → subscription/subscribe.mjs} +1 -1
- package/type/definition.js +76 -10
- package/type/definition.js.flow +105 -13
- package/{module/type/definition.js → type/definition.mjs} +72 -4
- package/type/directives.js +4 -4
- package/type/directives.js.flow +3 -3
- package/{module/type/directives.js → type/directives.mjs} +8 -8
- package/type/index.js +2 -5
- package/type/index.js.flow +6 -5
- package/{module/type/index.js → type/index.mjs} +3 -5
- package/type/introspection.js +34 -41
- package/type/introspection.js.flow +7 -10
- package/{module/type/introspection.js → type/introspection.mjs} +6 -15
- package/type/scalars.js +6 -10
- package/type/scalars.js.flow +2 -2
- package/{module/type/scalars.js → type/scalars.mjs} +2 -2
- package/type/schema.js +39 -15
- package/type/schema.js.flow +73 -22
- package/{module/type/schema.js → type/schema.mjs} +37 -16
- package/type/validate.js +33 -30
- package/type/validate.js.flow +40 -37
- package/{module/type/validate.js → type/validate.mjs} +30 -30
- package/utilities/TypeInfo.js +23 -27
- package/utilities/TypeInfo.js.flow +2 -2
- package/{module/utilities/TypeInfo.js → utilities/TypeInfo.mjs} +2 -2
- package/utilities/assertValidName.js +2 -6
- package/utilities/assertValidName.js.flow +2 -10
- package/{module/utilities/assertValidName.js → utilities/assertValidName.mjs} +2 -6
- package/utilities/astFromValue.js +37 -37
- package/utilities/astFromValue.js.flow +36 -44
- package/{module/utilities/astFromValue.js → utilities/astFromValue.mjs} +26 -25
- package/utilities/buildASTSchema.js +65 -82
- package/utilities/buildASTSchema.js.flow +52 -59
- package/{module/utilities/buildASTSchema.js → utilities/buildASTSchema.mjs} +48 -62
- package/utilities/buildClientSchema.js +12 -15
- package/utilities/buildClientSchema.js.flow +7 -11
- package/{module/utilities/buildClientSchema.js → utilities/buildClientSchema.mjs} +4 -5
- package/utilities/coerceValue.js +1 -1
- package/utilities/coerceValue.js.flow +1 -1
- package/{module/utilities/coerceValue.js → utilities/coerceValue.mjs} +1 -1
- package/utilities/concatAST.js +1 -1
- package/utilities/concatAST.js.flow +1 -1
- package/{module/utilities/concatAST.js → utilities/concatAST.mjs} +1 -1
- package/utilities/extendSchema.js +91 -77
- package/utilities/extendSchema.js.flow +93 -68
- package/{module/utilities/extendSchema.js → utilities/extendSchema.mjs} +65 -52
- package/utilities/findBreakingChanges.js +1 -1
- package/utilities/findBreakingChanges.js.flow +1 -1
- package/{module/utilities/findBreakingChanges.js → utilities/findBreakingChanges.mjs} +1 -1
- package/utilities/findDeprecatedUsages.js +1 -1
- package/utilities/findDeprecatedUsages.js.flow +1 -1
- package/{module/utilities/findDeprecatedUsages.js → utilities/findDeprecatedUsages.mjs} +1 -1
- package/utilities/getOperationAST.js +2 -2
- package/utilities/getOperationAST.js.flow +3 -3
- package/{module/utilities/getOperationAST.js → utilities/getOperationAST.mjs} +3 -3
- package/utilities/index.js +30 -0
- package/utilities/index.js.flow +10 -3
- package/{module/utilities/index.js → utilities/index.mjs} +10 -3
- package/utilities/introspectionFromSchema.js +43 -0
- package/utilities/introspectionFromSchema.js.flow +37 -0
- package/utilities/introspectionFromSchema.mjs +31 -0
- package/utilities/introspectionQuery.js +1 -1
- package/utilities/introspectionQuery.js.flow +1 -1
- package/{module/utilities/introspectionQuery.js → utilities/introspectionQuery.mjs} +1 -1
- package/utilities/isValidJSValue.js +1 -1
- package/utilities/isValidJSValue.js.flow +1 -1
- package/{module/utilities/isValidJSValue.js → utilities/isValidJSValue.mjs} +1 -1
- package/utilities/isValidLiteralValue.js +8 -4
- package/utilities/isValidLiteralValue.js.flow +4 -4
- package/{module/utilities/isValidLiteralValue.js → utilities/isValidLiteralValue.mjs} +4 -4
- package/utilities/lexicographicSortSchema.js +243 -0
- package/utilities/lexicographicSortSchema.js.flow +198 -0
- package/utilities/lexicographicSortSchema.mjs +225 -0
- package/utilities/schemaPrinter.js +31 -29
- package/utilities/schemaPrinter.js.flow +28 -15
- package/{module/utilities/schemaPrinter.js → utilities/schemaPrinter.mjs} +21 -20
- package/utilities/separateOperations.js +1 -1
- package/utilities/separateOperations.js.flow +1 -1
- package/{module/utilities/separateOperations.js → utilities/separateOperations.mjs} +1 -1
- package/utilities/typeComparators.js +7 -10
- package/utilities/typeComparators.js.flow +7 -10
- package/{module/utilities/typeComparators.js → utilities/typeComparators.mjs} +7 -10
- package/utilities/typeFromAST.js +7 -11
- package/utilities/typeFromAST.js.flow +3 -3
- package/{module/utilities/typeFromAST.js → utilities/typeFromAST.mjs} +3 -3
- package/utilities/valueFromAST.js +26 -28
- package/utilities/valueFromAST.js.flow +14 -23
- package/{module/utilities/valueFromAST.js → utilities/valueFromAST.mjs} +9 -10
- package/utilities/valueFromASTUntyped.js +17 -22
- package/utilities/valueFromASTUntyped.js.flow +6 -7
- package/{module/utilities/valueFromASTUntyped.js → utilities/valueFromASTUntyped.mjs} +6 -7
- package/validation/ValidationContext.js +184 -0
- package/{module/validation/validate.js.flow → validation/ValidationContext.js.flow} +4 -60
- package/{module/validation/validate.js → validation/ValidationContext.mjs} +15 -57
- package/validation/index.js +12 -7
- package/validation/index.js.flow +6 -2
- package/{module/validation/index.js → validation/index.mjs} +6 -2
- package/validation/rules/ExecutableDefinitions.js +3 -3
- package/validation/rules/ExecutableDefinitions.js.flow +6 -10
- package/{module/validation/rules/ExecutableDefinitions.js → validation/rules/ExecutableDefinitions.mjs} +4 -4
- package/validation/rules/FieldsOnCorrectType.js +1 -1
- package/validation/rules/FieldsOnCorrectType.js.flow +2 -2
- package/{module/validation/rules/FieldsOnCorrectType.js → validation/rules/FieldsOnCorrectType.mjs} +1 -1
- package/validation/rules/FragmentsOnCompositeTypes.js +1 -1
- package/validation/rules/FragmentsOnCompositeTypes.js.flow +2 -2
- package/{module/validation/rules/FragmentsOnCompositeTypes.js → validation/rules/FragmentsOnCompositeTypes.mjs} +1 -1
- package/validation/rules/KnownArgumentNames.js +3 -3
- package/validation/rules/KnownArgumentNames.js.flow +6 -8
- package/{module/validation/rules/KnownArgumentNames.js → validation/rules/KnownArgumentNames.mjs} +4 -4
- package/validation/rules/KnownDirectives.js +23 -27
- package/validation/rules/KnownDirectives.js.flow +3 -3
- package/{module/validation/rules/KnownDirectives.js → validation/rules/KnownDirectives.mjs} +2 -2
- package/validation/rules/KnownFragmentNames.js +1 -1
- package/validation/rules/KnownFragmentNames.js.flow +2 -2
- package/{module/validation/rules/KnownFragmentNames.js → validation/rules/KnownFragmentNames.mjs} +1 -1
- package/validation/rules/KnownTypeNames.js +1 -1
- package/validation/rules/KnownTypeNames.js.flow +2 -2
- package/{module/validation/rules/KnownTypeNames.js → validation/rules/KnownTypeNames.mjs} +1 -1
- package/validation/rules/LoneAnonymousOperation.js +2 -2
- package/validation/rules/LoneAnonymousOperation.js.flow +4 -4
- package/{module/validation/rules/LoneAnonymousOperation.js → validation/rules/LoneAnonymousOperation.mjs} +3 -3
- package/validation/rules/NoFragmentCycles.js +1 -1
- package/validation/rules/NoFragmentCycles.js.flow +2 -2
- package/{module/validation/rules/NoFragmentCycles.js → validation/rules/NoFragmentCycles.mjs} +1 -1
- package/validation/rules/NoUndefinedVariables.js +1 -1
- package/validation/rules/NoUndefinedVariables.js.flow +2 -2
- package/{module/validation/rules/NoUndefinedVariables.js → validation/rules/NoUndefinedVariables.mjs} +1 -1
- package/validation/rules/NoUnusedFragments.js +1 -1
- package/validation/rules/NoUnusedFragments.js.flow +2 -2
- package/{module/validation/rules/NoUnusedFragments.js → validation/rules/NoUnusedFragments.mjs} +1 -1
- package/validation/rules/NoUnusedVariables.js +1 -1
- package/validation/rules/NoUnusedVariables.js.flow +2 -2
- package/{module/validation/rules/NoUnusedVariables.js → validation/rules/NoUnusedVariables.mjs} +1 -1
- package/validation/rules/OverlappingFieldsCanBeMerged.js +4 -8
- package/validation/rules/OverlappingFieldsCanBeMerged.js.flow +3 -3
- package/{module/validation/rules/OverlappingFieldsCanBeMerged.js → validation/rules/OverlappingFieldsCanBeMerged.mjs} +2 -2
- package/validation/rules/PossibleFragmentSpreads.js +1 -1
- package/validation/rules/PossibleFragmentSpreads.js.flow +2 -2
- package/{module/validation/rules/PossibleFragmentSpreads.js → validation/rules/PossibleFragmentSpreads.mjs} +1 -1
- package/validation/rules/ProvidedNonNullArguments.js +1 -1
- package/validation/rules/ProvidedNonNullArguments.js.flow +2 -2
- package/{module/validation/rules/ProvidedNonNullArguments.js → validation/rules/ProvidedNonNullArguments.mjs} +1 -1
- package/validation/rules/ScalarLeafs.js +1 -1
- package/validation/rules/ScalarLeafs.js.flow +2 -2
- package/{module/validation/rules/ScalarLeafs.js → validation/rules/ScalarLeafs.mjs} +1 -1
- package/validation/rules/SingleFieldSubscriptions.js +1 -1
- package/validation/rules/SingleFieldSubscriptions.js.flow +2 -2
- package/{module/validation/rules/SingleFieldSubscriptions.js → validation/rules/SingleFieldSubscriptions.mjs} +1 -1
- package/validation/rules/UniqueArgumentNames.js +1 -1
- package/validation/rules/UniqueArgumentNames.js.flow +2 -2
- package/{module/validation/rules/UniqueArgumentNames.js → validation/rules/UniqueArgumentNames.mjs} +1 -1
- package/validation/rules/UniqueDirectivesPerLocation.js +1 -1
- package/validation/rules/UniqueDirectivesPerLocation.js.flow +2 -2
- package/{module/validation/rules/UniqueDirectivesPerLocation.js → validation/rules/UniqueDirectivesPerLocation.mjs} +1 -1
- package/validation/rules/UniqueFragmentNames.js +1 -1
- package/validation/rules/UniqueFragmentNames.js.flow +2 -2
- package/{module/validation/rules/UniqueFragmentNames.js → validation/rules/UniqueFragmentNames.mjs} +1 -1
- package/validation/rules/UniqueInputFieldNames.js +1 -1
- package/validation/rules/UniqueInputFieldNames.js.flow +2 -2
- package/{module/validation/rules/UniqueInputFieldNames.js → validation/rules/UniqueInputFieldNames.mjs} +1 -1
- package/validation/rules/UniqueOperationNames.js +1 -1
- package/validation/rules/UniqueOperationNames.js.flow +2 -2
- package/{module/validation/rules/UniqueOperationNames.js → validation/rules/UniqueOperationNames.mjs} +1 -1
- package/validation/rules/UniqueVariableNames.js +1 -1
- package/validation/rules/UniqueVariableNames.js.flow +2 -2
- package/{module/validation/rules/UniqueVariableNames.js → validation/rules/UniqueVariableNames.mjs} +1 -1
- package/validation/rules/ValuesOfCorrectType.js +1 -1
- package/validation/rules/ValuesOfCorrectType.js.flow +2 -2
- package/{module/validation/rules/ValuesOfCorrectType.js → validation/rules/ValuesOfCorrectType.mjs} +1 -1
- package/validation/rules/VariablesAreInputTypes.js +1 -1
- package/validation/rules/VariablesAreInputTypes.js.flow +2 -2
- package/{module/validation/rules/VariablesAreInputTypes.js → validation/rules/VariablesAreInputTypes.mjs} +1 -1
- package/validation/rules/VariablesDefaultValueAllowed.js +1 -1
- package/validation/rules/VariablesDefaultValueAllowed.js.flow +2 -2
- package/{module/validation/rules/VariablesDefaultValueAllowed.js → validation/rules/VariablesDefaultValueAllowed.mjs} +1 -1
- package/validation/rules/VariablesInAllowedPosition.js +9 -11
- package/validation/rules/VariablesInAllowedPosition.js.flow +3 -4
- package/{module/validation/rules/VariablesInAllowedPosition.js → validation/rules/VariablesInAllowedPosition.mjs} +2 -3
- package/validation/specifiedRules.js +1 -1
- package/validation/specifiedRules.js.flow +2 -2
- package/{module/validation/specifiedRules.js → validation/specifiedRules.mjs} +1 -1
- package/validation/validate.js +14 -175
- package/validation/validate.js.flow +3 -209
- package/validation/validate.mjs +57 -0
- package/module/error/GraphQLError.js.flow +0 -209
- package/module/error/formatError.js.flow +0 -34
- package/module/error/index.js.flow +0 -16
- package/module/error/locatedError.js.flow +0 -37
- package/module/error/printError.js.flow +0 -82
- package/module/error/syntaxError.js.flow +0 -25
- package/module/execution/execute.js.flow +0 -1375
- package/module/execution/index.js.flow +0 -13
- package/module/execution/values.js.flow +0 -206
- package/module/graphql.js.flow +0 -202
- package/module/index.js.flow +0 -389
- package/module/jsutils/dedent.js +0 -45
- package/module/jsutils/dedent.js.flow +0 -49
- package/module/jsutils/find.js.flow +0 -19
- package/module/jsutils/instanceOf.js +0 -27
- package/module/jsutils/instanceOf.js.flow +0 -44
- package/module/jsutils/invariant.js.flow +0 -15
- package/module/jsutils/isInvalid.js.flow +0 -15
- package/module/jsutils/isNullish.js.flow +0 -15
- package/module/jsutils/keyMap.js.flow +0 -43
- package/module/jsutils/keyValMap.js.flow +0 -38
- package/module/jsutils/orList.js.flow +0 -24
- package/module/jsutils/quotedOrList.js.flow +0 -17
- package/module/jsutils/suggestionList.js.flow +0 -94
- package/module/language/ast.js.flow +0 -594
- package/module/language/blockStringValue.js.flow +0 -64
- package/module/language/directiveLocation.js.flow +0 -39
- package/module/language/index.js.flow +0 -84
- package/module/language/kinds.js +0 -80
- package/module/language/kinds.js.flow +0 -80
- package/module/language/lexer.js.flow +0 -762
- package/module/language/location.js.flow +0 -34
- package/module/language/parser.js.flow +0 -1537
- package/module/language/printer.js.flow +0 -311
- package/module/language/source.js.flow +0 -43
- package/module/language/visitor.js.flow +0 -476
- package/module/subscription/asyncIteratorReject.js.flow +0 -41
- package/module/subscription/index.js.flow +0 -10
- package/module/subscription/mapAsyncIterator.js.flow +0 -78
- package/module/subscription/subscribe.js.flow +0 -288
- package/module/type/definition.js.flow +0 -1225
- package/module/type/directives.js.flow +0 -168
- package/module/type/index.js.flow +0 -156
- package/module/type/introspection.js.flow +0 -482
- package/module/type/scalars.js.flow +0 -158
- package/module/type/schema.js.flow +0 -271
- package/module/type/validate.js.flow +0 -723
- package/module/type/wrappers.js +0 -80
- package/module/type/wrappers.js.flow +0 -91
- package/module/utilities/TypeInfo.js.flow +0 -296
- package/module/utilities/assertValidName.js.flow +0 -56
- package/module/utilities/astFromValue.js.flow +0 -159
- package/module/utilities/buildASTSchema.js.flow +0 -518
- package/module/utilities/buildClientSchema.js.flow +0 -418
- package/module/utilities/coerceValue.js.flow +0 -257
- package/module/utilities/concatAST.js.flow +0 -29
- package/module/utilities/extendSchema.js.flow +0 -374
- package/module/utilities/findBreakingChanges.js.flow +0 -851
- package/module/utilities/findDeprecatedUsages.js.flow +0 -68
- package/module/utilities/getOperationAST.js.flow +0 -40
- package/module/utilities/index.js.flow +0 -111
- package/module/utilities/introspectionQuery.js.flow +0 -271
- package/module/utilities/isValidJSValue.js.flow +0 -22
- package/module/utilities/isValidLiteralValue.js.flow +0 -36
- package/module/utilities/schemaPrinter.js.flow +0 -402
- package/module/utilities/separateOperations.js.flow +0 -100
- package/module/utilities/typeComparators.js.flow +0 -135
- package/module/utilities/typeFromAST.js.flow +0 -56
- package/module/utilities/valueFromAST.js.flow +0 -184
- package/module/utilities/valueFromASTUntyped.js.flow +0 -64
- package/module/validation/index.js.flow +0 -138
- package/module/validation/rules/ExecutableDefinitions.js.flow +0 -52
- package/module/validation/rules/FieldsOnCorrectType.js.flow +0 -144
- package/module/validation/rules/FragmentsOnCompositeTypes.js.flow +0 -74
- package/module/validation/rules/KnownArgumentNames.js.flow +0 -98
- package/module/validation/rules/KnownDirectives.js.flow +0 -116
- package/module/validation/rules/KnownFragmentNames.js.flow +0 -36
- package/module/validation/rules/KnownTypeNames.js.flow +0 -59
- package/module/validation/rules/LoneAnonymousOperation.js.flow +0 -41
- package/module/validation/rules/NoFragmentCycles.js.flow +0 -85
- package/module/validation/rules/NoUndefinedVariables.js.flow +0 -57
- package/module/validation/rules/NoUnusedFragments.js.flow +0 -59
- package/module/validation/rules/NoUnusedVariables.js.flow +0 -62
- package/module/validation/rules/OverlappingFieldsCanBeMerged.js.flow +0 -847
- package/module/validation/rules/PossibleFragmentSpreads.js.flow +0 -94
- package/module/validation/rules/ProvidedNonNullArguments.js.flow +0 -105
- package/module/validation/rules/ScalarLeafs.js.flow +0 -69
- package/module/validation/rules/SingleFieldSubscriptions.js.flow +0 -44
- package/module/validation/rules/UniqueArgumentNames.js.flow +0 -48
- package/module/validation/rules/UniqueDirectivesPerLocation.js.flow +0 -57
- package/module/validation/rules/UniqueFragmentNames.js.flow +0 -42
- package/module/validation/rules/UniqueInputFieldNames.js.flow +0 -53
- package/module/validation/rules/UniqueOperationNames.js.flow +0 -44
- package/module/validation/rules/UniqueVariableNames.js.flow +0 -44
- package/module/validation/rules/ValuesOfCorrectType.js.flow +0 -218
- package/module/validation/rules/VariablesAreInputTypes.js.flow +0 -48
- package/module/validation/rules/VariablesDefaultValueAllowed.js.flow +0 -55
- package/module/validation/rules/VariablesInAllowedPosition.js.flow +0 -83
- package/module/validation/specifiedRules.js.flow +0 -127
- package/type/wrappers.js +0 -89
- package/type/wrappers.js.flow +0 -91
|
@@ -1,1375 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) 2015-present, Facebook, Inc.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*
|
|
7
|
-
* @flow
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { forEach, isCollection } from 'iterall';
|
|
11
|
-
import { GraphQLError, locatedError } from '../error';
|
|
12
|
-
import invariant from '../jsutils/invariant';
|
|
13
|
-
import isInvalid from '../jsutils/isInvalid';
|
|
14
|
-
import isNullish from '../jsutils/isNullish';
|
|
15
|
-
import type { ObjMap } from '../jsutils/ObjMap';
|
|
16
|
-
|
|
17
|
-
import { typeFromAST } from '../utilities/typeFromAST';
|
|
18
|
-
import * as Kind from '../language/kinds';
|
|
19
|
-
import {
|
|
20
|
-
getVariableValues,
|
|
21
|
-
getArgumentValues,
|
|
22
|
-
getDirectiveValues,
|
|
23
|
-
} from './values';
|
|
24
|
-
import {
|
|
25
|
-
isObjectType,
|
|
26
|
-
isAbstractType,
|
|
27
|
-
isLeafType,
|
|
28
|
-
isListType,
|
|
29
|
-
isNonNullType,
|
|
30
|
-
} from '../type/definition';
|
|
31
|
-
import type { GraphQLList } from '../type/wrappers';
|
|
32
|
-
import type {
|
|
33
|
-
GraphQLObjectType,
|
|
34
|
-
GraphQLOutputType,
|
|
35
|
-
GraphQLLeafType,
|
|
36
|
-
GraphQLAbstractType,
|
|
37
|
-
GraphQLField,
|
|
38
|
-
GraphQLFieldResolver,
|
|
39
|
-
GraphQLResolveInfo,
|
|
40
|
-
ResponsePath,
|
|
41
|
-
} from '../type/definition';
|
|
42
|
-
import { GraphQLSchema } from '../type/schema';
|
|
43
|
-
import {
|
|
44
|
-
SchemaMetaFieldDef,
|
|
45
|
-
TypeMetaFieldDef,
|
|
46
|
-
TypeNameMetaFieldDef,
|
|
47
|
-
} from '../type/introspection';
|
|
48
|
-
import {
|
|
49
|
-
GraphQLIncludeDirective,
|
|
50
|
-
GraphQLSkipDirective,
|
|
51
|
-
} from '../type/directives';
|
|
52
|
-
import { assertValidSchema } from '../type/validate';
|
|
53
|
-
import type {
|
|
54
|
-
DocumentNode,
|
|
55
|
-
OperationDefinitionNode,
|
|
56
|
-
SelectionSetNode,
|
|
57
|
-
FieldNode,
|
|
58
|
-
FragmentSpreadNode,
|
|
59
|
-
InlineFragmentNode,
|
|
60
|
-
FragmentDefinitionNode,
|
|
61
|
-
} from '../language/ast';
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Terminology
|
|
65
|
-
*
|
|
66
|
-
* "Definitions" are the generic name for top-level statements in the document.
|
|
67
|
-
* Examples of this include:
|
|
68
|
-
* 1) Operations (such as a query)
|
|
69
|
-
* 2) Fragments
|
|
70
|
-
*
|
|
71
|
-
* "Operations" are a generic name for requests in the document.
|
|
72
|
-
* Examples of this include:
|
|
73
|
-
* 1) query,
|
|
74
|
-
* 2) mutation
|
|
75
|
-
*
|
|
76
|
-
* "Selections" are the definitions that can appear legally and at
|
|
77
|
-
* single level of the query. These include:
|
|
78
|
-
* 1) field references e.g "a"
|
|
79
|
-
* 2) fragment "spreads" e.g. "...c"
|
|
80
|
-
* 3) inline fragment "spreads" e.g. "...on Type { a }"
|
|
81
|
-
*/
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Data that must be available at all points during query execution.
|
|
85
|
-
*
|
|
86
|
-
* Namely, schema of the type system that is currently executing,
|
|
87
|
-
* and the fragments defined in the query document
|
|
88
|
-
*/
|
|
89
|
-
export type ExecutionContext = {
|
|
90
|
-
schema: GraphQLSchema,
|
|
91
|
-
fragments: ObjMap<FragmentDefinitionNode>,
|
|
92
|
-
rootValue: mixed,
|
|
93
|
-
contextValue: mixed,
|
|
94
|
-
operation: OperationDefinitionNode,
|
|
95
|
-
variableValues: { [variable: string]: mixed },
|
|
96
|
-
fieldResolver: GraphQLFieldResolver<any, any>,
|
|
97
|
-
errors: Array<GraphQLError>,
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* The result of GraphQL execution.
|
|
102
|
-
*
|
|
103
|
-
* - `errors` is included when any errors occurred as a non-empty array.
|
|
104
|
-
* - `data` is the result of a successful execution of the query.
|
|
105
|
-
*/
|
|
106
|
-
export type ExecutionResult = {
|
|
107
|
-
errors?: $ReadOnlyArray<GraphQLError>,
|
|
108
|
-
data?: ObjMap<mixed>,
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
export type ExecutionArgs = {|
|
|
112
|
-
schema: GraphQLSchema,
|
|
113
|
-
document: DocumentNode,
|
|
114
|
-
rootValue?: mixed,
|
|
115
|
-
contextValue?: mixed,
|
|
116
|
-
variableValues?: ?{ [variable: string]: mixed },
|
|
117
|
-
operationName?: ?string,
|
|
118
|
-
fieldResolver?: ?GraphQLFieldResolver<any, any>,
|
|
119
|
-
|};
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Implements the "Evaluating requests" section of the GraphQL specification.
|
|
123
|
-
*
|
|
124
|
-
* Returns either a synchronous ExecutionResult (if all encountered resolvers
|
|
125
|
-
* are synchronous), or a Promise of an ExecutionResult that will eventually be
|
|
126
|
-
* resolved and never rejected.
|
|
127
|
-
*
|
|
128
|
-
* If the arguments to this function do not result in a legal execution context,
|
|
129
|
-
* a GraphQLError will be thrown immediately explaining the invalid input.
|
|
130
|
-
*
|
|
131
|
-
* Accepts either an object with named arguments, or individual arguments.
|
|
132
|
-
*/
|
|
133
|
-
declare function execute(
|
|
134
|
-
ExecutionArgs,
|
|
135
|
-
..._: []
|
|
136
|
-
): Promise<ExecutionResult> | ExecutionResult;
|
|
137
|
-
/* eslint-disable no-redeclare */
|
|
138
|
-
declare function execute(
|
|
139
|
-
schema: GraphQLSchema,
|
|
140
|
-
document: DocumentNode,
|
|
141
|
-
rootValue?: mixed,
|
|
142
|
-
contextValue?: mixed,
|
|
143
|
-
variableValues?: ?{ [variable: string]: mixed },
|
|
144
|
-
operationName?: ?string,
|
|
145
|
-
fieldResolver?: ?GraphQLFieldResolver<any, any>,
|
|
146
|
-
): Promise<ExecutionResult> | ExecutionResult;
|
|
147
|
-
export function execute(
|
|
148
|
-
argsOrSchema,
|
|
149
|
-
document,
|
|
150
|
-
rootValue,
|
|
151
|
-
contextValue,
|
|
152
|
-
variableValues,
|
|
153
|
-
operationName,
|
|
154
|
-
fieldResolver,
|
|
155
|
-
) {
|
|
156
|
-
/* eslint-enable no-redeclare */
|
|
157
|
-
// Extract arguments from object args if provided.
|
|
158
|
-
return arguments.length === 1
|
|
159
|
-
? executeImpl(
|
|
160
|
-
argsOrSchema.schema,
|
|
161
|
-
argsOrSchema.document,
|
|
162
|
-
argsOrSchema.rootValue,
|
|
163
|
-
argsOrSchema.contextValue,
|
|
164
|
-
argsOrSchema.variableValues,
|
|
165
|
-
argsOrSchema.operationName,
|
|
166
|
-
argsOrSchema.fieldResolver,
|
|
167
|
-
)
|
|
168
|
-
: executeImpl(
|
|
169
|
-
argsOrSchema,
|
|
170
|
-
document,
|
|
171
|
-
rootValue,
|
|
172
|
-
contextValue,
|
|
173
|
-
variableValues,
|
|
174
|
-
operationName,
|
|
175
|
-
fieldResolver,
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function executeImpl(
|
|
180
|
-
schema,
|
|
181
|
-
document,
|
|
182
|
-
rootValue,
|
|
183
|
-
contextValue,
|
|
184
|
-
variableValues,
|
|
185
|
-
operationName,
|
|
186
|
-
fieldResolver,
|
|
187
|
-
) {
|
|
188
|
-
// If arguments are missing or incorrect, throw an error.
|
|
189
|
-
assertValidExecutionArguments(schema, document, variableValues);
|
|
190
|
-
|
|
191
|
-
// If a valid context cannot be created due to incorrect arguments,
|
|
192
|
-
// a "Response" with only errors is returned.
|
|
193
|
-
const context = buildExecutionContext(
|
|
194
|
-
schema,
|
|
195
|
-
document,
|
|
196
|
-
rootValue,
|
|
197
|
-
contextValue,
|
|
198
|
-
variableValues,
|
|
199
|
-
operationName,
|
|
200
|
-
fieldResolver,
|
|
201
|
-
);
|
|
202
|
-
|
|
203
|
-
// Return early errors if execution context failed.
|
|
204
|
-
if (Array.isArray(context)) {
|
|
205
|
-
return { errors: context };
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Return a Promise that will eventually resolve to the data described by
|
|
209
|
-
// The "Response" section of the GraphQL specification.
|
|
210
|
-
//
|
|
211
|
-
// If errors are encountered while executing a GraphQL field, only that
|
|
212
|
-
// field and its descendants will be omitted, and sibling fields will still
|
|
213
|
-
// be executed. An execution which encounters errors will still result in a
|
|
214
|
-
// resolved Promise.
|
|
215
|
-
const data = executeOperation(context, context.operation, rootValue);
|
|
216
|
-
return buildResponse(context, data);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Given a completed execution context and data, build the { errors, data }
|
|
221
|
-
* response defined by the "Response" section of the GraphQL specification.
|
|
222
|
-
*/
|
|
223
|
-
function buildResponse(
|
|
224
|
-
context: ExecutionContext,
|
|
225
|
-
data: Promise<ObjMap<mixed> | null> | ObjMap<mixed> | null,
|
|
226
|
-
) {
|
|
227
|
-
const promise = getPromise(data);
|
|
228
|
-
if (promise) {
|
|
229
|
-
return promise.then(resolved => buildResponse(context, resolved));
|
|
230
|
-
}
|
|
231
|
-
return context.errors.length === 0
|
|
232
|
-
? { data }
|
|
233
|
-
: { errors: context.errors, data };
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Given a ResponsePath (found in the `path` entry in the information provided
|
|
238
|
-
* as the last argument to a field resolver), return an Array of the path keys.
|
|
239
|
-
*/
|
|
240
|
-
export function responsePathAsArray(
|
|
241
|
-
path: ResponsePath,
|
|
242
|
-
): $ReadOnlyArray<string | number> {
|
|
243
|
-
const flattened = [];
|
|
244
|
-
let curr = path;
|
|
245
|
-
while (curr) {
|
|
246
|
-
flattened.push(curr.key);
|
|
247
|
-
curr = curr.prev;
|
|
248
|
-
}
|
|
249
|
-
return flattened.reverse();
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Given a ResponsePath and a key, return a new ResponsePath containing the
|
|
254
|
-
* new key.
|
|
255
|
-
*/
|
|
256
|
-
export function addPath(prev: ResponsePath | void, key: string | number) {
|
|
257
|
-
return { prev, key };
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Essential assertions before executing to provide developer feedback for
|
|
262
|
-
* improper use of the GraphQL library.
|
|
263
|
-
*/
|
|
264
|
-
export function assertValidExecutionArguments(
|
|
265
|
-
schema: GraphQLSchema,
|
|
266
|
-
document: DocumentNode,
|
|
267
|
-
rawVariableValues: ?ObjMap<mixed>,
|
|
268
|
-
): void {
|
|
269
|
-
invariant(document, 'Must provide document');
|
|
270
|
-
|
|
271
|
-
// If the schema used for execution is invalid, throw an error.
|
|
272
|
-
assertValidSchema(schema);
|
|
273
|
-
|
|
274
|
-
// Variables, if provided, must be an object.
|
|
275
|
-
invariant(
|
|
276
|
-
!rawVariableValues || typeof rawVariableValues === 'object',
|
|
277
|
-
'Variables must be provided as an Object where each property is a ' +
|
|
278
|
-
'variable value. Perhaps look to see if an unparsed JSON string ' +
|
|
279
|
-
'was provided.',
|
|
280
|
-
);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Constructs a ExecutionContext object from the arguments passed to
|
|
285
|
-
* execute, which we will pass throughout the other execution methods.
|
|
286
|
-
*
|
|
287
|
-
* Throws a GraphQLError if a valid execution context cannot be created.
|
|
288
|
-
*/
|
|
289
|
-
export function buildExecutionContext(
|
|
290
|
-
schema: GraphQLSchema,
|
|
291
|
-
document: DocumentNode,
|
|
292
|
-
rootValue: mixed,
|
|
293
|
-
contextValue: mixed,
|
|
294
|
-
rawVariableValues: ?ObjMap<mixed>,
|
|
295
|
-
operationName: ?string,
|
|
296
|
-
fieldResolver: ?GraphQLFieldResolver<any, any>,
|
|
297
|
-
): $ReadOnlyArray<GraphQLError> | ExecutionContext {
|
|
298
|
-
const errors: Array<GraphQLError> = [];
|
|
299
|
-
let operation: OperationDefinitionNode | void;
|
|
300
|
-
let hasMultipleAssumedOperations = false;
|
|
301
|
-
const fragments: ObjMap<FragmentDefinitionNode> = Object.create(null);
|
|
302
|
-
for (let i = 0; i < document.definitions.length; i++) {
|
|
303
|
-
const definition = document.definitions[i];
|
|
304
|
-
switch (definition.kind) {
|
|
305
|
-
case Kind.OPERATION_DEFINITION:
|
|
306
|
-
if (!operationName && operation) {
|
|
307
|
-
hasMultipleAssumedOperations = true;
|
|
308
|
-
} else if (
|
|
309
|
-
!operationName ||
|
|
310
|
-
(definition.name && definition.name.value === operationName)
|
|
311
|
-
) {
|
|
312
|
-
operation = definition;
|
|
313
|
-
}
|
|
314
|
-
break;
|
|
315
|
-
case Kind.FRAGMENT_DEFINITION:
|
|
316
|
-
fragments[definition.name.value] = definition;
|
|
317
|
-
break;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
if (!operation) {
|
|
322
|
-
if (operationName) {
|
|
323
|
-
errors.push(
|
|
324
|
-
new GraphQLError(`Unknown operation named "${operationName}".`),
|
|
325
|
-
);
|
|
326
|
-
} else {
|
|
327
|
-
errors.push(new GraphQLError('Must provide an operation.'));
|
|
328
|
-
}
|
|
329
|
-
} else if (hasMultipleAssumedOperations) {
|
|
330
|
-
errors.push(
|
|
331
|
-
new GraphQLError(
|
|
332
|
-
'Must provide operation name if query contains ' +
|
|
333
|
-
'multiple operations.',
|
|
334
|
-
),
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
let variableValues;
|
|
339
|
-
if (operation) {
|
|
340
|
-
const coercedVariableValues = getVariableValues(
|
|
341
|
-
schema,
|
|
342
|
-
operation.variableDefinitions || [],
|
|
343
|
-
rawVariableValues || {},
|
|
344
|
-
);
|
|
345
|
-
|
|
346
|
-
if (coercedVariableValues.errors) {
|
|
347
|
-
errors.push(...coercedVariableValues.errors);
|
|
348
|
-
} else {
|
|
349
|
-
variableValues = coercedVariableValues.coerced;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
if (errors.length !== 0) {
|
|
354
|
-
return errors;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
invariant(operation, 'Has operation if no errors.');
|
|
358
|
-
invariant(variableValues, 'Has variables if no errors.');
|
|
359
|
-
|
|
360
|
-
return {
|
|
361
|
-
schema,
|
|
362
|
-
fragments,
|
|
363
|
-
rootValue,
|
|
364
|
-
contextValue,
|
|
365
|
-
operation,
|
|
366
|
-
variableValues,
|
|
367
|
-
fieldResolver: fieldResolver || defaultFieldResolver,
|
|
368
|
-
errors,
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Implements the "Evaluating operations" section of the spec.
|
|
374
|
-
*/
|
|
375
|
-
function executeOperation(
|
|
376
|
-
exeContext: ExecutionContext,
|
|
377
|
-
operation: OperationDefinitionNode,
|
|
378
|
-
rootValue: mixed,
|
|
379
|
-
): Promise<ObjMap<mixed> | null> | ObjMap<mixed> | null {
|
|
380
|
-
const type = getOperationRootType(exeContext.schema, operation);
|
|
381
|
-
const fields = collectFields(
|
|
382
|
-
exeContext,
|
|
383
|
-
type,
|
|
384
|
-
operation.selectionSet,
|
|
385
|
-
Object.create(null),
|
|
386
|
-
Object.create(null),
|
|
387
|
-
);
|
|
388
|
-
|
|
389
|
-
const path = undefined;
|
|
390
|
-
|
|
391
|
-
// Errors from sub-fields of a NonNull type may propagate to the top level,
|
|
392
|
-
// at which point we still log the error and null the parent field, which
|
|
393
|
-
// in this case is the entire response.
|
|
394
|
-
//
|
|
395
|
-
// Similar to completeValueCatchingError.
|
|
396
|
-
try {
|
|
397
|
-
const result =
|
|
398
|
-
operation.operation === 'mutation'
|
|
399
|
-
? executeFieldsSerially(exeContext, type, rootValue, path, fields)
|
|
400
|
-
: executeFields(exeContext, type, rootValue, path, fields);
|
|
401
|
-
const promise = getPromise(result);
|
|
402
|
-
if (promise) {
|
|
403
|
-
return promise.then(undefined, error => {
|
|
404
|
-
exeContext.errors.push(error);
|
|
405
|
-
return Promise.resolve(null);
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
return result;
|
|
409
|
-
} catch (error) {
|
|
410
|
-
exeContext.errors.push(error);
|
|
411
|
-
return null;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
/**
|
|
416
|
-
* Extracts the root type of the operation from the schema.
|
|
417
|
-
*/
|
|
418
|
-
export function getOperationRootType(
|
|
419
|
-
schema: GraphQLSchema,
|
|
420
|
-
operation: OperationDefinitionNode,
|
|
421
|
-
): GraphQLObjectType {
|
|
422
|
-
switch (operation.operation) {
|
|
423
|
-
case 'query':
|
|
424
|
-
const queryType = schema.getQueryType();
|
|
425
|
-
if (!queryType) {
|
|
426
|
-
throw new GraphQLError(
|
|
427
|
-
'Schema does not define the required query root type.',
|
|
428
|
-
[operation],
|
|
429
|
-
);
|
|
430
|
-
}
|
|
431
|
-
return queryType;
|
|
432
|
-
case 'mutation':
|
|
433
|
-
const mutationType = schema.getMutationType();
|
|
434
|
-
if (!mutationType) {
|
|
435
|
-
throw new GraphQLError('Schema is not configured for mutations.', [
|
|
436
|
-
operation,
|
|
437
|
-
]);
|
|
438
|
-
}
|
|
439
|
-
return mutationType;
|
|
440
|
-
case 'subscription':
|
|
441
|
-
const subscriptionType = schema.getSubscriptionType();
|
|
442
|
-
if (!subscriptionType) {
|
|
443
|
-
throw new GraphQLError('Schema is not configured for subscriptions.', [
|
|
444
|
-
operation,
|
|
445
|
-
]);
|
|
446
|
-
}
|
|
447
|
-
return subscriptionType;
|
|
448
|
-
default:
|
|
449
|
-
throw new GraphQLError(
|
|
450
|
-
'Can only execute queries, mutations and subscriptions.',
|
|
451
|
-
[operation],
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
/**
|
|
457
|
-
* Implements the "Evaluating selection sets" section of the spec
|
|
458
|
-
* for "write" mode.
|
|
459
|
-
*/
|
|
460
|
-
function executeFieldsSerially(
|
|
461
|
-
exeContext: ExecutionContext,
|
|
462
|
-
parentType: GraphQLObjectType,
|
|
463
|
-
sourceValue: mixed,
|
|
464
|
-
path: ResponsePath | void,
|
|
465
|
-
fields: ObjMap<Array<FieldNode>>,
|
|
466
|
-
): Promise<ObjMap<mixed>> {
|
|
467
|
-
return Object.keys(fields).reduce(
|
|
468
|
-
(prevPromise, responseName) =>
|
|
469
|
-
prevPromise.then(results => {
|
|
470
|
-
const fieldNodes = fields[responseName];
|
|
471
|
-
const fieldPath = addPath(path, responseName);
|
|
472
|
-
const result = resolveField(
|
|
473
|
-
exeContext,
|
|
474
|
-
parentType,
|
|
475
|
-
sourceValue,
|
|
476
|
-
fieldNodes,
|
|
477
|
-
fieldPath,
|
|
478
|
-
);
|
|
479
|
-
if (result === undefined) {
|
|
480
|
-
return results;
|
|
481
|
-
}
|
|
482
|
-
const promise = getPromise(result);
|
|
483
|
-
if (promise) {
|
|
484
|
-
return promise.then(resolvedResult => {
|
|
485
|
-
results[responseName] = resolvedResult;
|
|
486
|
-
return results;
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
results[responseName] = result;
|
|
490
|
-
return results;
|
|
491
|
-
}),
|
|
492
|
-
Promise.resolve({}),
|
|
493
|
-
);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
/**
|
|
497
|
-
* Implements the "Evaluating selection sets" section of the spec
|
|
498
|
-
* for "read" mode.
|
|
499
|
-
*/
|
|
500
|
-
function executeFields(
|
|
501
|
-
exeContext: ExecutionContext,
|
|
502
|
-
parentType: GraphQLObjectType,
|
|
503
|
-
sourceValue: mixed,
|
|
504
|
-
path: ResponsePath | void,
|
|
505
|
-
fields: ObjMap<Array<FieldNode>>,
|
|
506
|
-
): Promise<ObjMap<mixed>> | ObjMap<mixed> {
|
|
507
|
-
let containsPromise = false;
|
|
508
|
-
|
|
509
|
-
const finalResults = Object.keys(fields).reduce((results, responseName) => {
|
|
510
|
-
const fieldNodes = fields[responseName];
|
|
511
|
-
const fieldPath = addPath(path, responseName);
|
|
512
|
-
const result = resolveField(
|
|
513
|
-
exeContext,
|
|
514
|
-
parentType,
|
|
515
|
-
sourceValue,
|
|
516
|
-
fieldNodes,
|
|
517
|
-
fieldPath,
|
|
518
|
-
);
|
|
519
|
-
if (result === undefined) {
|
|
520
|
-
return results;
|
|
521
|
-
}
|
|
522
|
-
results[responseName] = result;
|
|
523
|
-
if (getPromise(result)) {
|
|
524
|
-
containsPromise = true;
|
|
525
|
-
}
|
|
526
|
-
return results;
|
|
527
|
-
}, Object.create(null));
|
|
528
|
-
|
|
529
|
-
// If there are no promises, we can just return the object
|
|
530
|
-
if (!containsPromise) {
|
|
531
|
-
return finalResults;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
// Otherwise, results is a map from field name to the result
|
|
535
|
-
// of resolving that field, which is possibly a promise. Return
|
|
536
|
-
// a promise that will return this same map, but with any
|
|
537
|
-
// promises replaced with the values they resolved to.
|
|
538
|
-
return promiseForObject(finalResults);
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
/**
|
|
542
|
-
* Given a selectionSet, adds all of the fields in that selection to
|
|
543
|
-
* the passed in map of fields, and returns it at the end.
|
|
544
|
-
*
|
|
545
|
-
* CollectFields requires the "runtime type" of an object. For a field which
|
|
546
|
-
* returns an Interface or Union type, the "runtime type" will be the actual
|
|
547
|
-
* Object type returned by that field.
|
|
548
|
-
*/
|
|
549
|
-
export function collectFields(
|
|
550
|
-
exeContext: ExecutionContext,
|
|
551
|
-
runtimeType: GraphQLObjectType,
|
|
552
|
-
selectionSet: SelectionSetNode,
|
|
553
|
-
fields: ObjMap<Array<FieldNode>>,
|
|
554
|
-
visitedFragmentNames: ObjMap<boolean>,
|
|
555
|
-
): ObjMap<Array<FieldNode>> {
|
|
556
|
-
for (let i = 0; i < selectionSet.selections.length; i++) {
|
|
557
|
-
const selection = selectionSet.selections[i];
|
|
558
|
-
switch (selection.kind) {
|
|
559
|
-
case Kind.FIELD:
|
|
560
|
-
if (!shouldIncludeNode(exeContext, selection)) {
|
|
561
|
-
continue;
|
|
562
|
-
}
|
|
563
|
-
const name = getFieldEntryKey(selection);
|
|
564
|
-
if (!fields[name]) {
|
|
565
|
-
fields[name] = [];
|
|
566
|
-
}
|
|
567
|
-
fields[name].push(selection);
|
|
568
|
-
break;
|
|
569
|
-
case Kind.INLINE_FRAGMENT:
|
|
570
|
-
if (
|
|
571
|
-
!shouldIncludeNode(exeContext, selection) ||
|
|
572
|
-
!doesFragmentConditionMatch(exeContext, selection, runtimeType)
|
|
573
|
-
) {
|
|
574
|
-
continue;
|
|
575
|
-
}
|
|
576
|
-
collectFields(
|
|
577
|
-
exeContext,
|
|
578
|
-
runtimeType,
|
|
579
|
-
selection.selectionSet,
|
|
580
|
-
fields,
|
|
581
|
-
visitedFragmentNames,
|
|
582
|
-
);
|
|
583
|
-
break;
|
|
584
|
-
case Kind.FRAGMENT_SPREAD:
|
|
585
|
-
const fragName = selection.name.value;
|
|
586
|
-
if (
|
|
587
|
-
visitedFragmentNames[fragName] ||
|
|
588
|
-
!shouldIncludeNode(exeContext, selection)
|
|
589
|
-
) {
|
|
590
|
-
continue;
|
|
591
|
-
}
|
|
592
|
-
visitedFragmentNames[fragName] = true;
|
|
593
|
-
const fragment = exeContext.fragments[fragName];
|
|
594
|
-
if (
|
|
595
|
-
!fragment ||
|
|
596
|
-
!doesFragmentConditionMatch(exeContext, fragment, runtimeType)
|
|
597
|
-
) {
|
|
598
|
-
continue;
|
|
599
|
-
}
|
|
600
|
-
collectFields(
|
|
601
|
-
exeContext,
|
|
602
|
-
runtimeType,
|
|
603
|
-
fragment.selectionSet,
|
|
604
|
-
fields,
|
|
605
|
-
visitedFragmentNames,
|
|
606
|
-
);
|
|
607
|
-
break;
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
return fields;
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
/**
|
|
614
|
-
* Determines if a field should be included based on the @include and @skip
|
|
615
|
-
* directives, where @skip has higher precidence than @include.
|
|
616
|
-
*/
|
|
617
|
-
function shouldIncludeNode(
|
|
618
|
-
exeContext: ExecutionContext,
|
|
619
|
-
node: FragmentSpreadNode | FieldNode | InlineFragmentNode,
|
|
620
|
-
): boolean {
|
|
621
|
-
const skip = getDirectiveValues(
|
|
622
|
-
GraphQLSkipDirective,
|
|
623
|
-
node,
|
|
624
|
-
exeContext.variableValues,
|
|
625
|
-
);
|
|
626
|
-
if (skip && skip.if === true) {
|
|
627
|
-
return false;
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
const include = getDirectiveValues(
|
|
631
|
-
GraphQLIncludeDirective,
|
|
632
|
-
node,
|
|
633
|
-
exeContext.variableValues,
|
|
634
|
-
);
|
|
635
|
-
if (include && include.if === false) {
|
|
636
|
-
return false;
|
|
637
|
-
}
|
|
638
|
-
return true;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
/**
|
|
642
|
-
* Determines if a fragment is applicable to the given type.
|
|
643
|
-
*/
|
|
644
|
-
function doesFragmentConditionMatch(
|
|
645
|
-
exeContext: ExecutionContext,
|
|
646
|
-
fragment: FragmentDefinitionNode | InlineFragmentNode,
|
|
647
|
-
type: GraphQLObjectType,
|
|
648
|
-
): boolean {
|
|
649
|
-
const typeConditionNode = fragment.typeCondition;
|
|
650
|
-
if (!typeConditionNode) {
|
|
651
|
-
return true;
|
|
652
|
-
}
|
|
653
|
-
const conditionalType = typeFromAST(exeContext.schema, typeConditionNode);
|
|
654
|
-
if (conditionalType === type) {
|
|
655
|
-
return true;
|
|
656
|
-
}
|
|
657
|
-
if (isAbstractType(conditionalType)) {
|
|
658
|
-
return exeContext.schema.isPossibleType(conditionalType, type);
|
|
659
|
-
}
|
|
660
|
-
return false;
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
/**
|
|
664
|
-
* This function transforms a JS object `ObjMap<Promise<T>>` into
|
|
665
|
-
* a `Promise<ObjMap<T>>`
|
|
666
|
-
*
|
|
667
|
-
* This is akin to bluebird's `Promise.props`, but implemented only using
|
|
668
|
-
* `Promise.all` so it will work with any implementation of ES6 promises.
|
|
669
|
-
*/
|
|
670
|
-
function promiseForObject<T>(object: ObjMap<Promise<T>>): Promise<ObjMap<T>> {
|
|
671
|
-
const keys = Object.keys(object);
|
|
672
|
-
const valuesAndPromises = keys.map(name => object[name]);
|
|
673
|
-
return Promise.all(valuesAndPromises).then(values =>
|
|
674
|
-
values.reduce((resolvedObject, value, i) => {
|
|
675
|
-
resolvedObject[keys[i]] = value;
|
|
676
|
-
return resolvedObject;
|
|
677
|
-
}, Object.create(null)),
|
|
678
|
-
);
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
/**
|
|
682
|
-
* Implements the logic to compute the key of a given field's entry
|
|
683
|
-
*/
|
|
684
|
-
function getFieldEntryKey(node: FieldNode): string {
|
|
685
|
-
return node.alias ? node.alias.value : node.name.value;
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
/**
|
|
689
|
-
* Resolves the field on the given source object. In particular, this
|
|
690
|
-
* figures out the value that the field returns by calling its resolve function,
|
|
691
|
-
* then calls completeValue to complete promises, serialize scalars, or execute
|
|
692
|
-
* the sub-selection-set for objects.
|
|
693
|
-
*/
|
|
694
|
-
function resolveField(
|
|
695
|
-
exeContext: ExecutionContext,
|
|
696
|
-
parentType: GraphQLObjectType,
|
|
697
|
-
source: mixed,
|
|
698
|
-
fieldNodes: $ReadOnlyArray<FieldNode>,
|
|
699
|
-
path: ResponsePath,
|
|
700
|
-
): mixed {
|
|
701
|
-
const fieldNode = fieldNodes[0];
|
|
702
|
-
const fieldName = fieldNode.name.value;
|
|
703
|
-
|
|
704
|
-
const fieldDef = getFieldDef(exeContext.schema, parentType, fieldName);
|
|
705
|
-
if (!fieldDef) {
|
|
706
|
-
return;
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
const resolveFn = fieldDef.resolve || exeContext.fieldResolver;
|
|
710
|
-
|
|
711
|
-
const info = buildResolveInfo(
|
|
712
|
-
exeContext,
|
|
713
|
-
fieldDef,
|
|
714
|
-
fieldNodes,
|
|
715
|
-
parentType,
|
|
716
|
-
path,
|
|
717
|
-
);
|
|
718
|
-
|
|
719
|
-
// Get the resolve function, regardless of if its result is normal
|
|
720
|
-
// or abrupt (error).
|
|
721
|
-
const result = resolveFieldValueOrError(
|
|
722
|
-
exeContext,
|
|
723
|
-
fieldDef,
|
|
724
|
-
fieldNodes,
|
|
725
|
-
resolveFn,
|
|
726
|
-
source,
|
|
727
|
-
info,
|
|
728
|
-
);
|
|
729
|
-
|
|
730
|
-
return completeValueCatchingError(
|
|
731
|
-
exeContext,
|
|
732
|
-
fieldDef.type,
|
|
733
|
-
fieldNodes,
|
|
734
|
-
info,
|
|
735
|
-
path,
|
|
736
|
-
result,
|
|
737
|
-
);
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
export function buildResolveInfo(
|
|
741
|
-
exeContext: ExecutionContext,
|
|
742
|
-
fieldDef: GraphQLField<*, *>,
|
|
743
|
-
fieldNodes: $ReadOnlyArray<FieldNode>,
|
|
744
|
-
parentType: GraphQLObjectType,
|
|
745
|
-
path: ResponsePath,
|
|
746
|
-
): GraphQLResolveInfo {
|
|
747
|
-
// The resolve function's optional fourth argument is a collection of
|
|
748
|
-
// information about the current execution state.
|
|
749
|
-
return {
|
|
750
|
-
fieldName: fieldNodes[0].name.value,
|
|
751
|
-
fieldNodes,
|
|
752
|
-
returnType: fieldDef.type,
|
|
753
|
-
parentType,
|
|
754
|
-
path,
|
|
755
|
-
schema: exeContext.schema,
|
|
756
|
-
fragments: exeContext.fragments,
|
|
757
|
-
rootValue: exeContext.rootValue,
|
|
758
|
-
operation: exeContext.operation,
|
|
759
|
-
variableValues: exeContext.variableValues,
|
|
760
|
-
};
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
// Isolates the "ReturnOrAbrupt" behavior to not de-opt the `resolveField`
|
|
764
|
-
// function. Returns the result of resolveFn or the abrupt-return Error object.
|
|
765
|
-
export function resolveFieldValueOrError<TSource>(
|
|
766
|
-
exeContext: ExecutionContext,
|
|
767
|
-
fieldDef: GraphQLField<TSource, *>,
|
|
768
|
-
fieldNodes: $ReadOnlyArray<FieldNode>,
|
|
769
|
-
resolveFn: GraphQLFieldResolver<TSource, *>,
|
|
770
|
-
source: TSource,
|
|
771
|
-
info: GraphQLResolveInfo,
|
|
772
|
-
): Error | mixed {
|
|
773
|
-
try {
|
|
774
|
-
// Build a JS object of arguments from the field.arguments AST, using the
|
|
775
|
-
// variables scope to fulfill any variable references.
|
|
776
|
-
// TODO: find a way to memoize, in case this field is within a List type.
|
|
777
|
-
const args = getArgumentValues(
|
|
778
|
-
fieldDef,
|
|
779
|
-
fieldNodes[0],
|
|
780
|
-
exeContext.variableValues,
|
|
781
|
-
);
|
|
782
|
-
|
|
783
|
-
// The resolve function's optional third argument is a context value that
|
|
784
|
-
// is provided to every resolve function within an execution. It is commonly
|
|
785
|
-
// used to represent an authenticated user, or request-specific caches.
|
|
786
|
-
const context = exeContext.contextValue;
|
|
787
|
-
|
|
788
|
-
const result = resolveFn(source, args, context, info);
|
|
789
|
-
const promise = getPromise(result);
|
|
790
|
-
return promise ? promise.then(undefined, asErrorInstance) : result;
|
|
791
|
-
} catch (error) {
|
|
792
|
-
return asErrorInstance(error);
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
// Sometimes a non-error is thrown, wrap it as an Error instance to ensure a
|
|
797
|
-
// consistent Error interface.
|
|
798
|
-
function asErrorInstance(error: mixed): Error {
|
|
799
|
-
return error instanceof Error ? error : new Error(error || undefined);
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
// This is a small wrapper around completeValue which detects and logs errors
|
|
803
|
-
// in the execution context.
|
|
804
|
-
function completeValueCatchingError(
|
|
805
|
-
exeContext: ExecutionContext,
|
|
806
|
-
returnType: GraphQLOutputType,
|
|
807
|
-
fieldNodes: $ReadOnlyArray<FieldNode>,
|
|
808
|
-
info: GraphQLResolveInfo,
|
|
809
|
-
path: ResponsePath,
|
|
810
|
-
result: mixed,
|
|
811
|
-
): mixed {
|
|
812
|
-
// If the field type is non-nullable, then it is resolved without any
|
|
813
|
-
// protection from errors, however it still properly locates the error.
|
|
814
|
-
if (isNonNullType(returnType)) {
|
|
815
|
-
return completeValueWithLocatedError(
|
|
816
|
-
exeContext,
|
|
817
|
-
returnType,
|
|
818
|
-
fieldNodes,
|
|
819
|
-
info,
|
|
820
|
-
path,
|
|
821
|
-
result,
|
|
822
|
-
);
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
// Otherwise, error protection is applied, logging the error and resolving
|
|
826
|
-
// a null value for this field if one is encountered.
|
|
827
|
-
try {
|
|
828
|
-
const completed = completeValueWithLocatedError(
|
|
829
|
-
exeContext,
|
|
830
|
-
returnType,
|
|
831
|
-
fieldNodes,
|
|
832
|
-
info,
|
|
833
|
-
path,
|
|
834
|
-
result,
|
|
835
|
-
);
|
|
836
|
-
const promise = getPromise(completed);
|
|
837
|
-
if (promise) {
|
|
838
|
-
// If `completeValueWithLocatedError` returned a rejected promise, log
|
|
839
|
-
// the rejection error and resolve to null.
|
|
840
|
-
// Note: we don't rely on a `catch` method, but we do expect "thenable"
|
|
841
|
-
// to take a second callback for the error case.
|
|
842
|
-
return promise.then(undefined, error => {
|
|
843
|
-
exeContext.errors.push(error);
|
|
844
|
-
return Promise.resolve(null);
|
|
845
|
-
});
|
|
846
|
-
}
|
|
847
|
-
return completed;
|
|
848
|
-
} catch (error) {
|
|
849
|
-
// If `completeValueWithLocatedError` returned abruptly (threw an error),
|
|
850
|
-
// log the error and return null.
|
|
851
|
-
exeContext.errors.push(error);
|
|
852
|
-
return null;
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
// This is a small wrapper around completeValue which annotates errors with
|
|
857
|
-
// location information.
|
|
858
|
-
function completeValueWithLocatedError(
|
|
859
|
-
exeContext: ExecutionContext,
|
|
860
|
-
returnType: GraphQLOutputType,
|
|
861
|
-
fieldNodes: $ReadOnlyArray<FieldNode>,
|
|
862
|
-
info: GraphQLResolveInfo,
|
|
863
|
-
path: ResponsePath,
|
|
864
|
-
result: mixed,
|
|
865
|
-
): mixed {
|
|
866
|
-
try {
|
|
867
|
-
const completed = completeValue(
|
|
868
|
-
exeContext,
|
|
869
|
-
returnType,
|
|
870
|
-
fieldNodes,
|
|
871
|
-
info,
|
|
872
|
-
path,
|
|
873
|
-
result,
|
|
874
|
-
);
|
|
875
|
-
const promise = getPromise(completed);
|
|
876
|
-
if (promise) {
|
|
877
|
-
return promise.then(undefined, error =>
|
|
878
|
-
Promise.reject(
|
|
879
|
-
locatedError(
|
|
880
|
-
asErrorInstance(error),
|
|
881
|
-
fieldNodes,
|
|
882
|
-
responsePathAsArray(path),
|
|
883
|
-
),
|
|
884
|
-
),
|
|
885
|
-
);
|
|
886
|
-
}
|
|
887
|
-
return completed;
|
|
888
|
-
} catch (error) {
|
|
889
|
-
throw locatedError(
|
|
890
|
-
asErrorInstance(error),
|
|
891
|
-
fieldNodes,
|
|
892
|
-
responsePathAsArray(path),
|
|
893
|
-
);
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
/**
|
|
898
|
-
* Implements the instructions for completeValue as defined in the
|
|
899
|
-
* "Field entries" section of the spec.
|
|
900
|
-
*
|
|
901
|
-
* If the field type is Non-Null, then this recursively completes the value
|
|
902
|
-
* for the inner type. It throws a field error if that completion returns null,
|
|
903
|
-
* as per the "Nullability" section of the spec.
|
|
904
|
-
*
|
|
905
|
-
* If the field type is a List, then this recursively completes the value
|
|
906
|
-
* for the inner type on each item in the list.
|
|
907
|
-
*
|
|
908
|
-
* If the field type is a Scalar or Enum, ensures the completed value is a legal
|
|
909
|
-
* value of the type by calling the `serialize` method of GraphQL type
|
|
910
|
-
* definition.
|
|
911
|
-
*
|
|
912
|
-
* If the field is an abstract type, determine the runtime type of the value
|
|
913
|
-
* and then complete based on that type
|
|
914
|
-
*
|
|
915
|
-
* Otherwise, the field type expects a sub-selection set, and will complete the
|
|
916
|
-
* value by evaluating all sub-selections.
|
|
917
|
-
*/
|
|
918
|
-
function completeValue(
|
|
919
|
-
exeContext: ExecutionContext,
|
|
920
|
-
returnType: GraphQLOutputType,
|
|
921
|
-
fieldNodes: $ReadOnlyArray<FieldNode>,
|
|
922
|
-
info: GraphQLResolveInfo,
|
|
923
|
-
path: ResponsePath,
|
|
924
|
-
result: mixed,
|
|
925
|
-
): mixed {
|
|
926
|
-
// If result is a Promise, apply-lift over completeValue.
|
|
927
|
-
const promise = getPromise(result);
|
|
928
|
-
if (promise) {
|
|
929
|
-
return promise.then(resolved =>
|
|
930
|
-
completeValue(exeContext, returnType, fieldNodes, info, path, resolved),
|
|
931
|
-
);
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
// If result is an Error, throw a located error.
|
|
935
|
-
if (result instanceof Error) {
|
|
936
|
-
throw result;
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
// If field type is NonNull, complete for inner type, and throw field error
|
|
940
|
-
// if result is null.
|
|
941
|
-
if (isNonNullType(returnType)) {
|
|
942
|
-
const completed = completeValue(
|
|
943
|
-
exeContext,
|
|
944
|
-
returnType.ofType,
|
|
945
|
-
fieldNodes,
|
|
946
|
-
info,
|
|
947
|
-
path,
|
|
948
|
-
result,
|
|
949
|
-
);
|
|
950
|
-
if (completed === null) {
|
|
951
|
-
throw new Error(
|
|
952
|
-
`Cannot return null for non-nullable field ${info.parentType.name}.${
|
|
953
|
-
info.fieldName
|
|
954
|
-
}.`,
|
|
955
|
-
);
|
|
956
|
-
}
|
|
957
|
-
return completed;
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
// If result value is null-ish (null, undefined, or NaN) then return null.
|
|
961
|
-
if (isNullish(result)) {
|
|
962
|
-
return null;
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
// If field type is List, complete each item in the list with the inner type
|
|
966
|
-
if (isListType(returnType)) {
|
|
967
|
-
return completeListValue(
|
|
968
|
-
exeContext,
|
|
969
|
-
returnType,
|
|
970
|
-
fieldNodes,
|
|
971
|
-
info,
|
|
972
|
-
path,
|
|
973
|
-
result,
|
|
974
|
-
);
|
|
975
|
-
}
|
|
976
|
-
|
|
977
|
-
// If field type is a leaf type, Scalar or Enum, serialize to a valid value,
|
|
978
|
-
// returning null if serialization is not possible.
|
|
979
|
-
if (isLeafType(returnType)) {
|
|
980
|
-
return completeLeafValue(returnType, result);
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
// If field type is an abstract type, Interface or Union, determine the
|
|
984
|
-
// runtime Object type and complete for that type.
|
|
985
|
-
if (isAbstractType(returnType)) {
|
|
986
|
-
return completeAbstractValue(
|
|
987
|
-
exeContext,
|
|
988
|
-
returnType,
|
|
989
|
-
fieldNodes,
|
|
990
|
-
info,
|
|
991
|
-
path,
|
|
992
|
-
result,
|
|
993
|
-
);
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
// If field type is Object, execute and complete all sub-selections.
|
|
997
|
-
if (isObjectType(returnType)) {
|
|
998
|
-
return completeObjectValue(
|
|
999
|
-
exeContext,
|
|
1000
|
-
returnType,
|
|
1001
|
-
fieldNodes,
|
|
1002
|
-
info,
|
|
1003
|
-
path,
|
|
1004
|
-
result,
|
|
1005
|
-
);
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
// Not reachable. All possible output types have been considered.
|
|
1009
|
-
/* istanbul ignore next */
|
|
1010
|
-
throw new Error(
|
|
1011
|
-
`Cannot complete value of unexpected type "${String(
|
|
1012
|
-
(returnType: empty),
|
|
1013
|
-
)}".`,
|
|
1014
|
-
);
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
/**
|
|
1018
|
-
* Complete a list value by completing each item in the list with the
|
|
1019
|
-
* inner type
|
|
1020
|
-
*/
|
|
1021
|
-
function completeListValue(
|
|
1022
|
-
exeContext: ExecutionContext,
|
|
1023
|
-
returnType: GraphQLList<GraphQLOutputType>,
|
|
1024
|
-
fieldNodes: $ReadOnlyArray<FieldNode>,
|
|
1025
|
-
info: GraphQLResolveInfo,
|
|
1026
|
-
path: ResponsePath,
|
|
1027
|
-
result: mixed,
|
|
1028
|
-
): mixed {
|
|
1029
|
-
invariant(
|
|
1030
|
-
isCollection(result),
|
|
1031
|
-
`Expected Iterable, but did not find one for field ${
|
|
1032
|
-
info.parentType.name
|
|
1033
|
-
}.${info.fieldName}.`,
|
|
1034
|
-
);
|
|
1035
|
-
|
|
1036
|
-
// This is specified as a simple map, however we're optimizing the path
|
|
1037
|
-
// where the list contains no Promises by avoiding creating another Promise.
|
|
1038
|
-
const itemType = returnType.ofType;
|
|
1039
|
-
let containsPromise = false;
|
|
1040
|
-
const completedResults = [];
|
|
1041
|
-
forEach((result: any), (item, index) => {
|
|
1042
|
-
// No need to modify the info object containing the path,
|
|
1043
|
-
// since from here on it is not ever accessed by resolver functions.
|
|
1044
|
-
const fieldPath = addPath(path, index);
|
|
1045
|
-
const completedItem = completeValueCatchingError(
|
|
1046
|
-
exeContext,
|
|
1047
|
-
itemType,
|
|
1048
|
-
fieldNodes,
|
|
1049
|
-
info,
|
|
1050
|
-
fieldPath,
|
|
1051
|
-
item,
|
|
1052
|
-
);
|
|
1053
|
-
|
|
1054
|
-
if (!containsPromise && getPromise(completedItem)) {
|
|
1055
|
-
containsPromise = true;
|
|
1056
|
-
}
|
|
1057
|
-
completedResults.push(completedItem);
|
|
1058
|
-
});
|
|
1059
|
-
|
|
1060
|
-
return containsPromise ? Promise.all(completedResults) : completedResults;
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
|
-
/**
|
|
1064
|
-
* Complete a Scalar or Enum by serializing to a valid value, returning
|
|
1065
|
-
* null if serialization is not possible.
|
|
1066
|
-
*/
|
|
1067
|
-
function completeLeafValue(returnType: GraphQLLeafType, result: mixed): mixed {
|
|
1068
|
-
invariant(returnType.serialize, 'Missing serialize method on type');
|
|
1069
|
-
const serializedResult = returnType.serialize(result);
|
|
1070
|
-
if (isInvalid(serializedResult)) {
|
|
1071
|
-
throw new Error(
|
|
1072
|
-
`Expected a value of type "${String(returnType)}" but ` +
|
|
1073
|
-
`received: ${String(result)}`,
|
|
1074
|
-
);
|
|
1075
|
-
}
|
|
1076
|
-
return serializedResult;
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
/**
|
|
1080
|
-
* Complete a value of an abstract type by determining the runtime object type
|
|
1081
|
-
* of that value, then complete the value for that type.
|
|
1082
|
-
*/
|
|
1083
|
-
function completeAbstractValue(
|
|
1084
|
-
exeContext: ExecutionContext,
|
|
1085
|
-
returnType: GraphQLAbstractType,
|
|
1086
|
-
fieldNodes: $ReadOnlyArray<FieldNode>,
|
|
1087
|
-
info: GraphQLResolveInfo,
|
|
1088
|
-
path: ResponsePath,
|
|
1089
|
-
result: mixed,
|
|
1090
|
-
): mixed {
|
|
1091
|
-
const runtimeType = returnType.resolveType
|
|
1092
|
-
? returnType.resolveType(result, exeContext.contextValue, info)
|
|
1093
|
-
: defaultResolveTypeFn(result, exeContext.contextValue, info, returnType);
|
|
1094
|
-
|
|
1095
|
-
const promise = getPromise(runtimeType);
|
|
1096
|
-
if (promise) {
|
|
1097
|
-
return promise.then(resolvedRuntimeType =>
|
|
1098
|
-
completeObjectValue(
|
|
1099
|
-
exeContext,
|
|
1100
|
-
ensureValidRuntimeType(
|
|
1101
|
-
resolvedRuntimeType,
|
|
1102
|
-
exeContext,
|
|
1103
|
-
returnType,
|
|
1104
|
-
fieldNodes,
|
|
1105
|
-
info,
|
|
1106
|
-
result,
|
|
1107
|
-
),
|
|
1108
|
-
fieldNodes,
|
|
1109
|
-
info,
|
|
1110
|
-
path,
|
|
1111
|
-
result,
|
|
1112
|
-
),
|
|
1113
|
-
);
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
return completeObjectValue(
|
|
1117
|
-
exeContext,
|
|
1118
|
-
ensureValidRuntimeType(
|
|
1119
|
-
((runtimeType: any): ?GraphQLObjectType | string),
|
|
1120
|
-
exeContext,
|
|
1121
|
-
returnType,
|
|
1122
|
-
fieldNodes,
|
|
1123
|
-
info,
|
|
1124
|
-
result,
|
|
1125
|
-
),
|
|
1126
|
-
fieldNodes,
|
|
1127
|
-
info,
|
|
1128
|
-
path,
|
|
1129
|
-
result,
|
|
1130
|
-
);
|
|
1131
|
-
}
|
|
1132
|
-
|
|
1133
|
-
function ensureValidRuntimeType(
|
|
1134
|
-
runtimeTypeOrName: ?GraphQLObjectType | string,
|
|
1135
|
-
exeContext: ExecutionContext,
|
|
1136
|
-
returnType: GraphQLAbstractType,
|
|
1137
|
-
fieldNodes: $ReadOnlyArray<FieldNode>,
|
|
1138
|
-
info: GraphQLResolveInfo,
|
|
1139
|
-
result: mixed,
|
|
1140
|
-
): GraphQLObjectType {
|
|
1141
|
-
const runtimeType =
|
|
1142
|
-
typeof runtimeTypeOrName === 'string'
|
|
1143
|
-
? exeContext.schema.getType(runtimeTypeOrName)
|
|
1144
|
-
: runtimeTypeOrName;
|
|
1145
|
-
|
|
1146
|
-
if (!isObjectType(runtimeType)) {
|
|
1147
|
-
throw new GraphQLError(
|
|
1148
|
-
`Abstract type ${returnType.name} must resolve to an Object type at ` +
|
|
1149
|
-
`runtime for field ${info.parentType.name}.${info.fieldName} with ` +
|
|
1150
|
-
`value "${String(result)}", received "${String(runtimeType)}". ` +
|
|
1151
|
-
`Either the ${returnType.name} type should provide a "resolveType" ` +
|
|
1152
|
-
'function or each possible types should provide an ' +
|
|
1153
|
-
'"isTypeOf" function.',
|
|
1154
|
-
fieldNodes,
|
|
1155
|
-
);
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
if (!exeContext.schema.isPossibleType(returnType, runtimeType)) {
|
|
1159
|
-
throw new GraphQLError(
|
|
1160
|
-
`Runtime Object type "${runtimeType.name}" is not a possible type ` +
|
|
1161
|
-
`for "${returnType.name}".`,
|
|
1162
|
-
fieldNodes,
|
|
1163
|
-
);
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
return runtimeType;
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
/**
|
|
1170
|
-
* Complete an Object value by executing all sub-selections.
|
|
1171
|
-
*/
|
|
1172
|
-
function completeObjectValue(
|
|
1173
|
-
exeContext: ExecutionContext,
|
|
1174
|
-
returnType: GraphQLObjectType,
|
|
1175
|
-
fieldNodes: $ReadOnlyArray<FieldNode>,
|
|
1176
|
-
info: GraphQLResolveInfo,
|
|
1177
|
-
path: ResponsePath,
|
|
1178
|
-
result: mixed,
|
|
1179
|
-
): mixed {
|
|
1180
|
-
// If there is an isTypeOf predicate function, call it with the
|
|
1181
|
-
// current result. If isTypeOf returns false, then raise an error rather
|
|
1182
|
-
// than continuing execution.
|
|
1183
|
-
if (returnType.isTypeOf) {
|
|
1184
|
-
const isTypeOf = returnType.isTypeOf(result, exeContext.contextValue, info);
|
|
1185
|
-
|
|
1186
|
-
const promise = getPromise(isTypeOf);
|
|
1187
|
-
if (promise) {
|
|
1188
|
-
return promise.then(isTypeOfResult => {
|
|
1189
|
-
if (!isTypeOfResult) {
|
|
1190
|
-
throw invalidReturnTypeError(returnType, result, fieldNodes);
|
|
1191
|
-
}
|
|
1192
|
-
return collectAndExecuteSubfields(
|
|
1193
|
-
exeContext,
|
|
1194
|
-
returnType,
|
|
1195
|
-
fieldNodes,
|
|
1196
|
-
info,
|
|
1197
|
-
path,
|
|
1198
|
-
result,
|
|
1199
|
-
);
|
|
1200
|
-
});
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
if (!isTypeOf) {
|
|
1204
|
-
throw invalidReturnTypeError(returnType, result, fieldNodes);
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
return collectAndExecuteSubfields(
|
|
1209
|
-
exeContext,
|
|
1210
|
-
returnType,
|
|
1211
|
-
fieldNodes,
|
|
1212
|
-
info,
|
|
1213
|
-
path,
|
|
1214
|
-
result,
|
|
1215
|
-
);
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
function invalidReturnTypeError(
|
|
1219
|
-
returnType: GraphQLObjectType,
|
|
1220
|
-
result: mixed,
|
|
1221
|
-
fieldNodes: $ReadOnlyArray<FieldNode>,
|
|
1222
|
-
): GraphQLError {
|
|
1223
|
-
return new GraphQLError(
|
|
1224
|
-
`Expected value of type "${returnType.name}" but got: ${String(result)}.`,
|
|
1225
|
-
fieldNodes,
|
|
1226
|
-
);
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1229
|
-
function collectAndExecuteSubfields(
|
|
1230
|
-
exeContext: ExecutionContext,
|
|
1231
|
-
returnType: GraphQLObjectType,
|
|
1232
|
-
fieldNodes: $ReadOnlyArray<FieldNode>,
|
|
1233
|
-
info: GraphQLResolveInfo,
|
|
1234
|
-
path: ResponsePath,
|
|
1235
|
-
result: mixed,
|
|
1236
|
-
): mixed {
|
|
1237
|
-
// Collect sub-fields to execute to complete this value.
|
|
1238
|
-
let subFieldNodes = Object.create(null);
|
|
1239
|
-
const visitedFragmentNames = Object.create(null);
|
|
1240
|
-
for (let i = 0; i < fieldNodes.length; i++) {
|
|
1241
|
-
const selectionSet = fieldNodes[i].selectionSet;
|
|
1242
|
-
if (selectionSet) {
|
|
1243
|
-
subFieldNodes = collectFields(
|
|
1244
|
-
exeContext,
|
|
1245
|
-
returnType,
|
|
1246
|
-
selectionSet,
|
|
1247
|
-
subFieldNodes,
|
|
1248
|
-
visitedFragmentNames,
|
|
1249
|
-
);
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
return executeFields(exeContext, returnType, result, path, subFieldNodes);
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
/**
|
|
1257
|
-
* If a resolveType function is not given, then a default resolve behavior is
|
|
1258
|
-
* used which attempts two strategies:
|
|
1259
|
-
*
|
|
1260
|
-
* First, See if the provided value has a `__typename` field defined, if so, use
|
|
1261
|
-
* that value as name of the resolved type.
|
|
1262
|
-
*
|
|
1263
|
-
* Otherwise, test each possible type for the abstract type by calling
|
|
1264
|
-
* isTypeOf for the object being coerced, returning the first type that matches.
|
|
1265
|
-
*/
|
|
1266
|
-
function defaultResolveTypeFn(
|
|
1267
|
-
value: mixed,
|
|
1268
|
-
context: mixed,
|
|
1269
|
-
info: GraphQLResolveInfo,
|
|
1270
|
-
abstractType: GraphQLAbstractType,
|
|
1271
|
-
): ?GraphQLObjectType | string | Promise<?GraphQLObjectType | string> {
|
|
1272
|
-
// First, look for `__typename`.
|
|
1273
|
-
if (
|
|
1274
|
-
value !== null &&
|
|
1275
|
-
typeof value === 'object' &&
|
|
1276
|
-
typeof value.__typename === 'string'
|
|
1277
|
-
) {
|
|
1278
|
-
return value.__typename;
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
// Otherwise, test each possible type.
|
|
1282
|
-
const possibleTypes = info.schema.getPossibleTypes(abstractType);
|
|
1283
|
-
const promisedIsTypeOfResults = [];
|
|
1284
|
-
|
|
1285
|
-
for (let i = 0; i < possibleTypes.length; i++) {
|
|
1286
|
-
const type = possibleTypes[i];
|
|
1287
|
-
|
|
1288
|
-
if (type.isTypeOf) {
|
|
1289
|
-
const isTypeOfResult = type.isTypeOf(value, context, info);
|
|
1290
|
-
|
|
1291
|
-
const promise = getPromise(isTypeOfResult);
|
|
1292
|
-
if (promise) {
|
|
1293
|
-
promisedIsTypeOfResults[i] = promise;
|
|
1294
|
-
} else if (isTypeOfResult) {
|
|
1295
|
-
return type;
|
|
1296
|
-
}
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
|
-
if (promisedIsTypeOfResults.length) {
|
|
1301
|
-
return Promise.all(promisedIsTypeOfResults).then(isTypeOfResults => {
|
|
1302
|
-
for (let i = 0; i < isTypeOfResults.length; i++) {
|
|
1303
|
-
if (isTypeOfResults[i]) {
|
|
1304
|
-
return possibleTypes[i];
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
});
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
|
|
1311
|
-
/**
|
|
1312
|
-
* If a resolve function is not given, then a default resolve behavior is used
|
|
1313
|
-
* which takes the property of the source object of the same name as the field
|
|
1314
|
-
* and returns it as the result, or if it's a function, returns the result
|
|
1315
|
-
* of calling that function while passing along args and context.
|
|
1316
|
-
*/
|
|
1317
|
-
export const defaultFieldResolver: GraphQLFieldResolver<any, *> = function(
|
|
1318
|
-
source,
|
|
1319
|
-
args,
|
|
1320
|
-
context,
|
|
1321
|
-
info,
|
|
1322
|
-
) {
|
|
1323
|
-
// ensure source is a value for which property access is acceptable.
|
|
1324
|
-
if (typeof source === 'object' || typeof source === 'function') {
|
|
1325
|
-
const property = source[info.fieldName];
|
|
1326
|
-
if (typeof property === 'function') {
|
|
1327
|
-
return source[info.fieldName](args, context, info);
|
|
1328
|
-
}
|
|
1329
|
-
return property;
|
|
1330
|
-
}
|
|
1331
|
-
};
|
|
1332
|
-
|
|
1333
|
-
/**
|
|
1334
|
-
* Only returns the value if it acts like a Promise, i.e. has a "then" function,
|
|
1335
|
-
* otherwise returns void.
|
|
1336
|
-
*/
|
|
1337
|
-
function getPromise<T>(value: Promise<T> | mixed): Promise<T> | void {
|
|
1338
|
-
if (
|
|
1339
|
-
typeof value === 'object' &&
|
|
1340
|
-
value !== null &&
|
|
1341
|
-
typeof value.then === 'function'
|
|
1342
|
-
) {
|
|
1343
|
-
return (value: any);
|
|
1344
|
-
}
|
|
1345
|
-
}
|
|
1346
|
-
|
|
1347
|
-
/**
|
|
1348
|
-
* This method looks up the field on the given type defintion.
|
|
1349
|
-
* It has special casing for the two introspection fields, __schema
|
|
1350
|
-
* and __typename. __typename is special because it can always be
|
|
1351
|
-
* queried as a field, even in situations where no other fields
|
|
1352
|
-
* are allowed, like on a Union. __schema could get automatically
|
|
1353
|
-
* added to the query type, but that would require mutating type
|
|
1354
|
-
* definitions, which would cause issues.
|
|
1355
|
-
*/
|
|
1356
|
-
export function getFieldDef(
|
|
1357
|
-
schema: GraphQLSchema,
|
|
1358
|
-
parentType: GraphQLObjectType,
|
|
1359
|
-
fieldName: string,
|
|
1360
|
-
): ?GraphQLField<*, *> {
|
|
1361
|
-
if (
|
|
1362
|
-
fieldName === SchemaMetaFieldDef.name &&
|
|
1363
|
-
schema.getQueryType() === parentType
|
|
1364
|
-
) {
|
|
1365
|
-
return SchemaMetaFieldDef;
|
|
1366
|
-
} else if (
|
|
1367
|
-
fieldName === TypeMetaFieldDef.name &&
|
|
1368
|
-
schema.getQueryType() === parentType
|
|
1369
|
-
) {
|
|
1370
|
-
return TypeMetaFieldDef;
|
|
1371
|
-
} else if (fieldName === TypeNameMetaFieldDef.name) {
|
|
1372
|
-
return TypeNameMetaFieldDef;
|
|
1373
|
-
}
|
|
1374
|
-
return parentType.getFields()[fieldName];
|
|
1375
|
-
}
|