import type { Maybe } from '../jsutils/Maybe.js';
import { GraphQLError } from '../error/GraphQLError.js';
import type { DocumentNode } from '../language/ast.js';
import { visit, visitInParallel } from '../language/visitor.js';
import type { GraphQLSchema } from '../type/schema.js';
import { assertValidSchema } from '../type/validate.js';
import { TypeInfo, visitWithTypeInfo } from '../utilities/TypeInfo.js';
import { specifiedRules, specifiedSDLRules } from './specifiedRules.js';
import type { SDLValidationRule, ValidationRule } from './ValidationContext.js';
import {
SDLValidationContext,
ValidationContext,
} from './ValidationContext.js';
export function validate(
schema: GraphQLSchema,
documentAST: DocumentNode,
rules: ReadonlyArray<ValidationRule> = specifiedRules,
options?: { maxErrors?: number },
typeInfo: TypeInfo = new TypeInfo(schema),
): ReadonlyArray<GraphQLError> {
const maxErrors = options?.maxErrors ?? 100;
assertValidSchema(schema);
const abortError = new GraphQLError(
'Too many validation errors, error limit reached. Validation aborted.',
);
const errors: Array<GraphQLError> = [];
const context = new ValidationContext(
schema,
documentAST,
typeInfo,
(error) => {
if (errors.length >= maxErrors) {
throw abortError;
}
errors.push(error);
},
);
const visitor = visitInParallel(rules.map((rule) => rule(context)));
try {
visit(documentAST, visitWithTypeInfo(typeInfo, visitor));
} catch (e: unknown) {
if (e === abortError) {
errors.push(abortError);
} else {
throw e;
}
}
return errors;
}
export function validateSDL(
documentAST: DocumentNode,
schemaToExtend?: Maybe<GraphQLSchema>,
rules: ReadonlyArray<SDLValidationRule> = specifiedSDLRules,
): ReadonlyArray<GraphQLError> {
const errors: Array<GraphQLError> = [];
const context = new SDLValidationContext(
documentAST,
schemaToExtend,
(error) => {
errors.push(error);
},
);
const visitors = rules.map((rule) => rule(context));
visit(documentAST, visitInParallel(visitors));
return errors;
}
export function assertValidSDL(documentAST: DocumentNode): void {
const errors = validateSDL(documentAST);
if (errors.length !== 0) {
throw new Error(errors.map((error) => error.message).join('\n\n'));
}
}
export function assertValidSDLExtension(
documentAST: DocumentNode,
schema: GraphQLSchema,
): void {
const errors = validateSDL(documentAST, schema);
if (errors.length !== 0) {
throw new Error(errors.map((error) => error.message).join('\n\n'));
}
}