UNPKG

graphql-codegen

Version:

Generate client code based on a GraphQL schema and query documents

430 lines (335 loc) 14.8 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.CodeGenerationContext = undefined; var _from = require('babel-runtime/core-js/array/from'); var _from2 = _interopRequireDefault(_from); var _assign = require('babel-runtime/core-js/object/assign'); var _assign2 = _interopRequireDefault(_assign); var _keys = require('babel-runtime/core-js/object/keys'); var _keys2 = _interopRequireDefault(_keys); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _getIterator2 = require('babel-runtime/core-js/get-iterator'); var _getIterator3 = _interopRequireDefault(_getIterator2); var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray'); var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); var _values = require('babel-runtime/core-js/object/values'); var _values2 = _interopRequireDefault(_values); var _create = require('babel-runtime/core-js/object/create'); var _create2 = _interopRequireDefault(_create); var _set = require('babel-runtime/core-js/set'); var _set2 = _interopRequireDefault(_set); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); exports.printFields = printFields; var _graphql = require('graphql'); var _printing = require('./utilities/printing.js'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // Parts of this code are adapted from graphql-js var CodeGenerationContext = exports.CodeGenerationContext = function () { function CodeGenerationContext(schema, document) { var _this = this; (0, _classCallCheck3.default)(this, CodeGenerationContext); this.schema = schema; this.typesUsedSet = new _set2.default(); this.fragmentMap = (0, _create2.default)(null); var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = (0, _getIterator3.default)(document.definitions), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var definition = _step.value; if (definition.kind === _graphql.Kind.FRAGMENT_DEFINITION) { this.fragmentMap[definition.name.value] = this.augmentWithTypes(definition); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } this.queries = []; var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = (0, _getIterator3.default)(document.definitions), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var _definition = _step2.value; if (_definition.kind === _graphql.Kind.OPERATION_DEFINITION) { var _augmentWithTypes = this.augmentWithTypes(_definition); var loc = _augmentWithTypes.loc; var name = _augmentWithTypes.name; var operation = _augmentWithTypes.operation; var variableDefinitions = _augmentWithTypes.variableDefinitions; var selectionSet = _augmentWithTypes.selectionSet; var variables = variableDefinitions.map(function (node) { return { name: node.variable.name.value, type: node.type }; }); var rootType = operationRootType(this.schema, operation); var _collectFieldsAndFrag3 = this.collectFieldsAndFragmentNames(rootType, selectionSet); var _collectFieldsAndFrag4 = (0, _slicedToArray3.default)(_collectFieldsAndFrag3, 1); var groupedFieldSet = _collectFieldsAndFrag4[0]; var _resolveFields3 = this.resolveFields(groupedFieldSet); var _resolveFields4 = (0, _slicedToArray3.default)(_resolveFields3, 2); var fields = _resolveFields4[0]; var fragmentNames = _resolveFields4[1]; this.queries.push({ name: name.value, variables: variables, fields: fields, source: sourceAt(loc), fragmentNames: fragmentNames }); } } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } this.fragments = (0, _values2.default)(this.fragmentMap).map(function (_ref) { var loc = _ref.loc; var name = _ref.name; var typeCondition = _ref.typeCondition; var selectionSet = _ref.selectionSet; var fragmentType = (0, _graphql.typeFromAST)(_this.schema, typeCondition); var _collectFieldsAndFrag = _this.collectFieldsAndFragmentNames(fragmentType, selectionSet); var _collectFieldsAndFrag2 = (0, _slicedToArray3.default)(_collectFieldsAndFrag, 1); var groupedFieldSet = _collectFieldsAndFrag2[0]; var _resolveFields = _this.resolveFields(groupedFieldSet); var _resolveFields2 = (0, _slicedToArray3.default)(_resolveFields, 1); var fields = _resolveFields2[0]; return { name: name.value, fields: fields, source: sourceAt(loc) }; }); } (0, _createClass3.default)(CodeGenerationContext, [{ key: 'augmentWithTypes', value: function augmentWithTypes(ast) { var _this2 = this; var typeInfo = new _graphql.TypeInfo(this.schema); return (0, _graphql.visit)(ast, (0, _graphql.visitWithTypeInfo)(typeInfo, { leave: { VariableDefinition: function VariableDefinition(node) { var type = typeInfo.getInputType(); _this2.addUsedType(type); return (0, _extends3.default)({}, node, { type: type }); }, Field: function Field(node) { var type = typeInfo.getType(); _this2.addUsedType(type); return (0, _extends3.default)({}, node, { type: type }); } } })); } }, { key: 'addUsedType', value: function addUsedType(type) { var namedType = (0, _graphql.getNamedType)(type); this.typesUsedSet.add(namedType); } }, { key: 'collectFieldsAndFragmentNames', value: function collectFieldsAndFragmentNames(parentType, selectionSet) { var groupedFieldSet = arguments.length <= 2 || arguments[2] === undefined ? (0, _create2.default)(null) : arguments[2]; var visitedFragmentSet = arguments.length <= 3 || arguments[3] === undefined ? (0, _create2.default)(null) : arguments[3]; if (!(0, _graphql.isCompositeType)(parentType)) { throw new Error('parentType should be a composite type'); } var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = (0, _getIterator3.default)(selectionSet.selections), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var selection = _step3.value; switch (selection.kind) { case _graphql.Kind.FIELD: { var fieldName = selection.name.value; var responseName = selection.alias ? selection.alias.value : fieldName; var field = parentType.getFields()[fieldName]; if (!field) { throw new _graphql.GraphQLError('Cannot query field "' + fieldName + '" on type "' + parentType.name + '"', [selection]); } var fieldType = field.type; if (!groupedFieldSet[responseName]) { groupedFieldSet[responseName] = []; } groupedFieldSet[responseName].push((0, _extends3.default)({}, selection, { type: fieldType })); break; } case _graphql.Kind.INLINE_FRAGMENT: { var typeCondition = selection.typeCondition; var inlineFragmentType = typeCondition ? (0, _graphql.typeFromAST)(this.schema, typeCondition) : parentType; if (inlineFragmentType !== parentType) { throw new _graphql.GraphQLError('Apollo iOS does not yet support polymorphic results through type conditions', [typeCondition]); } this.collectFieldsAndFragmentNames(inlineFragmentType, selection.selectionSet, groupedFieldSet, visitedFragmentSet); break; } case _graphql.Kind.FRAGMENT_SPREAD: { var fragmentName = selection.name.value; if (visitedFragmentSet[fragmentName]) continue; visitedFragmentSet[fragmentName] = true; var fragment = this.fragmentMap[fragmentName]; if (!fragment) continue; var _typeCondition = fragment.typeCondition; var fragmentType = (0, _graphql.typeFromAST)(this.schema, _typeCondition); if (fragmentType !== parentType) { throw new _graphql.GraphQLError('Apollo iOS does not yet support polymorphic results through type conditions', [_typeCondition]); } this.collectFieldsAndFragmentNames(fragmentType, fragment.selectionSet, groupedFieldSet, visitedFragmentSet); break; } } } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } return [groupedFieldSet, visitedFragmentSet]; } }, { key: 'resolveFields', value: function resolveFields(groupedFieldSet) { var fields = []; var fragmentNameSet = (0, _create2.default)(null); var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = (0, _getIterator3.default)((0, _keys2.default)(groupedFieldSet)), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var name = _step4.value; var fieldSet = groupedFieldSet[name]; var type = fieldSet[0].type; var field = { name: name, type: type }; var namedType = (0, _graphql.getNamedType)(type); if ((0, _graphql.isCompositeType)(namedType)) { var _mergeSelectionSets = this.mergeSelectionSets(namedType, fieldSet); var _mergeSelectionSets2 = (0, _slicedToArray3.default)(_mergeSelectionSets, 2); var nestedGroupedFieldSet = _mergeSelectionSets2[0]; var nestedFragmentNameSet = _mergeSelectionSets2[1]; fragmentNameSet = (0, _assign2.default)(fragmentNameSet, nestedFragmentNameSet); field.fragmentNames = (0, _keys2.default)(nestedFragmentNameSet); var _resolveFields5 = this.resolveFields(nestedGroupedFieldSet); var _resolveFields6 = (0, _slicedToArray3.default)(_resolveFields5, 1); var subfields = _resolveFields6[0]; field.subfields = subfields; } fields.push(field); } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } return [fields, (0, _keys2.default)(fragmentNameSet)]; } }, { key: 'mergeSelectionSets', value: function mergeSelectionSets(parentType, fieldSet) { var groupedFieldSet = (0, _create2.default)(null); var visitedFragmentSet = (0, _create2.default)(null); var _iteratorNormalCompletion5 = true; var _didIteratorError5 = false; var _iteratorError5 = undefined; try { for (var _iterator5 = (0, _getIterator3.default)(fieldSet), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { var field = _step5.value; var selectionSet = field.selectionSet; if (selectionSet) { this.collectFieldsAndFragmentNames(parentType, selectionSet, groupedFieldSet, visitedFragmentSet); }; } } catch (err) { _didIteratorError5 = true; _iteratorError5 = err; } finally { try { if (!_iteratorNormalCompletion5 && _iterator5.return) { _iterator5.return(); } } finally { if (_didIteratorError5) { throw _iteratorError5; } } } return [groupedFieldSet, visitedFragmentSet]; } }, { key: 'typesUsed', get: function get() { return (0, _from2.default)(this.typesUsedSet); } }]); return CodeGenerationContext; }(); function sourceAt(location) { return location.source.body.slice(location.start, location.end); } function printFields(fields) { return fields && (0, _printing.block)(fields.map(function (field) { return field.name + ': ' + String(field.type) + (0, _printing.wrap)(' ', printFields(field.subfields)); })); } /** * Extracts the root type of the operation from the schema. */ function operationRootType(schema, operation) { switch (operation) { case 'query': return schema.getQueryType(); case 'mutation': var mutationType = schema.getMutationType(); if (!mutationType) { throw new _graphql.GraphQLError('Schema is not configured for mutations', [operation]); } return mutationType; case 'subscription': var subscriptionType = schema.getSubscriptionType(); if (!subscriptionType) { throw new _graphql.GraphQLError('Schema is not configured for subscriptions', [operation]); } return subscriptionType; default: throw new _graphql.GraphQLError('Can only execute queries, mutations and subscriptions', [operation]); } }