Socket
Socket
Sign inDemoInstall

apollo-codegen

Package Overview
Dependencies
Maintainers
1
Versions
102
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apollo-codegen - npm Package Compare versions

Comparing version 0.12.1 to 0.12.3

lib/env-setup.js

151

lib/cli.js
#!/usr/bin/env node
'use strict';
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
require('./env-setup');
var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
var _glob = require('glob');

@@ -36,4 +32,6 @@

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
// Make sure unhandled errors in async code are propagated correctly
_process2.default.on('unhandledRejection', error => {
_process2.default.on('unhandledRejection', function (error) {
throw error;

@@ -49,3 +47,3 @@ });

_yargs2.default.command('download-schema <server>', 'Download a GraphQL schema from a server', {
_yargs2.default.command(['introspect-schema <schema>', 'download-schema'], 'Generate an introspection JSON from a local GraphQL file or from a remote GraphQL server', {
output: {

@@ -62,16 +60,37 @@ demand: true,

type: 'array',
coerce: arg => {
let additionalHeaders = {};
for (const header of arg) {
var _header$split = header.split(/\s*:\s*/),
_header$split2 = (0, _slicedToArray3.default)(_header$split, 2);
coerce: function coerce(arg) {
var additionalHeaders = {};
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
const name = _header$split2[0],
try {
for (var _iterator = arg[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var header = _step.value;
var _header$split = header.split(/\s*:\s*/),
_header$split2 = _slicedToArray(_header$split, 2),
name = _header$split2[0],
value = _header$split2[1];
if (!(name && value)) {
throw new _errors.ToolError('Headers should be specified as "Name: Value"');
if (!(name && value)) {
throw new _errors.ToolError('Headers should be specified as "Name: Value"');
}
additionalHeaders[name] = value;
}
additionalHeaders[name] = value;
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return additionalHeaders;

@@ -85,15 +104,79 @@ }

}
}, (() => {
var _ref = (0, _asyncToGenerator3.default)(function* (argv) {
const outputPath = _path2.default.resolve(argv.output);
const additionalHeaders = argv.header;
yield (0, _.downloadSchema)(argv.server, outputPath, additionalHeaders, argv.insecure);
});
}, function () {
var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee(argv) {
var schema, output, header, insecure, urlRegex;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
schema = argv.schema, output = argv.output, header = argv.header, insecure = argv.insecure;
urlRegex = /^https?:\/\//i;
if (!urlRegex.test(schema)) {
_context.next = 7;
break;
}
_context.next = 5;
return (0, _.downloadSchema)(schema, output, header, insecure);
case 5:
_context.next = 9;
break;
case 7:
_context.next = 9;
return (0, _.introspectSchema)(schema, output);
case 9:
case 'end':
return _context.stop();
}
}
}, _callee, undefined);
}));
return function (_x) {
return _ref.apply(this, arguments);
};
})()).command('generate [input...]', 'Generate code from a GraphQL schema and query documents', {
}()).command(['print-schema [schema]'], 'Print the provided schema in the GraphQL schema language format', {
schema: {
demand: true,
describe: 'Path to GraphQL introspection query result',
default: 'schema.json',
normalize: true,
coerce: _path2.default.resolve
},
output: {
demand: true,
describe: 'Output path for GraphQL schema language file',
default: 'schema.graphql',
normalize: true,
coerce: _path2.default.resolve
}
}, function () {
var _ref2 = _asyncToGenerator(regeneratorRuntime.mark(function _callee2(argv) {
var schema, output;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
schema = argv.schema, output = argv.output;
_context2.next = 3;
return (0, _.printSchema)(schema, output);
case 3:
case 'end':
return _context2.stop();
}
}
}, _callee2, undefined);
}));
return function (_x2) {
return _ref2.apply(this, arguments);
};
}()).command('generate [input...]', 'Generate code from a GraphQL schema and query documents', {
schema: {
demand: true,
describe: 'Path to GraphQL schema file',

@@ -130,5 +213,10 @@ default: 'schema.json',

normalize: true
},
"add-typename": {
demand: false,
describe: "For non-swift targets, always add the __typename GraphQL introspection type when generating target types",
default: false
}
}, argv => {
let input = argv.input;
}, function (argv) {
var input = argv.input;

@@ -140,9 +228,16 @@ // Use glob if the user's shell was unable to expand the pattern

}
const inputPaths = input.map(input => _path2.default.resolve(input));
const options = {
var inputPaths = input.map(function (input) {
return _path2.default.resolve(input);
}
// Sort to normalize different glob expansions between different terminals.
).sort();
var options = {
passthroughCustomScalars: argv["passthrough-custom-scalars"] || argv["custom-scalars-prefix"] !== '',
customScalarsPrefix: argv["custom-scalars-prefix"] || '',
addTypename: argv["add-typename"],
namespace: argv.namespace
};
(0, _.generate)(inputPaths, argv.schema, argv.output, argv.target, options);

@@ -149,0 +244,0 @@ }).fail(function (message, error) {

835

lib/compilation.js

@@ -8,42 +8,6 @@ 'use strict';

var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
var _entries = require('babel-runtime/core-js/object/entries');
var _entries2 = _interopRequireDefault(_entries);
var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _map = require('babel-runtime/core-js/map');
var _map2 = _interopRequireDefault(_map);
var _from = require('babel-runtime/core-js/array/from');
var _from2 = _interopRequireDefault(_from);
var _values = require('babel-runtime/core-js/object/values');
var _values2 = _interopRequireDefault(_values);
var _set = require('babel-runtime/core-js/set');
var _set2 = _interopRequireDefault(_set);
var _create = require('babel-runtime/core-js/object/create');
var _create2 = _interopRequireDefault(_create);
exports.compileToIR = compileToIR;

@@ -58,378 +22,677 @@ exports.printIR = printIR;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
// Parts of this code are adapted from graphql-js
function compileToIR(schema, document) {
const compiler = new Compiler(schema, (0, _graphql2.withTypenameFieldAddedWhereNeeded)(schema, document));
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { mergeInFieldsFromFragmentSpreads: true };
const operations = (0, _create2.default)(null);
if (options.addTypename) {
document = (0, _graphql2.withTypenameFieldAddedWhereNeeded)(schema, document);
}
compiler.operations.forEach(operation => {
var compiler = new Compiler(schema, document, options);
var operations = Object.create(null);
compiler.operations.forEach(function (operation) {
operations[operation.name.value] = compiler.compileOperation(operation);
});
const fragments = (0, _create2.default)(null);
var fragments = Object.create(null);
compiler.fragments.forEach(fragment => {
compiler.fragments.forEach(function (fragment) {
fragments[fragment.name.value] = compiler.compileFragment(fragment);
});
const typesUsed = compiler.typesUsed;
var typesUsed = compiler.typesUsed;
return { schema: schema, operations: operations, fragments: fragments, typesUsed: typesUsed };
return { schema, operations, fragments, typesUsed };
}
class Compiler {
constructor(schema, document) {
var Compiler = exports.Compiler = function () {
function Compiler(schema, document, options) {
_classCallCheck(this, Compiler);
this.schema = schema;
this.options = options;
this.typesUsedSet = new _set2.default();
this.typesUsedSet = new Set();
this.fragmentMap = (0, _create2.default)(null);
this.fragmentMap = Object.create(null);
this.operations = [];
for (const definition of document.definitions) {
switch (definition.kind) {
case _graphql.Kind.OPERATION_DEFINITION:
this.operations.push(definition);
break;
case _graphql.Kind.FRAGMENT_DEFINITION:
this.fragmentMap[definition.name.value] = definition;
break;
}
}
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
this.compiledFragmentMap = (0, _create2.default)(null);
}
try {
for (var _iterator = document.definitions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var definition = _step.value;
addTypeUsed(type) {
if (type instanceof _graphql.GraphQLEnumType || type instanceof _graphql.GraphQLInputObjectType || type instanceof _graphql.GraphQLScalarType && !(0, _graphql2.isBuiltInScalarType)(type)) {
this.typesUsedSet.add(type);
}
if (type instanceof _graphql.GraphQLInputObjectType) {
for (const field of (0, _values2.default)(type.getFields())) {
this.addTypeUsed((0, _graphql.getNamedType)(field.type));
switch (definition.kind) {
case _graphql.Kind.OPERATION_DEFINITION:
this.operations.push(definition);
break;
case _graphql.Kind.FRAGMENT_DEFINITION:
this.fragmentMap[definition.name.value] = definition;
break;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
get typesUsed() {
return (0, _from2.default)(this.typesUsedSet);
this.compiledFragmentMap = Object.create(null);
}
fragmentNamed(fragmentName) {
return this.fragmentMap[fragmentName];
}
_createClass(Compiler, [{
key: 'addTypeUsed',
value: function addTypeUsed(type) {
if (this.typesUsedSet.has(type)) return;
get fragments() {
return (0, _values2.default)(this.fragmentMap);
}
if (type instanceof _graphql.GraphQLEnumType || type instanceof _graphql.GraphQLInputObjectType || type instanceof _graphql.GraphQLScalarType && !(0, _graphql2.isBuiltInScalarType)(type)) {
this.typesUsedSet.add(type);
}
if (type instanceof _graphql.GraphQLInputObjectType) {
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
compileOperation(operationDefinition) {
const filePath = (0, _graphql2.filePathForNode)(operationDefinition);
const operationName = operationDefinition.name.value;
const operationType = operationDefinition.operation;
try {
for (var _iterator2 = Object.values(type.getFields())[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var field = _step2.value;
const variables = operationDefinition.variableDefinitions.map(node => {
const name = node.variable.name.value;
const type = (0, _graphql.typeFromAST)(this.schema, node.type);
this.addTypeUsed((0, _graphql.getNamedType)(type));
return { name: name, type: type };
});
this.addTypeUsed((0, _graphql.getNamedType)(field.type));
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
}
}, {
key: 'fragmentNamed',
value: function fragmentNamed(fragmentName) {
return this.fragmentMap[fragmentName];
}
}, {
key: 'compileOperation',
value: function compileOperation(operationDefinition) {
var _this = this;
const source = (0, _graphql.print)(operationDefinition);
var filePath = (0, _graphql2.filePathForNode)(operationDefinition);
var operationName = operationDefinition.name.value;
var operationType = operationDefinition.operation;
const rootType = (0, _graphql2.getOperationRootType)(this.schema, operationDefinition);
var variables = operationDefinition.variableDefinitions.map(function (node) {
var name = node.variable.name.value;
var type = (0, _graphql.typeFromAST)(_this.schema, node.type);
_this.addTypeUsed((0, _graphql.getNamedType)(type));
return { name, type };
});
const groupedVisitedFragmentSet = new _map2.default();
const groupedFieldSet = this.collectFields(rootType, operationDefinition.selectionSet, undefined, groupedVisitedFragmentSet);
var source = (0, _graphql.print)(operationDefinition);
var rootType = (0, _graphql2.getOperationRootType)(this.schema, operationDefinition);
const fragmentsReferencedSet = (0, _create2.default)(null);
var groupedVisitedFragmentSet = new Map();
var groupedFieldSet = this.collectFields(rootType, operationDefinition.selectionSet, undefined, groupedVisitedFragmentSet);
var _resolveFields = this.resolveFields(rootType, groupedFieldSet, groupedVisitedFragmentSet, fragmentsReferencedSet);
var fragmentsReferencedSet = Object.create(null);
const fields = _resolveFields.fields;
var _resolveFields = this.resolveFields(rootType, groupedFieldSet, groupedVisitedFragmentSet, fragmentsReferencedSet),
fields = _resolveFields.fields;
const fragmentsReferenced = (0, _keys2.default)(fragmentsReferencedSet);
var fragmentsReferenced = Object.keys(fragmentsReferencedSet);
return { filePath: filePath, operationName: operationName, operationType: operationType, variables: variables, source: source, fields: fields, fragmentsReferenced: fragmentsReferenced };
}
return { filePath, operationName, operationType, rootType, variables, source, fields, fragmentsReferenced };
}
}, {
key: 'compileFragment',
value: function compileFragment(fragmentDefinition) {
var filePath = (0, _graphql2.filePathForNode)(fragmentDefinition);
var fragmentName = fragmentDefinition.name.value;
compileFragment(fragmentDefinition) {
const filePath = (0, _graphql2.filePathForNode)(fragmentDefinition);
const fragmentName = fragmentDefinition.name.value;
var source = (0, _graphql.print)(fragmentDefinition);
const source = (0, _graphql.print)(fragmentDefinition);
var typeCondition = (0, _graphql.typeFromAST)(this.schema, fragmentDefinition.typeCondition);
var possibleTypes = this.possibleTypesForType(typeCondition);
const typeCondition = (0, _graphql.typeFromAST)(this.schema, fragmentDefinition.typeCondition);
var groupedVisitedFragmentSet = new Map();
var groupedFieldSet = this.collectFields(typeCondition, fragmentDefinition.selectionSet, undefined, groupedVisitedFragmentSet);
const groupedVisitedFragmentSet = new _map2.default();
const groupedFieldSet = this.collectFields(typeCondition, fragmentDefinition.selectionSet, undefined, groupedVisitedFragmentSet);
var fragmentsReferencedSet = Object.create(null);
const fragmentsReferencedSet = (0, _create2.default)(null);
var _resolveFields2 = this.resolveFields(typeCondition, groupedFieldSet, groupedVisitedFragmentSet, fragmentsReferencedSet);
const fields = _resolveFields2.fields,
var _resolveFields2 = this.resolveFields(typeCondition, groupedFieldSet, groupedVisitedFragmentSet, fragmentsReferencedSet),
fields = _resolveFields2.fields,
fragmentSpreads = _resolveFields2.fragmentSpreads,
inlineFragments = _resolveFields2.inlineFragments;
const fragmentsReferenced = (0, _keys2.default)(fragmentsReferencedSet);
var fragmentsReferenced = Object.keys(fragmentsReferencedSet);
return { filePath: filePath, fragmentName: fragmentName, source: source, typeCondition: typeCondition, fields: fields, fragmentSpreads: fragmentSpreads, inlineFragments: inlineFragments, fragmentsReferenced: fragmentsReferenced };
}
return { filePath, fragmentName, source, typeCondition, possibleTypes, fields, fragmentSpreads, inlineFragments, fragmentsReferenced };
}
}, {
key: 'collectFields',
value: function collectFields(parentType, selectionSet) {
var groupedFieldSet = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Object.create(null);
var groupedVisitedFragmentSet = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : new Map();
collectFields(parentType, selectionSet) {
let groupedFieldSet = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : (0, _create2.default)(null);
let groupedVisitedFragmentSet = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : new _map2.default();
if (!(0, _graphql.isCompositeType)(parentType)) {
throw new Error(`parentType should be a composite type, but is "${String(parentType)}"`);
}
if (!(0, _graphql.isCompositeType)(parentType)) {
throw new Error(`parentType should be a composite type, but is "${String(parentType)}"`);
}
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
for (const selection of selectionSet.selections) {
switch (selection.kind) {
case _graphql.Kind.FIELD:
{
const fieldName = selection.name.value;
const responseName = selection.alias ? selection.alias.value : fieldName;
try {
for (var _iterator3 = selectionSet.selections[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var selection = _step3.value;
const field = (0, _graphql2.getFieldDef)(this.schema, parentType, selection);
if (!field) {
throw new _graphql.GraphQLError(`Cannot query field "${fieldName}" on type "${String(parentType)}"`, [selection]);
}
switch (selection.kind) {
case _graphql.Kind.FIELD:
{
var fieldName = selection.name.value;
var responseName = selection.alias ? selection.alias.value : fieldName;
if (groupedFieldSet) {
if (!groupedFieldSet[responseName]) {
groupedFieldSet[responseName] = [];
var field = (0, _graphql2.getFieldDef)(this.schema, parentType, selection);
if (!field) {
throw new _graphql.GraphQLError(`Cannot query field "${fieldName}" on type "${String(parentType)}"`, [selection]);
}
if (groupedFieldSet) {
if (!groupedFieldSet[responseName]) {
groupedFieldSet[responseName] = [];
}
groupedFieldSet[responseName].push([parentType, {
responseName,
fieldName,
args: argumentsFromAST(selection.arguments),
type: field.type,
directives: selection.directives,
selectionSet: selection.selectionSet
}]);
}
break;
}
case _graphql.Kind.INLINE_FRAGMENT:
{
var typeCondition = selection.typeCondition;
var inlineFragmentType = typeCondition ? (0, _graphql.typeFromAST)(this.schema, typeCondition) : parentType;
groupedFieldSet[responseName].push([parentType, {
responseName: responseName,
fieldName: fieldName,
args: argumentsFromAST(selection.arguments),
type: field.type,
directives: selection.directives,
selectionSet: selection.selectionSet
}]);
}
break;
}
case _graphql.Kind.INLINE_FRAGMENT:
{
const typeCondition = selection.typeCondition;
const inlineFragmentType = typeCondition ? (0, _graphql.typeFromAST)(this.schema, typeCondition) : parentType;
if (!(0, _graphql.doTypesOverlap)(this.schema, inlineFragmentType, parentType)) continue;
var effectiveType = parentType instanceof _graphql.GraphQLObjectType ? parentType : inlineFragmentType;
const effectiveType = parentType instanceof _graphql.GraphQLObjectType ? parentType : inlineFragmentType;
this.collectFields(effectiveType, selection.selectionSet, groupedFieldSet, groupedVisitedFragmentSet);
break;
}
case _graphql.Kind.FRAGMENT_SPREAD:
{
var fragmentName = selection.name.value;
this.collectFields(effectiveType, selection.selectionSet, groupedFieldSet, groupedVisitedFragmentSet);
break;
}
case _graphql.Kind.FRAGMENT_SPREAD:
{
const fragmentName = selection.name.value;
var fragment = this.fragmentNamed(fragmentName);
if (!fragment) throw new _graphql.GraphQLError(`Cannot find fragment "${fragmentName}"`);
const fragment = this.fragmentNamed(fragmentName);
if (!fragment) throw new _graphql.GraphQLError(`Cannot find fragment "${fragmentName}"`);
var _typeCondition = fragment.typeCondition;
var fragmentType = (0, _graphql.typeFromAST)(this.schema, _typeCondition);
const typeCondition = fragment.typeCondition;
const fragmentType = (0, _graphql.typeFromAST)(this.schema, typeCondition);
if (groupedVisitedFragmentSet) {
var visitedFragmentSet = groupedVisitedFragmentSet.get(parentType);
if (!visitedFragmentSet) {
visitedFragmentSet = {};
groupedVisitedFragmentSet.set(parentType, visitedFragmentSet);
}
if (groupedVisitedFragmentSet) {
let visitedFragmentSet = groupedVisitedFragmentSet.get(parentType);
if (!visitedFragmentSet) {
visitedFragmentSet = {};
groupedVisitedFragmentSet.set(parentType, visitedFragmentSet);
}
if (visitedFragmentSet[fragmentName]) continue;
visitedFragmentSet[fragmentName] = true;
}
if (visitedFragmentSet[fragmentName]) continue;
visitedFragmentSet[fragmentName] = true;
}
if (!(0, _graphql.doTypesOverlap)(this.schema, fragmentType, parentType)) continue;
var _effectiveType = parentType instanceof _graphql.GraphQLObjectType ? parentType : fragmentType;
const effectiveType = parentType instanceof _graphql.GraphQLObjectType ? parentType : fragmentType;
this.collectFields(effectiveType, fragment.selectionSet, null, groupedVisitedFragmentSet);
break;
this.collectFields(_effectiveType, fragment.selectionSet, this.options.mergeInFieldsFromFragmentSpreads ? groupedFieldSet : null, groupedVisitedFragmentSet);
break;
}
}
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
return groupedFieldSet;
}
}, {
key: 'possibleTypesForType',
value: function possibleTypesForType(type) {
if ((0, _graphql.isAbstractType)(type)) {
return this.schema.getPossibleTypes(type);
} else {
return [type];
}
}
}, {
key: 'mergeSelectionSets',
value: function mergeSelectionSets(parentType, fieldSet, groupedVisitedFragmentSet) {
var groupedFieldSet = Object.create(null);
return groupedFieldSet;
}
var _iteratorNormalCompletion4 = true;
var _didIteratorError4 = false;
var _iteratorError4 = undefined;
mergeSelectionSets(parentType, fieldSet, groupedVisitedFragmentSet) {
const groupedFieldSet = (0, _create2.default)(null);
try {
for (var _iterator4 = fieldSet[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
var _ref = _step4.value;
for (const _ref of fieldSet) {
var _ref2 = (0, _slicedToArray3.default)(_ref, 2);
var _ref2 = _slicedToArray(_ref, 2);
const field = _ref2[1];
var field = _ref2[1];
const selectionSet = field.selectionSet;
var selectionSet = field.selectionSet;
if (selectionSet) {
this.collectFields(parentType, selectionSet, groupedFieldSet, groupedVisitedFragmentSet);
if (selectionSet) {
this.collectFields(parentType, selectionSet, groupedFieldSet, groupedVisitedFragmentSet);
}
}
} catch (err) {
_didIteratorError4 = true;
_iteratorError4 = err;
} finally {
try {
if (!_iteratorNormalCompletion4 && _iterator4.return) {
_iterator4.return();
}
} finally {
if (_didIteratorError4) {
throw _iteratorError4;
}
}
}
return groupedFieldSet;
}
}, {
key: 'resolveFields',
value: function resolveFields(parentType, groupedFieldSet, groupedVisitedFragmentSet, fragmentsReferencedSet) {
var _this2 = this;
return groupedFieldSet;
}
var fields = [];
resolveFields(parentType, groupedFieldSet, groupedVisitedFragmentSet, fragmentsReferencedSet) {
const fields = [];
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
var _iteratorError5 = undefined;
for (let _ref3 of (0, _entries2.default)(groupedFieldSet)) {
var _ref4 = (0, _slicedToArray3.default)(_ref3, 2);
try {
for (var _iterator5 = Object.entries(groupedFieldSet)[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
var _ref3 = _step5.value;
let responseName = _ref4[0];
let fieldSet = _ref4[1];
var _ref4 = _slicedToArray(_ref3, 2);
fieldSet = fieldSet.filter((_ref5) => {
var _ref6 = (0, _slicedToArray3.default)(_ref5, 1);
var responseName = _ref4[0];
var fieldSet = _ref4[1];
let typeCondition = _ref6[0];
return (0, _graphql.isTypeSubTypeOf)(this.schema, parentType, typeCondition);
});
if (fieldSet.length < 1) continue;
fieldSet = fieldSet.filter(function (_ref5) {
var _ref6 = _slicedToArray(_ref5, 1),
typeCondition = _ref6[0];
var _fieldSet$ = (0, _slicedToArray3.default)(fieldSet[0], 2);
return (0, _graphql.isTypeSubTypeOf)(_this2.schema, parentType, typeCondition);
});
if (fieldSet.length < 1) continue;
const firstField = _fieldSet$[1];
var _fieldSet$ = _slicedToArray(fieldSet[0], 2),
firstField = _fieldSet$[1];
const fieldName = firstField.fieldName;
const args = firstField.args;
const type = firstField.type;
var fieldName = firstField.fieldName;
var args = firstField.args;
var type = firstField.type;
let field = { responseName: responseName, fieldName: fieldName, type: type };
var field = { responseName, fieldName, type };
if (args && args.length > 0) {
field.args = args;
}
if (args && args.length > 0) {
field.args = args;
}
const isConditional = fieldSet.some((_ref7) => {
var _ref8 = (0, _slicedToArray3.default)(_ref7, 2);
var isConditional = fieldSet.some(function (_ref7) {
var _ref8 = _slicedToArray(_ref7, 2),
field = _ref8[1];
let field = _ref8[1];
return field.directives && field.directives.some(function (directive) {
var directiveName = directive.name.value;
return directiveName == 'skip' || directiveName == 'include';
});
});
return field.directives && field.directives.some(directive => {
const directiveName = directive.name.value;
return directiveName == 'skip' || directiveName == 'include';
});
});
if (isConditional) {
field.isConditional = true;
}
if (isConditional) {
field.isConditional = true;
}
// Introspection fields do not have descriptions
if (fieldName !== '__typename') {
var description = parentType.getFields()[fieldName].description;
if (description) {
field.description = description;
}
}
const bareType = (0, _graphql.getNamedType)(type);
var bareType = (0, _graphql.getNamedType)(type);
this.addTypeUsed(bareType);
this.addTypeUsed(bareType);
if ((0, _graphql.isCompositeType)(bareType)) {
const subSelectionGroupedVisitedFragmentSet = new _map2.default();
const subSelectionGroupedFieldSet = this.mergeSelectionSets(bareType, fieldSet, subSelectionGroupedVisitedFragmentSet);
if ((0, _graphql.isCompositeType)(bareType)) {
var subSelectionGroupedVisitedFragmentSet = new Map();
var subSelectionGroupedFieldSet = this.mergeSelectionSets(bareType, fieldSet, subSelectionGroupedVisitedFragmentSet);
var _resolveFields3 = this.resolveFields(bareType, subSelectionGroupedFieldSet, subSelectionGroupedVisitedFragmentSet, fragmentsReferencedSet);
var _resolveFields3 = this.resolveFields(bareType, subSelectionGroupedFieldSet, subSelectionGroupedVisitedFragmentSet, fragmentsReferencedSet),
_fields = _resolveFields3.fields,
_fragmentSpreads = _resolveFields3.fragmentSpreads,
_inlineFragments = _resolveFields3.inlineFragments;
const fields = _resolveFields3.fields,
fragmentSpreads = _resolveFields3.fragmentSpreads,
inlineFragments = _resolveFields3.inlineFragments;
Object.assign(field, { fields: _fields, fragmentSpreads: _fragmentSpreads, inlineFragments: _inlineFragments });
}
(0, _assign2.default)(field, { fields: fields, fragmentSpreads: fragmentSpreads, inlineFragments: inlineFragments });
fields.push(field);
}
} catch (err) {
_didIteratorError5 = true;
_iteratorError5 = err;
} finally {
try {
if (!_iteratorNormalCompletion5 && _iterator5.return) {
_iterator5.return();
}
} finally {
if (_didIteratorError5) {
throw _iteratorError5;
}
}
}
fields.push(field);
}
var fragmentSpreads = this.fragmentSpreadsForParentType(parentType, groupedVisitedFragmentSet);
var inlineFragments = this.resolveInlineFragments(parentType, groupedFieldSet, groupedVisitedFragmentSet, fragmentsReferencedSet);
const fragmentSpreads = this.fragmentSpreadsForParentType(parentType, groupedVisitedFragmentSet);
const inlineFragments = this.resolveInlineFragments(parentType, groupedFieldSet, groupedVisitedFragmentSet, fragmentsReferencedSet);
if (fragmentsReferencedSet) {
Object.assign.apply(Object, [fragmentsReferencedSet].concat(_toConsumableArray(groupedVisitedFragmentSet.values())));
if (fragmentsReferencedSet) {
_assign2.default.apply(Object, [fragmentsReferencedSet].concat((0, _toConsumableArray3.default)(groupedVisitedFragmentSet.values())));
// TODO: This is a really inefficient way of keeping track of fragments referenced by other fragments
// We need to either cache compiled fragments or find a way to make resolveFields smarter
var _iteratorNormalCompletion6 = true;
var _didIteratorError6 = false;
var _iteratorError6 = undefined;
// TODO: This is a really inefficient way of keeping track of fragments referenced by other fragments
// We need to either cache compiled fragments or find a way to make resolveFields smarter
for (let fragmentName of fragmentSpreads) {
const fragment = this.fragmentNamed(fragmentName);
if (!fragment) throw new _graphql.GraphQLError(`Cannot find fragment "${fragmentName}"`);
try {
for (var _iterator6 = fragmentSpreads[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
var fragmentName = _step6.value;
var _compileFragment = this.compileFragment(fragment);
var fragment = this.fragmentNamed(fragmentName);
if (!fragment) throw new _graphql.GraphQLError(`Cannot find fragment "${fragmentName}"`);
const fragmentsReferencedFromFragment = _compileFragment.fragmentsReferenced;
var _compileFragment = this.compileFragment(fragment),
fragmentsReferencedFromFragment = _compileFragment.fragmentsReferenced;
for (let fragmentReferenced of fragmentsReferencedFromFragment) {
fragmentsReferencedSet[fragmentReferenced] = true;
var _iteratorNormalCompletion7 = true;
var _didIteratorError7 = false;
var _iteratorError7 = undefined;
try {
for (var _iterator7 = fragmentsReferencedFromFragment[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
var fragmentReferenced = _step7.value;
fragmentsReferencedSet[fragmentReferenced] = true;
}
} catch (err) {
_didIteratorError7 = true;
_iteratorError7 = err;
} finally {
try {
if (!_iteratorNormalCompletion7 && _iterator7.return) {
_iterator7.return();
}
} finally {
if (_didIteratorError7) {
throw _iteratorError7;
}
}
}
}
} catch (err) {
_didIteratorError6 = true;
_iteratorError6 = err;
} finally {
try {
if (!_iteratorNormalCompletion6 && _iterator6.return) {
_iterator6.return();
}
} finally {
if (_didIteratorError6) {
throw _iteratorError6;
}
}
}
}
return { fields, fragmentSpreads, inlineFragments };
}
}, {
key: 'resolveInlineFragments',
value: function resolveInlineFragments(parentType, groupedFieldSet, groupedVisitedFragmentSet, fragmentsReferencedSet) {
var _this3 = this;
return { fields: fields, fragmentSpreads: fragmentSpreads, inlineFragments: inlineFragments };
}
return this.collectPossibleTypes(parentType, groupedFieldSet, groupedVisitedFragmentSet).map(function (typeCondition) {
var _resolveFields4 = _this3.resolveFields(typeCondition, groupedFieldSet, groupedVisitedFragmentSet, fragmentsReferencedSet),
fields = _resolveFields4.fields,
fragmentSpreads = _resolveFields4.fragmentSpreads;
resolveInlineFragments(parentType, groupedFieldSet, groupedVisitedFragmentSet, fragmentsReferencedSet) {
return this.collectPossibleTypes(parentType, groupedFieldSet, groupedVisitedFragmentSet).map(typeCondition => {
var _resolveFields4 = this.resolveFields(typeCondition, groupedFieldSet, groupedVisitedFragmentSet, fragmentsReferencedSet);
var possibleTypes = _this3.possibleTypesForType(typeCondition);
return { typeCondition, possibleTypes, fields, fragmentSpreads };
});
}
}, {
key: 'collectPossibleTypes',
value: function collectPossibleTypes(parentType, groupedFieldSet, groupedVisitedFragmentSet) {
if (!(0, _graphql.isAbstractType)(parentType)) return [];
const fields = _resolveFields4.fields,
fragmentSpreads = _resolveFields4.fragmentSpreads;
var possibleTypes = new Set();
return { typeCondition: typeCondition, fields: fields, fragmentSpreads: fragmentSpreads };
});
}
var _iteratorNormalCompletion8 = true;
var _didIteratorError8 = false;
var _iteratorError8 = undefined;
collectPossibleTypes(parentType, groupedFieldSet, groupedVisitedFragmentSet) {
if (!(0, _graphql.isAbstractType)(parentType)) return [];
try {
for (var _iterator8 = Object.values(groupedFieldSet)[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
var fieldSet = _step8.value;
var _iteratorNormalCompletion10 = true;
var _didIteratorError10 = false;
var _iteratorError10 = undefined;
const possibleTypes = new _set2.default();
try {
for (var _iterator10 = fieldSet[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
var _ref9 = _step10.value;
for (const fieldSet of (0, _values2.default)(groupedFieldSet)) {
for (const _ref9 of fieldSet) {
var _ref10 = (0, _slicedToArray3.default)(_ref9, 1);
var _ref10 = _slicedToArray(_ref9, 1);
const typeCondition = _ref10[0];
var typeCondition = _ref10[0];
if (this.schema.isPossibleType(parentType, typeCondition)) {
possibleTypes.add(typeCondition);
if (this.schema.isPossibleType(parentType, typeCondition)) {
possibleTypes.add(typeCondition);
}
}
} catch (err) {
_didIteratorError10 = true;
_iteratorError10 = err;
} finally {
try {
if (!_iteratorNormalCompletion10 && _iterator10.return) {
_iterator10.return();
}
} finally {
if (_didIteratorError10) {
throw _iteratorError10;
}
}
}
}
// Also include type conditions for fragment spreads
} catch (err) {
_didIteratorError8 = true;
_iteratorError8 = err;
} finally {
try {
if (!_iteratorNormalCompletion8 && _iterator8.return) {
_iterator8.return();
}
} finally {
if (_didIteratorError8) {
throw _iteratorError8;
}
}
}
}
// Also include type conditions for fragment spreads
if (groupedVisitedFragmentSet) {
for (const effectiveType of groupedVisitedFragmentSet.keys()) {
if (this.schema.isPossibleType(parentType, effectiveType)) {
possibleTypes.add(effectiveType);
if (groupedVisitedFragmentSet) {
var _iteratorNormalCompletion9 = true;
var _didIteratorError9 = false;
var _iteratorError9 = undefined;
try {
for (var _iterator9 = groupedVisitedFragmentSet.keys()[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
var effectiveType = _step9.value;
if (this.schema.isPossibleType(parentType, effectiveType)) {
possibleTypes.add(effectiveType);
}
}
} catch (err) {
_didIteratorError9 = true;
_iteratorError9 = err;
} finally {
try {
if (!_iteratorNormalCompletion9 && _iterator9.return) {
_iterator9.return();
}
} finally {
if (_didIteratorError9) {
throw _iteratorError9;
}
}
}
}
return Array.from(possibleTypes);
}
}, {
key: 'fragmentSpreadsForParentType',
value: function fragmentSpreadsForParentType(parentType, groupedVisitedFragmentSet) {
if (!groupedVisitedFragmentSet) return [];
return (0, _from2.default)(possibleTypes);
}
var fragmentSpreads = new Set();
fragmentSpreadsForParentType(parentType, groupedVisitedFragmentSet) {
if (!groupedVisitedFragmentSet) return [];
var _iteratorNormalCompletion11 = true;
var _didIteratorError11 = false;
var _iteratorError11 = undefined;
let fragmentSpreads = new _set2.default();
try {
for (var _iterator11 = groupedVisitedFragmentSet[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
var _ref11 = _step11.value;
for (const _ref11 of groupedVisitedFragmentSet) {
var _ref12 = (0, _slicedToArray3.default)(_ref11, 2);
var _ref12 = _slicedToArray(_ref11, 2);
const effectiveType = _ref12[0];
const visitedFragmentSet = _ref12[1];
var effectiveType = _ref12[0];
var visitedFragmentSet = _ref12[1];
if (!(0, _graphql2.isTypeProperSuperTypeOf)(this.schema, effectiveType, parentType)) continue;
if (!(0, _graphql2.isTypeProperSuperTypeOf)(this.schema, effectiveType, parentType)) continue;
for (const fragmentName of (0, _keys2.default)(visitedFragmentSet)) {
fragmentSpreads.add(fragmentName);
var _iteratorNormalCompletion12 = true;
var _didIteratorError12 = false;
var _iteratorError12 = undefined;
try {
for (var _iterator12 = Object.keys(visitedFragmentSet)[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
var fragmentName = _step12.value;
fragmentSpreads.add(fragmentName);
}
} catch (err) {
_didIteratorError12 = true;
_iteratorError12 = err;
} finally {
try {
if (!_iteratorNormalCompletion12 && _iterator12.return) {
_iterator12.return();
}
} finally {
if (_didIteratorError12) {
throw _iteratorError12;
}
}
}
}
} catch (err) {
_didIteratorError11 = true;
_iteratorError11 = err;
} finally {
try {
if (!_iteratorNormalCompletion11 && _iterator11.return) {
_iterator11.return();
}
} finally {
if (_didIteratorError11) {
throw _iteratorError11;
}
}
}
return Array.from(fragmentSpreads);
}
}, {
key: 'typesUsed',
get: function get() {
return Array.from(this.typesUsedSet);
}
}, {
key: 'fragments',
get: function get() {
return Object.values(this.fragmentMap);
}
}]);
return (0, _from2.default)(fragmentSpreads);
}
}
return Compiler;
}();
exports.Compiler = Compiler;
function argumentsFromAST(args) {
return args && args.map(arg => {
return args && args.map(function (arg) {
return { name: arg.name.value, value: (0, _graphql2.valueFromValueNode)(arg.value) };

@@ -440,8 +703,12 @@ });

function printIR(_ref13) {
let fields = _ref13.fields,
var fields = _ref13.fields,
inlineFragments = _ref13.inlineFragments,
fragmentSpreads = _ref13.fragmentSpreads;
return fields && (0, _printing.wrap)('<', (0, _printing.join)(fragmentSpreads, ', '), '> ') + (0, _printing.block)(fields.map(field => `${field.name}: ${String(field.type)}` + (0, _printing.wrap)(' ', printIR(field))).concat(inlineFragments && inlineFragments.map(inlineFragment => `${String(inlineFragment.typeCondition)}` + (0, _printing.wrap)(' ', printIR(inlineFragment)))));
return fields && (0, _printing.wrap)('<', (0, _printing.join)(fragmentSpreads, ', '), '> ') + (0, _printing.block)(fields.map(function (field) {
return `${field.name}: ${String(field.type)}` + (0, _printing.wrap)(' ', printIR(field));
}).concat(inlineFragments && inlineFragments.map(function (inlineFragment) {
return `${String(inlineFragment.typeCondition)}` + (0, _printing.wrap)(' ', printIR(inlineFragment));
})));
}
//# sourceMappingURL=compilation.js.map

@@ -7,14 +7,2 @@ 'use strict';

var _stringify = require('babel-runtime/core-js/json/stringify');
var _stringify2 = _interopRequireDefault(_stringify);
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
var _nodeFetch = require('node-fetch');

@@ -42,5 +30,5 @@

// Based on https://facebook.github.io/relay/docs/guides-babel-plugin.html#using-other-graphql-implementations
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } // Based on https://facebook.github.io/relay/docs/guides-babel-plugin.html#using-other-graphql-implementations
const defaultHeaders = {
var defaultHeaders = {
'Accept': 'application/json',

@@ -50,33 +38,66 @@ 'Content-Type': 'application/json'

exports.default = (() => {
var _ref = (0, _asyncToGenerator3.default)(function* (url, outputPath, additionalHeaders, insecure) {
const headers = (0, _assign2.default)(defaultHeaders, additionalHeaders);
const agent = insecure ? new _https2.default.Agent({ rejectUnauthorized: false }) : null;
exports.default = function () {
var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee(url, outputPath, additionalHeaders, insecure) {
var headers, agent, result, response, schemaData;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
headers = Object.assign(defaultHeaders, additionalHeaders);
agent = insecure ? new _https2.default.Agent({ rejectUnauthorized: false }) : null;
result = void 0;
_context.prev = 3;
_context.next = 6;
return (0, _nodeFetch2.default)(url, {
method: 'POST',
headers: headers,
body: JSON.stringify({ 'query': _utilities.introspectionQuery }),
agent
});
let result;
try {
const response = yield (0, _nodeFetch2.default)(url, {
method: 'POST',
headers: headers,
body: (0, _stringify2.default)({ 'query': _utilities.introspectionQuery }),
agent: agent
});
case 6:
response = _context.sent;
_context.next = 9;
return response.json();
result = yield response.json();
} catch (error) {
throw new _errors.ToolError(`Error while fetching introspection query result: ${error.message}`);
}
case 9:
result = _context.sent;
_context.next = 15;
break;
if (result.errors) {
throw new _errors.ToolError(`Errors in introspection query result: ${result.errors}`);
}
case 12:
_context.prev = 12;
_context.t0 = _context['catch'](3);
throw new _errors.ToolError(`Error while fetching introspection query result: ${_context.t0.message}`);
const schemaData = result;
if (!schemaData.data) {
throw new _errors.ToolError(`No introspection query result data found, server responded with: ${(0, _stringify2.default)(result)}`);
}
case 15:
if (!result.errors) {
_context.next = 17;
break;
}
_fs2.default.writeFileSync(outputPath, (0, _stringify2.default)(schemaData, null, 2));
});
throw new _errors.ToolError(`Errors in introspection query result: ${result.errors}`);
case 17:
schemaData = result;
if (schemaData.data) {
_context.next = 20;
break;
}
throw new _errors.ToolError(`No introspection query result data found, server responded with: ${JSON.stringify(result)}`);
case 20:
_fs2.default.writeFileSync(outputPath, JSON.stringify(schemaData, null, 2));
case 21:
case 'end':
return _context.stop();
}
}
}, _callee, this, [[3, 12]]);
}));
function downloadSchema(_x, _x2, _x3, _x4) {

@@ -87,3 +108,3 @@ return _ref.apply(this, arguments);

return downloadSchema;
})();
}();
//# sourceMappingURL=downloadSchema.js.map

@@ -6,7 +6,2 @@ 'use strict';

});
var _create = require('babel-runtime/core-js/object/create');
var _create2 = _interopRequireDefault(_create);
exports.ToolError = ToolError;

@@ -18,4 +13,2 @@ exports.logError = logError;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// ToolError is used for errors that are part of the expected flow

@@ -28,3 +21,3 @@ // and for which a stack trace should not be printed

ToolError.prototype = (0, _create2.default)(Error.prototype, {
ToolError.prototype = Object.create(Error.prototype, {
constructor: { value: ToolError },

@@ -34,3 +27,3 @@ name: { value: 'ToolError' }

const isRunningFromXcodeScript = process.env.XCODE_VERSION_ACTUAL;
var isRunningFromXcodeScript = process.env.XCODE_VERSION_ACTUAL;

@@ -41,6 +34,27 @@ function logError(error) {

} else if (error instanceof _graphql.GraphQLError) {
const fileName = error.source && error.source.name;
var fileName = error.source && error.source.name;
if (error.locations) {
for (const location of error.locations) {
logErrorMessage(error.message, fileName, location.line);
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = error.locations[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var location = _step.value;
logErrorMessage(error.message, fileName, location.line);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}

@@ -47,0 +61,0 @@ } else {

@@ -6,15 +6,2 @@ 'use strict';

});
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
var _values = require('babel-runtime/core-js/object/values');
var _values2 = _interopRequireDefault(_values);
exports.generateSource = generateSource;

@@ -51,14 +38,23 @@ exports.typeDeclarationForGraphQLType = typeDeclarationForGraphQLType;

function generateSource(context) {
const generator = new _CodeGenerator2.default(context);
function generateSource(context, options) {
var generator = new _CodeGenerator2.default(context);
generator.printOnNewline('/* @flow */');
generator.printOnNewline('// This file was automatically generated and should not be edited.');
typeDeclarationForGraphQLType(context.typesUsed.forEach(type => typeDeclarationForGraphQLType(generator, type)));
(0, _values2.default)(context.operations).forEach(operation => {
typeDeclarationForGraphQLType(context.typesUsed.forEach(function (type) {
return typeDeclarationForGraphQLType(generator, type);
}));
// When an object has fragment spreads or inline fragments
// and __typename is requested at the top level, __typename
// needs to be added as a property of the fragments
var fragmentsWithTypenameField = {};
Object.values(context.operations).forEach(function (operation) {
interfaceVariablesDeclarationForOperation(generator, operation);
typeDeclarationForOperation(generator, operation);
typeDeclarationForOperation(generator, operation, fragmentsWithTypenameField);
});
(0, _values2.default)(context.fragments).forEach(operation => typeDeclarationForFragment(generator, operation));
Object.values(context.fragments).forEach(function (operation) {
return typeDeclarationForFragment(generator, operation, fragmentsWithTypenameField);
});
return generator.output;

@@ -76,6 +72,6 @@ }

function enumerationDeclaration(generator, type) {
const name = type.name,
description = type.description;
var name = type.name,
description = type.description;
const values = type.getValues();
var values = type.getValues();

@@ -85,4 +81,6 @@ generator.printNewlineIfNeeded();

generator.printOnNewline(`export type ${name} =`);
const nValues = values.length;
values.forEach((value, i) => generator.printOnNewline(` "${value.value}"${i === nValues - 1 ? ';' : ' |'}${(0, _printing.wrap)(' // ', value.description)}`));
var nValues = values.length;
values.forEach(function (value, i) {
return generator.printOnNewline(` "${value.value}"${i === nValues - 1 ? ';' : ' |'}${(0, _printing.wrap)(' // ', value.description)}`);
});
generator.printNewline();

@@ -92,7 +90,7 @@ }

function structDeclarationForInputObjectType(generator, type) {
const interfaceName = (0, _changeCase.pascalCase)(type.name);
var interfaceName = (0, _changeCase.pascalCase)(type.name);
(0, _language.typeDeclaration)(generator, {
interfaceName: interfaceName
}, () => {
const properties = propertiesFromFields(generator.context, (0, _values2.default)(type.getFields()));
interfaceName
}, function () {
var properties = propertiesFromFields(generator.context, Object.values(type.getFields()));
propertyDeclarations(generator, properties, true);

@@ -103,3 +101,3 @@ });

function interfaceNameFromOperation(_ref) {
let operationName = _ref.operationName,
var operationName = _ref.operationName,
operationType = _ref.operationType;

@@ -123,3 +121,3 @@

function interfaceVariablesDeclarationForOperation(generator, _ref2) {
let operationName = _ref2.operationName,
var operationName = _ref2.operationName,
operationType = _ref2.operationType,

@@ -134,8 +132,8 @@ variables = _ref2.variables,

}
const interfaceName = `${interfaceNameFromOperation({ operationName: operationName, operationType: operationType })}Variables`;
var interfaceName = `${interfaceNameFromOperation({ operationName, operationType })}Variables`;
(0, _language.typeDeclaration)(generator, {
interfaceName: interfaceName
}, () => {
const properties = propertiesFromFields(generator.context, variables);
interfaceName
}, function () {
var properties = propertiesFromFields(generator.context, variables);
propertyDeclarations(generator, properties, true);

@@ -145,4 +143,4 @@ });

function typeDeclarationForOperation(generator, _ref3) {
let operationName = _ref3.operationName,
function typeDeclarationForOperation(generator, _ref3, fragmentsWithTypenameField) {
var operationName = _ref3.operationName,
operationType = _ref3.operationType,

@@ -152,43 +150,83 @@ variables = _ref3.variables,

fragmentSpreads = _ref3.fragmentSpreads,
inlineFragments = _ref3.inlineFragments,
fragmentsReferenced = _ref3.fragmentsReferenced,
source = _ref3.source;
const interfaceName = interfaceNameFromOperation({ operationName: operationName, operationType: operationType });
(0, _language.typeDeclaration)(generator, {
interfaceName: interfaceName,
extendTypes: fragmentSpreads ? fragmentSpreads.map(f => `${(0, _changeCase.pascalCase)(f)}Fragment`) : null
}, () => {
const properties = propertiesFromFields(generator.context, fields);
if (hasTypenameField(fields)) {
console.error('__typename on operations are not yet supported');
}
var interfaceName = interfaceNameFromOperation({ operationName, operationType });
var properties = propertiesFromFields(generator.context, fields, {
typeNameSuffix: `From${operationName}`
});
(0, _language.typeDeclaration)(generator, { interfaceName }, function () {
propertyDeclarations(generator, properties, true);
});
properties.forEach(function (_ref4) {
var fragmentSpreads = _ref4.fragmentSpreads,
inlineFragments = _ref4.inlineFragments,
bareTypeName = _ref4.bareTypeName;
if (fragmentSpreads.length > 0) {
fragmentSpreads.forEach(function (fragmentSpread) {
fragmentsWithTypenameField[fragmentSpread] = true;
});
}
if (inlineFragments.length > 0) {
var fragmentName = `${(0, _changeCase.pascalCase)(bareTypeName)}From${operationName}`;
handleInlineFragments(generator, fragmentName, inlineFragments);
}
});
}
function typeDeclarationForFragment(generator, _ref4) {
let fragmentName = _ref4.fragmentName,
typeCondition = _ref4.typeCondition,
fields = _ref4.fields,
inlineFragments = _ref4.inlineFragments,
fragmentSpreads = _ref4.fragmentSpreads,
source = _ref4.source;
function typeDeclarationForFragment(generator, _ref5, fragmentsWithTypenameField) {
var fragmentName = _ref5.fragmentName,
typeCondition = _ref5.typeCondition,
fields = _ref5.fields,
inlineFragments = _ref5.inlineFragments,
fragmentSpreads = _ref5.fragmentSpreads,
source = _ref5.source,
possibleTypes = _ref5.possibleTypes;
const interfaceName = `${(0, _changeCase.pascalCase)(fragmentName)}Fragment`;
var interfaceName = `${(0, _changeCase.pascalCase)(fragmentName)}Fragment`;
(0, _language.typeDeclaration)(generator, {
interfaceName: interfaceName,
extendTypes: fragmentSpreads ? fragmentSpreads.map(f => `${(0, _changeCase.pascalCase)(f)}Fragment`) : null
}, () => {
var _propertiesFromFields;
if (inlineFragments.length > 0) {
handleInlineFragments(generator, interfaceName, inlineFragments);
} else {
(0, _language.typeDeclaration)(generator, {
interfaceName
// extendTypes: fragmentSpreads ? fragmentSpreads.map(f => `${pascalCase(f)}Fragment`) : null,
}, function () {
if (fragmentsWithTypenameField[fragmentName]) {
addTypenameFieldIfNeeded(generator, fields, typeCondition);
}
const properties = (_propertiesFromFields = propertiesFromFields(generator.context, fields)).concat.apply(_propertiesFromFields, (0, _toConsumableArray3.default)((inlineFragments || []).map(fragment => propertiesFromFields(generator.context, fragment.fields, true))));
var properties = propertiesFromFields(generator.context, fields, {
typeNameSuffix: 'Fragment'
});
propertyDeclarations(generator, properties, true);
});
propertyDeclarations(generator, properties, true);
});
}
}
function propertiesFromFields(context, fields, forceNullable) {
return fields.map(field => propertyFromField(context, field, forceNullable));
function propertiesFromFields(context, fields) {
var _ref6 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
forceNullable = _ref6.forceNullable,
typeNameSuffix = _ref6.typeNameSuffix;
return fields.map(function (field) {
return propertyFromField(context, field, { forceNullable, typeNameSuffix });
});
}
function propertyFromField(context, field, forceNullable) {
let fieldName = field.name,
function propertyFromField(context, field) {
var _ref7 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
forceNullable = _ref7.forceNullable,
typeNameSuffix = _ref7.typeNameSuffix;
var fieldName = field.name,
fieldType = field.type,

@@ -201,12 +239,24 @@ description = field.description,

const propertyName = fieldName;
var propertyName = fieldName;
var property = { fieldName, fieldType, propertyName, description, inlineFragments };
var namedType = (0, _graphql.getNamedType)(fieldType);
let property = { fieldName: fieldName, fieldType: fieldType, propertyName: propertyName, description: description };
const namedType = (0, _graphql.getNamedType)(fieldType);
if ((0, _graphql.isCompositeType)(namedType)) {
const bareTypeName = (0, _changeCase.pascalCase)(_inflected2.default.singularize(propertyName));
const typeName = (0, _types.typeNameFromGraphQLType)(context, fieldType, bareTypeName);
let isArray = false;
var typeName = void 0,
bareTypeName = void 0;
if (propertyName === '__typename') {
// Handle the __typename field specially. the fieldType is set
// to the parentType but we want the target type to be a string literal
// of the parentType.
bareTypeName = `"${fieldType}"`;
typeName = `"${fieldType}"`;
} else {
bareTypeName = (0, _changeCase.pascalCase)(_inflected2.default.singularize(propertyName));
if (inlineFragments && inlineFragments.length > 0 || fragmentSpreads && fragmentSpreads.length > 0) {
typeName = (0, _types.typeNameFromGraphQLType)(context, fieldType, `${(0, _changeCase.pascalCase)(bareTypeName)}${typeNameSuffix}`);
} else {
typeName = (0, _types.typeNameFromGraphQLType)(context, fieldType, bareTypeName);
}
}
var isArray = false;
if (fieldType instanceof _graphql.GraphQLList) {

@@ -217,13 +267,13 @@ isArray = true;

}
let isNullable = true;
var isNullable = true;
if (fieldType instanceof _graphql.GraphQLNonNull && !forceNullable) {
isNullable = false;
}
return (0, _extends3.default)({}, property, {
typeName: typeName, bareTypeName: bareTypeName, fields: field.fields, isComposite: true, fragmentSpreads: fragmentSpreads, inlineFragments: inlineFragments, fieldType: fieldType,
isArray: isArray, isNullable: isNullable
return Object.assign({}, property, {
typeName, bareTypeName, fields: field.fields, isComposite: true, fragmentSpreads, inlineFragments, fieldType,
isArray, isNullable
});
} else {
const typeName = (0, _types.typeNameFromGraphQLType)(context, fieldType);
return (0, _extends3.default)({}, property, { typeName: typeName, isComposite: false, fieldType: fieldType });
var _typeName = (0, _types.typeNameFromGraphQLType)(context, fieldType);
return Object.assign({}, property, { typeName: _typeName, isComposite: false, fieldType });
}

@@ -234,15 +284,98 @@ }

if (!properties) return;
properties.forEach(property => {
properties.forEach(function (property) {
if (property.fields && property.fields.length > 0 || property.inlineFragments && property.inlineFragments.length > 0) {
(0, _language.propertyDeclaration)(generator, (0, _extends3.default)({}, property, { inInterface: inInterface }), () => {
var _propertiesFromFields2;
const properties = (_propertiesFromFields2 = propertiesFromFields(generator.context, property.fields)).concat.apply(_propertiesFromFields2, (0, _toConsumableArray3.default)((property.inlineFragments || []).map(fragment => propertiesFromFields(generator.context, fragment.fields, true))));
propertyDeclarations(generator, properties);
});
if (property.inlineFragments.length > 0) {
(0, _language.propertyDeclaration)(generator, Object.assign({}, property, {
inInterface
}));
} else {
(0, _language.propertyDeclaration)(generator, Object.assign({}, property, { inInterface }), function () {
var properties = propertiesFromFields(generator.context, property.fields);
propertyDeclarations(generator, properties);
});
}
} else {
(0, _language.propertyDeclaration)(generator, (0, _extends3.default)({}, property, { inInterface: inInterface }));
(0, _language.propertyDeclaration)(generator, Object.assign({}, property, { inInterface }));
}
});
}
function makeTypenameField(typeName) {
return {
responseName: '__typename',
fieldName: '__typename',
type: typeName
};
}
function hasTypenameField(fields) {
if (!fields) {
return false;
}
return fields.find(function (field) {
return field.fieldName === '__typename' || field.responseName === '__typename';
});
}
function removeTypenameFieldIfExists(generator, fields) {
if (hasTypenameField(fields)) {
fields = fields.filter(function (field) {
return field.fieldName !== '__typename' || field.responseName !== '__typename';
});
return true;
} else {
return false;
}
}
/**
* NOTE: Mutates `fields`
*/
function addTypenameFieldIfNeeded(generator, fields, parentTypeName) {
var removed = removeTypenameFieldIfExists();
if (generator.context.addTypename || removed) {
fields.unshift(makeTypenameField(parentTypeName));
}
}
function handleInlineFragments(generator, fragmentName, inlineFragments) {
// Keep track of these generated destination type names so we can build a union afterwards
var unionTypes = [];
inlineFragments.forEach(function (_ref8) {
var fields = _ref8.fields,
typeCondition = _ref8.typeCondition;
var typeName = `${fragmentName}On${typeCondition}`;
unionTypes.push(typeName);
addTypenameFieldIfNeeded(generator, fields, typeCondition);
var properties = propertiesFromFields(generator.context, fields, {
typeNameSuffix: 'Fragment'
});
(0, _language.typeDeclaration)(generator, {
interfaceName: typeName
}, function () {
propertyDeclarations(generator, properties, true);
});
properties.forEach(function (_ref9) {
var inlineFragments = _ref9.inlineFragments,
bareTypeName = _ref9.bareTypeName;
if (inlineFragments && inlineFragments.length > 0) {
var innerFragmentName = `${bareTypeName}Fragment`;
handleInlineFragments(generator, innerFragmentName, inlineFragments);
}
});
});
// TODO: Refactor typeDeclaration to not automatically assume bracketed type
(0, _language.typeDeclaration)(generator, { interfaceName: fragmentName, noBrackets: true }, function () {
(0, _language.unionDeclaration)(generator, unionTypes);
});
}
//# sourceMappingURL=codeGeneration.js.map

@@ -9,7 +9,11 @@ 'use strict';

exports.propertyDeclarations = propertyDeclarations;
exports.unionDeclaration = unionDeclaration;
var _printing = require('../utilities/printing');
var _changeCase = require('change-case');
function typeDeclaration(generator, _ref, closure) {
let interfaceName = _ref.interfaceName;
var interfaceName = _ref.interfaceName,
noBrackets = _ref.noBrackets;

@@ -20,3 +24,7 @@ generator.printNewlineIfNeeded();

generator.pushScope({ typeName: interfaceName });
generator.withinBlock(closure);
if (!noBrackets) {
generator.withinBlock(closure, ' {|', '|}');
} else {
generator.withinBlock(closure, '', '');
}
generator.popScope();

@@ -27,3 +35,3 @@ generator.print(';');

function propertyDeclaration(generator, _ref2, closure) {
let propertyName = _ref2.propertyName,
var propertyName = _ref2.propertyName,
typeName = _ref2.typeName,

@@ -48,21 +56,32 @@ description = _ref2.description,

}
if (fragmentSpreads && fragmentSpreads.length > 0) {
if (!isNullable) {
generator.print(' ');
} else {
generator.print('(');
generator.pushScope({ typeName: propertyName });
generator.withinBlock(function () {
if (fragmentSpreads && fragmentSpreads.length > 0) {
fragmentSpreads.forEach(function (n) {
return generator.printOnNewline(`...${(0, _changeCase.pascalCase)(n)}Fragment,`);
});
}
generator.print(`${fragmentSpreads.map(n => `${n}Fragment`).join(' & ')} &`);
}
generator.pushScope({ typeName: propertyName });
generator.withinBlock(closure);
closure();
}, ' {|', '|}');
generator.popScope();
if (isNullable && fragmentSpreads && fragmentSpreads.length > 0) {
generator.print(')');
}
if (isArray) {
generator.print(' >');
}
} else if (fragmentSpreads && fragmentSpreads.length > 0) {
generator.printOnNewline(`${propertyName}: ${isArray ? 'Array<' : ''}${fragmentSpreads.map(n => `${n}Fragment`).join(' & ')}${isArray ? '>' : ''}`);
} else if (fragmentSpreads && fragmentSpreads.length === 1) {
generator.printOnNewline(`${propertyName}: ${isArray ? 'Array<' : ''}${(0, _changeCase.pascalCase)(fragmentSpreads[0])}Fragment${isArray ? '>' : ''}`);
} else if (fragmentSpreads && fragmentSpreads.length > 1) {
generator.printOnNewline(`${propertyName}: ${isArray ? 'Array<' : ''}`);
generator.withinBlock(function () {
fragmentSpreads.forEach(function (n) {
return generator.printOnNewline(`...${(0, _changeCase.pascalCase)(n)}Fragment,`);
});
}, '{|', '|}');
generator.print(isArray ? '>' : '');
} else {

@@ -76,4 +95,14 @@ generator.printOnNewline(`${propertyName}: ${typeName}`);

if (!properties) return;
properties.forEach(property => propertyDeclaration(generator, property));
properties.forEach(function (property) {
return propertyDeclaration(generator, property);
});
}
function unionDeclaration(generator, typeNames) {
if (!typeNames) throw new Error('Union Declaration requires types');
typeNames.forEach(function (typeName) {
generator.printOnNewline(`| ${typeName}`);
});
}
//# sourceMappingURL=language.js.map

@@ -14,3 +14,3 @@ 'use strict';

const builtInScalarMap = {
var builtInScalarMap = {
[_graphql.GraphQLString.name]: 'string',

@@ -24,3 +24,3 @@ [_graphql.GraphQLInt.name]: 'number',

function typeNameFromGraphQLType(context, type, bareTypeName) {
let nullable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
var nullable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;

@@ -31,7 +31,7 @@ if (type instanceof _graphql.GraphQLNonNull) {

let typeName;
var typeName = void 0;
if (type instanceof _graphql.GraphQLList) {
typeName = `Array< ${typeNameFromGraphQLType(context, type.ofType, bareTypeName, true)} >`;
} else if (type instanceof _graphql.GraphQLScalarType) {
typeName = builtInScalarMap[type.name] || (context.passthroughCustomScalars ? context.customScalarsPrefix + type.name : _graphql.GraphQLString);
typeName = builtInScalarMap[type.name] || (context.passthroughCustomScalars ? context.customScalarsPrefix + type.name : 'any');
} else {

@@ -38,0 +38,0 @@ typeName = bareTypeName || type.name;

@@ -6,7 +6,2 @@ 'use strict';

});
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
exports.default = generate;

@@ -39,12 +34,22 @@

function generate(inputPaths, schemaPath, outputPath, target, options) {
const schema = (0, _loading.loadSchema)(schemaPath);
var schema = (0, _loading.loadSchema)(schemaPath);
const document = (0, _loading.loadAndMergeQueryDocuments)(inputPaths);
var document = (0, _loading.loadAndMergeQueryDocuments)(inputPaths);
(0, _validation.validateQueryDocument)(schema, document);
(0, _validation.validateQueryDocument)(schema, document, target);
const context = (0, _compilation.compileToIR)(schema, document);
(0, _assign2.default)(context, options);
if (target === 'swift') {
if (options.addTypename) {
console.warn('This option is a no-op for Swift because __typename is already added automatically');
}
options.addTypename = true;
options.mergeInFieldsFromFragmentSpreads = true;
} else {
options.mergeInFieldsFromFragmentSpreads = false;
}
let output;
var context = (0, _compilation.compileToIR)(schema, document, options);
Object.assign(context, options);
var output = void 0;
switch (target) {

@@ -56,10 +61,9 @@ case 'json':

case 'typescript':
output = (0, _typescript.generateSource)(context);
output = (0, _typescript.generateSource)(context, options);
break;
case 'flow':
output = (0, _flow.generateSource)(context);
output = (0, _flow.generateSource)(context, options);
break;
case 'swift':
default:
output = (0, _swift.generateSource)(context);
output = (0, _swift.generateSource)(context, options);
break;

@@ -66,0 +70,0 @@ }

@@ -6,16 +6,40 @@ 'use strict';

});
exports.generate = exports.downloadSchema = undefined;
var _downloadSchema2 = require('./downloadSchema');
var _downloadSchema = require('./downloadSchema');
var _downloadSchema3 = _interopRequireDefault(_downloadSchema2);
Object.defineProperty(exports, 'downloadSchema', {
enumerable: true,
get: function get() {
return _interopRequireDefault(_downloadSchema).default;
}
});
var _generate2 = require('./generate');
var _introspectSchema = require('./introspectSchema');
var _generate3 = _interopRequireDefault(_generate2);
Object.defineProperty(exports, 'introspectSchema', {
enumerable: true,
get: function get() {
return _interopRequireDefault(_introspectSchema).default;
}
});
var _printSchema = require('./printSchema');
Object.defineProperty(exports, 'printSchema', {
enumerable: true,
get: function get() {
return _interopRequireDefault(_printSchema).default;
}
});
var _generate = require('./generate');
Object.defineProperty(exports, 'generate', {
enumerable: true,
get: function get() {
return _interopRequireDefault(_generate).default;
}
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.downloadSchema = _downloadSchema3.default;
exports.generate = _generate3.default;
//# sourceMappingURL=index.js.map

@@ -31,3 +31,3 @@ 'use strict';

}
const schemaData = require(schemaPath);
var schemaData = require(schemaPath);

@@ -40,13 +40,38 @@ if (!schemaData.data && !schemaData.__schema) {

function extractDocumentFromJavascript(content) {
var re = /gql`([^`]*)`/g;
var match = void 0;
var matches = [];
while (match = re.exec(content)) {
var _doc = match[1].replace(/\${[^}]*}/g, '');
matches.push(_doc);
}
var doc = matches.join('\n');
return doc.length ? doc : null;
}
function loadAndMergeQueryDocuments(inputPaths) {
const sources = inputPaths.map(inputPath => {
const body = _fs2.default.readFileSync(inputPath, 'utf8');
var sources = inputPaths.map(function (inputPath) {
var body = _fs2.default.readFileSync(inputPath, 'utf8');
if (!body) {
return null;
}
if (inputPath.endsWith('.jsx') || inputPath.endsWith('.js') || inputPath.endsWith('.tsx') || inputPath.endsWith('.ts')) {
var doc = extractDocumentFromJavascript(body.toString());
return doc ? new _graphql.Source(doc, inputPath) : null;
}
return new _graphql.Source(body, inputPath);
}).filter(source => source);
}).filter(function (source) {
return source;
});
return (0, _graphql.concatAST)(sources.map(source => (0, _graphql.parse)(source)));
return (0, _graphql.concatAST)(sources.map(function (source) {
return (0, _graphql.parse)(source);
}));
}
//# sourceMappingURL=loading.js.map

@@ -6,11 +6,2 @@ 'use strict';

});
var _stringify = require('babel-runtime/core-js/json/stringify');
var _stringify2 = _interopRequireDefault(_stringify);
var _values = require('babel-runtime/core-js/object/values');
var _values2 = _interopRequireDefault(_values);
exports.default = serializeToJSON;

@@ -21,8 +12,6 @@ exports.serializeAST = serializeAST;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function serializeToJSON(context) {
return serializeAST({
operations: (0, _values2.default)(context.operations),
fragments: (0, _values2.default)(context.fragments),
operations: Object.values(context.operations),
fragments: Object.values(context.fragments),
typesUsed: context.typesUsed.map(serializeType)

@@ -33,9 +22,5 @@ }, '\t');

function serializeAST(ast, space) {
return (0, _stringify2.default)(ast, function (key, value) {
return JSON.stringify(ast, function (key, value) {
if ((0, _graphql.isType)(value)) {
if (expandTypes) {
return serializeType(value);
} else {
return String(value);
}
return String(value);
} else {

@@ -58,12 +43,14 @@ return value;

function serializeEnumType(type) {
const name = type.name,
description = type.description;
var name = type.name,
description = type.description;
const values = type.getValues();
var values = type.getValues();
return {
kind: 'EnumType',
name: name,
description: description,
values: values.map(value => ({ name: value.name, description: value.description }))
name,
description,
values: values.map(function (value) {
return { name: value.name, description: value.description };
})
};

@@ -73,12 +60,12 @@ }

function serializeInputObjectType(type) {
const name = type.name,
description = type.description;
var name = type.name,
description = type.description;
const fields = (0, _values2.default)(type.getFields());
var fields = Object.values(type.getFields());
return {
kind: 'InputObjectType',
name: name,
description: description,
fields: fields
name,
description,
fields
};

@@ -88,4 +75,4 @@ }

function serializeScalarType(type) {
const name = type.name,
description = type.description;
var name = type.name,
description = type.description;

@@ -95,6 +82,6 @@

kind: 'ScalarType',
name: name,
description: description
name,
description
};
}
//# sourceMappingURL=serializeToJSON.js.map

@@ -6,15 +6,2 @@ 'use strict';

});
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _values = require('babel-runtime/core-js/object/values');
var _values2 = _interopRequireDefault(_values);
exports.generateSource = generateSource;

@@ -38,3 +25,3 @@ exports.classDeclarationForOperation = classDeclarationForOperation;

var _values3 = require('./values');
var _values = require('./values');

@@ -49,4 +36,6 @@ var _types = require('./types');

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function generateSource(context) {
const generator = new _CodeGenerator2.default(context);
var generator = new _CodeGenerator2.default(context);

@@ -57,14 +46,14 @@ generator.printOnNewline('// This file was automatically generated and should not be edited.');

(0, _language.namespaceDeclaration)(generator, context.namespace, () => {
(0, _language.namespaceDeclaration)(generator, context.namespace, function () {
context.typesUsed.forEach(type => {
context.typesUsed.forEach(function (type) {
typeDeclarationForGraphQLType(generator, type);
});
(0, _values2.default)(context.operations).forEach(operation => {
classDeclarationForOperation(generator, (0, _extends3.default)({}, operation, { selectionSet: selectionSetFrom(operation) }));
Object.values(context.operations).forEach(function (operation) {
classDeclarationForOperation(generator, operation);
});
(0, _values2.default)(context.fragments).forEach(fragment => {
structDeclarationForFragment(generator, (0, _extends3.default)({}, fragment, { selectionSet: selectionSetFrom(fragment) }));
Object.values(context.fragments).forEach(function (fragment) {
structDeclarationForFragment(generator, fragment);
});

@@ -76,35 +65,16 @@ });

function selectionSetFrom(_ref) {
let fields = _ref.fields,
function classDeclarationForOperation(generator, _ref) {
var operationName = _ref.operationName,
operationType = _ref.operationType,
rootType = _ref.rootType,
variables = _ref.variables,
fields = _ref.fields,
inlineFragments = _ref.inlineFragments,
fragmentSpreads = _ref.fragmentSpreads;
fragmentSpreads = _ref.fragmentSpreads,
fragmentsReferenced = _ref.fragmentsReferenced,
source = _ref.source;
let selectionSet = [];
var className = void 0;
var protocol = void 0;
fields && fields.forEach(field => {
selectionSet.push((0, _extends3.default)({ kind: 'Field' }, field, { selectionSet: selectionSetFrom(field) }));
});
inlineFragments && inlineFragments.forEach(inlineFragment => {
selectionSet.push((0, _extends3.default)({ kind: 'InlineFragment' }, inlineFragment, { selectionSet: selectionSetFrom(inlineFragment) }));
});
fragmentSpreads && fragmentSpreads.forEach(fragmentSpread => {
selectionSet.push({ kind: 'FragmentSpread', fragmentName: fragmentSpread });
});
return selectionSet;
}
function classDeclarationForOperation(generator, _ref2) {
let operationName = _ref2.operationName,
operationType = _ref2.operationType,
variables = _ref2.variables,
selectionSet = _ref2.selectionSet,
fragmentsReferenced = _ref2.fragmentsReferenced,
source = _ref2.source;
let className;
let protocol;
switch (operationType) {

@@ -124,10 +94,10 @@ case 'query':

(0, _language.classDeclaration)(generator, {
className: className,
className,
modifiers: ['public', 'final'],
adoptedProtocols: [protocol]
}, () => {
}, function () {
if (source) {
generator.printOnNewline('public static let operationString =');
generator.withIndent(() => {
(0, _values3.multilineString)(generator, source);
generator.withIndent(function () {
(0, _values.multilineString)(generator, source);
});

@@ -138,3 +108,3 @@ }

generator.printOnNewline('public static var requestString: String { return operationString');
fragmentsReferenced.forEach(fragment => {
fragmentsReferenced.forEach(function (fragment) {
generator.print(`.appending(${(0, _naming.structNameForFragmentName)(fragment)}.fragmentString)`);

@@ -148,10 +118,10 @@ });

if (variables && variables.length > 0) {
const properties = variables.map((_ref3) => {
let name = _ref3.name,
type = _ref3.type;
var properties = variables.map(function (_ref2) {
var name = _ref2.name,
type = _ref2.type;
const propertyName = (0, _language.escapeIdentifierIfNeeded)(name);
const typeName = (0, _types.typeNameFromGraphQLType)(generator.context, type);
const isOptional = !(type instanceof _graphql.GraphQLNonNull || type.ofType instanceof _graphql.GraphQLNonNull);
return { name: name, propertyName: propertyName, type: type, typeName: typeName, isOptional: isOptional };
var propertyName = (0, _language.escapeIdentifierIfNeeded)(name);
var typeName = (0, _types.typeNameFromGraphQLType)(generator.context, type);
var isOptional = !(type instanceof _graphql.GraphQLNonNull || type.ofType instanceof _graphql.GraphQLNonNull);
return { name, propertyName, type, typeName, isOptional };
});

@@ -166,6 +136,6 @@

generator.printOnNewline(`public var variables: GraphQLMap?`);
generator.withinBlock(() => {
generator.printOnNewline((0, _printing.wrap)(`return [`, (0, _printing.join)(properties.map((_ref4) => {
let name = _ref4.name,
propertyName = _ref4.propertyName;
generator.withinBlock(function () {
generator.printOnNewline((0, _printing.wrap)(`return [`, (0, _printing.join)(properties.map(function (_ref3) {
var name = _ref3.name,
propertyName = _ref3.propertyName;
return `"${name}": ${propertyName}`;

@@ -180,3 +150,6 @@ }), ', ') || ':', `]`));

structName: "Data",
selectionSet: selectionSet
parentType: rootType,
fields,
inlineFragments,
fragmentSpreads
});

@@ -186,21 +159,24 @@ });

function structDeclarationForFragment(generator, _ref5) {
let fragmentName = _ref5.fragmentName,
typeCondition = _ref5.typeCondition,
selectionSet = _ref5.selectionSet,
source = _ref5.source;
function structDeclarationForFragment(generator, _ref4) {
var fragmentName = _ref4.fragmentName,
typeCondition = _ref4.typeCondition,
fields = _ref4.fields,
inlineFragments = _ref4.inlineFragments,
fragmentSpreads = _ref4.fragmentSpreads,
source = _ref4.source;
const structName = (0, _naming.structNameForFragmentName)(fragmentName);
var structName = (0, _naming.structNameForFragmentName)(fragmentName);
structDeclarationForSelectionSet(generator, {
structName: structName,
structName,
adoptedProtocols: ['GraphQLFragment'],
parentType: typeCondition,
possibleTypes: (0, _types.possibleTypesForType)(generator.context, typeCondition),
selectionSet: selectionSet
}, () => {
fields,
inlineFragments,
fragmentSpreads
}, function () {
if (source) {
generator.printOnNewline('public static let fragmentString =');
generator.withIndent(() => {
(0, _values3.multilineString)(generator, source);
generator.withIndent(function () {
(0, _values.multilineString)(generator, source);
});

@@ -211,11 +187,14 @@ }

function structDeclarationForSelectionSet(generator, _ref6, beforeClosure) {
let structName = _ref6.structName;
var _ref6$adoptedProtocol = _ref6.adoptedProtocols;
let adoptedProtocols = _ref6$adoptedProtocol === undefined ? ['GraphQLSelectionSet'] : _ref6$adoptedProtocol,
parentType = _ref6.parentType,
possibleTypes = _ref6.possibleTypes,
selectionSet = _ref6.selectionSet;
function structDeclarationForSelectionSet(generator, _ref5, beforeClosure) {
var structName = _ref5.structName,
_ref5$adoptedProtocol = _ref5.adoptedProtocols,
adoptedProtocols = _ref5$adoptedProtocol === undefined ? ['GraphQLSelectionSet'] : _ref5$adoptedProtocol,
parentType = _ref5.parentType,
fields = _ref5.fields,
inlineFragments = _ref5.inlineFragments,
fragmentSpreads = _ref5.fragmentSpreads;
(0, _language.structDeclaration)(generator, { structName: structName, adoptedProtocols: adoptedProtocols }, () => {
var possibleTypes = parentType ? (0, _types.possibleTypesForType)(generator.context, parentType) : null;
(0, _language.structDeclaration)(generator, { structName, adoptedProtocols }, function () {
if (beforeClosure) {

@@ -228,3 +207,5 @@ beforeClosure();

generator.printOnNewline('public static let possibleTypes = [');
generator.print((0, _printing.join)(possibleTypes.map(type => `"${String(type)}"`), ', '));
generator.print((0, _printing.join)(possibleTypes.map(function (type) {
return `"${String(type)}"`;
}), ', '));
generator.print(']');

@@ -235,3 +216,3 @@ }

generator.printOnNewline('public static let selections: [Selection] = ');
selectionSetInitialization(generator, selectionSet, structName);
selectionSetInitialization(generator, fields, inlineFragments, structName);

@@ -244,60 +225,49 @@ generator.printNewlineIfNeeded();

generator.printOnNewline('public init(snapshot: Snapshot)');
generator.withinBlock(() => {
generator.withinBlock(function () {
generator.printOnNewline(`self.snapshot = snapshot`);
});
const properties = (0, _naming.propertiesFromSelectionSet)(generator.context, selectionSet);
const fields = properties.filter(property => property.kind === 'Field');
const inlineFragments = properties.filter(property => property.kind === 'InlineFragment');
const fragmentSpreads = properties.filter(property => property.kind === 'FragmentSpread').map(fragmentSpread => {
if (!(0, _graphql2.isTypeProperSuperTypeOf)(generator.context.schema, fragmentSpread.fragment.typeCondition, parentType)) {
fragmentSpread.isOptional = true;
fragmentSpread.typeName += '?';
}
return fragmentSpread;
});
if (inlineFragments.length < 1) {
if (!possibleTypes || possibleTypes.length == 1) {
generator.printNewlineIfNeeded();
generator.printOnNewline(`public init`);
generator.print('(');
generator.print((0, _printing.join)(fields.map((_ref7) => {
let propertyName = _ref7.propertyName,
type = _ref7.type,
typeName = _ref7.typeName,
isOptional = _ref7.isOptional;
return (0, _printing.join)([`${propertyName}: ${typeName}`, isOptional && ' = nil']);
}), ', '));
generator.print(')');
generator.withinBlock(() => {
generator.printOnNewline((0, _printing.wrap)(`self.init(snapshot: [`, (0, _printing.join)(fields.map((_ref8) => {
let name = _ref8.name,
propertyName = _ref8.propertyName;
var properties = fields.map(function (field) {
return (0, _naming.propertyFromField)(generator.context, field);
}).filter(function (field) {
return field.propertyName != "__typename";
});
parametersForProperties(generator, properties);
generator.withinBlock(function () {
generator.printOnNewline((0, _printing.wrap)(`self.init(snapshot: [`, (0, _printing.join)([`"__typename": "${possibleTypes[0]}"`].concat(_toConsumableArray(properties.map(function (_ref6) {
var propertyName = _ref6.propertyName;
return `"${propertyName}": ${propertyName}`;
}), ', ') || ':', `])`));
}))), ', ') || ':', `])`));
});
} else {
inlineFragments.forEach(inlineFragment => {
possibleTypes.forEach(function (possibleType) {
generator.printNewlineIfNeeded();
generator.printOnNewline(`public static func make${inlineFragment.typeCondition}`);
generator.print('(');
const properties = (0, _naming.propertiesFromSelectionSet)(generator.context, inlineFragment.selectionSet, inlineFragment.structName);
const fields = properties.filter(property => property.kind === 'Field' && property.propertyName !== '__typename');
generator.print((0, _printing.join)(fields.map((_ref9) => {
let propertyName = _ref9.propertyName,
type = _ref9.type,
typeName = _ref9.typeName,
isOptional = _ref9.isOptional;
return (0, _printing.join)([`${propertyName}: ${typeName}`, isOptional && ' = nil']);
}), ', '));
generator.print(`) -> ${structName}`);
generator.printOnNewline(`public static func make${possibleType}`);
generator.withinBlock(() => {
generator.printOnNewline((0, _printing.wrap)(`return ${structName}(snapshot: [`, (0, _printing.join)([`"__typename": "${inlineFragment.typeCondition}"`].concat((0, _toConsumableArray3.default)(fields.map((_ref10) => {
let name = _ref10.name,
propertyName = _ref10.propertyName;
var inlineFragment = inlineFragments && inlineFragments.find(function (inlineFragment) {
return inlineFragment.typeCondition === possibleType;
});
var fieldsForPossibleType = inlineFragment ? inlineFragment.fields : fields;
var properties = fieldsForPossibleType.map(function (field) {
return (0, _naming.propertyFromField)(generator.context, field, inlineFragment && (0, _naming.structNameForInlineFragment)(inlineFragment));
}).filter(function (field) {
return field.propertyName != "__typename";
});
parametersForProperties(generator, properties);
generator.print(` -> ${structName}`);
generator.withinBlock(function () {
generator.printOnNewline((0, _printing.wrap)(`return ${structName}(snapshot: [`, (0, _printing.join)([`"__typename": "${possibleType}"`].concat(_toConsumableArray(properties.map(function (_ref7) {
var propertyName = _ref7.propertyName;
return `"${propertyName}": ${propertyName}`;
}))), ', '), `])`));
}))), ', ') || ':', `])`));
});

@@ -307,19 +277,19 @@ });

properties.forEach(property => {
if (property.kind === 'FragmentSpread') return;
generator.printNewlineIfNeeded();
propertyDeclarationForSelection(generator, property);
fields.forEach(function (field) {
return propertyDeclarationForField(generator, field);
});
inlineFragments && inlineFragments.forEach(function (inlineFragment) {
return propertyDeclarationForInlineFragment(generator, inlineFragment);
});
if (fragmentSpreads.length > 0) {
if (fragmentSpreads && fragmentSpreads.length > 0) {
generator.printNewlineIfNeeded();
generator.printOnNewline(`public var fragments: Fragments`);
generator.withinBlock(() => {
generator.withinBlock(function () {
generator.printOnNewline("get");
generator.withinBlock(() => {
generator.withinBlock(function () {
generator.printOnNewline(`return Fragments(snapshot: snapshot)`);
});
generator.printOnNewline("set");
generator.withinBlock(() => {
generator.withinBlock(function () {
generator.printOnNewline(`snapshot = newValue.snapshot`);

@@ -330,14 +300,11 @@ });

if (inlineFragments.length > 0) {
inlineFragments.forEach((_ref11) => {
let structName = _ref11.structName,
typeCondition = _ref11.typeCondition,
selectionSet = _ref11.selectionSet;
if (inlineFragments && inlineFragments.length > 0) {
inlineFragments.forEach(function (inlineFragment) {
structDeclarationForSelectionSet(generator, {
structName: structName,
parentType: typeCondition,
possibleTypes: (0, _types.possibleTypesForType)(generator.context, typeCondition),
structName: (0, _naming.structNameForInlineFragment)(inlineFragment),
parentType: inlineFragment.typeCondition,
adoptedProtocols: ['GraphQLFragment'],
selectionSet: selectionSet
fields: inlineFragment.fields,
inlineFragments: inlineFragment.inlineFragments,
fragmentSpreads: inlineFragment.fragmentSpreads
});

@@ -347,20 +314,23 @@ });

if (fragmentSpreads.length > 0) {
if (fragmentSpreads && fragmentSpreads.length > 0) {
(0, _language.structDeclaration)(generator, {
structName: 'Fragments'
}, () => {
}, function () {
(0, _language.propertyDeclaration)(generator, { propertyName: "snapshot", typeName: "Snapshot" });
fragmentSpreads.forEach((_ref12) => {
let propertyName = _ref12.propertyName,
bareTypeName = _ref12.bareTypeName,
typeName = _ref12.typeName,
isOptional = _ref12.isOptional;
fragmentSpreads.forEach(function (fragmentSpread) {
var _propertyFromFragment = (0, _naming.propertyFromFragmentSpread)(generator.context, fragmentSpread),
propertyName = _propertyFromFragment.propertyName,
bareTypeName = _propertyFromFragment.bareTypeName,
typeName = _propertyFromFragment.typeName,
fragment = _propertyFromFragment.fragment;
var isOptional = !(0, _graphql2.isTypeProperSuperTypeOf)(generator.context.schema, fragment.typeCondition, parentType);
generator.printNewlineIfNeeded();
generator.printOnNewline(`public var ${propertyName}: ${typeName}`);
generator.withinBlock(() => {
generator.printOnNewline(`public var ${propertyName}: ${isOptional ? typeName + '?' : typeName}`);
generator.withinBlock(function () {
generator.printOnNewline("get");
generator.withinBlock(() => {
generator.withinBlock(function () {
if (isOptional) {
generator.printOnNewline(`if !${typeName}.possibleTypes.contains(__typename) { return nil }`);
generator.printOnNewline(`if !${typeName}.possibleTypes.contains(snapshot["__typename"]! as! String) { return nil }`);
}

@@ -370,4 +340,9 @@ generator.printOnNewline(`return ${typeName}(snapshot: snapshot)`);

generator.printOnNewline("set");
generator.withinBlock(() => {
generator.printOnNewline(`snapshot = newValue.snapshot`);
generator.withinBlock(function () {
if (isOptional) {
generator.printOnNewline(`guard let newValue = newValue else { return }`);
generator.printOnNewline(`snapshot = newValue.snapshot`);
} else {
generator.printOnNewline(`snapshot = newValue.snapshot`);
}
});

@@ -379,7 +354,11 @@ });

fields.filter(field => (0, _graphql.isCompositeType)((0, _graphql.getNamedType)(field.type))).forEach(field => {
fields.filter(function (field) {
return (0, _graphql.isCompositeType)((0, _graphql.getNamedType)(field.type));
}).forEach(function (field) {
structDeclarationForSelectionSet(generator, {
structName: (0, _naming.structNameForPropertyName)(field.responseName),
parentType: (0, _graphql.getNamedType)(field.type),
selectionSet: field.selectionSet
fields: field.fields,
inlineFragments: field.inlineFragments,
fragmentSpreads: field.fragmentSpreads
});

@@ -390,63 +369,27 @@ });

function mapExpressionForType(context, type, expression) {
let prefix = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
function propertyDeclarationForField(generator, field) {
var _propertyFromField = (0, _naming.propertyFromField)(generator.context, field),
kind = _propertyFromField.kind,
propertyName = _propertyFromField.propertyName,
typeName = _propertyFromField.typeName,
type = _propertyFromField.type,
isConditional = _propertyFromField.isConditional,
description = _propertyFromField.description;
let isOptional;
if (type instanceof _graphql.GraphQLNonNull) {
isOptional = false;
type = type.ofType;
} else {
isOptional = true;
}
var namedType = (0, _graphql.getNamedType)(type);
if (type instanceof _graphql.GraphQLList) {
if (isOptional) {
return `${prefix}.flatMap { $0.map { ${mapExpressionForType(context, type.ofType, expression, '$0')} } }`;
} else {
return `${prefix}.map { ${mapExpressionForType(context, type.ofType, expression, '$0')} }`;
}
} else if (isOptional) {
return `${prefix}.flatMap { ${expression} }`;
} else {
return expression;
}
}
function propertyDeclarationForSelection(generator, selection) {
const kind = selection.kind,
propertyName = selection.propertyName,
typeName = selection.typeName,
type = selection.type,
isConditional = selection.isConditional,
description = selection.description;
generator.printOnNewline(description && ` /// ${description}`);
generator.printNewlineIfNeeded();
(0, _language.comment)(generator, description);
generator.printOnNewline(`public var ${propertyName}: ${typeName}`);
generator.withinBlock(() => {
const namedType = (0, _graphql.getNamedType)(type);
generator.withinBlock(function () {
if ((0, _graphql.isCompositeType)(namedType)) {
var isOptional = isConditional || !(type instanceof _graphql.GraphQLNonNull);
var isList = type instanceof _graphql.GraphQLList || type.ofType instanceof _graphql.GraphQLList;
var structName = (0, _language.escapeIdentifierIfNeeded)((0, _naming.structNameForPropertyName)(propertyName));
if (kind === 'InlineFragment') {
const structName = (0, _naming.structNameForInlineFragment)(selection);
generator.printOnNewline("get");
generator.withinBlock(() => {
generator.printOnNewline(`if !${structName}.possibleTypes.contains(__typename) { return nil }`);
generator.printOnNewline(`return ${structName}(snapshot: snapshot)`);
});
generator.printOnNewline("set");
generator.withinBlock(() => {
generator.printOnNewline(`guard let newValue = newValue else { return }`);
generator.printOnNewline(`snapshot = newValue.snapshot`);
});
} else if ((0, _graphql.isCompositeType)(namedType)) {
const isOptional = isConditional || !(type instanceof _graphql.GraphQLNonNull);
const isList = type instanceof _graphql.GraphQLList || type.ofType instanceof _graphql.GraphQLList;
const structName = (0, _language.escapeIdentifierIfNeeded)((0, _naming.structNameForPropertyName)(propertyName));
if (isList) {
generator.printOnNewline("get");
generator.withinBlock(() => {
const snapshotTypeName = (0, _types.typeNameFromGraphQLType)(generator.context, type, 'Snapshot', isOptional);
let getter = `return (snapshot["${propertyName}"]! as! ${snapshotTypeName})`;
generator.withinBlock(function () {
var snapshotTypeName = (0, _types.typeNameFromGraphQLType)(generator.context, type, 'Snapshot', isOptional);
var getter = `return (snapshot["${propertyName}"]! as! ${snapshotTypeName})`;
getter += mapExpressionForType(generator.context, type, `${structName}(snapshot: $0)`);

@@ -456,4 +399,4 @@ generator.printOnNewline(getter);

generator.printOnNewline("set");
generator.withinBlock(() => {
let newValueExpression = "newValue" + mapExpressionForType(generator.context, type, `$0.snapshot`);
generator.withinBlock(function () {
var newValueExpression = "newValue" + mapExpressionForType(generator.context, type, `$0.snapshot`);
generator.printOnNewline(`snapshot.updateValue(${newValueExpression}, forKey: "${propertyName}")`);

@@ -463,8 +406,8 @@ });

generator.printOnNewline("get");
generator.withinBlock(() => {
generator.withinBlock(function () {
generator.printOnNewline(`return ${structName}(snapshot: snapshot["${propertyName}"]! as! Snapshot)`);
});
generator.printOnNewline("set");
generator.withinBlock(() => {
let newValueExpression;
generator.withinBlock(function () {
var newValueExpression = void 0;
if (isOptional) {

@@ -480,7 +423,7 @@ newValueExpression = 'newValue?.snapshot';

generator.printOnNewline("get");
generator.withinBlock(() => {
generator.withinBlock(function () {
generator.printOnNewline(`return snapshot["${propertyName}"]! as! ${typeName}`);
});
generator.printOnNewline("set");
generator.withinBlock(() => {
generator.withinBlock(function () {
generator.printOnNewline(`snapshot.updateValue(newValue, forKey: "${propertyName}")`);

@@ -492,17 +435,63 @@ });

function propertyDeclarationForInlineFragment(generator, inlineFragment) {
var _propertyFromInlineFr = (0, _naming.propertyFromInlineFragment)(generator.context, inlineFragment),
kind = _propertyFromInlineFr.kind,
propertyName = _propertyFromInlineFr.propertyName,
typeName = _propertyFromInlineFr.typeName,
type = _propertyFromInlineFr.type,
isConditional = _propertyFromInlineFr.isConditional,
description = _propertyFromInlineFr.description;
var namedType = (0, _graphql.getNamedType)(type);
generator.printNewlineIfNeeded();
(0, _language.comment)(generator, description);
generator.printOnNewline(`public var ${propertyName}: ${typeName}`);
generator.withinBlock(function () {
var structName = (0, _naming.structNameForInlineFragment)(inlineFragment);
generator.printOnNewline("get");
generator.withinBlock(function () {
generator.printOnNewline(`if !${structName}.possibleTypes.contains(__typename) { return nil }`);
generator.printOnNewline(`return ${structName}(snapshot: snapshot)`);
});
generator.printOnNewline("set");
generator.withinBlock(function () {
generator.printOnNewline(`guard let newValue = newValue else { return }`);
generator.printOnNewline(`snapshot = newValue.snapshot`);
});
});
}
function mapExpressionForType(context, type, expression) {
var prefix = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
var isOptional = void 0;
if (type instanceof _graphql.GraphQLNonNull) {
isOptional = false;
type = type.ofType;
} else {
isOptional = true;
}
if (type instanceof _graphql.GraphQLList) {
if (isOptional) {
return `${prefix}.flatMap { $0.map { ${mapExpressionForType(context, type.ofType, expression, '$0')} } }`;
} else {
return `${prefix}.map { ${mapExpressionForType(context, type.ofType, expression, '$0')} }`;
}
} else if (isOptional) {
return `${prefix}.flatMap { ${expression} }`;
} else {
return expression;
}
}
function initializerDeclarationForProperties(generator, properties) {
generator.printOnNewline(`public init`);
generator.print('(');
generator.print((0, _printing.join)(properties.map((_ref13) => {
let propertyName = _ref13.propertyName,
type = _ref13.type,
typeName = _ref13.typeName,
isOptional = _ref13.isOptional;
return (0, _printing.join)([`${propertyName}: ${typeName}`, isOptional && ' = nil']);
}), ', '));
generator.print(')');
parametersForProperties(generator, properties);
generator.withinBlock(() => {
properties.forEach((_ref14) => {
let propertyName = _ref14.propertyName;
generator.withinBlock(function () {
properties.forEach(function (_ref8) {
var propertyName = _ref8.propertyName;

@@ -514,25 +503,34 @@ generator.printOnNewline(`self.${propertyName} = ${propertyName}`);

function selectionSetInitialization(generator, selectionSet, parentStructName) {
function parametersForProperties(generator, properties) {
generator.print('(');
generator.print((0, _printing.join)(properties.map(function (_ref9) {
var propertyName = _ref9.propertyName,
type = _ref9.type,
typeName = _ref9.typeName,
isOptional = _ref9.isOptional;
return (0, _printing.join)([`${propertyName}: ${typeName}`, isOptional && ' = nil']);
}), ', '));
generator.print(')');
}
function selectionSetInitialization(generator, fields, inlineFragments, parentStructName) {
generator.print('[');
generator.withIndent(() => {
selectionSet.forEach(selection => {
if (selection.kind === 'Field') {
const responseName = selection.responseName,
fieldName = selection.fieldName,
args = selection.args,
type = selection.type;
generator.withIndent(function () {
fields.forEach(function (field) {
var responseName = field.responseName,
fieldName = field.fieldName,
args = field.args,
type = field.type;
const structName = (0, _printing.join)([parentStructName, (0, _naming.structNameForPropertyName)(responseName)], '.');
var structName = (0, _printing.join)([parentStructName, (0, _naming.structNameForPropertyName)(responseName)], '.');
generator.printOnNewline(`Field(`);
generator.print((0, _printing.join)([`"${fieldName}"`, responseName != fieldName ? `alias: "${responseName}"` : null, args && args.length && `arguments: ${(0, _values3.dictionaryLiteralForFieldArguments)(args)}`, `type: ${(0, _types.fieldTypeEnum)(generator.context, type, structName)}`], ', '));
generator.print('),');
} else if (selection.kind === 'FragmentSpread') {
const structName = (0, _naming.structNameForFragmentName)(selection.fragmentName);
generator.printOnNewline(`FragmentSpread(${structName}.self),`);
} else if (selection.kind === 'InlineFragment') {
const structName = (0, _printing.join)([parentStructName, (0, _naming.structNameForInlineFragment)(selection)], '.');
generator.printOnNewline(`FragmentSpread(${structName}.self),`);
}
generator.printOnNewline(`Field(`);
generator.print((0, _printing.join)([`"${fieldName}"`, responseName != fieldName ? `alias: "${responseName}"` : null, args && args.length && `arguments: ${(0, _values.dictionaryLiteralForFieldArguments)(args)}`, `type: ${(0, _types.fieldTypeEnum)(generator.context, type, structName)}`], ', '));
generator.print('),');
});
inlineFragments && inlineFragments.forEach(function (InlineFragment) {
var structName = (0, _printing.join)([parentStructName, (0, _naming.structNameForInlineFragment)(InlineFragment)], '.');
generator.printOnNewline(`FragmentSpread(${structName}.self),`);
});
});

@@ -551,6 +549,6 @@ generator.printOnNewline(']');

function enumerationDeclaration(generator, type) {
const name = type.name,
description = type.description;
var name = type.name,
description = type.description;
const values = type.getValues();
var values = type.getValues();

@@ -560,41 +558,40 @@ generator.printNewlineIfNeeded();

generator.printOnNewline(`public enum ${name}: String`);
generator.withinBlock(() => {
values.forEach(value => generator.printOnNewline(`case ${(0, _language.escapeIdentifierIfNeeded)((0, _naming.enumCaseName)(value.name))} = "${value.value}"${(0, _printing.wrap)(' /// ', value.description)}`));
generator.withinBlock(function () {
values.forEach(function (value) {
return generator.printOnNewline(`case ${(0, _language.escapeIdentifierIfNeeded)((0, _naming.enumCaseName)(value.name))} = "${value.value}"${(0, _printing.wrap)(' /// ', value.description)}`);
});
});
generator.printNewline();
generator.printOnNewline(`extension ${name}: JSONDecodable, JSONEncodable {}`);
generator.printOnNewline(`extension ${name}: Apollo.JSONDecodable, Apollo.JSONEncodable {}`);
}
function structDeclarationForInputObjectType(generator, type) {
const structName = type.name,
description = type.description;
var structName = type.name,
description = type.description;
const adoptedProtocols = ['GraphQLMapConvertible'];
const fields = (0, _values2.default)(type.getFields());
const properties = fields.map(field => (0, _naming.propertyFromField)(generator.context, field));
var adoptedProtocols = ['GraphQLMapConvertible'];
var fields = Object.values(type.getFields());
var properties = fields.map(function (field) {
return (0, _naming.propertyFromField)(generator.context, field);
});
(0, _language.structDeclaration)(generator, { structName: structName, description: description, adoptedProtocols: adoptedProtocols }, () => {
generator.printOnNewline(`public var graphQLMap: GraphQLMap`);
properties.forEach(function (property) {
if (property.isOptional) {
property.typeName = `Optional<${property.typeName}>`;
}
});
(0, _language.structDeclaration)(generator, { structName, description, adoptedProtocols }, function () {
(0, _language.propertyDeclarations)(generator, properties);
generator.printNewlineIfNeeded();
generator.printOnNewline(`public init`);
generator.print('(');
generator.print((0, _printing.join)(properties.map((_ref15) => {
let propertyName = _ref15.propertyName,
type = _ref15.type,
typeName = _ref15.typeName,
isOptional = _ref15.isOptional;
if (isOptional) {
return `${propertyName}: Optional<${typeName}> = nil`;
} else {
return `${propertyName}: ${typeName}`;
}
}), ', '));
generator.print(')');
initializerDeclarationForProperties(generator, properties);
generator.withinBlock(() => {
generator.printOnNewline((0, _printing.wrap)(`graphQLMap = [`, (0, _printing.join)(properties.map((_ref16) => {
let name = _ref16.name,
propertyName = _ref16.propertyName;
generator.printNewlineIfNeeded();
generator.printOnNewline(`public var graphQLMap: GraphQLMap`);
generator.withinBlock(function () {
generator.printOnNewline((0, _printing.wrap)(`return [`, (0, _printing.join)(properties.map(function (_ref10) {
var name = _ref10.name,
propertyName = _ref10.propertyName;
return `"${name}": ${propertyName}`;

@@ -601,0 +598,0 @@ }), ', ') || ':', `]`));

@@ -6,11 +6,3 @@ 'use strict';

});
var _set = require('babel-runtime/core-js/set');
var _set2 = _interopRequireDefault(_set);
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
exports.comment = comment;
exports.namespaceDeclaration = namespaceDeclaration;

@@ -28,8 +20,13 @@ exports.classDeclaration = classDeclaration;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function comment(generator, comment) {
comment && comment.split('\n').forEach(function (line) {
generator.printOnNewline(`/// ${line.trim()}`);
});
}
function namespaceDeclaration(generator, namespace, closure) {
if (namespace) {
generator.printNewlineIfNeeded();
generator.printNewline();
generator.printOnNewline(`/// ${namespace} namespace`);

@@ -46,13 +43,12 @@ generator.printOnNewline(`public enum ${namespace}`);

function classDeclaration(generator, _ref, closure) {
let className = _ref.className,
var className = _ref.className,
modifiers = _ref.modifiers,
superClass = _ref.superClass;
var _ref$adoptedProtocols = _ref.adoptedProtocols;
let adoptedProtocols = _ref$adoptedProtocols === undefined ? [] : _ref$adoptedProtocols,
superClass = _ref.superClass,
_ref$adoptedProtocols = _ref.adoptedProtocols,
adoptedProtocols = _ref$adoptedProtocols === undefined ? [] : _ref$adoptedProtocols,
properties = _ref.properties;
generator.printNewlineIfNeeded();
generator.printNewline();
generator.printOnNewline((0, _printing.wrap)('', (0, _printing.join)(modifiers, ' '), ' ') + `class ${className}`);
generator.print((0, _printing.wrap)(': ', (0, _printing.join)([superClass].concat((0, _toConsumableArray3.default)(adoptedProtocols)), ', ')));
generator.print((0, _printing.wrap)(': ', (0, _printing.join)([superClass].concat(_toConsumableArray(adoptedProtocols)), ', ')));
generator.pushScope({ typeName: className });

@@ -64,9 +60,9 @@ generator.withinBlock(closure);

function structDeclaration(generator, _ref2, closure) {
let structName = _ref2.structName,
description = _ref2.description;
var _ref2$adoptedProtocol = _ref2.adoptedProtocols;
let adoptedProtocols = _ref2$adoptedProtocol === undefined ? [] : _ref2$adoptedProtocol;
var structName = _ref2.structName,
description = _ref2.description,
_ref2$adoptedProtocol = _ref2.adoptedProtocols,
adoptedProtocols = _ref2$adoptedProtocol === undefined ? [] : _ref2$adoptedProtocol;
generator.printNewlineIfNeeded();
generator.printOnNewline(description && `/// ${description}`);
comment(generator, description);
generator.printOnNewline(`public struct ${structName}`);

@@ -80,7 +76,7 @@ generator.print((0, _printing.wrap)(': ', (0, _printing.join)(adoptedProtocols, ', ')));

function propertyDeclaration(generator, _ref3) {
let propertyName = _ref3.propertyName,
var propertyName = _ref3.propertyName,
typeName = _ref3.typeName,
description = _ref3.description;
generator.printOnNewline(description && ` /// ${description}`);
comment(generator, description);
generator.printOnNewline(`public var ${propertyName}: ${typeName}`);

@@ -91,7 +87,9 @@ }

if (!properties) return;
properties.forEach(property => propertyDeclaration(generator, property));
properties.forEach(function (property) {
return propertyDeclaration(generator, property);
});
}
function protocolDeclaration(generator, _ref4, closure) {
let protocolName = _ref4.protocolName,
var protocolName = _ref4.protocolName,
adoptedProtocols = _ref4.adoptedProtocols,

@@ -109,3 +107,3 @@ properties = _ref4.properties;

function protocolPropertyDeclaration(generator, _ref5) {
let propertyName = _ref5.propertyName,
var propertyName = _ref5.propertyName,
typeName = _ref5.typeName;

@@ -118,6 +116,8 @@

if (!properties) return;
properties.forEach(property => protocolPropertyDeclaration(generator, property));
properties.forEach(function (property) {
return protocolPropertyDeclaration(generator, property);
});
}
const reservedKeywords = new _set2.default(['associatedtype', 'class', 'deinit', 'enum', 'extension', 'fileprivate', 'func', 'import', 'init', 'inout', 'internal', 'let', 'open', 'operator', 'private', 'protocol', 'public', 'static', 'struct', 'subscript', 'typealias', 'var', 'break', 'case', 'continue', 'default', 'defer', 'do', 'else', 'fallthrough', 'for', 'guard', 'if', 'in', 'repeat', 'return', 'switch', 'where', 'while', 'as', 'Any', 'catch', 'false', 'is', 'nil', 'rethrows', 'super', 'self', 'Self', 'throw', 'throws', 'true', 'try', 'associativity', 'convenience', 'dynamic', 'didSet', 'final', 'get', 'infix', 'indirect', 'lazy', 'left', 'mutating', 'none', 'nonmutating', 'optional', 'override', 'postfix', 'precedence', 'prefix', 'Protocol', 'required', 'right', 'set', 'Type', 'unowned', 'weak', 'willSet']);
var reservedKeywords = new Set(['associatedtype', 'class', 'deinit', 'enum', 'extension', 'fileprivate', 'func', 'import', 'init', 'inout', 'internal', 'let', 'open', 'operator', 'private', 'protocol', 'public', 'static', 'struct', 'subscript', 'typealias', 'var', 'break', 'case', 'continue', 'default', 'defer', 'do', 'else', 'fallthrough', 'for', 'guard', 'if', 'in', 'repeat', 'return', 'switch', 'where', 'while', 'as', 'Any', 'catch', 'false', 'is', 'nil', 'rethrows', 'super', 'self', 'Self', 'throw', 'throws', 'true', 'try', 'associativity', 'convenience', 'dynamic', 'didSet', 'final', 'get', 'infix', 'indirect', 'lazy', 'left', 'mutating', 'none', 'nonmutating', 'optional', 'override', 'postfix', 'precedence', 'prefix', 'Protocol', 'required', 'right', 'set', 'Type', 'unowned', 'weak', 'willSet']);

@@ -124,0 +124,0 @@ function escapeIdentifierIfNeeded(identifier) {

@@ -6,7 +6,2 @@ 'use strict';

});
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
exports.enumCaseName = enumCaseName;

@@ -17,3 +12,2 @@ exports.operationClassName = operationClassName;

exports.structNameForInlineFragment = structNameForInlineFragment;
exports.propertiesFromSelectionSet = propertiesFromSelectionSet;
exports.propertyFromField = propertyFromField;

@@ -59,31 +53,19 @@ exports.propertyFromInlineFragment = propertyFromInlineFragment;

function propertiesFromSelectionSet(context, selectionSet, namespace) {
return selectionSet.map(selection => {
if (selection.kind === 'Field') {
return propertyFromField(context, selection, namespace);
} else if (selection.kind === 'InlineFragment') {
return propertyFromInlineFragment(context, selection);
} else if (selection.kind === 'FragmentSpread') {
return propertyFromFragmentSpread(context, selection);
}
});
}
function propertyFromField(context, field, namespace) {
const name = field.name || field.responseName;
const unescapedPropertyName = isMetaFieldName(name) ? name : (0, _changeCase.camelCase)(name);
const propertyName = (0, _language.escapeIdentifierIfNeeded)(unescapedPropertyName);
var name = field.name || field.responseName;
var unescapedPropertyName = isMetaFieldName(name) ? name : (0, _changeCase.camelCase)(name);
var propertyName = (0, _language.escapeIdentifierIfNeeded)(unescapedPropertyName);
const type = field.type;
const isList = type instanceof _graphql.GraphQLList || type.ofType instanceof _graphql.GraphQLList;
const isOptional = field.isConditional || !(type instanceof _graphql.GraphQLNonNull);
const bareType = (0, _graphql.getNamedType)(type);
var type = field.type;
var isList = type instanceof _graphql.GraphQLList || type.ofType instanceof _graphql.GraphQLList;
var isOptional = field.isConditional || !(type instanceof _graphql.GraphQLNonNull);
var bareType = (0, _graphql.getNamedType)(type);
if ((0, _graphql.isCompositeType)(bareType)) {
const bareTypeName = (0, _printing.join)([namespace, (0, _language.escapeIdentifierIfNeeded)((0, _changeCase.pascalCase)(_inflected2.default.singularize(name)))], '.');
const typeName = (0, _types.typeNameFromGraphQLType)(context, type, bareTypeName, isOptional);
return (0, _extends3.default)({}, field, { propertyName: propertyName, typeName: typeName, bareTypeName: bareTypeName, isOptional: isOptional, isList: isList, isComposite: true });
var bareTypeName = (0, _printing.join)([namespace, (0, _language.escapeIdentifierIfNeeded)((0, _changeCase.pascalCase)(_inflected2.default.singularize(name)))], '.');
var typeName = (0, _types.typeNameFromGraphQLType)(context, type, bareTypeName, isOptional);
return Object.assign({}, field, { propertyName, typeName, bareTypeName, isOptional, isList, isComposite: true });
} else {
const typeName = (0, _types.typeNameFromGraphQLType)(context, type, undefined, isOptional);
return (0, _extends3.default)({}, field, { propertyName: propertyName, typeName: typeName, isOptional: isOptional, isList: isList, isComposite: false });
var _typeName = (0, _types.typeNameFromGraphQLType)(context, type, undefined, isOptional);
return Object.assign({}, field, { propertyName, typeName: _typeName, isOptional, isList, isComposite: false });
}

@@ -93,17 +75,17 @@ }

function propertyFromInlineFragment(context, inlineFragment) {
const structName = structNameForInlineFragment(inlineFragment);
const propertyName = (0, _changeCase.camelCase)(structName);
const typeName = structName + '?';
return (0, _extends3.default)({ propertyName: propertyName, typeName: typeName, structName: structName, isComposite: true }, inlineFragment);
var structName = structNameForInlineFragment(inlineFragment);
var propertyName = (0, _changeCase.camelCase)(structName);
var typeName = structName + '?';
return Object.assign({ propertyName, typeName, structName, isComposite: true }, inlineFragment);
}
function propertyFromFragmentSpread(context, fragmentSpread) {
const fragmentName = fragmentSpread.fragmentName;
const fragment = context.fragments[fragmentName];
var fragmentName = fragmentSpread;
var fragment = context.fragments[fragmentName];
if (!fragment) {
throw new _graphql.GraphQLError(`Cannot find fragment "${fragmentName}"`);
}
const propertyName = (0, _changeCase.camelCase)(fragmentName);
const typeName = structNameForFragmentName(fragmentName);
return (0, _extends3.default)({ propertyName: propertyName, typeName: typeName, fragment: fragment, isComposite: true }, fragmentSpread);
var propertyName = (0, _changeCase.camelCase)(fragmentName);
var typeName = structNameForFragmentName(fragmentName);
return { propertyName, typeName, fragment, isComposite: true };
}

@@ -110,0 +92,0 @@

@@ -16,3 +16,3 @@ 'use strict';

const builtInScalarMap = {
var builtInScalarMap = {
[_graphql.GraphQLString.name]: 'String',

@@ -40,3 +40,3 @@ [_graphql.GraphQLInt.name]: 'Int',

let typeName;
var typeName = void 0;
if (type instanceof _graphql.GraphQLList) {

@@ -43,0 +43,0 @@ typeName = '[' + typeNameFromGraphQLType(context, type.ofType, bareTypeName) + ']';

@@ -7,14 +7,4 @@ 'use strict';

var _stringify = require('babel-runtime/core-js/json/stringify');
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _stringify2 = _interopRequireDefault(_stringify);
var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
var _entries = require('babel-runtime/core-js/object/entries');
var _entries2 = _interopRequireDefault(_entries);
exports.escapedString = escapedString;

@@ -26,4 +16,2 @@ exports.multilineString = multilineString;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function escapedString(string) {

@@ -34,5 +22,5 @@ return string.replace(/"/g, '\\"');

function multilineString(context, string) {
const lines = string.split('\n');
lines.forEach((line, index) => {
const isLastLine = index != lines.length - 1;
var lines = string.split('\n');
lines.forEach(function (line, index) {
var isLastLine = index != lines.length - 1;
context.printOnNewline(`"${escapedString(line)}"` + (isLastLine ? ' +' : ''));

@@ -49,6 +37,5 @@ });

} else if (typeof value === 'object') {
return (0, _printing.wrap)('[', (0, _printing.join)((0, _entries2.default)(value).map((_ref) => {
var _ref2 = (0, _slicedToArray3.default)(_ref, 2);
let key = _ref2[0],
return (0, _printing.wrap)('[', (0, _printing.join)(Object.entries(value).map(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
key = _ref2[0],
value = _ref2[1];

@@ -59,7 +46,7 @@

} else {
return (0, _stringify2.default)(value);
return JSON.stringify(value);
}
}
return (0, _printing.wrap)('[', (0, _printing.join)(args.map(arg => {
return (0, _printing.wrap)('[', (0, _printing.join)(args.map(function (arg) {
return `"${arg.name}": ${expressionFromValue(arg.value)}`;

@@ -66,0 +53,0 @@ }), ', ') || ':', ']');

@@ -6,15 +6,2 @@ 'use strict';

});
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
var _values = require('babel-runtime/core-js/object/values');
var _values2 = _interopRequireDefault(_values);
exports.generateSource = generateSource;

@@ -51,14 +38,23 @@ exports.typeDeclarationForGraphQLType = typeDeclarationForGraphQLType;

function generateSource(context) {
const generator = new _CodeGenerator2.default(context);
function generateSource(context, options) {
var generator = new _CodeGenerator2.default(context);
generator.printOnNewline('/* tslint:disable */');
generator.printOnNewline('// This file was automatically generated and should not be edited.');
generator.printOnNewline('/* tslint:disable */');
typeDeclarationForGraphQLType(context.typesUsed.forEach(type => typeDeclarationForGraphQLType(generator, type)));
(0, _values2.default)(context.operations).forEach(operation => {
typeDeclarationForGraphQLType(context.typesUsed.forEach(function (type) {
return typeDeclarationForGraphQLType(generator, type);
}));
// When an object has fragment spreads or inline fragments
// and __typename is requested at the top level, __typename
// needs to be added as a property of the fragments
var fragmentsWithTypenameField = {};
Object.values(context.operations).forEach(function (operation) {
interfaceVariablesDeclarationForOperation(generator, operation);
interfaceDeclarationForOperation(generator, operation);
interfaceDeclarationForOperation(generator, operation, fragmentsWithTypenameField);
});
(0, _values2.default)(context.fragments).forEach(operation => interfaceDeclarationForFragment(generator, operation));
Object.values(context.fragments).forEach(function (operation) {
return interfaceDeclarationForFragment(generator, operation, fragmentsWithTypenameField);
});

@@ -80,6 +76,6 @@ generator.printOnNewline('/* tslint:enable */');

function enumerationDeclaration(generator, type) {
const name = type.name,
description = type.description;
var name = type.name,
description = type.description;
const values = type.getValues();
var values = type.getValues();

@@ -89,4 +85,6 @@ generator.printNewlineIfNeeded();

generator.printOnNewline(`export type ${name} =`);
const nValues = values.length;
values.forEach((value, i) => generator.printOnNewline(` "${value.value}"${i === nValues - 1 ? ';' : ' |'}${(0, _printing.wrap)(' // ', value.description)}`));
var nValues = values.length;
values.forEach(function (value, i) {
return generator.printOnNewline(` "${value.value}"${i === nValues - 1 ? ';' : ' |'}${(0, _printing.wrap)(' // ', value.description)}`);
});
generator.printNewline();

@@ -96,7 +94,7 @@ }

function structDeclarationForInputObjectType(generator, type) {
const interfaceName = (0, _changeCase.pascalCase)(type.name);
var interfaceName = (0, _changeCase.pascalCase)(type.name);
(0, _language.interfaceDeclaration)(generator, {
interfaceName: interfaceName
}, () => {
const properties = propertiesFromFields(generator.context, (0, _values2.default)(type.getFields()));
interfaceName
}, function () {
var properties = propertiesFromFields(generator.context, Object.values(type.getFields()));
propertyDeclarations(generator, properties, true);

@@ -107,3 +105,3 @@ });

function interfaceNameFromOperation(_ref) {
let operationName = _ref.operationName,
var operationName = _ref.operationName,
operationType = _ref.operationType;

@@ -127,3 +125,3 @@

function interfaceVariablesDeclarationForOperation(generator, _ref2) {
let operationName = _ref2.operationName,
var operationName = _ref2.operationName,
operationType = _ref2.operationType,

@@ -138,8 +136,8 @@ variables = _ref2.variables,

}
const interfaceName = `${interfaceNameFromOperation({ operationName: operationName, operationType: operationType })}Variables`;
var interfaceName = `${interfaceNameFromOperation({ operationName, operationType })}Variables`;
(0, _language.interfaceDeclaration)(generator, {
interfaceName: interfaceName
}, () => {
const properties = propertiesFromFields(generator.context, variables);
interfaceName
}, function () {
var properties = propertiesFromFields(generator.context, variables);
propertyDeclarations(generator, properties, true);

@@ -149,4 +147,4 @@ });

function interfaceDeclarationForOperation(generator, _ref3) {
let operationName = _ref3.operationName,
function interfaceDeclarationForOperation(generator, _ref3, fragmentsWithTypenameField) {
var operationName = _ref3.operationName,
operationType = _ref3.operationType,

@@ -159,40 +157,87 @@ variables = _ref3.variables,

const interfaceName = interfaceNameFromOperation({ operationName: operationName, operationType: operationType });
if (hasTypenameField(fields)) {
console.error('__typename on operations are not yet supported');
}
var interfaceName = interfaceNameFromOperation({ operationName, operationType });
var properties = propertiesFromFields(generator.context, fields, {
typeNameSuffix: `From${operationName}`
});
(0, _language.interfaceDeclaration)(generator, {
interfaceName: interfaceName,
extendTypes: fragmentSpreads ? fragmentSpreads.map(f => `${(0, _changeCase.pascalCase)(f)}Fragment`) : null
}, () => {
const properties = propertiesFromFields(generator.context, fields);
interfaceName,
extendTypes: fragmentSpreads ? fragmentSpreads.map(function (f) {
return `${(0, _changeCase.pascalCase)(f)}Fragment`;
}) : null
}, function () {
propertyDeclarations(generator, properties, true);
});
properties.forEach(function (_ref4) {
var fragmentSpreads = _ref4.fragmentSpreads,
inlineFragments = _ref4.inlineFragments,
bareTypeName = _ref4.bareTypeName;
if (fragmentSpreads.length > 0) {
fragmentSpreads.forEach(function (fragmentSpread) {
fragmentsWithTypenameField[fragmentSpread] = true;
});
}
if (inlineFragments.length > 0) {
var objectName = `${(0, _changeCase.pascalCase)(bareTypeName)}From${operationName}`;
handleInlineFragments(generator, objectName, inlineFragments);
}
});
}
function interfaceDeclarationForFragment(generator, _ref4) {
let fragmentName = _ref4.fragmentName,
typeCondition = _ref4.typeCondition,
fields = _ref4.fields,
inlineFragments = _ref4.inlineFragments,
fragmentSpreads = _ref4.fragmentSpreads,
source = _ref4.source;
function interfaceDeclarationForFragment(generator, _ref5, fragmentsWithTypenameField) {
var fragmentName = _ref5.fragmentName,
typeCondition = _ref5.typeCondition,
fields = _ref5.fields,
inlineFragments = _ref5.inlineFragments,
fragmentSpreads = _ref5.fragmentSpreads,
source = _ref5.source,
possibleTypes = _ref5.possibleTypes;
const interfaceName = `${(0, _changeCase.pascalCase)(fragmentName)}Fragment`;
var interfaceName = `${(0, _changeCase.pascalCase)(fragmentName)}Fragment`;
(0, _language.interfaceDeclaration)(generator, {
interfaceName: interfaceName,
extendTypes: fragmentSpreads ? fragmentSpreads.map(f => `${(0, _changeCase.pascalCase)(f)}Fragment`) : null
}, () => {
var _propertiesFromFields;
if (inlineFragments.length > 0) {
handleInlineFragments(generator, interfaceName, inlineFragments);
} else {
(0, _language.interfaceDeclaration)(generator, {
interfaceName,
extendTypes: fragmentSpreads ? fragmentSpreads.map(function (f) {
return `${(0, _changeCase.pascalCase)(f)}Fragment`;
}) : null
}, function () {
if (fragmentsWithTypenameField[fragmentName]) {
addTypenameFieldIfNeeded(generator, fields, typeCondition);
}
const properties = (_propertiesFromFields = propertiesFromFields(generator.context, fields)).concat.apply(_propertiesFromFields, (0, _toConsumableArray3.default)((inlineFragments || []).map(fragment => propertiesFromFields(generator.context, fragment.fields, true))));
var properties = propertiesFromFields(generator.context, fields, {
typeNameSuffix: 'Fragment'
});
propertyDeclarations(generator, properties, true);
});
propertyDeclarations(generator, properties, true);
});
}
}
function propertiesFromFields(context, fields, forceNullable) {
return fields.map(field => propertyFromField(context, field, forceNullable));
function propertiesFromFields(context, fields) {
var _ref6 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
forceNullable = _ref6.forceNullable,
typeNameSuffix = _ref6.typeNameSuffix;
return fields.map(function (field) {
return propertyFromField(context, field, { forceNullable, typeNameSuffix });
});
}
function propertyFromField(context, field, forceNullable) {
let fieldName = field.name,
function propertyFromField(context, field) {
var _ref7 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
forceNullable = _ref7.forceNullable,
typeNameSuffix = _ref7.typeNameSuffix;
var fieldName = field.name,
fieldType = field.type,

@@ -205,12 +250,26 @@ description = field.description,

const propertyName = fieldName;
var propertyName = fieldName;
let property = { fieldName: fieldName, fieldType: fieldType, propertyName: propertyName, description: description };
var property = { fieldName, fieldType, propertyName, description, inlineFragments };
const namedType = (0, _graphql.getNamedType)(fieldType);
var namedType = (0, _graphql.getNamedType)(fieldType);
if ((0, _graphql.isCompositeType)(namedType)) {
const bareTypeName = (0, _changeCase.pascalCase)(_inflected2.default.singularize(propertyName));
const typeName = (0, _types.typeNameFromGraphQLType)(context, fieldType, bareTypeName);
let isArray = false;
var typeName = void 0,
bareTypeName = void 0;
if (propertyName === '__typename') {
// Handle the __typename field specially. the fieldType is set
// to the parentType but we want the flow type to be a string literal
// of the parentType.
bareTypeName = `"${fieldType}"`;
typeName = `"${fieldType}"`;
} else {
bareTypeName = (0, _changeCase.pascalCase)(_inflected2.default.singularize(propertyName));
if (property.inlineFragments && property.inlineFragments.length > 0) {
typeName = (0, _types.typeNameFromGraphQLType)(context, fieldType, `${(0, _changeCase.pascalCase)(bareTypeName)}${typeNameSuffix}`);
} else {
typeName = (0, _types.typeNameFromGraphQLType)(context, fieldType, bareTypeName);
}
}
var isArray = false;
if (fieldType instanceof _graphql.GraphQLList) {

@@ -221,13 +280,13 @@ isArray = true;

}
let isNullable = true;
var isNullable = true;
if (fieldType instanceof _graphql.GraphQLNonNull && !forceNullable) {
isNullable = false;
}
return (0, _extends3.default)({}, property, {
typeName: typeName, bareTypeName: bareTypeName, fields: field.fields, isComposite: true, fragmentSpreads: fragmentSpreads, inlineFragments: inlineFragments, fieldType: fieldType,
isArray: isArray, isNullable: isNullable
return Object.assign({}, property, {
typeName, bareTypeName, fields: field.fields, isComposite: true, fragmentSpreads, inlineFragments, fieldType,
isArray, isNullable
});
} else {
const typeName = (0, _types.typeNameFromGraphQLType)(context, fieldType);
return (0, _extends3.default)({}, property, { typeName: typeName, isComposite: false, fieldType: fieldType });
var _typeName = (0, _types.typeNameFromGraphQLType)(context, fieldType);
return Object.assign({}, property, { typeName: _typeName, isComposite: false, fieldType });
}

@@ -238,15 +297,104 @@ }

if (!properties) return;
properties.forEach(property => {
properties.forEach(function (property) {
if (property.fields && property.fields.length > 0 || property.inlineFragments && property.inlineFragments.length > 0) {
(0, _language.propertyDeclaration)(generator, (0, _extends3.default)({}, property, { inInterface: inInterface }), () => {
var _propertiesFromFields2;
if (property.inlineFragments.length > 0) {
(0, _language.propertyDeclaration)(generator, Object.assign({}, property, {
inInterface
}));
} else {
(0, _language.propertyDeclaration)(generator, Object.assign({}, property, { inInterface }), function () {
var properties = propertiesFromFields(generator.context, property.fields);
propertyDeclarations(generator, properties);
});
}
} else {
(0, _language.propertyDeclaration)(generator, Object.assign({}, property, { inInterface }));
}
});
}
const properties = (_propertiesFromFields2 = propertiesFromFields(generator.context, property.fields)).concat.apply(_propertiesFromFields2, (0, _toConsumableArray3.default)((property.inlineFragments || []).map(fragment => propertiesFromFields(generator.context, fragment.fields, true))));
propertyDeclarations(generator, properties);
function makeTypenameField(typeName) {
return {
responseName: '__typename',
fieldName: '__typename',
type: typeName
};
}
function hasTypenameField(fields) {
if (!fields) {
return false;
}
return fields.find(function (field) {
return field.fieldName === '__typename' || field.responseName === '__typename';
});
}
function removeTypenameFieldIfExists(generator, fields) {
if (hasTypenameField(fields)) {
fields = fields.filter(function (field) {
return field.fieldName !== '__typename' || field.responseName !== '__typename';
});
return true;
} else {
return false;
}
}
/**
* NOTE: Mutates `fields`
*/
function addTypenameFieldIfNeeded(generator, fields, parentTypeName) {
var removed = removeTypenameFieldIfExists();
if (generator.context.addTypename || removed) {
fields.unshift(makeTypenameField(parentTypeName));
}
}
function handleInlineFragments(generator, fragmentName, inlineFragments) {
var typeNames = [];
inlineFragments.forEach(function (inlineFragment) {
var typeName = `${fragmentName}On${inlineFragment.typeCondition}`;
typeNames.push(typeName);
var hasTypenameField = inlineFragment.fields.find(function (field) {
return field.fieldName === '__typename' || field.responseName === '__typename';
});
var fields = inlineFragment.fields;
if (hasTypenameField) {
fields = fields.filter(function (field) {
return field.fieldName !== '__typename' || field.responseName !== '__typename';
});
} else {
(0, _language.propertyDeclaration)(generator, (0, _extends3.default)({}, property, { inInterface: inInterface }));
}
if (generator.context.addTypename || hasTypenameField) {
fields.unshift(makeTypenameField(inlineFragment.typeCondition));
}
var properties = propertiesFromFields(generator.context, fields, {
typeNameSuffix: 'Fragment'
});
(0, _language.interfaceDeclaration)(generator, {
interfaceName: typeName
}, function () {
propertyDeclarations(generator, properties, true);
});
properties.forEach(function (property) {
if (property.inlineFragments && property.inlineFragments.length > 0) {
var innerFragmentName = `${(0, _changeCase.pascalCase)(property.bareTypeName)}Fragment`;
handleInlineFragments(generator, innerFragmentName, property.inlineFragments);
}
});
});
// TODO: Refactor typeDeclaration to not automatically assume bracketed type
(0, _language.typeDeclaration)(generator, { interfaceName: fragmentName, noBrackets: true }, function () {
(0, _language.unionDeclaration)(generator, typeNames);
});
}
//# sourceMappingURL=codeGeneration.js.map

@@ -7,9 +7,13 @@ 'use strict';

exports.interfaceDeclaration = interfaceDeclaration;
exports.typeDeclaration = typeDeclaration;
exports.propertyDeclaration = propertyDeclaration;
exports.propertyDeclarations = propertyDeclarations;
exports.unionDeclaration = unionDeclaration;
var _printing = require('../utilities/printing');
var _changeCase = require('change-case');
function interfaceDeclaration(generator, _ref, closure) {
let interfaceName = _ref.interfaceName,
var interfaceName = _ref.interfaceName,
extendTypes = _ref.extendTypes;

@@ -28,11 +32,27 @@

function propertyDeclaration(generator, _ref2, closure) {
let propertyName = _ref2.propertyName,
typeName = _ref2.typeName,
description = _ref2.description,
isArray = _ref2.isArray,
isNullable = _ref2.isNullable,
inInterface = _ref2.inInterface,
fragmentSpreads = _ref2.fragmentSpreads;
function typeDeclaration(generator, _ref2, closure) {
var interfaceName = _ref2.interfaceName,
noBrackets = _ref2.noBrackets;
generator.printNewlineIfNeeded();
generator.printNewline();
generator.print(`export type ${interfaceName} =`);
generator.pushScope({ typeName: interfaceName });
if (!noBrackets) {
generator.withinBlock(closure);
} else {
generator.withinBlock(closure, '', '');
}
generator.popScope();
}
function propertyDeclaration(generator, _ref3, closure) {
var propertyName = _ref3.propertyName,
typeName = _ref3.typeName,
description = _ref3.description,
isArray = _ref3.isArray,
isNullable = _ref3.isNullable,
inInterface = _ref3.inInterface,
fragmentSpreads = _ref3.fragmentSpreads;
generator.printOnNewline(description && `// ${description}`);

@@ -45,3 +65,5 @@ if (closure) {

if (fragmentSpreads && fragmentSpreads.length > 0) {
generator.print(` ${fragmentSpreads.map(n => `${n}Fragment`).join(' & ')} &`);
generator.print(` ${fragmentSpreads.map(function (n) {
return `${(0, _changeCase.pascalCase)(n)}Fragment`;
}).join(' & ')} &`);
}

@@ -58,3 +80,5 @@ generator.pushScope({ typeName: propertyName });

} else if (fragmentSpreads && fragmentSpreads.length > 0) {
generator.printOnNewline(`${propertyName}: ${isArray ? 'Array<' : ''}${fragmentSpreads.map(n => `${n}Fragment`).join(' & ')}${isArray ? '>' : ''}`);
generator.printOnNewline(`${propertyName}: ${isArray ? 'Array<' : ''}${fragmentSpreads.map(function (n) {
return `${(0, _changeCase.pascalCase)(n)}Fragment`;
}).join(' & ')}${isArray ? '>' : ''}`);
} else {

@@ -68,4 +92,14 @@ generator.printOnNewline(`${propertyName}: ${typeName}`);

if (!properties) return;
properties.forEach(property => propertyDeclaration(generator, property));
properties.forEach(function (property) {
return propertyDeclaration(generator, property);
});
}
function unionDeclaration(generator, typeNames) {
if (!typeNames) throw new Error('Union Declaration requires types');
typeNames.forEach(function (typeName) {
generator.printOnNewline(`| ${typeName}`);
});
}
//# sourceMappingURL=language.js.map

@@ -14,3 +14,3 @@ 'use strict';

const builtInScalarMap = {
var builtInScalarMap = {
[_graphql.GraphQLString.name]: 'string',

@@ -24,3 +24,3 @@ [_graphql.GraphQLInt.name]: 'number',

function typeNameFromGraphQLType(context, type, bareTypeName) {
let nullable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
var nullable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;

@@ -31,7 +31,7 @@ if (type instanceof _graphql.GraphQLNonNull) {

let typeName;
var typeName = void 0;
if (type instanceof _graphql.GraphQLList) {
typeName = `Array< ${typeNameFromGraphQLType(context, type.ofType, bareTypeName, true)} >`;
} else if (type instanceof _graphql.GraphQLScalarType) {
typeName = builtInScalarMap[type.name] || (context.passthroughCustomScalars ? context.customScalarsPrefix + type.name : _graphql.GraphQLString);
typeName = builtInScalarMap[type.name] || (context.passthroughCustomScalars ? context.customScalarsPrefix + type.name : builtInScalarMap[_graphql.GraphQLString.name]);
} else {

@@ -38,0 +38,0 @@ typeName = bareTypeName || type.name;

@@ -7,6 +7,12 @@ 'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _printing = require('./printing');
class CodeGenerator {
constructor(context) {
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var CodeGenerator = function () {
function CodeGenerator(context) {
_classCallCheck(this, CodeGenerator);
this.context = context;

@@ -22,58 +28,75 @@

pushScope(scope) {
this.scopeStack.push(scope);
}
popScope() {
return this.scopeStack.pop();
}
print(maybeString) {
if (maybeString) {
this.output += maybeString;
_createClass(CodeGenerator, [{
key: 'pushScope',
value: function pushScope(scope) {
this.scopeStack.push(scope);
}
}
printNewline() {
if (this.output) {
this.print('\n');
this.startOfIndentLevel = false;
}, {
key: 'popScope',
value: function popScope() {
return this.scopeStack.pop();
}
}
}, {
key: 'print',
value: function print(maybeString) {
if (maybeString) {
this.output += maybeString;
}
}
}, {
key: 'printNewline',
value: function printNewline() {
if (this.output) {
this.print('\n');
this.startOfIndentLevel = false;
}
}
}, {
key: 'printNewlineIfNeeded',
value: function printNewlineIfNeeded() {
if (!this.startOfIndentLevel) {
this.printNewline();
}
}
}, {
key: 'printOnNewline',
value: function printOnNewline(maybeString) {
if (maybeString) {
this.printNewline();
this.printIndent();
this.print(maybeString);
}
}
}, {
key: 'printIndent',
value: function printIndent() {
var indentation = ' '.repeat(this.indentLevel * this.indentWidth);
this.output += indentation;
}
}, {
key: 'withIndent',
value: function withIndent(closure) {
if (!closure) return;
printNewlineIfNeeded() {
if (!this.startOfIndentLevel) {
this.printNewline();
this.indentLevel++;
this.startOfIndentLevel = true;
closure();
this.indentLevel--;
}
}
}, {
key: 'withinBlock',
value: function withinBlock(closure) {
var open = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ' {';
var close = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '}';
printOnNewline(maybeString) {
if (maybeString) {
this.printNewline();
this.printIndent();
this.print(maybeString);
this.print(open);
this.withIndent(closure);
this.printOnNewline(close);
}
}
}]);
printIndent() {
const indentation = ' '.repeat(this.indentLevel * this.indentWidth);
this.output += indentation;
}
return CodeGenerator;
}();
withIndent(closure) {
if (!closure) return;
this.indentLevel++;
this.startOfIndentLevel = true;
closure();
this.indentLevel--;
}
withinBlock(closure) {
this.print(' {');
this.withIndent(closure);
this.printOnNewline('}');
}
}
exports.default = CodeGenerator;
//# sourceMappingURL=CodeGenerator.js.map

@@ -6,15 +6,2 @@ 'use strict';

});
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _set = require('babel-runtime/core-js/set');
var _set2 = _interopRequireDefault(_set);
exports.isBuiltInScalarType = isBuiltInScalarType;

@@ -31,5 +18,5 @@ exports.withTypenameFieldAddedWhereNeeded = withTypenameFieldAddedWhereNeeded;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
const builtInScalarTypes = new _set2.default([_graphql.GraphQLString, _graphql.GraphQLInt, _graphql.GraphQLFloat, _graphql.GraphQLBoolean, _graphql.GraphQLID]);
var builtInScalarTypes = new Set([_graphql.GraphQLString, _graphql.GraphQLInt, _graphql.GraphQLFloat, _graphql.GraphQLBoolean, _graphql.GraphQLID]);

@@ -40,3 +27,3 @@ function isBuiltInScalarType(type) {

const typenameField = { kind: _graphql.Kind.FIELD, name: { kind: _graphql.Kind.NAME, value: '__typename' } };
var typenameField = { kind: _graphql.Kind.FIELD, name: { kind: _graphql.Kind.NAME, value: '__typename' } };

@@ -48,11 +35,11 @@ function withTypenameFieldAddedWhereNeeded(schema, ast) {

const typeInfo = new _graphql.TypeInfo(schema);
var typeInfo = new _graphql.TypeInfo(schema);
return (0, _graphql.visit)(ast, (0, _graphql.visitWithTypeInfo)(typeInfo, {
leave: {
SelectionSet: node => {
const parentType = typeInfo.getParentType();
SelectionSet: function SelectionSet(node) {
var parentType = typeInfo.getParentType();
if (!isOperationRootType(parentType)) {
return (0, _extends3.default)({}, node, { selections: [typenameField].concat((0, _toConsumableArray3.default)(node.selections)) });
return Object.assign({}, node, { selections: [typenameField].concat(_toConsumableArray(node.selections)) });
}

@@ -69,3 +56,3 @@ }

function filePathForNode(node) {
const name = node.loc.source && node.loc.source.name;
var name = node.loc.source && node.loc.source.name;
return name === "GraphQL" ? undefined : name;

@@ -75,3 +62,3 @@ }

function valueFromValueNode(valueNode) {
const kind = valueNode.kind;
var kind = valueNode.kind;

@@ -85,3 +72,3 @@ if (kind === 'IntValue' || kind === 'FloatValue') {

} else if (kind === 'ObjectValue') {
return valueNode.fields.reduce((object, field) => {
return valueNode.fields.reduce(function (object, field) {
object[field.name.value] = valueFromValueNode(field.value);

@@ -91,3 +78,3 @@ return object;

} else if (kind === 'Variable') {
return { kind: kind, variableName: valueNode.name.value };
return { kind, variableName: valueNode.name.value };
} else {

@@ -112,3 +99,3 @@ return valueNode.value;

case 'mutation':
const mutationType = schema.getMutationType();
var mutationType = schema.getMutationType();
if (!mutationType) {

@@ -119,3 +106,3 @@ throw new GraphQLError('Schema is not configured for mutations', [operation]);

case 'subscription':
const subscriptionType = schema.getSubscriptionType();
var subscriptionType = schema.getSubscriptionType();
if (!subscriptionType) {

@@ -136,3 +123,3 @@ throw new GraphQLError('Schema is not configured for subscriptions', [operation]);

function getFieldDef(schema, parentType, fieldAST) {
const name = fieldAST.name.value;
var name = fieldAST.name.value;
if (name === _graphql.SchemaMetaFieldDef.name && schema.getQueryType() === parentType) {

@@ -139,0 +126,0 @@ return _graphql.SchemaMetaFieldDef;

@@ -17,3 +17,5 @@ 'use strict';

function join(maybeArray, separator) {
return maybeArray ? maybeArray.filter(x => x).join(separator || '') : '';
return maybeArray ? maybeArray.filter(function (x) {
return x;
}).join(separator || '') : '';
}

@@ -20,0 +22,0 @@

@@ -15,10 +15,38 @@ 'use strict';

function validateQueryDocument(schema, document) {
const rules = [NoAnonymousQueries, NoExplicitTypename, NoTypenameAlias].concat(_graphql.specifiedRules);
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
const validationErrors = (0, _graphql.validate)(schema, document, rules);
function validateQueryDocument(schema, document, target) {
var specifiedRulesToBeRemoved = [_graphql.NoUnusedFragments];
var rules = [NoAnonymousQueries, NoTypenameAlias].concat(_toConsumableArray(target === 'swift' ? [NoExplicitTypename] : []), _toConsumableArray(_graphql.specifiedRules.filter(function (rule) {
return specifiedRulesToBeRemoved.includes(rule);
})));
var validationErrors = (0, _graphql.validate)(schema, document, rules);
if (validationErrors && validationErrors.length > 0) {
for (const error of validationErrors) {
(0, _errors.logError)(error);
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = validationErrors[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var error = _step.value;
(0, _errors.logError)(error);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
throw new _errors.ToolError("Validation of GraphQL query document failed");

@@ -30,5 +58,5 @@ }

return {
OperationDefinition: function OperationDefinition(node) {
OperationDefinition(node) {
if (!node.name) {
context.reportError(new _graphql.GraphQLError('Apollo iOS does not support anonymous operations', [node]));
context.reportError(new _graphql.GraphQLError('Apollo does not support anonymous operations', [node]));
}

@@ -42,6 +70,6 @@ return false;

return {
Field: function Field(node) {
const fieldName = node.name.value;
Field(node) {
var fieldName = node.name.value;
if (fieldName == "__typename") {
context.reportError(new _graphql.GraphQLError('Apollo iOS inserts __typename automatically when needed, please do not include it explicitly', [node]));
context.reportError(new _graphql.GraphQLError('Apollo inserts __typename automatically when needed, please do not include it explicitly', [node]));
}

@@ -54,6 +82,6 @@ }

return {
Field: function Field(node) {
const aliasName = node.alias && node.alias.value;
Field(node) {
var aliasName = node.alias && node.alias.value;
if (aliasName == "__typename") {
context.reportError(new _graphql.GraphQLError('Apollo iOS needs to be able to insert __typename when needed, please do not use it as an alias', [node]));
context.reportError(new _graphql.GraphQLError('Apollo needs to be able to insert __typename when needed, please do not use it as an alias', [node]));
}

@@ -60,0 +88,0 @@ }

{
"name": "apollo-codegen",
"version": "0.12.1",
"version": "0.12.3",
"description": "Generate API code or type annotations based on a GraphQL schema and query documents",

@@ -11,3 +11,3 @@ "main": "./lib/index.js",

"prepublish": "rm -rf lib && npm run compile",
"test": "mocha --recursive --compilers js:babel-register"
"test": "jest"
},

@@ -21,25 +21,41 @@ "repository": {

"engines": {
"node": ">=4.0"
"node": ">=6.0"
},
"devDependencies": {
"babel-cli": "^6.11.4",
"babel-plugin-transform-runtime": "^6.12.0",
"babel-preset-full-node4": "^1.0.0",
"babel-register": "^6.16.3",
"chai": "^3.5.0",
"chai-subset": "^1.3.0",
"ansi-regex": "^2.1.1",
"babel-cli": "^6.24.1",
"babel-jest": "^20.0.3",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-preset-env": "^1.4.0",
"babel-register": "^6.24.1",
"common-tags": "^1.3.0",
"mocha": "^3.1.2"
"jest": "^20.0.4",
"jest-matcher-utils": "^20.0.0",
"regenerator-runtime": "^0.10.5"
},
"dependencies": {
"babel-runtime": "^6.20.0",
"babel-polyfill": "^6.23.0",
"change-case": "^3.0.0",
"glob": "^7.0.5",
"source-map-support": "^0.4.2",
"change-case": "^3.0.0",
"graphql": "^0.9.1",
"graphql": "^0.9.5",
"inflected": "^1.1.7",
"mkdirp": "^0.5.1",
"node-fetch": "^1.5.3",
"yargs": "^6.4.0"
"source-map-support": "^0.4.2",
"yargs": "^8.0.1"
},
"jest": {
"testMatch": [
"**/test/**/*.js",
"**/test/*.js"
],
"testPathIgnorePatterns": [
"<rootDir>/node_modules/",
"<rootDir>/lib/",
"<rootDir>/test/starwars/"
],
"setupFiles": [
"<rootDir>/src/env-setup.js"
]
}
}
# Apollo GraphQL code generator
[![GitHub license](https://img.shields.io/badge/license-MIT-lightgrey.svg?maxAge=2592000)](https://raw.githubusercontent.com/apollostack/apollo-ios/master/LICENSE) [![npm](https://img.shields.io/npm/v/apollo-codegen.svg)](https://www.npmjs.com/package/apollo-codegen) [![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](http://www.apollostack.com/#slack)
[![GitHub license](https://img.shields.io/badge/license-MIT-lightgrey.svg?maxAge=2592000)](https://raw.githubusercontent.com/apollographql/apollo-ios/master/LICENSE) [![npm](https://img.shields.io/npm/v/apollo-codegen.svg)](https://www.npmjs.com/package/apollo-codegen) [![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](http://www.apollostack.com/#slack)

@@ -9,3 +9,3 @@ This is a tool to generate API code or type annotations based on a GraphQL schema and query documents.

See [Apollo iOS](https://github.com/apollostack/apollo-ios) for details on the mapping from GraphQL results to Swift types, as well as runtime support for executing queries and mutations.
See [Apollo iOS](https://github.com/apollographql/apollo-ios) for details on the mapping from GraphQL results to Swift types, as well as runtime support for executing queries and mutations.

@@ -20,6 +20,8 @@ ## Usage

### `introspect-schema`
To download a GraphQL schema by sending an introspection query to a server:
```sh
apollo-codegen download-schema http://localhost:8080/graphql --output schema.json
apollo-codegen introspect-schema http://localhost:8080/graphql --output schema.json
```

@@ -29,2 +31,14 @@

You can use the `insecure` option to ignore any SSL errors (for example if the server is running with self-signed certificate).
**Note:** The command for downloading an introspection query was named `download-schema` but it was renamed to `introspect-schema` in order to have a single command for introspecting local or remote schemas. The old name `download-schema` is still available is an alias for backward compatibility.
To generate a GraphQL schema introspection JSON from a local GraphQL schema:
```sh
apollo-codegen introspect-schema schema.graphql --output schema.json
```
### `generate`
This tool will generate Swift code by default from a set of query definitions in `.graphql` files:

@@ -45,5 +59,9 @@

#### `gql` template support
If the source file for generation is a javascript or typescript file, the codegen will try to extrapolate the queries inside the [gql tag](https://github.com/apollographql/graphql-tag) templates.
## Contributing
[![Build status](https://travis-ci.org/apollostack/apollo-codegen.svg?branch=master)](https://travis-ci.org/apollostack/apollo-codegen)
[![Build status](https://travis-ci.org/apollographql/apollo-codegen.svg?branch=master)](https://travis-ci.org/apollographql/apollo-codegen)

@@ -50,0 +68,0 @@ Running tests locally:

@@ -1,5 +0,1 @@

import chai, { expect } from 'chai'
import chaiSubset from 'chai-subset'
chai.use(chaiSubset);
import { stripIndent } from 'common-tags'

@@ -21,6 +17,10 @@

function withStringifiedTypes(ir) {
return JSON.parse(serializeAST(ir));
}
const schema = loadSchema(require.resolve('./starwars/schema.json'));
describe('Compiling query documents', () => {
it(`should include variables defined in operations`, () => {
test(`should include variables defined in operations`, () => {
const document = parse(`

@@ -49,5 +49,5 @@ query HeroName($episode: Episode) {

const { operations } = compileToIR(schema, document);
const { operations } = withStringifiedTypes(compileToIR(schema, document));
expect(filteredIR(operations['HeroName']).variables).to.deep.equal(
expect(operations['HeroName'].variables).toEqual(
[

@@ -58,3 +58,3 @@ { name: 'episode', type: 'Episode' }

expect(filteredIR(operations['Search']).variables).to.deep.equal(
expect(operations['Search'].variables).toEqual(
[

@@ -65,3 +65,3 @@ { name: 'text', type: 'String!' }

expect(filteredIR(operations['CreateReviewForEpisode']).variables).to.deep.equal(
expect(operations['CreateReviewForEpisode'].variables).toEqual(
[

@@ -74,3 +74,3 @@ { name: 'episode', type: 'Episode!' },

it(`should keep track of enums and input object types used in variables`, () => {
test(`should keep track of enums and input object types used in variables`, () => {
const document = parse(`

@@ -99,8 +99,8 @@ query HeroName($episode: Episode) {

const { typesUsed } = compileToIR(schema, document);
const { typesUsed } = withStringifiedTypes(compileToIR(schema, document));
expect(filteredIR(typesUsed)).to.deep.equal(['Episode', 'ReviewInput', 'ColorInput']);
expect(typesUsed).toEqual(['Episode', 'ReviewInput', 'ColorInput']);
});
it(`should keep track of enums used in fields`, () => {
test(`should keep track of enums used in fields`, () => {
const document = parse(`

@@ -119,8 +119,8 @@ query Hero {

const { typesUsed } = compileToIR(schema, document);
const { typesUsed } = withStringifiedTypes(compileToIR(schema, document));
expect(filteredIR(typesUsed)).to.deep.equal(['Episode']);
expect(typesUsed).toEqual(['Episode']);
});
it(`should keep track of types used in fields of input objects`, () => {
test(`should keep track of types used in fields of input objects`, () => {
const bookstore_schema = loadSchema(require.resolve('./bookstore/schema.json'));

@@ -153,8 +153,9 @@ const document = parse(`

const { typesUsed } = compileToIR(bookstore_schema, document);
expect(filteredIR(typesUsed)).to.deep.include('IdInput');
expect(filteredIR(typesUsed)).to.deep.include('WrittenByInput');
const { typesUsed } = withStringifiedTypes(compileToIR(bookstore_schema, document));
expect(typesUsed).toContain('IdInput');
expect(typesUsed).toContain('WrittenByInput');
});
it(`should include the original field name for an aliased field`, () => {
test(`should include the original field name for an aliased field`, () => {
const document = parse(`

@@ -173,6 +174,6 @@ query HeroName {

expect(operations['HeroName'].fields[0].fieldName).to.equal("hero");
expect(operations['HeroName'].fields[0].fieldName).toBe("hero");
});
it(`should include field arguments`, () => {
test(`should include field arguments`, () => {
const document = parse(`

@@ -189,6 +190,6 @@ query HeroName {

expect(operations['HeroName'].fields[0].args)
.to.deep.equal([{ name: "episode", value: "EMPIRE" }]);
.toEqual([{ name: "episode", value: "EMPIRE" }]);
});
it(`should include isOptional if a field has skip or include directives`, () => {
test(`should include isOptional if a field has skip or include directives`, () => {
const document = parse(`

@@ -210,52 +211,14 @@ query HeroNameConditionalInclusion {

expect(filteredIR(operations['HeroNameConditionalInclusion'])).to.deep.equal({
operationName: 'HeroNameConditionalInclusion',
operationType: 'query',
variables: [],
fragmentsReferenced: [],
fields: [
{
responseName: 'hero',
fieldName: 'hero',
type: 'Character',
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!',
isConditional: true
},
],
fragmentSpreads: [],
inlineFragments: []
}
]
expect(operations['HeroNameConditionalInclusion'].fields[0].fields[0]).toMatchObject({
fieldName: 'name',
isConditional: true
});
expect(filteredIR(operations['HeroNameConditionalExclusion'])).to.deep.equal({
operationName: 'HeroNameConditionalExclusion',
operationType: 'query',
variables: [],
fragmentsReferenced: [],
fields: [
{
responseName: 'hero',
fieldName: 'hero',
type: 'Character',
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!',
isConditional: true
},
],
fragmentSpreads: [],
inlineFragments: []
}
]
expect(operations['HeroNameConditionalExclusion'].fields[0].fields[0]).toMatchObject({
fieldName: 'name',
isConditional: true
});
});
it(`should recursively flatten inline fragments with type conditions that match the parent type`, () => {
test(`should recursively flatten inline fragments with type conditions that match the parent type`, () => {
const document = parse(`

@@ -279,37 +242,7 @@ query Hero {

expect(filteredIR(operations['Hero'])).to.deep.equal({
operationName: 'Hero',
operationType: 'query',
variables: [],
fragmentsReferenced: [],
fields: [
{
responseName: 'hero',
fieldName: 'hero',
type: 'Character',
fields: [
{
responseName: 'id',
fieldName: 'id',
type: 'ID!'
},
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
},
{
responseName: 'appearsIn',
fieldName: 'appearsIn',
type: '[Episode]!'
}
],
fragmentSpreads: [],
inlineFragments: []
}
]
});
expect(operations['Hero'].fields[0].fields.map(field => field.fieldName))
.toEqual(['id', 'name', 'appearsIn']);
});
it(`should recursively include fragment spreads with type conditions that match the parent type`, () => {
test(`should recursively include fragment spreads with type conditions that match the parent type`, () => {
const document = parse(`

@@ -324,5 +257,5 @@ query Hero {

fragment HeroDetails on Character {
name
...MoreHeroDetails
id
...MoreHeroDetails
name
}

@@ -332,3 +265,2 @@

appearsIn
id
}

@@ -339,66 +271,17 @@ `);

expect(filteredIR(operations['Hero'])).to.deep.equal({
operationName: 'Hero',
operationType: 'query',
variables: [],
fragmentsReferenced: ['HeroDetails', 'MoreHeroDetails'],
fields: [
{
responseName: 'hero',
fieldName: 'hero',
type: 'Character',
fields: [
{
responseName: 'id',
fieldName: 'id',
type: 'ID!'
}
],
fragmentSpreads: ['HeroDetails', 'MoreHeroDetails'],
inlineFragments: [],
}
],
});
expect(operations['Hero'].fields[0].fields.map(field => field.fieldName))
.toEqual(['id', 'name', 'appearsIn']);
expect(filteredIR(fragments['HeroDetails'])).to.deep.equal({
fragmentName: 'HeroDetails',
typeCondition: 'Character',
fragmentsReferenced: ['MoreHeroDetails'],
fields: [
{
responseName: 'id',
fieldName: 'id',
type: 'ID!'
},
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
}
],
fragmentSpreads: ['MoreHeroDetails'],
inlineFragments: []
});
expect(fragments['HeroDetails'].fields.map(field => field.fieldName))
.toEqual(['name', 'appearsIn', 'id']);
expect(filteredIR(fragments['MoreHeroDetails'])).to.deep.equal({
fragmentName: 'MoreHeroDetails',
typeCondition: 'Character',
fragmentsReferenced: [],
fields: [
{ responseName: 'appearsIn',
fieldName: 'appearsIn',
type: '[Episode]!'
},
{
responseName: 'id',
fieldName: 'id',
type: 'ID!'
}
],
fragmentSpreads: [],
inlineFragments: []
});
expect(fragments['MoreHeroDetails'].fields.map(field => field.fieldName))
.toEqual(['appearsIn']);
expect(operations['Hero'].fragmentsReferenced).toEqual(['HeroDetails', 'MoreHeroDetails']);
expect(operations['Hero'].fields[0].fragmentSpreads).toEqual(['HeroDetails', 'MoreHeroDetails']);
expect(fragments['HeroDetails'].fragmentSpreads).toEqual(['MoreHeroDetails']);
});
it(`should include fragment spreads from subselections`, () => {
test(`should include fragment spreads from subselections`, () => {
const document = parse(`

@@ -425,65 +308,15 @@ query HeroAndFriends {

expect(filteredIR(operations['HeroAndFriends'])).to.deep.equal({
operationName: 'HeroAndFriends',
operationType: 'query',
variables: [],
fragmentsReferenced: ['HeroDetails'],
fields: [
{
responseName: 'hero',
fieldName: 'hero',
type: 'Character',
fields: [
{ responseName: 'appearsIn',
fieldName: 'appearsIn',
type: '[Episode]!'
},
{
responseName: 'id',
fieldName: 'id',
type: 'ID!'
},
{
responseName: 'friends',
fieldName: 'friends',
type: '[Character]',
fields: [
{
responseName: 'id',
fieldName: 'id',
type: 'ID!'
}
],
fragmentSpreads: ['HeroDetails'],
inlineFragments: []
}
],
fragmentSpreads: ['HeroDetails'],
inlineFragments: []
}
]
});
expect(operations['HeroAndFriends'].fields[0].fields.map(field => field.fieldName))
.toEqual(['name', 'id', 'appearsIn', 'friends']);
expect(operations['HeroAndFriends'].fields[0].fields[3].fields.map(field => field.fieldName))
.toEqual(['id', 'name']);
expect(filteredIR(fragments['HeroDetails'])).to.deep.equal({
fragmentName: 'HeroDetails',
typeCondition: 'Character',
fragmentsReferenced: [],
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
},
{
responseName: 'id',
fieldName: 'id',
type: 'ID!'
}
],
fragmentSpreads: [],
inlineFragments: []
});
expect(fragments['HeroDetails'].fields.map(field => field.fieldName))
.toEqual(['name', 'id']);
expect(operations['HeroAndFriends'].fragmentsReferenced).toEqual(['HeroDetails']);
expect(operations['HeroAndFriends'].fields[0].fragmentSpreads).toEqual(['HeroDetails']);
});
it(`should include type conditions with merged fields for inline fragments`, () => {
test(`should include type conditions with merged fields for inline fragments`, () => {
const document = parse(`

@@ -505,60 +338,15 @@ query Hero {

expect(filteredIR(operations['Hero'])).to.deep.equal({
operationName: 'Hero',
operationType: 'query',
variables: [],
fragmentsReferenced: [],
fields: [
{
responseName: 'hero',
fieldName: 'hero',
type: 'Character',
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
}
],
fragmentSpreads: [],
inlineFragments: [
{
typeCondition: 'Droid',
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
},
{
responseName: 'primaryFunction',
fieldName: 'primaryFunction',
type: 'String'
},
],
fragmentSpreads: []
},
{
typeCondition: 'Human',
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
},
{
responseName: 'height',
fieldName: 'height',
type: 'Float'
},
],
fragmentSpreads: []
}
]
}
]
});
expect(operations['Hero'].fields[0].fields.map(field => field.fieldName))
.toEqual(['name']);
expect(operations['Hero'].fields[0].inlineFragments[0].typeCondition.toString()).toEqual('Droid');
expect(operations['Hero'].fields[0].inlineFragments[0].fields.map(field => field.fieldName))
.toEqual(['name', 'primaryFunction']);
expect(operations['Hero'].fields[0].inlineFragments[1].typeCondition.toString()).toEqual('Human');
expect(operations['Hero'].fields[0].inlineFragments[1].fields.map(field => field.fieldName))
.toEqual(['name', 'height']);
});
it(`should include fragment spreads with type conditions`, () => {
test(`should include fragment spreads with type conditions`, () => {
const document = parse(`

@@ -584,57 +372,18 @@ query Hero {

expect(filteredIR(operations['Hero'])).to.deep.equal({
operationName: 'Hero',
operationType: 'query',
variables: [],
fragmentsReferenced: ['DroidDetails', 'HumanDetails'],
fields: [
{
responseName: 'hero',
fieldName: 'hero',
type: 'Character',
fragmentSpreads: ['DroidDetails', 'HumanDetails'],
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
}
],
inlineFragments: []
}
]
});
expect(operations['Hero'].fields[0].fields.map(field => field.fieldName))
.toEqual(['name']);
expect(filteredIR(fragments['DroidDetails'])).to.deep.equal({
fragmentName: 'DroidDetails',
typeCondition: 'Droid',
fragmentsReferenced: [],
fields: [
{
responseName: 'primaryFunction',
fieldName: 'primaryFunction',
type: 'String'
}
],
fragmentSpreads: [],
inlineFragments: []
});
expect(operations['Hero'].fields[0].inlineFragments[0].typeCondition.toString()).toEqual('Droid');
expect(operations['Hero'].fields[0].inlineFragments[0].fields.map(field => field.fieldName))
.toEqual(['name', 'primaryFunction']);
expect(filteredIR(fragments['HumanDetails'])).to.deep.equal({
fragmentName: 'HumanDetails',
typeCondition: 'Human',
fragmentsReferenced: [],
fields: [
{
responseName: 'height',
fieldName: 'height',
type: 'Float'
}
],
fragmentSpreads: [],
inlineFragments: []
});
expect(operations['Hero'].fields[0].inlineFragments[1].typeCondition.toString()).toEqual('Human');
expect(operations['Hero'].fields[0].inlineFragments[1].fields.map(field => field.fieldName))
.toEqual(['name', 'height']);
expect(operations['Hero'].fragmentsReferenced).toEqual(['DroidDetails', 'HumanDetails']);
expect(operations['Hero'].fields[0].fragmentSpreads).toEqual(['DroidDetails', 'HumanDetails']);
});
it(`should not include type conditions for fragment spreads with type conditions that match the parent type`, () => {
test(`should not include type conditions for fragment spreads with type conditions that match the parent type`, () => {
const document = parse(`

@@ -655,27 +404,6 @@ query Hero {

expect(filteredIR(operations['Hero'])).to.deep.equal({
operationName: 'Hero',
operationType: 'query',
variables: [],
fragmentsReferenced: ['HeroDetails'],
fields: [
{
responseName: 'hero',
fieldName: 'hero',
type: 'Character',
fragmentSpreads: ['HeroDetails'],
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
}
],
inlineFragments: []
}
],
});
expect(operations['Hero'].fields[0].inlineFragments).toEqual([]);
});
it(`should include type conditions for inline fragments in fragments`, () => {
test(`should include type conditions for inline fragments in fragments`, () => {
const document = parse(`

@@ -701,69 +429,18 @@ query Hero {

expect(filteredIR(operations['Hero'])).to.deep.equal({
operationName: 'Hero',
operationType: 'query',
variables: [],
fragmentsReferenced: ['HeroDetails'],
fields: [
{
responseName: 'hero',
fieldName: 'hero',
type: 'Character',
fields: [],
fragmentSpreads: ['HeroDetails'],
inlineFragments: []
}
]
});
expect(operations['Hero'].fields[0].fields.map(field => field.fieldName))
.toEqual(['name']);
expect(filteredIR(fragments['HeroDetails'])).to.deep.equal({
fragmentName: 'HeroDetails',
typeCondition: 'Character',
fragmentsReferenced: [],
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
}
],
fragmentSpreads: [],
inlineFragments: [
{
typeCondition: 'Droid',
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
},
{
responseName: 'primaryFunction',
fieldName: 'primaryFunction',
type: 'String'
},
],
fragmentSpreads: []
},
{
typeCondition: 'Human',
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
},
{
responseName: 'height',
fieldName: 'height',
type: 'Float'
},
],
fragmentSpreads: []
}
]
});
expect(operations['Hero'].fields[0].inlineFragments[0].typeCondition.toString()).toEqual('Droid');
expect(operations['Hero'].fields[0].inlineFragments[0].fields.map(field => field.fieldName))
.toEqual(['name', 'primaryFunction']);
expect(operations['Hero'].fields[0].inlineFragments[1].typeCondition.toString()).toEqual('Human');
expect(operations['Hero'].fields[0].inlineFragments[1].fields.map(field => field.fieldName))
.toEqual(['name', 'height']);
expect(operations['Hero'].fragmentsReferenced).toEqual(['HeroDetails']);
expect(operations['Hero'].fields[0].fragmentSpreads).toEqual(['HeroDetails']);
});
it(`should inherit type condition when nesting an inline fragment in an inline fragment with a more specific type condition`, () => {
test(`should inherit type condition when nesting an inline fragment in an inline fragment with a more specific type condition`, () => {
const document = parse(`

@@ -783,33 +460,10 @@ query HeroName {

expect(filteredIR(operations['HeroName'])).to.deep.equal({
operationName: 'HeroName',
operationType: 'query',
variables: [],
fragmentsReferenced: [],
fields: [
{
responseName: 'hero',
fieldName: 'hero',
type: 'Character',
fields: [],
fragmentSpreads: [],
inlineFragments: [
{
typeCondition: 'Droid',
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
}
],
fragmentSpreads: []
}
]
}
]
});
expect(operations['HeroName'].fields[0].fields.map(field => field.fieldName))
.toEqual([]);
expect(operations['HeroName'].fields[0].inlineFragments[0].typeCondition.toString()).toEqual('Droid');
expect(operations['HeroName'].fields[0].inlineFragments[0].fields.map(field => field.fieldName))
.toEqual(['name']);
});
it(`should not inherit type condition when nesting an inline fragment in an inline fragment with a less specific type condition`, () => {
test(`should not inherit type condition when nesting an inline fragment in an inline fragment with a less specific type condition`, () => {
const document = parse(`

@@ -829,33 +483,10 @@ query HeroName {

expect(filteredIR(operations['HeroName'])).to.deep.equal({
operationName: 'HeroName',
operationType: 'query',
variables: [],
fragmentsReferenced: [],
fields: [
{
responseName: 'hero',
fieldName: 'hero',
type: 'Character',
fields: [],
fragmentSpreads: [],
inlineFragments: [
{
typeCondition: 'Droid',
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
}
],
fragmentSpreads: [],
}
]
}
]
});
expect(operations['HeroName'].fields[0].fields.map(field => field.fieldName))
.toEqual([]);
expect(operations['HeroName'].fields[0].inlineFragments[0].typeCondition.toString()).toEqual('Droid');
expect(operations['HeroName'].fields[0].inlineFragments[0].fields.map(field => field.fieldName))
.toEqual(['name']);
});
it(`should inherit type condition when nesting a fragment spread in an inline fragment with a more specific type condition`, () => {
test(`should inherit type condition when nesting a fragment spread in an inline fragment with a more specific type condition`, () => {
const document = parse(`

@@ -865,3 +496,3 @@ query HeroName {

... on Droid {
...HeroName
...CharacterName
}

@@ -871,3 +502,3 @@ }

fragment HeroName on Character {
fragment CharacterName on Character {
name

@@ -879,27 +510,14 @@ }

expect(filteredIR(operations['HeroName'])).to.deep.equal({
operationName: 'HeroName',
operationType: 'query',
variables: [],
fragmentsReferenced: ['HeroName'],
fields: [
{
responseName: 'hero',
fieldName: 'hero',
type: 'Character',
fields: [],
fragmentSpreads: [],
inlineFragments: [
{
typeCondition: 'Droid',
fragmentSpreads: ['HeroName'],
fields: [],
}
]
}
]
});
expect(operations['HeroName'].fields[0].fields.map(field => field.fieldName))
.toEqual([]);
expect(operations['HeroName'].fields[0].inlineFragments[0].typeCondition.toString()).toEqual('Droid');
expect(operations['HeroName'].fields[0].inlineFragments[0].fields.map(field => field.fieldName))
.toEqual(['name']);
expect(operations['HeroName'].fields[0].inlineFragments[0].fragmentSpreads).toEqual(['CharacterName']);
expect(operations['HeroName'].fragmentsReferenced).toEqual(['CharacterName']);
expect(operations['HeroName'].fields[0].fragmentSpreads).toEqual([]);
});
it(`should not inherit type condition when nesting a fragment spread in an inline fragment with a less specific type condition`, () => {
test(`should not inherit type condition when nesting a fragment spread in an inline fragment with a less specific type condition`, () => {
const document = parse(`

@@ -921,22 +539,86 @@ query HeroName {

expect(filteredIR(operations['HeroName'])).to.deep.equal({
operationName: 'HeroName',
operationType: 'query',
variables: [],
fragmentsReferenced: ['DroidName'],
fields: [
{
responseName: 'hero',
fieldName: 'hero',
type: 'Character',
fields: [],
fragmentSpreads: ['DroidName'],
inlineFragments: []
expect(operations['HeroName'].fields[0].fields.map(field => field.fieldName))
.toEqual([]);
expect(operations['HeroName'].fields[0].inlineFragments[0].typeCondition.toString()).toEqual('Droid');
expect(operations['HeroName'].fields[0].inlineFragments[0].fields.map(field => field.fieldName))
.toEqual(['name']);
expect(operations['HeroName'].fields[0].inlineFragments[0].fragmentSpreads).toEqual(['DroidName']);
expect(operations['HeroName'].fragmentsReferenced).toEqual(['DroidName']);
// FIXME
// expect(operations['HeroName'].fields[0].fragmentSpreads).toEqual([]);
});
test(`should ignore inline fragment when the type condition does not overlap with the currently effective type`, () => {
const document = parse(`
fragment CharacterDetails on Character {
... on Droid {
primaryFunction
}
]
});
... on Human {
height
}
}
query HumanAndDroid {
human(id: "human") {
...CharacterDetails
}
droid(id: "droid") {
...CharacterDetails
}
}
`);
const { operations } = compileToIR(schema, document);
expect(operations['HumanAndDroid'].fields.map(field => field.fieldName))
.toEqual(['human', 'droid']);
expect(operations['HumanAndDroid'].fields[0].fields.map(field => field.fieldName))
.toEqual(['height']);
expect(operations['HumanAndDroid'].fields[0].inlineFragments).toEqual([]);
expect(operations['HumanAndDroid'].fields[1].fields.map(field => field.fieldName))
.toEqual(['primaryFunction']);
expect(operations['HumanAndDroid'].fields[1].inlineFragments).toEqual([]);
});
it(`should include type conditions for inline fragments on a union type`, () => {
test(`should ignore fragment spread when the type condition does not overlap with the currently effective type`, () => {
const document = parse(`
fragment DroidPrimaryFunction on Droid {
primaryFunction
}
fragment HumanHeight on Human {
height
}
fragment CharacterDetails on Character {
...DroidPrimaryFunction
...HumanHeight
}
query HumanAndDroid {
human(id: "human") {
...CharacterDetails
}
droid(id: "droid") {
...CharacterDetails
}
}
`);
const { operations } = compileToIR(schema, document);
expect(operations['HumanAndDroid'].fields.map(field => field.fieldName))
.toEqual(['human', 'droid']);
expect(operations['HumanAndDroid'].fields[0].fields.map(field => field.fieldName))
.toEqual(['height']);
expect(operations['HumanAndDroid'].fields[0].inlineFragments).toEqual([]);
expect(operations['HumanAndDroid'].fields[1].fields.map(field => field.fieldName))
.toEqual(['primaryFunction']);
expect(operations['HumanAndDroid'].fields[1].inlineFragments).toEqual([]);
});
test(`should include type conditions for inline fragments on a union type`, () => {
const document = parse(`
query Search {

@@ -959,39 +641,36 @@ search(text: "an") {

expect(filteredIR(operations['Search']).fields[0].inlineFragments).to.deep.equal([
{
typeCondition: 'Droid',
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
},
{
responseName: 'primaryFunction',
fieldName: 'primaryFunction',
type: 'String'
},
],
fragmentSpreads: [],
},
{
typeCondition: 'Human',
fields: [
{
responseName: 'name',
fieldName: 'name',
type: 'String!'
},
{
responseName: 'height',
fieldName: 'height',
type: 'Float'
},
],
fragmentSpreads: [],
expect(operations['Search'].fields[0].fields.map(field => field.fieldName))
.toEqual([]);
expect(operations['Search'].fields[0].inlineFragments[0].typeCondition.toString()).toEqual('Droid');
expect(operations['Search'].fields[0].inlineFragments[0].fields.map(field => field.fieldName))
.toEqual(['name', 'primaryFunction']);
expect(operations['Search'].fields[0].inlineFragments[1].typeCondition.toString()).toEqual('Human');
expect(operations['Search'].fields[0].inlineFragments[1].fields.map(field => field.fieldName))
.toEqual(['name', 'height']);
});
xtest(`should keep correct field ordering even if field has been visited before for other type condition`, () => {
const document = parse(`
fragment HeroDetails on Character {
... on Human {
appearsIn
}
... on Droid {
name
appearsIn
}
}
]);
`);
const { fragments } = compileToIR(schema, document);
expect(fragments['HeroDetails'].inlineFragments[1].typeCondition.toString()).toEqual('Droid');
expect(fragments['HeroDetails'].inlineFragments[1].fields.map(field => field.fieldName))
.toEqual(['name', 'appearsIn']);
});
it(`should keep track of fragments referenced in a subselection`, () => {
test(`should keep track of fragments referenced in a subselection`, () => {
const document = parse(`

@@ -1014,6 +693,6 @@ query HeroAndFriends {

expect(operations['HeroAndFriends'].fragmentsReferenced).to.deep.equal(['HeroDetails']);
expect(operations['HeroAndFriends'].fragmentsReferenced).toEqual(['HeroDetails']);
});
it(`should keep track of fragments referenced in a fragment within a subselection`, () => {
test(`should keep track of fragments referenced in a fragment within a subselection`, () => {
const document = parse(`

@@ -1039,6 +718,6 @@ query HeroAndFriends {

expect(operations['HeroAndFriends'].fragmentsReferenced).to.deep.equal(['HeroDetails', 'HeroName']);
expect(operations['HeroAndFriends'].fragmentsReferenced).toEqual(['HeroName', 'HeroDetails']);
});
it(`should keep track of fragments referenced in a subselection nested in an inline fragment`, () => {
test(`should keep track of fragments referenced in a subselection nested in an inline fragment`, () => {
const document = parse(`

@@ -1063,6 +742,6 @@ query HeroAndFriends {

expect(operations['HeroAndFriends'].fragmentsReferenced).to.deep.equal(['HeroDetails']);
expect(operations['HeroAndFriends'].fragmentsReferenced).toEqual(['HeroDetails']);
});
it(`should include the source of operations with __typename added for abstract types`, () => {
test(`should include the source of operations`, () => {
const source = stripIndent`

@@ -1079,5 +758,33 @@ query HeroName {

expect(operations['HeroName'].source).to.equal(stripIndent`
expect(operations['HeroName'].source).toBe(source);
});
test(`should include the source of fragments`, () => {
const source = stripIndent`
fragment HeroDetails on Character {
name
}
`
const document = parse(source);
const { fragments } = compileToIR(schema, document);
expect(fragments['HeroDetails'].source).toBe(source);
});
test(`should include the source of operations with __typename added when addTypename is true`, () => {
const source = stripIndent`
query HeroName {
hero {
name
}
}
`
const document = parse(source);
const { operations } = compileToIR(schema, document, { addTypename: true });
expect(operations['HeroName'].source).toBe(stripIndent`
query HeroName {
hero {
__typename

@@ -1090,3 +797,3 @@ name

it(`should include the source of fragments with __typename added for abstract types`, () => {
test(`should include the source of fragments with __typename added when addTypename is true`, () => {
const source = stripIndent`

@@ -1099,5 +806,5 @@ fragment HeroDetails on Character {

const { fragments } = compileToIR(schema, document);
const { fragments } = compileToIR(schema, document, { addTypename: true });
expect(fragments['HeroDetails'].source).to.equal(stripIndent`
expect(fragments['HeroDetails'].source).toBe(stripIndent`
fragment HeroDetails on Character {

@@ -1110,3 +817,3 @@ __typename

it(`should include the operationType for a query`, () => {
test(`should include the operationType for a query`, () => {
const source = stripIndent`

@@ -1123,6 +830,6 @@ query HeroName {

expect(operations['HeroName'].operationType).to.equal('query');
expect(operations['HeroName'].operationType).toBe('query');
});
it(`should include the operationType for a mutation`, () => {
test(`should include the operationType for a mutation`, () => {
const source = stripIndent`

@@ -1140,13 +847,4 @@ mutation CreateReview {

expect(operations['CreateReview'].operationType).to.equal('mutation');
expect(operations['CreateReview'].operationType).toBe('mutation');
});
});
function filteredIR(ir) {
return JSON.parse(serializeAST(ir), function(key, value) {
if (key === 'source') {
return undefined;
}
return value;
});
}

@@ -1,5 +0,1 @@

import { expect } from 'chai';
import { stripIndent } from 'common-tags';
import {

@@ -20,3 +16,4 @@ parse,

import { loadSchema } from '../../src/loading';
const schema = loadSchema(require.resolve('../starwars/schema.json'));
const swapiSchema = loadSchema(require.resolve('../starwars/schema.json'));
const miscSchema = loadSchema(require.resolve('../misc/schema.json'));

@@ -27,28 +24,137 @@ import CodeGenerator from '../../src/utilities/CodeGenerator';

function setup(schema) {
const context = {
schema: schema,
operations: {},
fragments: {},
typesUsed: {}
}
const generator = new CodeGenerator(context);
const compileFromSource = (source, addTypename = false) => {
const document = parse(source);
const context = compileToIR(schema, document, { mergeInFieldsFromFragmentSpreads: false } );
context.addTypename = addTypename;
generator.context = context;
return context;
};
const addFragment = (fragment) => {
generator.context.fragments[fragment.fragmentName] = fragment;
};
return { generator, compileFromSource, addFragment };
}
describe('Flow code generation', function() {
beforeEach(function() {
const context = {
schema: schema,
operations: {},
fragments: {},
typesUsed: {}
}
describe('#generateSource()', function() {
describe('__typename', function() {
test('in an object', function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
query HeroName {
hero {
__typename
name
}
}
`);
this.generator = new CodeGenerator(context);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
this.compileFromSource = (source) => {
const document = parse(source);
const context = compileToIR(schema, document);
this.generator.context = context;
return context;
};
// TODO: Enable after fixing operation
test.skip('in an operation', function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
query Hero {
...Hero
}
this.addFragment = (fragment) => {
this.generator.context.fragments[fragment.fragmentName] = fragment;
};
});
fragment Hero on Query {
hero {
__typename
name
}
}
`);
describe('#generateSource()', function() {
it(`should generate simple query operations`, function() {
const context = this.compileFromSource(`
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('single fragment spread', () => {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
query HeroName {
hero {
...humanFriends
}
}
fragment humanFriends on Character {
friends {
__typename
name
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('in fragment spreads, allows for disjoint union via __typename string literals', function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
query HeroName {
hero {
__typename
...humanHero
...droidHero
}
}
fragment droidHero on Droid {
primaryFunction
}
fragment humanHero on Human {
homePlanet
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('in inline fragments, allows for disjoint union via __typename string literals', function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
query HeroName {
hero {
__typename
... on Droid {
friends {
name
}
}
... on Human {
homePlanet
}
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
});
test(`should generate simple query operations`, function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
query HeroName {

@@ -62,17 +168,8 @@ hero {

const source = generateSource(context);
expect(source).to.include(stripIndent`
/* @flow */
// This file was automatically generated and should not be edited.
export type HeroNameQuery = {
hero: ? {
name: string,
},
};
`);
expect(source).toMatchSnapshot();
});
it(`should generate simple query operations including input variables`, function() {
const context = this.compileFromSource(`
test(`should generate simple query operations including input variables`, function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
query HeroName($episode: Episode) {

@@ -86,28 +183,8 @@ hero(episode: $episode) {

const source = generateSource(context);
expect(source).to.include(stripIndent`
/* @flow */
// This file was automatically generated and should not be edited.
// The episodes in the Star Wars trilogy
export type Episode =
"NEWHOPE" | // Star Wars Episode IV: A New Hope, released in 1977.
"EMPIRE" | // Star Wars Episode V: The Empire Strikes Back, released in 1980.
"JEDI"; // Star Wars Episode VI: Return of the Jedi, released in 1983.
export type HeroNameQueryVariables = {
episode: ?Episode,
};
export type HeroNameQuery = {
hero: ? {
name: string,
},
};
`);
expect(source).toMatchSnapshot();
});
it(`should generate simple nested query operations including input variables`, function() {
const context = this.compileFromSource(`
test(`should generate simple nested query operations including input variables`, function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
query HeroAndFriendsNames($episode: Episode) {

@@ -124,39 +201,16 @@ hero(episode: $episode) {

const source = generateSource(context);
expect(source).to.include(stripIndent`
/* @flow */
// This file was automatically generated and should not be edited.
// The episodes in the Star Wars trilogy
export type Episode =
"NEWHOPE" | // Star Wars Episode IV: A New Hope, released in 1977.
"EMPIRE" | // Star Wars Episode V: The Empire Strikes Back, released in 1980.
"JEDI"; // Star Wars Episode VI: Return of the Jedi, released in 1983.
export type HeroAndFriendsNamesQueryVariables = {
episode: ?Episode,
};
export type HeroAndFriendsNamesQuery = {
hero: ? {
name: string,
friends: ?Array< {
name: string,
} >,
},
};
`);
expect(source).toMatchSnapshot();
});
it(`should generate fragmented query operations`, function() {
const context = this.compileFromSource(`
test(`should generate fragmented query operations`, function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
query HeroAndFriendsNames {
hero {
name
...HeroFriends
...heroFriends
}
}
fragment HeroFriends on Character {
fragment heroFriends on Character {
friends {

@@ -169,23 +223,34 @@ name

const source = generateSource(context);
expect(source).toMatchSnapshot();
});
expect(source).to.include(stripIndent`
/* @flow */
// This file was automatically generated and should not be edited.
test(`should handle multi-fragmented query operations`, function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
query HeroAndFriendsNames {
hero {
name
...heroFriends
...heroAppears
}
}
export type HeroAndFriendsNamesQuery = {
hero: ?(HeroFriendsFragment & {
name: string,
}),
};
fragment heroFriends on Character {
friends {
name
}
}
export type HeroFriendsFragment = {
friends: ?Array< {
name: string,
} >,
};
fragment heroAppears on Character {
appearsIn
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
it(`should generate query operations with inline fragments`, function() {
const context = this.compileFromSource(`
test(`should generate query operations with inline fragments`, function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
query HeroAndDetails {

@@ -209,22 +274,8 @@ hero {

const source = generateSource(context);
expect(source).to.include(stripIndent`
/* @flow */
// This file was automatically generated and should not be edited.
export type HeroAndDetailsQuery = {
hero: ?(HeroDetailsFragment & {
name: string,
}),
};
export type HeroDetailsFragment = {
primaryFunction: ?string,
height: ?number,
};
`);
expect(source).toMatchSnapshot();
});
it(`should generate mutation operations with complex input types`, function() {
const context = this.compileFromSource(`
test(`should generate mutation operations with complex input types`, function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
mutation ReviewMovie($episode: Episode, $review: ReviewInput) {

@@ -239,45 +290,29 @@ createReview(episode: $episode, review: $review) {

const source = generateSource(context);
expect(source).toMatchSnapshot();
});
expect(source).to.include(stripIndent`
/* @flow */
// This file was automatically generated and should not be edited.
test(`should generate correct typedefs with a single custom fragment`, function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
fragment Friend on Character {
name
}
// The episodes in the Star Wars trilogy
export type Episode =
"NEWHOPE" | // Star Wars Episode IV: A New Hope, released in 1977.
"EMPIRE" | // Star Wars Episode V: The Empire Strikes Back, released in 1980.
"JEDI"; // Star Wars Episode VI: Return of the Jedi, released in 1983.
query HeroAndFriendsNames($episode: Episode) {
hero(episode: $episode) {
name
friends {
...Friend
}
}
}
`);
export type ReviewInput = {
// 0-5 stars
stars: number,
// Comment about the movie, optional
commentary: ?string,
// Favorite color, optional
favorite_color: ?ColorInput,
};
export type ColorInput = {
red: number,
green: number,
blue: number,
};
export type ReviewMovieMutationVariables = {
episode: ?Episode,
review: ?ReviewInput,
};
export type ReviewMovieMutation = {
createReview: ? {
stars: number,
commentary: ?string,
},
};
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
it(`should generate correct list with custom fragment`, function() {
const context = this.compileFromSource(`
test(`should generate correct typedefs with a multiple custom fragments`, function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
fragment Friend on Character {

@@ -287,2 +322,6 @@ name

fragment Person on Character {
name
}
query HeroAndFriendsNames($episode: Episode) {

@@ -293,2 +332,3 @@ hero(episode: $episode) {

...Friend
...Person
}

@@ -300,31 +340,220 @@ }

const source = generateSource(context);
expect(source).toMatchSnapshot();
});
expect(source).to.include(stripIndent`
/* @flow */
// This file was automatically generated and should not be edited.
test(`should handle complex fragments with type aliases`, function() {
const { compileFromSource } = setup(swapiSchema);
const context = compileFromSource(`
query HeroAndFriendsNames {
hero(episode: NEWHOPE) {
name
...Something
}
empireHero: hero(episode: EMPIRE) {
name
...Something
}
}
// The episodes in the Star Wars trilogy
export type Episode =
"NEWHOPE" | // Star Wars Episode IV: A New Hope, released in 1977.
"EMPIRE" | // Star Wars Episode V: The Empire Strikes Back, released in 1980.
"JEDI"; // Star Wars Episode VI: Return of the Jedi, released in 1983.
fragment Something on Character {
... on Human {
friends {
... on Human {
homePlanet
}
... on Droid {
primaryFunction
}
}
}
export type HeroAndFriendsNamesQueryVariables = {
episode: ?Episode,
};
... on Droid {
appearsIn
}
}
`);
export type HeroAndFriendsNamesQuery = {
hero: ? {
name: string,
friends: Array<FriendFragment>,
},
};
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
export type FriendFragment = {
name: string,
};
test(`should annotate custom scalars as string`, function() {
const { compileFromSource } = setup(miscSchema);
const context = compileFromSource(`
query CustomScalar {
misc {
date
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should correctly handle fragments on interfaces', function() {
const {compileFromSource} = setup(swapiSchema);
const context = compileFromSource(
`
query HeroQuery($episode: Episode){
hero(episode: $episode) {
name
... on Human {
homePlanet
}
... on Droid {
primaryFunction
}
}
}
`
);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should correctly handle fragment spreads on interfaces', function() {
const {compileFromSource} = setup(swapiSchema);
const context = compileFromSource(
`
query HeroQuery($episode: Episode){
hero(episode: $episode) {
name
...humanFragment
...droidFragment
}
}
fragment humanFragment on Human {
homePlanet
}
fragment droidFragment on Droid {
primaryFunction
}
`
);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should correctly handle nested fragments on interfaces', function() {
const {compileFromSource} = setup(swapiSchema);
const context = compileFromSource(
`
query HeroQuery($episode: Episode){
hero(episode: $episode) {
name
friendsConnection {
friends {
...CharacterFragment
}
}
}
}
fragment CharacterFragment on Character {
name
... on Human {
homePlanet
}
... on Droid {
primaryFunction
}
}
`
);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should correctly add typename to nested fragments on interfaces if addTypename is true', function() {
const {compileFromSource} = setup(swapiSchema);
const context = compileFromSource(
`
query HeroQuery($episode: Episode){
hero(episode: $episode) {
name
friendsConnection {
friends {
...CharacterFragment
}
}
}
}
fragment CharacterFragment on Character {
name
... on Human {
homePlanet
}
... on Droid {
primaryFunction
}
}
`
);
const source = generateSource(context, { addTypename: true });
expect(source).toMatchSnapshot();
});
test('should correctly handle doubly nested fragments on interfaces', function() {
const {compileFromSource} = setup(swapiSchema);
const context = compileFromSource(
`
query HeroQuery($episode: Episode) {
hero(episode: $episode) {
name
friendsConnection {
friends {
...CharacterFragment
}
}
}
}
fragment CharacterFragment on Character {
name
... on Human {
homePlanet
friends {
...OtherCharacterFragment
}
}
... on Droid {
primaryFunction
}
}
fragment OtherCharacterFragment on Character {
... on Human {
height
}
... on Droid {
appearsIn
}
}
`
);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
});
});

@@ -1,3 +0,1 @@

import { expect } from 'chai';
import { stripIndent } from 'common-tags';

@@ -22,6 +20,9 @@

structDeclarationForSelectionSet,
dictionaryLiteralForFieldArguments,
typeDeclarationForGraphQLType,
} from '../../src/swift/codeGeneration';
import {
dictionaryLiteralForFieldArguments,
} from '../../src/swift/values';
import { loadSchema } from '../../src/loading';

@@ -35,2 +36,6 @@ const schema = loadSchema(require.resolve('../starwars/schema.json'));

describe('Swift code generation', function() {
let generator;
let compileFromSource;
let addFragment;
beforeEach(function() {

@@ -44,13 +49,13 @@ const context = {

this.generator = new CodeGenerator(context);
generator = new CodeGenerator(context);
this.compileFromSource = (source) => {
compileFromSource = (source) => {
const document = parse(source);
const context = compileToIR(schema, document);
this.generator.context = context;
generator.context = context;
return context;
};
this.addFragment = (fragment) => {
this.generator.context.fragments[fragment.fragmentName] = fragment;
addFragment = (fragment) => {
generator.context.fragments[fragment.fragmentName] = fragment;
};

@@ -60,4 +65,4 @@ });

describe('#classDeclarationForOperation()', function() {
it(`should generate a class declaration for a query with variables`, function() {
const { operations } = this.compileFromSource(`
test(`should generate a class declaration for a query with variables`, function() {
const { operations } = compileFromSource(`
query HeroName($episode: Episode) {

@@ -70,28 +75,8 @@ hero(episode: $episode) {

classDeclarationForOperation(this.generator, operations['HeroName']);
expect(this.generator.output).to.include(stripIndent`
public final class HeroNameQuery: GraphQLQuery {
public static let operationDefinition =
"query HeroName($episode: Episode) {" +
" hero(episode: $episode) {" +
" __typename" +
" name" +
" }" +
"}"
public let episode: Episode?
public init(episode: Episode? = nil) {
self.episode = episode
}
public var variables: GraphQLMap? {
return ["episode": episode]
}
`);
classDeclarationForOperation(generator, operations['HeroName']);
expect(generator.output).toMatchSnapshot();
});
it(`should generate a class declaration for a query with fragment spreads`, function() {
const { operations } = this.compileFromSource(`
test(`should generate a class declaration for a query with fragment spreads`, function() {
const { operations } = compileFromSource(`
query Hero {

@@ -108,47 +93,8 @@ hero {

classDeclarationForOperation(this.generator, operations['Hero']);
expect(this.generator.output).to.equal(stripIndent`
public final class HeroQuery: GraphQLQuery {
public static let operationDefinition =
"query Hero {" +
" hero {" +
" __typename" +
" ...HeroDetails" +
" }" +
"}"
public static let queryDocument = operationDefinition.appending(HeroDetails.fragmentDefinition)
public init() {
}
public struct Data: GraphQLMappable {
public let hero: Hero?
public init(reader: GraphQLResultReader) throws {
hero = try reader.optionalValue(for: Field(responseName: "hero"))
}
public struct Hero: GraphQLMappable {
public let __typename: String
public let fragments: Fragments
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
let heroDetails = try HeroDetails(reader: reader)
fragments = Fragments(heroDetails: heroDetails)
}
public struct Fragments {
public let heroDetails: HeroDetails
}
}
}
}
`);
classDeclarationForOperation(generator, operations['Hero']);
expect(generator.output).toMatchSnapshot();
});
it(`should generate a class declaration for a query with conditional fragment spreads`, function() {
const { operations } = this.compileFromSource(`
test(`should generate a class declaration for a query with conditional fragment spreads`, function() {
const { operations } = compileFromSource(`
query Hero {

@@ -165,47 +111,8 @@ hero {

classDeclarationForOperation(this.generator, operations['Hero']);
expect(this.generator.output).to.equal(stripIndent`
public final class HeroQuery: GraphQLQuery {
public static let operationDefinition =
"query Hero {" +
" hero {" +
" __typename" +
" ...DroidDetails" +
" }" +
"}"
public static let queryDocument = operationDefinition.appending(DroidDetails.fragmentDefinition)
public init() {
}
public struct Data: GraphQLMappable {
public let hero: Hero?
public init(reader: GraphQLResultReader) throws {
hero = try reader.optionalValue(for: Field(responseName: "hero"))
}
public struct Hero: GraphQLMappable {
public let __typename: String
public let fragments: Fragments
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
let droidDetails = try DroidDetails(reader: reader, ifTypeMatches: __typename)
fragments = Fragments(droidDetails: droidDetails)
}
public struct Fragments {
public let droidDetails: DroidDetails?
}
}
}
}
`);
classDeclarationForOperation(generator, operations['Hero']);
expect(generator.output).toMatchSnapshot();
});
it(`should generate a class declaration for a query with a fragment spread nested in an inline fragment`, function() {
const { operations } = this.compileFromSource(`
test(`should generate a class declaration for a query with a fragment spread nested in an inline fragment`, function() {
const { operations } = compileFromSource(`
query Hero {

@@ -224,64 +131,9 @@ hero {

classDeclarationForOperation(this.generator, operations['Hero']);
classDeclarationForOperation(generator, operations['Hero']);
expect(this.generator.output).to.equal(stripIndent`
public final class HeroQuery: GraphQLQuery {
public static let operationDefinition =
"query Hero {" +
" hero {" +
" __typename" +
" ... on Droid {" +
" __typename" +
" ...HeroDetails" +
" }" +
" }" +
"}"
public static let queryDocument = operationDefinition.appending(HeroDetails.fragmentDefinition)
public init() {
}
public struct Data: GraphQLMappable {
public let hero: Hero?
public init(reader: GraphQLResultReader) throws {
hero = try reader.optionalValue(for: Field(responseName: "hero"))
}
public struct Hero: GraphQLMappable {
public let __typename: String
public let asDroid: AsDroid?
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
asDroid = try AsDroid(reader: reader, ifTypeMatches: __typename)
}
public struct AsDroid: GraphQLConditionalFragment {
public static let possibleTypes = ["Droid"]
public let __typename: String
public let fragments: Fragments
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
let heroDetails = try HeroDetails(reader: reader)
fragments = Fragments(heroDetails: heroDetails)
}
public struct Fragments {
public let heroDetails: HeroDetails
}
}
}
}
}
`);
expect(generator.output).toMatchSnapshot();
});
it(`should generate a class declaration for a mutation with variables`, function() {
const { operations } = this.compileFromSource(`
test(`should generate a class declaration for a mutation with variables`, function() {
const { operations } = compileFromSource(`
mutation CreateReview($episode: Episode) {

@@ -295,25 +147,5 @@ createReview(episode: $episode, review: { stars: 5, commentary: "Wow!" }) {

classDeclarationForOperation(this.generator, operations['CreateReview']);
classDeclarationForOperation(generator, operations['CreateReview']);
expect(this.generator.output).to.include(stripIndent`
public final class CreateReviewMutation: GraphQLMutation {
public static let operationDefinition =
"mutation CreateReview($episode: Episode) {" +
" createReview(episode: $episode, review: {stars: 5, commentary: \\"Wow!\\"}) {" +
" __typename" +
" stars" +
" commentary" +
" }" +
"}"
public let episode: Episode?
public init(episode: Episode? = nil) {
self.episode = episode
}
public var variables: GraphQLMap? {
return ["episode": episode]
}
`);
expect(generator.output).toMatchSnapshot();
});

@@ -323,28 +155,20 @@ });

describe('#initializerDeclarationForProperties()', function() {
it(`should generate initializer for a property`, function() {
initializerDeclarationForProperties(this.generator, [
test(`should generate initializer for a property`, function() {
initializerDeclarationForProperties(generator, [
{ propertyName: 'episode', type: new GraphQLNonNull(schema.getType('Episode')), typeName: 'Episode' }
]);
expect(this.generator.output).to.equal(stripIndent`
public init(episode: Episode) {
self.episode = episode
}
`);
expect(generator.output).toMatchSnapshot();
});
it(`should generate initializer for an optional property`, function() {
initializerDeclarationForProperties(this.generator, [
test(`should generate initializer for an optional property`, function() {
initializerDeclarationForProperties(generator, [
{ propertyName: 'episode', type: schema.getType('Episode'), typeName: 'Episode?', isOptional: true }
]);
expect(this.generator.output).to.equal(stripIndent`
public init(episode: Episode? = nil) {
self.episode = episode
}
`);
expect(generator.output).toMatchSnapshot();
});
it(`should generate initializer for multiple properties`, function() {
initializerDeclarationForProperties(this.generator, [
test(`should generate initializer for multiple properties`, function() {
initializerDeclarationForProperties(generator, [
{ propertyName: 'episode', type: schema.getType('Episode'), typeName: 'Episode?', isOptional: true },

@@ -354,8 +178,3 @@ { propertyName: 'scene', type: GraphQLString, typeName: 'String?', isOptional: true }

expect(this.generator.output).to.equal(stripIndent`
public init(episode: Episode? = nil, scene: String? = nil) {
self.episode = episode
self.scene = scene
}
`);
expect(generator.output).toMatchSnapshot();
});

@@ -365,4 +184,4 @@ });

describe('#structDeclarationForFragment()', function() {
it(`should generate a struct declaration for a fragment with an abstract type condition`, function() {
const { fragments } = this.compileFromSource(`
test(`should generate a struct declaration for a fragment with an abstract type condition`, function() {
const { fragments } = compileFromSource(`
fragment HeroDetails on Character {

@@ -374,30 +193,9 @@ name

structDeclarationForFragment(this.generator, fragments['HeroDetails']);
structDeclarationForFragment(generator, fragments['HeroDetails']);
expect(this.generator.output).to.equal(stripIndent`
public struct HeroDetails: GraphQLNamedFragment {
public static let fragmentDefinition =
"fragment HeroDetails on Character {" +
" __typename" +
" name" +
" appearsIn" +
"}"
public static let possibleTypes = ["Human", "Droid"]
public let __typename: String
public let name: String
public let appearsIn: [Episode?]
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
name = try reader.value(for: Field(responseName: "name"))
appearsIn = try reader.list(for: Field(responseName: "appearsIn"))
}
}
`);
expect(generator.output).toMatchSnapshot();
});
it(`should generate a struct declaration for a fragment with a concrete type condition`, function() {
const { fragments } = this.compileFromSource(`
test(`should generate a struct declaration for a fragment with a concrete type condition`, function() {
const { fragments } = compileFromSource(`
fragment DroidDetails on Droid {

@@ -409,30 +207,9 @@ name

structDeclarationForFragment(this.generator, fragments['DroidDetails']);
structDeclarationForFragment(generator, fragments['DroidDetails']);
expect(this.generator.output).to.equal(stripIndent`
public struct DroidDetails: GraphQLNamedFragment {
public static let fragmentDefinition =
"fragment DroidDetails on Droid {" +
" __typename" +
" name" +
" primaryFunction" +
"}"
public static let possibleTypes = ["Droid"]
public let __typename: String
public let name: String
public let primaryFunction: String?
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
name = try reader.value(for: Field(responseName: "name"))
primaryFunction = try reader.optionalValue(for: Field(responseName: "primaryFunction"))
}
}
`);
expect(generator.output).toMatchSnapshot();
});
it(`should generate a struct declaration for a fragment with a subselection`, function() {
const { fragments } = this.compileFromSource(`
test(`should generate a struct declaration for a fragment with a subselection`, function() {
const { fragments } = compileFromSource(`
fragment HeroDetails on Character {

@@ -446,43 +223,9 @@ name

structDeclarationForFragment(this.generator, fragments['HeroDetails']);
structDeclarationForFragment(generator, fragments['HeroDetails']);
expect(this.generator.output).to.equal(stripIndent`
public struct HeroDetails: GraphQLNamedFragment {
public static let fragmentDefinition =
"fragment HeroDetails on Character {" +
" __typename" +
" name" +
" friends {" +
" __typename" +
" name" +
" }" +
"}"
public static let possibleTypes = ["Human", "Droid"]
public let __typename: String
public let name: String
public let friends: [Friend?]?
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
name = try reader.value(for: Field(responseName: "name"))
friends = try reader.optionalList(for: Field(responseName: "friends"))
}
public struct Friend: GraphQLMappable {
public let __typename: String
public let name: String
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
name = try reader.value(for: Field(responseName: "name"))
}
}
}
`);
expect(generator.output).toMatchSnapshot();
});
it(`should generate a struct declaration for a fragment that includes a fragment spread`, function() {
const { fragments } = this.compileFromSource(`
test(`should generate a struct declaration for a fragment that includes a fragment spread`, function() {
const { fragments } = compileFromSource(`
fragment HeroDetails on Character {

@@ -498,33 +241,5 @@ name

structDeclarationForFragment(this.generator, fragments['HeroDetails']);
structDeclarationForFragment(generator, fragments['HeroDetails']);
expect(this.generator.output).to.equal(stripIndent`
public struct HeroDetails: GraphQLNamedFragment {
public static let fragmentDefinition =
"fragment HeroDetails on Character {" +
" __typename" +
" name" +
" ...MoreHeroDetails" +
"}"
public static let possibleTypes = ["Human", "Droid"]
public let __typename: String
public let name: String
public let fragments: Fragments
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
name = try reader.value(for: Field(responseName: "name"))
let moreHeroDetails = try MoreHeroDetails(reader: reader)
fragments = Fragments(moreHeroDetails: moreHeroDetails)
}
public struct Fragments {
public let moreHeroDetails: MoreHeroDetails
}
}
`);
expect(generator.output).toMatchSnapshot();
});

@@ -534,4 +249,4 @@ });

describe('#structDeclarationForSelectionSet()', function() {
it(`should generate a struct declaration for a selection set`, function() {
structDeclarationForSelectionSet(this.generator, {
test(`should generate a struct declaration for a selection set`, function() {
structDeclarationForSelectionSet(generator, {
structName: 'Hero',

@@ -548,17 +263,7 @@ parentType: schema.getType('Character'),

expect(this.generator.output).to.equal(stripIndent`
public struct Hero: GraphQLMappable {
public let __typename: String
public let name: String?
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
name = try reader.optionalValue(for: Field(responseName: "name"))
}
}
`);
expect(generator.output).toMatchSnapshot();
});
it(`should escape reserved keywords in a struct declaration for a selection set`, function() {
structDeclarationForSelectionSet(this.generator, {
test(`should escape reserved keywords in a struct declaration for a selection set`, function() {
structDeclarationForSelectionSet(generator, {
structName: 'Hero',

@@ -575,17 +280,7 @@ parentType: schema.getType('Character'),

expect(this.generator.output).to.equal(stripIndent`
public struct Hero: GraphQLMappable {
public let __typename: String
public let \`private\`: String?
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
\`private\` = try reader.optionalValue(for: Field(responseName: "private", fieldName: "name"))
}
}
`);
expect(generator.output).toMatchSnapshot();
});
it(`should generate a nested struct declaration for a selection set with subselections`, function() {
structDeclarationForSelectionSet(this.generator, {
test(`should generate a nested struct declaration for a selection set with subselections`, function() {
structDeclarationForSelectionSet(generator, {
structName: 'Hero',

@@ -609,27 +304,7 @@ parentType: schema.getType('Character'),

expect(this.generator.output).to.equal(stripIndent`
public struct Hero: GraphQLMappable {
public let __typename: String
public let friends: [Friend?]?
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
friends = try reader.optionalList(for: Field(responseName: "friends"))
}
public struct Friend: GraphQLMappable {
public let __typename: String
public let name: String?
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
name = try reader.optionalValue(for: Field(responseName: "name"))
}
}
}
`);
expect(generator.output).toMatchSnapshot();
});
it(`should generate a struct declaration for a selection set with a fragment spread that matches the parent type`, function() {
this.addFragment({
test(`should generate a struct declaration for a selection set with a fragment spread that matches the parent type`, function() {
addFragment({
fragmentName: 'HeroDetails',

@@ -639,3 +314,3 @@ typeCondition: schema.getType('Character')

structDeclarationForSelectionSet(this.generator, {
structDeclarationForSelectionSet(generator, {
structName: 'Hero',

@@ -653,26 +328,7 @@ parentType: schema.getType('Character'),

expect(this.generator.output).to.equal(stripIndent`
public struct Hero: GraphQLMappable {
public let __typename: String
public let name: String?
public let fragments: Fragments
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
name = try reader.optionalValue(for: Field(responseName: "name"))
let heroDetails = try HeroDetails(reader: reader)
fragments = Fragments(heroDetails: heroDetails)
}
public struct Fragments {
public let heroDetails: HeroDetails
}
}
`);
expect(generator.output).toMatchSnapshot();
});
it(`should generate a struct declaration for a selection set with a fragment spread with a more specific type condition`, function() {
this.addFragment({
test(`should generate a struct declaration for a selection set with a fragment spread with a more specific type condition`, function() {
addFragment({
fragmentName: 'DroidDetails',

@@ -682,3 +338,3 @@ typeCondition: schema.getType('Droid')

structDeclarationForSelectionSet(this.generator, {
structDeclarationForSelectionSet(generator, {
structName: 'Hero',

@@ -696,26 +352,7 @@ parentType: schema.getType('Character'),

expect(this.generator.output).to.equal(stripIndent`
public struct Hero: GraphQLMappable {
public let __typename: String
public let name: String?
public let fragments: Fragments
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
name = try reader.optionalValue(for: Field(responseName: "name"))
let droidDetails = try DroidDetails(reader: reader, ifTypeMatches: __typename)
fragments = Fragments(droidDetails: droidDetails)
}
public struct Fragments {
public let droidDetails: DroidDetails?
}
}
`);
expect(generator.output).toMatchSnapshot();
});
it(`should generate a struct declaration for a selection set with an inline fragment`, function() {
structDeclarationForSelectionSet(this.generator, {
test(`should generate a struct declaration for a selection set with an inline fragment`, function() {
structDeclarationForSelectionSet(generator, {
structName: 'Hero',

@@ -733,2 +370,3 @@ parentType: schema.getType('Character'),

typeCondition: schema.getType('Droid'),
possibleTypes: ['Droid'],
fields: [

@@ -750,35 +388,7 @@ {

expect(this.generator.output).to.equal(stripIndent`
public struct Hero: GraphQLMappable {
public let __typename: String
public let name: String
public let asDroid: AsDroid?
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
name = try reader.value(for: Field(responseName: "name"))
asDroid = try AsDroid(reader: reader, ifTypeMatches: __typename)
}
public struct AsDroid: GraphQLConditionalFragment {
public static let possibleTypes = ["Droid"]
public let __typename: String
public let name: String
public let primaryFunction: String?
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
name = try reader.value(for: Field(responseName: "name"))
primaryFunction = try reader.optionalValue(for: Field(responseName: "primaryFunction"))
}
}
}
`);
expect(generator.output).toMatchSnapshot();
});
it(`should generate a struct declaration for a fragment spread nested in an inline fragment`, function() {
this.addFragment({
test(`should generate a struct declaration for a fragment spread nested in an inline fragment`, function() {
addFragment({
fragmentName: 'HeroDetails',

@@ -788,3 +398,3 @@ typeCondition: schema.getType('Character')

structDeclarationForSelectionSet(this.generator, {
structDeclarationForSelectionSet(generator, {
structName: 'Hero',

@@ -796,2 +406,3 @@ parentType: schema.getType('Character'),

typeCondition: schema.getType('Droid'),
possibleTypes: ['Droid'],
fields: [],

@@ -803,34 +414,3 @@ fragmentSpreads: ['HeroDetails'],

expect(this.generator.output).to.equal(stripIndent`
public struct Hero: GraphQLMappable {
public let __typename: String
public let asDroid: AsDroid?
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
asDroid = try AsDroid(reader: reader, ifTypeMatches: __typename)
}
public struct AsDroid: GraphQLConditionalFragment {
public static let possibleTypes = ["Droid"]
public let __typename: String
public let fragments: Fragments
public init(reader: GraphQLResultReader) throws {
__typename = try reader.value(for: Field(responseName: "__typename"))
let heroDetails = try HeroDetails(reader: reader)
fragments = Fragments(heroDetails: heroDetails)
}
public struct Fragments {
public let heroDetails: HeroDetails
}
}
}
`);
expect(generator.output).toMatchSnapshot();
});

@@ -840,4 +420,4 @@ });

describe('#dictionaryLiteralForFieldArguments()', function() {
it('should include expressions for input objects with variables', function() {
const { operations } = this.compileFromSource(`
test('should include expressions for input objects with variables', function() {
const { operations } = compileFromSource(`
mutation FieldArgumentsWithInputObjects($commentary: String!, $red: Int!) {

@@ -853,3 +433,3 @@ createReview(episode: JEDI, review: { stars: 2, commentary: $commentary, favorite_color: { red: $red, blue: 100, green: 50 } }) {

expect(dictionaryLiteral).to.equal('["episode": "JEDI", "review": ["stars": 2, "commentary": reader.variables["commentary"], "favorite_color": ["red": reader.variables["red"], "blue": 100, "green": 50]]]');
expect(dictionaryLiteral).toBe('["episode": "JEDI", "review": ["stars": 2, "commentary": Variable("commentary"), "favorite_color": ["red": Variable("red"), "blue": 100, "green": 50]]]');
});

@@ -859,3 +439,3 @@ });

describe('#typeDeclarationForGraphQLType()', function() {
it('should generate an enum declaration for a GraphQLEnumType', function() {
test('should generate an enum declaration for a GraphQLEnumType', function() {
const generator = new CodeGenerator();

@@ -865,15 +445,6 @@

expect(generator.output).to.equal(stripIndent`
/// The episodes in the Star Wars trilogy
public enum Episode: String {
case newhope = "NEWHOPE" /// Star Wars Episode IV: A New Hope, released in 1977.
case empire = "EMPIRE" /// Star Wars Episode V: The Empire Strikes Back, released in 1980.
case jedi = "JEDI" /// Star Wars Episode VI: Return of the Jedi, released in 1983.
}
extension Episode: JSONDecodable, JSONEncodable {}
`);
expect(generator.output).toMatchSnapshot();
});
it('should escape identifiers in cases of enum declaration for a GraphQLEnumType', function() {
test('should escape identifiers in cases of enum declaration for a GraphQLEnumType', function() {
const generator = new CodeGenerator();

@@ -888,13 +459,6 @@

expect(generator.output).to.equal(stripIndent`
public enum AlbumPrivacies: String {
case \`public\` = "PUBLIC"
case \`private\` = "PRIVATE"
}
extension AlbumPrivacies: JSONDecodable, JSONEncodable {}
`);
expect(generator.output).toMatchSnapshot();
});
it('should generate a struct declaration for a GraphQLInputObjectType', function() {
test('should generate a struct declaration for a GraphQLInputObjectType', function() {
const generator = new CodeGenerator();

@@ -904,14 +468,5 @@

expect(generator.output).to.equal(stripIndent`
/// The input object sent when someone is creating a new review
public struct ReviewInput: GraphQLMapConvertible {
public var graphQLMap: GraphQLMap
public init(stars: Int, commentary: String? = nil, favoriteColor: ColorInput? = nil) {
graphQLMap = ["stars": stars, "commentary": commentary, "favorite_color": favoriteColor]
}
}
`);
expect(generator.output).toMatchSnapshot();
});
});
});

@@ -1,3 +0,1 @@

import { expect } from 'chai';
import { stripIndent } from 'common-tags';

@@ -16,16 +14,18 @@

describe('Swift code generation: Basic language constructs', function() {
let generator;
beforeEach(function() {
this.generator = new CodeGenerator();
generator = new CodeGenerator();
});
it(`should generate a class declaration`, function() {
classDeclaration(this.generator, { className: 'Hero', modifiers: ['public', 'final'] }, () => {
propertyDeclaration(this.generator, { propertyName: 'name', typeName: 'String' });
propertyDeclaration(this.generator, { propertyName: 'age', typeName: 'Int' });
test(`should generate a class declaration`, function() {
classDeclaration(generator, { className: 'Hero', modifiers: ['public', 'final'] }, () => {
propertyDeclaration(generator, { propertyName: 'name', typeName: 'String' });
propertyDeclaration(generator, { propertyName: 'age', typeName: 'Int' });
});
expect(this.generator.output).to.equal(stripIndent`
expect(generator.output).toBe(stripIndent`
public final class Hero {
public let name: String
public let age: Int
public var name: String
public var age: Int
}

@@ -35,12 +35,12 @@ `);

it(`should generate a struct declaration`, function() {
structDeclaration(this.generator, { structName: 'Hero' }, () => {
propertyDeclaration(this.generator, { propertyName: 'name', typeName: 'String' });
propertyDeclaration(this.generator, { propertyName: 'age', typeName: 'Int' });
test(`should generate a struct declaration`, function() {
structDeclaration(generator, { structName: 'Hero' }, () => {
propertyDeclaration(generator, { propertyName: 'name', typeName: 'String' });
propertyDeclaration(generator, { propertyName: 'age', typeName: 'Int' });
});
expect(this.generator.output).to.equal(stripIndent`
expect(generator.output).toBe(stripIndent`
public struct Hero {
public let name: String
public let age: Int
public var name: String
public var age: Int
}

@@ -50,19 +50,19 @@ `);

it(`should generate nested struct declarations`, function() {
structDeclaration(this.generator, { structName: 'Hero' }, () => {
propertyDeclaration(this.generator, { propertyName: 'name', typeName: 'String' });
propertyDeclaration(this.generator, { propertyName: 'friends', typeName: '[Friend]' });
test(`should generate nested struct declarations`, function() {
structDeclaration(generator, { structName: 'Hero' }, () => {
propertyDeclaration(generator, { propertyName: 'name', typeName: 'String' });
propertyDeclaration(generator, { propertyName: 'friends', typeName: '[Friend]' });
structDeclaration(this.generator, { structName: 'Friend' }, () => {
propertyDeclaration(this.generator, { propertyName: 'name', typeName: 'String' });
structDeclaration(generator, { structName: 'Friend' }, () => {
propertyDeclaration(generator, { propertyName: 'name', typeName: 'String' });
});
});
expect(this.generator.output).to.equal(stripIndent`
expect(generator.output).toBe(stripIndent`
public struct Hero {
public let name: String
public let friends: [Friend]
public var name: String
public var friends: [Friend]
public struct Friend {
public let name: String
public var name: String
}

@@ -73,9 +73,9 @@ }

it(`should generate a protocol declaration`, function() {
protocolDeclaration(this.generator, { protocolName: 'HeroDetails', adoptedProtocols: ['HasName'] }, () => {
protocolPropertyDeclaration(this.generator, { propertyName: 'name', typeName: 'String' });
protocolPropertyDeclaration(this.generator, { propertyName: 'age', typeName: 'Int' });
test(`should generate a protocol declaration`, function() {
protocolDeclaration(generator, { protocolName: 'HeroDetails', adoptedProtocols: ['HasName'] }, () => {
protocolPropertyDeclaration(generator, { propertyName: 'name', typeName: 'String' });
protocolPropertyDeclaration(generator, { propertyName: 'age', typeName: 'Int' });
});
expect(this.generator.output).to.equal(stripIndent`
expect(generator.output).toBe(stripIndent`
public protocol HeroDetails: HasName {

@@ -87,2 +87,11 @@ var name: String { get }

});
test(`should handle multi-line descriptions`, () => {
structDeclaration(generator, { structName: 'Hero', description: 'A hero' }, () => {
propertyDeclaration(generator, { propertyName: 'name', typeName: 'String', description: `A multiline comment \n on the hero's name.` });
propertyDeclaration(generator, { propertyName: 'age', typeName: 'String', description: `A multiline comment \n on the hero's age.` });
});
expect(generator.output).toMatchSnapshot();
});
});

@@ -1,3 +0,1 @@

import { expect } from 'chai';
import { stripIndent } from 'common-tags'

@@ -25,62 +23,62 @@

describe('#typeNameFromGraphQLType()', function() {
it('should return String? for GraphQLString', function() {
expect(typeNameFromGraphQLType({}, GraphQLString)).to.equal('String?');
test('should return String? for GraphQLString', function() {
expect(typeNameFromGraphQLType({}, GraphQLString)).toBe('String?');
});
it('should return String for GraphQLNonNull(GraphQLString)', function() {
expect(typeNameFromGraphQLType({}, new GraphQLNonNull(GraphQLString))).to.equal('String');
test('should return String for GraphQLNonNull(GraphQLString)', function() {
expect(typeNameFromGraphQLType({}, new GraphQLNonNull(GraphQLString))).toBe('String');
});
it('should return [String?]? for GraphQLList(GraphQLString)', function() {
expect(typeNameFromGraphQLType({}, new GraphQLList(GraphQLString))).to.equal('[String?]?');
test('should return [String?]? for GraphQLList(GraphQLString)', function() {
expect(typeNameFromGraphQLType({}, new GraphQLList(GraphQLString))).toBe('[String?]?');
});
it('should return [String?] for GraphQLNonNull(GraphQLList(GraphQLString))', function() {
expect(typeNameFromGraphQLType({}, new GraphQLNonNull(new GraphQLList(GraphQLString)))).to.equal('[String?]');
test('should return [String?] for GraphQLNonNull(GraphQLList(GraphQLString))', function() {
expect(typeNameFromGraphQLType({}, new GraphQLNonNull(new GraphQLList(GraphQLString)))).toBe('[String?]');
});
it('should return [String]? for GraphQLList(GraphQLNonNull(GraphQLString))', function() {
expect(typeNameFromGraphQLType({}, new GraphQLList(new GraphQLNonNull(GraphQLString)))).to.equal('[String]?');
test('should return [String]? for GraphQLList(GraphQLNonNull(GraphQLString))', function() {
expect(typeNameFromGraphQLType({}, new GraphQLList(new GraphQLNonNull(GraphQLString)))).toBe('[String]?');
});
it('should return [String] for GraphQLNonNull(GraphQLList(GraphQLNonNull(GraphQLString)))', function() {
expect(typeNameFromGraphQLType({}, new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))))).to.equal('[String]');
test('should return [String] for GraphQLNonNull(GraphQLList(GraphQLNonNull(GraphQLString)))', function() {
expect(typeNameFromGraphQLType({}, new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(GraphQLString))))).toBe('[String]');
});
it('should return [[String?]?]? for GraphQLList(GraphQLList(GraphQLString))', function() {
expect(typeNameFromGraphQLType({}, new GraphQLList(new GraphQLList(GraphQLString)))).to.equal('[[String?]?]?');
test('should return [[String?]?]? for GraphQLList(GraphQLList(GraphQLString))', function() {
expect(typeNameFromGraphQLType({}, new GraphQLList(new GraphQLList(GraphQLString)))).toBe('[[String?]?]?');
});
it('should return [[String?]]? for GraphQLList(GraphQLNonNull(GraphQLList(GraphQLString)))', function() {
expect(typeNameFromGraphQLType({}, new GraphQLList(new GraphQLNonNull(new GraphQLList(GraphQLString))))).to.equal('[[String?]]?');
test('should return [[String?]]? for GraphQLList(GraphQLNonNull(GraphQLList(GraphQLString)))', function() {
expect(typeNameFromGraphQLType({}, new GraphQLList(new GraphQLNonNull(new GraphQLList(GraphQLString))))).toBe('[[String?]]?');
});
it('should return Int? for GraphQLInt', function() {
expect(typeNameFromGraphQLType({}, GraphQLInt)).to.equal('Int?');
test('should return Int? for GraphQLInt', function() {
expect(typeNameFromGraphQLType({}, GraphQLInt)).toBe('Int?');
});
it('should return Double? for GraphQLFloat', function() {
expect(typeNameFromGraphQLType({}, GraphQLFloat)).to.equal('Double?');
test('should return Double? for GraphQLFloat', function() {
expect(typeNameFromGraphQLType({}, GraphQLFloat)).toBe('Double?');
});
it('should return Bool? for GraphQLBoolean', function() {
expect(typeNameFromGraphQLType({}, GraphQLBoolean)).to.equal('Bool?');
test('should return Bool? for GraphQLBoolean', function() {
expect(typeNameFromGraphQLType({}, GraphQLBoolean)).toBe('Bool?');
});
it('should return GraphQLID? for GraphQLID', function() {
expect(typeNameFromGraphQLType({}, GraphQLID)).to.equal('GraphQLID?');
test('should return GraphQLID? for GraphQLID', function() {
expect(typeNameFromGraphQLType({}, GraphQLID)).toBe('GraphQLID?');
});
it('should return String? for a custom scalar type', function() {
expect(typeNameFromGraphQLType({}, new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).to.equal('String?');
test('should return String? for a custom scalar type', function() {
expect(typeNameFromGraphQLType({}, new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).toBe('String?');
});
it('should return a passed through custom scalar type with the passthroughCustomScalars option', function() {
expect(typeNameFromGraphQLType({ passthroughCustomScalars: true, customScalarsPrefix: '' }, new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).to.equal('CustomScalarType?');
test('should return a passed through custom scalar type with the passthroughCustomScalars option', function() {
expect(typeNameFromGraphQLType({ passthroughCustomScalars: true, customScalarsPrefix: '' }, new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).toBe('CustomScalarType?');
});
it('should return a passed through custom scalar type with a prefix with the customScalarsPrefix option', function() {
expect(typeNameFromGraphQLType({ passthroughCustomScalars: true, customScalarsPrefix: 'My' }, new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).to.equal('MyCustomScalarType?');
test('should return a passed through custom scalar type with a prefix with the customScalarsPrefix option', function() {
expect(typeNameFromGraphQLType({ passthroughCustomScalars: true, customScalarsPrefix: 'My' }, new GraphQLScalarType({ name: 'CustomScalarType', serialize: String }))).toBe('MyCustomScalarType?');
});
});
});

@@ -1,3 +0,1 @@

import { expect } from 'chai';
import { stripIndent } from 'common-tags';

@@ -27,2 +25,6 @@

describe('TypeScript code generation', function() {
let generator;
let compileFromSource;
let addFragment;
beforeEach(function() {

@@ -33,16 +35,17 @@ const context = {

fragments: {},
typesUsed: {}
typesUsed: {},
}
this.generator = new CodeGenerator(context);
generator = new CodeGenerator(context);
this.compileFromSource = (source) => {
compileFromSource = (source, addTypename = false) => {
const document = parse(source);
const context = compileToIR(schema, document);
this.generator.context = context;
const context = compileToIR(schema, document, { mergeInFieldsFromFragmentSpreads: false });
context.addTypename = addTypename;
generator.context = context;
return context;
};
this.addFragment = (fragment) => {
this.generator.context.fragments[fragment.fragmentName] = fragment;
addFragment = (fragment) => {
generator.context.fragments[fragment.fragmentName] = fragment;
};

@@ -52,4 +55,104 @@ });

describe('#generateSource()', function() {
it(`should generate simple query operations`, function() {
const context = this.compileFromSource(`
describe('__typename', function() {
test('in an object', function() {
const context = compileFromSource(`
query HeroName {
hero {
__typename
name
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
// TODO: Enable after fixing operation
test.skip('in an operation', function() {
const context = compileFromSource(`
query Hero {
...Hero
}
fragment Hero on Query {
hero {
__typename
name
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('single fragment spread', () => {
const context = compileFromSource(`
query HeroName {
hero {
...humanFriends
}
}
fragment humanFriends on Character {
friends {
__typename
name
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('in fragment spreads, allows for disjoint union via __typename string literals', function() {
const context = compileFromSource(`
query HeroName {
hero {
__typename
...humanHero
...droidHero
}
}
fragment droidHero on Droid {
primaryFunction
}
fragment humanHero on Human {
homePlanet
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('in inline fragments, allows for disjoint union via __typename string literals', function() {
const context = compileFromSource(`
query HeroName {
hero {
__typename
... on Droid {
friends {
name
}
}
... on Human {
homePlanet
}
}
}
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
});
test(`should generate simple query operations`, function() {
const context = compileFromSource(`
query HeroName {

@@ -63,18 +166,7 @@ hero {

const source = generateSource(context);
expect(source).to.include(stripIndent`
// This file was automatically generated and should not be edited.
/* tslint:disable */
export interface HeroNameQuery {
hero: {
name: string,
} | null;
}
/* tslint:enable */
` + `\n`);
expect(source).toMatchSnapshot();
});
it(`should generate simple query operations including input variables`, function() {
const context = this.compileFromSource(`
test(`should generate simple query operations including input variables`, function() {
const context = compileFromSource(`
query HeroName($episode: Episode) {

@@ -88,29 +180,7 @@ hero(episode: $episode) {

const source = generateSource(context);
expect(source).to.include(stripIndent`
// This file was automatically generated and should not be edited.
/* tslint:disable */
// The episodes in the Star Wars trilogy
export type Episode =
"NEWHOPE" | // Star Wars Episode IV: A New Hope, released in 1977.
"EMPIRE" | // Star Wars Episode V: The Empire Strikes Back, released in 1980.
"JEDI"; // Star Wars Episode VI: Return of the Jedi, released in 1983.
export interface HeroNameQueryVariables {
episode: Episode | null;
}
export interface HeroNameQuery {
hero: {
name: string,
} | null;
}
/* tslint:enable */
` + `\n`);
expect(source).toMatchSnapshot();
});
it(`should generate simple nested query operations including input variables`, function() {
const context = this.compileFromSource(`
test(`should generate simple nested query operations including input variables`, function() {
const context = compileFromSource(`
query HeroAndFriendsNames($episode: Episode) {

@@ -127,40 +197,15 @@ hero(episode: $episode) {

const source = generateSource(context);
expect(source).to.include(stripIndent`
// This file was automatically generated and should not be edited.
/* tslint:disable */
// The episodes in the Star Wars trilogy
export type Episode =
"NEWHOPE" | // Star Wars Episode IV: A New Hope, released in 1977.
"EMPIRE" | // Star Wars Episode V: The Empire Strikes Back, released in 1980.
"JEDI"; // Star Wars Episode VI: Return of the Jedi, released in 1983.
export interface HeroAndFriendsNamesQueryVariables {
episode: Episode | null;
}
export interface HeroAndFriendsNamesQuery {
hero: {
name: string,
friends: Array< {
name: string,
} > | null,
} | null;
}
/* tslint:enable */
` + `\n`);
expect(source).toMatchSnapshot();
});
it(`should generate fragmented query operations`, function() {
const context = this.compileFromSource(`
test(`should generate fragmented query operations`, function() {
const context = compileFromSource(`
query HeroAndFriendsNames {
hero {
name
...HeroFriends
...heroFriends
}
}
fragment HeroFriends on Character {
fragment heroFriends on Character {
friends {

@@ -173,24 +218,32 @@ name

const source = generateSource(context);
expect(source).toMatchSnapshot();
});
expect(source).to.include(stripIndent`
// This file was automatically generated and should not be edited.
/* tslint:disable */
test(`should handle multi-fragmented query operations`, function() {
const context = compileFromSource(`
query HeroAndFriendsNames {
hero {
name
...heroFriends
...heroAppears
}
}
export interface HeroAndFriendsNamesQuery {
hero: HeroFriendsFragment & {
name: string,
} | null;
fragment heroFriends on Character {
friends {
name
}
}
export interface HeroFriendsFragment {
friends: Array< {
name: string,
} > | null;
fragment heroAppears on Character {
appearsIn
}
/* tslint:enable */
` + `\n`);
`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
it(`should generate query operations with inline fragments`, function() {
const context = this.compileFromSource(`
test(`should generate query operations with inline fragments`, function() {
const context = compileFromSource(`
query HeroAndDetails {

@@ -214,23 +267,7 @@ hero {

const source = generateSource(context);
expect(source).to.include(stripIndent`
// This file was automatically generated and should not be edited.
/* tslint:disable */
export interface HeroAndDetailsQuery {
hero: HeroDetailsFragment & {
name: string,
} | null;
}
export interface HeroDetailsFragment {
primaryFunction: string | null;
height: number | null;
}
/* tslint:enable */
` + `\n`);
expect(source).toMatchSnapshot();
});
it(`should generate mutation operations with complex input types`, function() {
const context = this.compileFromSource(`
test(`should generate mutation operations with complex input types`, function() {
const context = compileFromSource(`
mutation ReviewMovie($episode: Episode, $review: ReviewInput) {

@@ -245,46 +282,27 @@ createReview(episode: $episode, review: $review) {

const source = generateSource(context);
expect(source).toMatchSnapshot();
});
expect(source).to.include(stripIndent`
// This file was automatically generated and should not be edited.
/* tslint:disable */
// The episodes in the Star Wars trilogy
export type Episode =
"NEWHOPE" | // Star Wars Episode IV: A New Hope, released in 1977.
"EMPIRE" | // Star Wars Episode V: The Empire Strikes Back, released in 1980.
"JEDI"; // Star Wars Episode VI: Return of the Jedi, released in 1983.
export interface ReviewInput {
// 0-5 stars
stars: number;
// Comment about the movie, optional
commentary: string | null;
// Favorite color, optional
favorite_color: ColorInput | null;
test(`should generate correct typedefs with a single custom fragment`, function() {
const context = compileFromSource(`
fragment Friend on Character {
name
}
export interface ColorInput {
red: number;
green: number;
blue: number;
query HeroAndFriendsNames($episode: Episode) {
hero(episode: $episode) {
name
friends {
...Friend
}
}
}
`);
export interface ReviewMovieMutationVariables {
episode: Episode | null;
review: ReviewInput | null;
}
export interface ReviewMovieMutation {
createReview: {
stars: number,
commentary: string | null,
} | null;
}
/* tslint:enable */
` + `\n`);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
it(`should generate correct list with custom fragment`, function() {
const context = this.compileFromSource(`
test(`should generate correct typedefs with a multiple custom fragments`, function() {
const context = compileFromSource(`
fragment Friend on Character {

@@ -294,2 +312,6 @@ name

fragment Person on Character {
name
}
query HeroAndFriendsNames($episode: Episode) {

@@ -300,2 +322,3 @@ hero(episode: $episode) {

...Friend
...Person
}

@@ -307,32 +330,177 @@ }

const source = generateSource(context);
expect(source).toMatchSnapshot();
});
expect(source).to.include(stripIndent`
// This file was automatically generated and should not be edited.
/* tslint:disable */
test(`should handle complex fragments with type aliases`, function() {
const context = compileFromSource(`
query HeroAndFriendsNames {
hero(episode: NEWHOPE) {
name
...Something
}
empireHero: hero(episode: EMPIRE) {
name
...Something
}
}
// The episodes in the Star Wars trilogy
export type Episode =
"NEWHOPE" | // Star Wars Episode IV: A New Hope, released in 1977.
"EMPIRE" | // Star Wars Episode V: The Empire Strikes Back, released in 1980.
"JEDI"; // Star Wars Episode VI: Return of the Jedi, released in 1983.
fragment Something on Character {
... on Human {
friends {
... on Human {
homePlanet
}
... on Droid {
primaryFunction
}
}
}
export interface HeroAndFriendsNamesQueryVariables {
episode: Episode | null;
... on Droid {
appearsIn
}
}
`);
export interface HeroAndFriendsNamesQuery {
hero: {
name: string,
friends: Array<FriendFragment>,
} | null;
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should correctly handle fragments on interfaces', function() {
const context = compileFromSource(
`
query HeroQuery($episode: Episode){
hero(episode: $episode) {
name
... on Human {
homePlanet
}
... on Droid {
primaryFunction
}
}
}
`
);
export interface FriendFragment {
name: string;
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should correctly handle nested fragments on interfaces', function() {
const context = compileFromSource(
`
query HeroQuery($episode: Episode){
hero(episode: $episode) {
name
friendsConnection {
friends {
...CharacterFragment
}
}
}
}
/* tslint:enable */
` + `\n`);
fragment CharacterFragment on Character {
name
__typename
... on Human {
homePlanet
}
... on Droid {
primaryFunction
}
}
`
);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
test('should correctly add typename to nested fragments on interfaces if addTypename is true', function() {
const context = compileFromSource(
`
query HeroQuery($episode: Episode){
hero(episode: $episode) {
name
friendsConnection {
friends {
...CharacterFragment
}
}
}
}
fragment CharacterFragment on Character {
name
__typename
... on Human {
homePlanet
}
... on Droid {
primaryFunction
}
}
`
);
const source = generateSource(context, { addTypename: true });
expect(source).toMatchSnapshot();
});
test('should correctly handle doubly nested fragments on interfaces', function() {
const context = compileFromSource(
`
query HeroQuery($episode: Episode) {
hero(episode: $episode) {
name
friendsConnection {
friends {
...CharacterFragment
}
}
}
}
fragment CharacterFragment on Character {
name
... on Human {
homePlanet
friends {
...OtherCharacterFragment
}
}
... on Droid {
primaryFunction
}
}
fragment OtherCharacterFragment on Character {
... on Human {
height
}
... on Droid {
appearsIn
}
}
`
);
const source = generateSource(context);
expect(source).toMatchSnapshot();
});
});
});

@@ -1,22 +0,20 @@

import { assert } from 'chai'
import {readFileSync} from 'fs';
import path from 'path';
import { readFileSync } from 'fs'
import path from 'path'
import {loadSchema, loadAndMergeQueryDocuments} from '../src/loading';
import {
loadSchema,
loadAndMergeQueryDocuments,
} from '../src/loading'
import {validateQueryDocument} from '../src/validation';
import { validateQueryDocument } from '../src/validation'
const schema = loadSchema(require.resolve('./starwars/schema.json'));
describe('Validation', () => {
it(`should throw an error for AnonymousQuery.graphql`, () => {
const inputPaths = [path.join(__dirname, './starwars/AnonymousQuery.graphql')];
test(`should throw an error for AnonymousQuery.graphql`, () => {
const inputPaths = [
path.join(__dirname, './starwars/AnonymousQuery.graphql'),
];
const document = loadAndMergeQueryDocuments(inputPaths);
assert.throws(
() => validateQueryDocument(schema, document),
expect(
() => validateQueryDocument(schema, document)
).toThrow(
'Validation of GraphQL query document failed'

@@ -26,8 +24,11 @@ );

it(`should throw an error for ExplicitTypename.graphql`, () => {
const inputPaths = [path.join(__dirname, './starwars/ExplicitTypename.graphql')];
test(`should throw an error for ExplicitTypename.graphql when the target is Swift`, () => {
const inputPaths = [
path.join(__dirname, './starwars/ExplicitTypename.graphql'),
];
const document = loadAndMergeQueryDocuments(inputPaths);
assert.throws(
() => validateQueryDocument(schema, document),
expect(
() => validateQueryDocument(schema, document, 'swift')
).toThrow(
'Validation of GraphQL query document failed'

@@ -37,8 +38,23 @@ );

it(`should throw an error for TypenameAlias.graphql`, () => {
const inputPaths = [path.join(__dirname, './starwars/TypenameAlias.graphql')];
test(`should not throw an error for ExplicitTypename.graphql when the target is not Swift`, () => {
const inputPaths = [
path.join(__dirname, './starwars/ExplicitTypename.graphql'),
];
const document = loadAndMergeQueryDocuments(inputPaths);
assert.throws(
() => validateQueryDocument(schema, document),
validateQueryDocument(schema, document, 'flow');
validateQueryDocument(schema, document, 'typescript');
validateQueryDocument(schema, document, 'ts');
validateQueryDocument(schema, document, 'json');
});
test(`should throw an error for TypenameAlias.graphql`, () => {
const inputPaths = [
path.join(__dirname, './starwars/TypenameAlias.graphql'),
];
const document = loadAndMergeQueryDocuments(inputPaths);
expect(
() => validateQueryDocument(schema, document)
).toThrow(
'Validation of GraphQL query document failed'

@@ -45,0 +61,0 @@ );

@@ -1,3 +0,1 @@

import { expect } from 'chai'
import {

@@ -10,64 +8,64 @@ parseValue,

describe('#valueFromValueNode', () => {
it(`should return a number for an IntValue`, () => {
test(`should return a number for an IntValue`, () => {
const valueNode = parseValue("1");
const value = valueFromValueNode(valueNode);
expect(value).to.equal(1);
expect(value).toBe(1);
});
it(`should return a number for a FloatValue`, () => {
test(`should return a number for a FloatValue`, () => {
const valueNode = parseValue("1.0");
const value = valueFromValueNode(valueNode);
expect(value).to.equal(1.0);
expect(value).toBe(1.0);
});
it(`should return a boolean for a BooleanValue`, () => {
test(`should return a boolean for a BooleanValue`, () => {
const valueNode = parseValue("true");
const value = valueFromValueNode(valueNode);
expect(value).to.equal(true);
expect(value).toBe(true);
});
it(`should return null for a NullValue`, () => {
test(`should return null for a NullValue`, () => {
const valueNode = parseValue("null");
const value = valueFromValueNode(valueNode);
expect(value).to.equal(null);
expect(value).toBe(null);
});
it(`should return a string for a StringValue`, () => {
test(`should return a string for a StringValue`, () => {
const valueNode = parseValue("\"foo\"");
const value = valueFromValueNode(valueNode);
expect(value).to.equal("foo");
expect(value).toBe("foo");
});
it(`should return a string for an EnumValue`, () => {
test(`should return a string for an EnumValue`, () => {
const valueNode = parseValue("JEDI");
const value = valueFromValueNode(valueNode);
expect(value).to.equal("JEDI");
expect(value).toBe("JEDI");
});
it(`should return an object for a Variable`, () => {
test(`should return an object for a Variable`, () => {
const valueNode = parseValue("$something");
const value = valueFromValueNode(valueNode);
expect(value).to.deep.equal({ kind: 'Variable', variableName: 'something' });
expect(value).toEqual({ kind: 'Variable', variableName: 'something' });
});
it(`should return an array for a ListValue`, () => {
test(`should return an array for a ListValue`, () => {
const valueNode = parseValue("[ \"foo\", 1, JEDI, $something ]");
const value = valueFromValueNode(valueNode);
expect(value).to.deep.equal([ "foo", 1, "JEDI", { kind: 'Variable', variableName: 'something' } ]);
expect(value).toEqual([ "foo", 1, "JEDI", { kind: 'Variable', variableName: 'something' } ]);
});
it(`should return an object for an ObjectValue`, () => {
test(`should return an object for an ObjectValue`, () => {
const valueNode = parseValue("{ foo: \"foo\", bar: 1, bla: JEDI, baz: $something }");
const value = valueFromValueNode(valueNode);
expect(value).to.deep.equal({ foo: "foo", bar: 1, bla: "JEDI", baz: { kind: 'Variable', variableName: 'something' } });
expect(value).toEqual({ foo: "foo", bar: 1, bla: "JEDI", baz: { kind: 'Variable', variableName: 'something' } });
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc