From 4a9505fe1a3a1b378b068ada02eca07950030315 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Fri, 3 Aug 2018 18:54:19 +0300 Subject: [PATCH] Split out 'ASTValidationContext' --- src/utilities/isValidLiteralValue.js | 2 +- src/validation/ValidationContext.js | 41 +++++++++++-------- src/validation/index.js | 4 +- src/validation/rules/ExecutableDefinitions.js | 6 ++- src/validation/rules/FieldsOnCorrectType.js | 2 +- .../rules/FragmentsOnCompositeTypes.js | 2 +- src/validation/rules/KnownArgumentNames.js | 2 +- src/validation/rules/KnownDirectives.js | 2 +- src/validation/rules/KnownFragmentNames.js | 2 +- src/validation/rules/KnownTypeNames.js | 2 +- .../rules/LoneAnonymousOperation.js | 6 ++- src/validation/rules/NoFragmentCycles.js | 2 +- src/validation/rules/NoUndefinedVariables.js | 2 +- src/validation/rules/NoUnusedFragments.js | 2 +- src/validation/rules/NoUnusedVariables.js | 2 +- .../rules/OverlappingFieldsCanBeMerged.js | 2 +- .../rules/PossibleFragmentSpreads.js | 2 +- .../rules/ProvidedRequiredArguments.js | 2 +- src/validation/rules/ScalarLeafs.js | 2 +- .../rules/SingleFieldSubscriptions.js | 4 +- src/validation/rules/UniqueArgumentNames.js | 4 +- .../rules/UniqueDirectivesPerLocation.js | 4 +- src/validation/rules/UniqueFragmentNames.js | 4 +- src/validation/rules/UniqueInputFieldNames.js | 6 ++- src/validation/rules/UniqueOperationNames.js | 6 ++- src/validation/rules/UniqueVariableNames.js | 4 +- src/validation/rules/ValuesOfCorrectType.js | 2 +- .../rules/VariablesAreInputTypes.js | 2 +- .../rules/VariablesInAllowedPosition.js | 2 +- src/validation/specifiedRules.js | 2 +- src/validation/validate.js | 2 +- 31 files changed, 71 insertions(+), 58 deletions(-) diff --git a/src/utilities/isValidLiteralValue.js b/src/utilities/isValidLiteralValue.js index 2ecb60f9d9..1b7806cf83 100644 --- a/src/utilities/isValidLiteralValue.js +++ b/src/utilities/isValidLiteralValue.js @@ -15,7 +15,7 @@ import { visit, visitWithTypeInfo } from '../language/visitor'; import type { GraphQLInputType } from '../type/definition'; import { GraphQLSchema } from '../type/schema'; import { ValuesOfCorrectType } from '../validation/rules/ValuesOfCorrectType'; -import ValidationContext from '../validation/ValidationContext'; +import { ValidationContext } from '../validation/ValidationContext'; /** * Utility which determines if a value literal node is valid for an input type. diff --git a/src/validation/ValidationContext.js b/src/validation/ValidationContext.js index d8a98a0bdd..ba7b358a0d 100644 --- a/src/validation/ValidationContext.js +++ b/src/validation/ValidationContext.js @@ -42,11 +42,31 @@ type VariableUsage = {| * allowing access to commonly useful contextual information from within a * validation rule. */ -export default class ValidationContext { - _schema: GraphQLSchema; +export class ASTValidationContext { _ast: DocumentNode; - _typeInfo: TypeInfo; _errors: Array; + + constructor(ast: DocumentNode): void { + this._ast = ast; + this._errors = []; + } + + reportError(error: GraphQLError): void { + this._errors.push(error); + } + + getErrors(): $ReadOnlyArray { + return this._errors; + } + + getDocument(): DocumentNode { + return this._ast; + } +} + +export class ValidationContext extends ASTValidationContext { + _schema: GraphQLSchema; + _typeInfo: TypeInfo; _fragments: ObjMap; _fragmentSpreads: Map>; _recursivelyReferencedFragments: Map< @@ -64,32 +84,19 @@ export default class ValidationContext { ast: DocumentNode, typeInfo: TypeInfo, ): void { + super(ast); this._schema = schema; - this._ast = ast; this._typeInfo = typeInfo; - this._errors = []; this._fragmentSpreads = new Map(); this._recursivelyReferencedFragments = new Map(); this._variableUsages = new Map(); this._recursiveVariableUsages = new Map(); } - reportError(error: GraphQLError): void { - this._errors.push(error); - } - - getErrors(): $ReadOnlyArray { - return this._errors; - } - getSchema(): GraphQLSchema { return this._schema; } - getDocument(): DocumentNode { - return this._ast; - } - getFragment(name: string): ?FragmentDefinitionNode { let fragments = this._fragments; if (!fragments) { diff --git a/src/validation/index.js b/src/validation/index.js index afcff6994b..5bd949765e 100644 --- a/src/validation/index.js +++ b/src/validation/index.js @@ -9,9 +9,7 @@ export { validate } from './validate'; -// https://github.com/tc39/proposal-export-default-from -import ValidationContext from './ValidationContext'; -export { ValidationContext }; +export { ValidationContext } from './ValidationContext'; export { specifiedRules } from './specifiedRules'; diff --git a/src/validation/rules/ExecutableDefinitions.js b/src/validation/rules/ExecutableDefinitions.js index dc9ee61282..188bbbcb29 100644 --- a/src/validation/rules/ExecutableDefinitions.js +++ b/src/validation/rules/ExecutableDefinitions.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ASTValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import { Kind } from '../../language/kinds'; import type { ASTVisitor } from '../../language/visitor'; @@ -22,7 +22,9 @@ export function nonExecutableDefinitionMessage(defName: string): string { * A GraphQL document is only valid for execution if all definitions are either * operation or fragment definitions. */ -export function ExecutableDefinitions(context: ValidationContext): ASTVisitor { +export function ExecutableDefinitions( + context: ASTValidationContext, +): ASTVisitor { return { Document(node) { for (const definition of node.definitions) { diff --git a/src/validation/rules/FieldsOnCorrectType.js b/src/validation/rules/FieldsOnCorrectType.js index d20ba9e93d..a67c394c4c 100644 --- a/src/validation/rules/FieldsOnCorrectType.js +++ b/src/validation/rules/FieldsOnCorrectType.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import suggestionList from '../../jsutils/suggestionList'; import quotedOrList from '../../jsutils/quotedOrList'; diff --git a/src/validation/rules/FragmentsOnCompositeTypes.js b/src/validation/rules/FragmentsOnCompositeTypes.js index 6f2e0b87f5..36d2eac404 100644 --- a/src/validation/rules/FragmentsOnCompositeTypes.js +++ b/src/validation/rules/FragmentsOnCompositeTypes.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import { print } from '../../language/printer'; import type { ASTVisitor } from '../../language/visitor'; diff --git a/src/validation/rules/KnownArgumentNames.js b/src/validation/rules/KnownArgumentNames.js index a775880c21..36a5e82e79 100644 --- a/src/validation/rules/KnownArgumentNames.js +++ b/src/validation/rules/KnownArgumentNames.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { ASTVisitor } from '../../language/visitor'; import suggestionList from '../../jsutils/suggestionList'; diff --git a/src/validation/rules/KnownDirectives.js b/src/validation/rules/KnownDirectives.js index 05c12f39f6..c812f8e23f 100644 --- a/src/validation/rules/KnownDirectives.js +++ b/src/validation/rules/KnownDirectives.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import find from '../../jsutils/find'; import { Kind } from '../../language/kinds'; diff --git a/src/validation/rules/KnownFragmentNames.js b/src/validation/rules/KnownFragmentNames.js index c3893415f0..7135801c11 100644 --- a/src/validation/rules/KnownFragmentNames.js +++ b/src/validation/rules/KnownFragmentNames.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { ASTVisitor } from '../../language/visitor'; diff --git a/src/validation/rules/KnownTypeNames.js b/src/validation/rules/KnownTypeNames.js index 8ad1b7775f..04daa4191d 100644 --- a/src/validation/rules/KnownTypeNames.js +++ b/src/validation/rules/KnownTypeNames.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import suggestionList from '../../jsutils/suggestionList'; import quotedOrList from '../../jsutils/quotedOrList'; diff --git a/src/validation/rules/LoneAnonymousOperation.js b/src/validation/rules/LoneAnonymousOperation.js index 745de201cb..e3ef981cd8 100644 --- a/src/validation/rules/LoneAnonymousOperation.js +++ b/src/validation/rules/LoneAnonymousOperation.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ASTValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import { Kind } from '../../language/kinds'; import type { ASTVisitor } from '../../language/visitor'; @@ -22,7 +22,9 @@ export function anonOperationNotAloneMessage(): string { * A GraphQL document is only valid if when it contains an anonymous operation * (the query short-hand) that it contains only that one operation definition. */ -export function LoneAnonymousOperation(context: ValidationContext): ASTVisitor { +export function LoneAnonymousOperation( + context: ASTValidationContext, +): ASTVisitor { let operationCount = 0; return { Document(node) { diff --git a/src/validation/rules/NoFragmentCycles.js b/src/validation/rules/NoFragmentCycles.js index 1066e2a83b..63219028fe 100644 --- a/src/validation/rules/NoFragmentCycles.js +++ b/src/validation/rules/NoFragmentCycles.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { FragmentDefinitionNode } from '../../language/ast'; import type { ASTVisitor } from '../../language/visitor'; diff --git a/src/validation/rules/NoUndefinedVariables.js b/src/validation/rules/NoUndefinedVariables.js index 142142f437..0fcfe50af5 100644 --- a/src/validation/rules/NoUndefinedVariables.js +++ b/src/validation/rules/NoUndefinedVariables.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { ASTVisitor } from '../../language/visitor'; diff --git a/src/validation/rules/NoUnusedFragments.js b/src/validation/rules/NoUnusedFragments.js index 51d54bc51d..a3ff40758b 100644 --- a/src/validation/rules/NoUnusedFragments.js +++ b/src/validation/rules/NoUnusedFragments.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { ASTVisitor } from '../../language/visitor'; diff --git a/src/validation/rules/NoUnusedVariables.js b/src/validation/rules/NoUnusedVariables.js index a964837cc0..378616fd7f 100644 --- a/src/validation/rules/NoUnusedVariables.js +++ b/src/validation/rules/NoUnusedVariables.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { ASTVisitor } from '../../language/visitor'; diff --git a/src/validation/rules/OverlappingFieldsCanBeMerged.js b/src/validation/rules/OverlappingFieldsCanBeMerged.js index a75ecb0f56..aa546971a7 100644 --- a/src/validation/rules/OverlappingFieldsCanBeMerged.js +++ b/src/validation/rules/OverlappingFieldsCanBeMerged.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import inspect from '../../jsutils/inspect'; import find from '../../jsutils/find'; diff --git a/src/validation/rules/PossibleFragmentSpreads.js b/src/validation/rules/PossibleFragmentSpreads.js index 4461d5aeb3..465efa126c 100644 --- a/src/validation/rules/PossibleFragmentSpreads.js +++ b/src/validation/rules/PossibleFragmentSpreads.js @@ -8,7 +8,7 @@ */ import inspect from '../../jsutils/inspect'; -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { ASTVisitor } from '../../language/visitor'; import { doTypesOverlap } from '../../utilities/typeComparators'; diff --git a/src/validation/rules/ProvidedRequiredArguments.js b/src/validation/rules/ProvidedRequiredArguments.js index a4a97cc3d3..38a911b333 100644 --- a/src/validation/rules/ProvidedRequiredArguments.js +++ b/src/validation/rules/ProvidedRequiredArguments.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import inspect from '../../jsutils/inspect'; import keyMap from '../../jsutils/keyMap'; diff --git a/src/validation/rules/ScalarLeafs.js b/src/validation/rules/ScalarLeafs.js index ba2818d00a..28b82dae0f 100644 --- a/src/validation/rules/ScalarLeafs.js +++ b/src/validation/rules/ScalarLeafs.js @@ -8,7 +8,7 @@ */ import inspect from '../../jsutils/inspect'; -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { FieldNode } from '../../language/ast'; import { getNamedType, isLeafType } from '../../type/definition'; diff --git a/src/validation/rules/SingleFieldSubscriptions.js b/src/validation/rules/SingleFieldSubscriptions.js index 622e6fc5f8..900295689d 100644 --- a/src/validation/rules/SingleFieldSubscriptions.js +++ b/src/validation/rules/SingleFieldSubscriptions.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ASTValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { OperationDefinitionNode } from '../../language/ast'; import type { ASTVisitor } from '../../language/visitor'; @@ -25,7 +25,7 @@ export function singleFieldOnlyMessage(name: ?string): string { * A GraphQL subscription is valid only if it contains a single root field. */ export function SingleFieldSubscriptions( - context: ValidationContext, + context: ASTValidationContext, ): ASTVisitor { return { OperationDefinition(node: OperationDefinitionNode) { diff --git a/src/validation/rules/UniqueArgumentNames.js b/src/validation/rules/UniqueArgumentNames.js index 0516401079..474072b13d 100644 --- a/src/validation/rules/UniqueArgumentNames.js +++ b/src/validation/rules/UniqueArgumentNames.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ASTValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { ASTVisitor } from '../../language/visitor'; @@ -21,7 +21,7 @@ export function duplicateArgMessage(argName: string): string { * A GraphQL field or directive is only valid if all supplied arguments are * uniquely named. */ -export function UniqueArgumentNames(context: ValidationContext): ASTVisitor { +export function UniqueArgumentNames(context: ASTValidationContext): ASTVisitor { let knownArgNames = Object.create(null); return { Field() { diff --git a/src/validation/rules/UniqueDirectivesPerLocation.js b/src/validation/rules/UniqueDirectivesPerLocation.js index a714312bd5..393ca0c947 100644 --- a/src/validation/rules/UniqueDirectivesPerLocation.js +++ b/src/validation/rules/UniqueDirectivesPerLocation.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ASTValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { DirectiveNode } from '../../language/ast'; import type { ASTVisitor } from '../../language/visitor'; @@ -26,7 +26,7 @@ export function duplicateDirectiveMessage(directiveName: string): string { * are uniquely named. */ export function UniqueDirectivesPerLocation( - context: ValidationContext, + context: ASTValidationContext, ): ASTVisitor { return { // Many different AST nodes may contain directives. Rather than listing diff --git a/src/validation/rules/UniqueFragmentNames.js b/src/validation/rules/UniqueFragmentNames.js index 1a55cd7967..9bedb9e116 100644 --- a/src/validation/rules/UniqueFragmentNames.js +++ b/src/validation/rules/UniqueFragmentNames.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ASTValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { ASTVisitor } from '../../language/visitor'; @@ -20,7 +20,7 @@ export function duplicateFragmentNameMessage(fragName: string): string { * * A GraphQL document is only valid if all defined fragments have unique names. */ -export function UniqueFragmentNames(context: ValidationContext): ASTVisitor { +export function UniqueFragmentNames(context: ASTValidationContext): ASTVisitor { const knownFragmentNames = Object.create(null); return { OperationDefinition: () => false, diff --git a/src/validation/rules/UniqueInputFieldNames.js b/src/validation/rules/UniqueInputFieldNames.js index 9290b60305..38ecec05db 100644 --- a/src/validation/rules/UniqueInputFieldNames.js +++ b/src/validation/rules/UniqueInputFieldNames.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ASTValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { ASTVisitor } from '../../language/visitor'; @@ -21,7 +21,9 @@ export function duplicateInputFieldMessage(fieldName: string): string { * A GraphQL input object value is only valid if all supplied fields are * uniquely named. */ -export function UniqueInputFieldNames(context: ValidationContext): ASTVisitor { +export function UniqueInputFieldNames( + context: ASTValidationContext, +): ASTVisitor { const knownNameStack = []; let knownNames = Object.create(null); diff --git a/src/validation/rules/UniqueOperationNames.js b/src/validation/rules/UniqueOperationNames.js index 765b0b80f4..96ba243d77 100644 --- a/src/validation/rules/UniqueOperationNames.js +++ b/src/validation/rules/UniqueOperationNames.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ASTValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { ASTVisitor } from '../../language/visitor'; @@ -20,7 +20,9 @@ export function duplicateOperationNameMessage(operationName: string): string { * * A GraphQL document is only valid if all defined operations have unique names. */ -export function UniqueOperationNames(context: ValidationContext): ASTVisitor { +export function UniqueOperationNames( + context: ASTValidationContext, +): ASTVisitor { const knownOperationNames = Object.create(null); return { OperationDefinition(node) { diff --git a/src/validation/rules/UniqueVariableNames.js b/src/validation/rules/UniqueVariableNames.js index 90f84483ec..5b71c00d76 100644 --- a/src/validation/rules/UniqueVariableNames.js +++ b/src/validation/rules/UniqueVariableNames.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ASTValidationContext } from '../ValidationContext'; import type { VariableDefinitionNode } from '../../language/ast'; import { GraphQLError } from '../../error'; import type { ASTVisitor } from '../../language/visitor'; @@ -21,7 +21,7 @@ export function duplicateVariableMessage(variableName: string): string { * * A GraphQL operation is only valid if all its variables are uniquely named. */ -export function UniqueVariableNames(context: ValidationContext): ASTVisitor { +export function UniqueVariableNames(context: ASTValidationContext): ASTVisitor { let knownVariableNames = Object.create(null); return { OperationDefinition() { diff --git a/src/validation/rules/ValuesOfCorrectType.js b/src/validation/rules/ValuesOfCorrectType.js index f7197e64bb..5c2d3b58d3 100644 --- a/src/validation/rules/ValuesOfCorrectType.js +++ b/src/validation/rules/ValuesOfCorrectType.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { ValueNode } from '../../language/ast'; import { print } from '../../language/printer'; diff --git a/src/validation/rules/VariablesAreInputTypes.js b/src/validation/rules/VariablesAreInputTypes.js index b152025c02..7076bd8a1f 100644 --- a/src/validation/rules/VariablesAreInputTypes.js +++ b/src/validation/rules/VariablesAreInputTypes.js @@ -7,7 +7,7 @@ * @flow strict */ -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import type { VariableDefinitionNode } from '../../language/ast'; import { print } from '../../language/printer'; diff --git a/src/validation/rules/VariablesInAllowedPosition.js b/src/validation/rules/VariablesInAllowedPosition.js index 551ec79922..2d80c37e46 100644 --- a/src/validation/rules/VariablesInAllowedPosition.js +++ b/src/validation/rules/VariablesInAllowedPosition.js @@ -8,7 +8,7 @@ */ import inspect from '../../jsutils/inspect'; -import type ValidationContext from '../ValidationContext'; +import type { ValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error'; import { Kind } from '../../language/kinds'; import type { ValueNode } from '../../language/ast'; diff --git a/src/validation/specifiedRules.js b/src/validation/specifiedRules.js index 93c115cb3c..63677e154e 100644 --- a/src/validation/specifiedRules.js +++ b/src/validation/specifiedRules.js @@ -8,7 +8,7 @@ */ import type { ASTVisitor } from '../language/visitor'; -import type ValidationContext from './ValidationContext'; +import type { ValidationContext } from './ValidationContext'; // Spec Section: "Executable Definitions" import { ExecutableDefinitions } from './rules/ExecutableDefinitions'; diff --git a/src/validation/validate.js b/src/validation/validate.js index 25dac126d4..bde2f699e3 100644 --- a/src/validation/validate.js +++ b/src/validation/validate.js @@ -16,7 +16,7 @@ import type { GraphQLSchema } from '../type/schema'; import { assertValidSchema } from '../type/validate'; import { TypeInfo } from '../utilities/TypeInfo'; import { specifiedRules } from './specifiedRules'; -import ValidationContext from './ValidationContext'; +import { ValidationContext } from './ValidationContext'; /** * Implements the "Validation" section of the spec.