UNPKG

graphql

Version:

A Query Language and Runtime which can target any service.

201 lines 7.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ValidationContext = exports.SDLValidationContext = exports.ASTValidationContext = void 0; const kinds_ts_1 = require("../language/kinds.js"); const visitor_ts_1 = require("../language/visitor.js"); const TypeInfo_ts_1 = require("../utilities/TypeInfo.js"); class ASTValidationContext { constructor(ast, onError) { this._ast = ast; this._fragments = undefined; this._fragmentSpreads = new Map(); this._recursivelyReferencedFragments = new Map(); this._onError = onError; } get [Symbol.toStringTag]() { return 'ASTValidationContext'; } reportError(error) { this._onError(error); } getDocument() { return this._ast; } getFragment(name) { let fragments; if (this._fragments) { fragments = this._fragments; } else { fragments = Object.create(null); for (const defNode of this.getDocument().definitions) { if (defNode.kind === kinds_ts_1.Kind.FRAGMENT_DEFINITION) { fragments[defNode.name.value] = defNode; } } this._fragments = fragments; } return fragments[name]; } getFragmentSpreads(node) { let spreads = this._fragmentSpreads.get(node); if (!spreads) { spreads = []; const setsToVisit = [node]; let set; while ((set = setsToVisit.pop())) { for (const selection of set.selections) { if (selection.kind === kinds_ts_1.Kind.FRAGMENT_SPREAD) { spreads.push(selection); } else if (selection.selectionSet) { setsToVisit.push(selection.selectionSet); } } } this._fragmentSpreads.set(node, spreads); } return spreads; } getRecursivelyReferencedFragments(operation) { let fragments = this._recursivelyReferencedFragments.get(operation); if (!fragments) { fragments = []; const collectedNames = new Set(); const nodesToVisit = [operation.selectionSet]; let node; while ((node = nodesToVisit.pop())) { for (const spread of this.getFragmentSpreads(node)) { const fragName = spread.name.value; if (!collectedNames.has(fragName)) { collectedNames.add(fragName); const fragment = this.getFragment(fragName); if (fragment) { fragments.push(fragment); nodesToVisit.push(fragment.selectionSet); } } } } this._recursivelyReferencedFragments.set(operation, fragments); } return fragments; } } exports.ASTValidationContext = ASTValidationContext; class SDLValidationContext extends ASTValidationContext { constructor(ast, schema, onError) { super(ast, onError); this._schema = schema; } get hideSuggestions() { return false; } get [Symbol.toStringTag]() { return 'SDLValidationContext'; } getSchema() { return this._schema; } } exports.SDLValidationContext = SDLValidationContext; class ValidationContext extends ASTValidationContext { constructor(schema, ast, typeInfo, onError, hideSuggestions) { super(ast, onError); this._schema = schema; this._typeInfo = typeInfo; this._variableUsages = new Map(); this._recursiveVariableUsages = new Map(); this._hideSuggestions = hideSuggestions ?? false; } get [Symbol.toStringTag]() { return 'ValidationContext'; } get hideSuggestions() { return this._hideSuggestions; } getSchema() { return this._schema; } getVariableUsages(node) { let usages = this._variableUsages.get(node); if (!usages) { const newUsages = []; const typeInfo = new TypeInfo_ts_1.TypeInfo(this._schema, undefined, this._typeInfo.getFragmentSignatureByName()); const fragmentDefinition = node.kind === kinds_ts_1.Kind.FRAGMENT_DEFINITION ? node : undefined; (0, visitor_ts_1.visit)(node, (0, TypeInfo_ts_1.visitWithTypeInfo)(typeInfo, { VariableDefinition: () => false, Variable(variable) { let fragmentVariableDefinition; if (fragmentDefinition) { const fragmentSignature = typeInfo.getFragmentSignatureByName()(fragmentDefinition.name.value); fragmentVariableDefinition = fragmentSignature?.variableDefinitions.get(variable.name.value); newUsages.push({ node: variable, type: typeInfo.getInputType(), parentType: typeInfo.getParentInputType(), defaultValue: undefined, fragmentVariableDefinition, }); } else { newUsages.push({ node: variable, type: typeInfo.getInputType(), parentType: typeInfo.getParentInputType(), defaultValue: typeInfo.getDefaultValue(), fragmentVariableDefinition: undefined, }); } }, })); usages = newUsages; this._variableUsages.set(node, usages); } return usages; } getRecursiveVariableUsages(operation) { let usages = this._recursiveVariableUsages.get(operation); if (!usages) { usages = this.getVariableUsages(operation); for (const frag of this.getRecursivelyReferencedFragments(operation)) { usages = usages.concat(this.getVariableUsages(frag)); } this._recursiveVariableUsages.set(operation, usages); } return usages; } getType() { return this._typeInfo.getType(); } getParentType() { return this._typeInfo.getParentType(); } getInputType() { return this._typeInfo.getInputType(); } getParentInputType() { return this._typeInfo.getParentInputType(); } getFieldDef() { return this._typeInfo.getFieldDef(); } getDirective() { return this._typeInfo.getDirective(); } getArgument() { return this._typeInfo.getArgument(); } getFragmentSignature() { return this._typeInfo.getFragmentSignature(); } getFragmentSignatureByName() { return this._typeInfo.getFragmentSignatureByName(); } getEnumValue() { return this._typeInfo.getEnumValue(); } } exports.ValidationContext = ValidationContext; //# sourceMappingURL=ValidationContext.js.map