node_modules.graphql.validation.validate.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apollo-client-maven-plugin Show documentation
Show all versions of apollo-client-maven-plugin Show documentation
Maven plugin for generating graphql clients
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ValidationContext = undefined;
exports.validate = validate;
var _invariant = require('../jsutils/invariant');
var _invariant2 = _interopRequireDefault(_invariant);
var _error = require('../error');
var _visitor = require('../language/visitor');
var _kinds = require('../language/kinds');
var Kind = _interopRequireWildcard(_kinds);
var _schema = require('../type/schema');
var _TypeInfo = require('../utilities/TypeInfo');
var _specifiedRules = require('./specifiedRules');
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
/**
* Implements the "Validation" section of the spec.
*
* Validation runs synchronously, returning an array of encountered errors, or
* an empty array if no errors were encountered and the document is valid.
*
* A list of specific validation rules may be provided. If not provided, the
* default list of rules defined by the GraphQL specification will be used.
*
* Each validation rules is a function which returns a visitor
* (see the language/visitor API). Visitor methods are expected to return
* GraphQLErrors, or Arrays of GraphQLErrors when invalid.
*
* Optionally a custom TypeInfo instance may be provided. If not provided, one
* will be created from the provided schema.
*/
function validate(schema, ast, rules, typeInfo) {
!schema ? (0, _invariant2.default)(0, 'Must provide schema') : void 0;
!ast ? (0, _invariant2.default)(0, 'Must provide document') : void 0;
!(schema instanceof _schema.GraphQLSchema) ? (0, _invariant2.default)(0, 'Schema must be an instance of GraphQLSchema. Also ensure that there are ' + 'not multiple versions of GraphQL installed in your node_modules directory.') : void 0;
return visitUsingRules(schema, typeInfo || new _TypeInfo.TypeInfo(schema), ast, rules || _specifiedRules.specifiedRules);
}
/**
* This uses a specialized visitor which runs multiple visitors in parallel,
* while maintaining the visitor skip and break API.
*
* @internal
*/
function visitUsingRules(schema, typeInfo, documentAST, rules) {
var context = new ValidationContext(schema, documentAST, typeInfo);
var visitors = rules.map(function (rule) {
return rule(context);
});
// Visit the whole document with each instance of all provided rules.
(0, _visitor.visit)(documentAST, (0, _visitor.visitWithTypeInfo)(typeInfo, (0, _visitor.visitInParallel)(visitors)));
return context.getErrors();
}
/**
* An instance of this class is passed as the "this" context to all validators,
* allowing access to commonly useful contextual information from within a
* validation rule.
*/
var ValidationContext = exports.ValidationContext = function () {
function ValidationContext(schema, ast, typeInfo) {
_classCallCheck(this, ValidationContext);
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();
}
ValidationContext.prototype.reportError = function reportError(error) {
this._errors.push(error);
};
ValidationContext.prototype.getErrors = function getErrors() {
return this._errors;
};
ValidationContext.prototype.getSchema = function getSchema() {
return this._schema;
};
ValidationContext.prototype.getDocument = function getDocument() {
return this._ast;
};
ValidationContext.prototype.getFragment = function getFragment(name) {
var fragments = this._fragments;
if (!fragments) {
this._fragments = fragments = this.getDocument().definitions.reduce(function (frags, statement) {
if (statement.kind === Kind.FRAGMENT_DEFINITION) {
frags[statement.name.value] = statement;
}
return frags;
}, Object.create(null));
}
return fragments[name];
};
ValidationContext.prototype.getFragmentSpreads = function getFragmentSpreads(node) {
var spreads = this._fragmentSpreads.get(node);
if (!spreads) {
spreads = [];
var setsToVisit = [node];
while (setsToVisit.length !== 0) {
var set = setsToVisit.pop();
for (var i = 0; i < set.selections.length; i++) {
var selection = set.selections[i];
if (selection.kind === Kind.FRAGMENT_SPREAD) {
spreads.push(selection);
} else if (selection.selectionSet) {
setsToVisit.push(selection.selectionSet);
}
}
}
this._fragmentSpreads.set(node, spreads);
}
return spreads;
};
ValidationContext.prototype.getRecursivelyReferencedFragments = function getRecursivelyReferencedFragments(operation) {
var fragments = this._recursivelyReferencedFragments.get(operation);
if (!fragments) {
fragments = [];
var collectedNames = Object.create(null);
var nodesToVisit = [operation.selectionSet];
while (nodesToVisit.length !== 0) {
var _node = nodesToVisit.pop();
var spreads = this.getFragmentSpreads(_node);
for (var i = 0; i < spreads.length; i++) {
var fragName = spreads[i].name.value;
if (collectedNames[fragName] !== true) {
collectedNames[fragName] = true;
var fragment = this.getFragment(fragName);
if (fragment) {
fragments.push(fragment);
nodesToVisit.push(fragment.selectionSet);
}
}
}
}
this._recursivelyReferencedFragments.set(operation, fragments);
}
return fragments;
};
ValidationContext.prototype.getVariableUsages = function getVariableUsages(node) {
var usages = this._variableUsages.get(node);
if (!usages) {
var newUsages = [];
var typeInfo = new _TypeInfo.TypeInfo(this._schema);
(0, _visitor.visit)(node, (0, _visitor.visitWithTypeInfo)(typeInfo, {
VariableDefinition: function VariableDefinition() {
return false;
},
Variable: function Variable(variable) {
newUsages.push({ node: variable, type: typeInfo.getInputType() });
}
}));
usages = newUsages;
this._variableUsages.set(node, usages);
}
return usages;
};
ValidationContext.prototype.getRecursiveVariableUsages = function getRecursiveVariableUsages(operation) {
var usages = this._recursiveVariableUsages.get(operation);
if (!usages) {
usages = this.getVariableUsages(operation);
var fragments = this.getRecursivelyReferencedFragments(operation);
for (var i = 0; i < fragments.length; i++) {
Array.prototype.push.apply(usages, this.getVariableUsages(fragments[i]));
}
this._recursiveVariableUsages.set(operation, usages);
}
return usages;
};
ValidationContext.prototype.getType = function getType() {
return this._typeInfo.getType();
};
ValidationContext.prototype.getParentType = function getParentType() {
return this._typeInfo.getParentType();
};
ValidationContext.prototype.getInputType = function getInputType() {
return this._typeInfo.getInputType();
};
ValidationContext.prototype.getFieldDef = function getFieldDef() {
return this._typeInfo.getFieldDef();
};
ValidationContext.prototype.getDirective = function getDirective() {
return this._typeInfo.getDirective();
};
ValidationContext.prototype.getArgument = function getArgument() {
return this._typeInfo.getArgument();
};
return ValidationContext;
}();