node_modules.apollo-codegen.lib.compiler.index.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apollo-client-maven-plugin Show documentation
Show all versions of apollo-client-maven-plugin Show documentation
Maven plugin for generating graphql clients
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const graphql_1 = require("graphql");
const graphql_2 = require("../utilities/graphql");
function compileToIR(schema, document, options = {}) {
if (options.addTypename) {
document = graphql_2.withTypenameFieldAddedWhereNeeded(document);
}
const compiler = new Compiler(schema, options);
const operations = Object.create(null);
const fragments = Object.create(null);
for (const definition of document.definitions) {
switch (definition.kind) {
case graphql_1.Kind.OPERATION_DEFINITION:
const operation = compiler.compileOperation(definition);
operations[operation.operationName] = operation;
break;
case graphql_1.Kind.FRAGMENT_DEFINITION:
const fragment = compiler.compileFragment(definition);
fragments[fragment.fragmentName] = fragment;
break;
}
}
for (const fragmentSpread of compiler.unresolvedFragmentSpreads) {
const fragment = fragments[fragmentSpread.fragmentName];
if (!fragment) {
throw new Error(`Cannot find fragment "${fragmentSpread.fragmentName}"`);
}
const possibleTypes = fragment.selectionSet.possibleTypes.filter(type => fragmentSpread.selectionSet.possibleTypes.includes(type));
fragmentSpread.isConditional = fragment.selectionSet.possibleTypes.some(type => !fragmentSpread.selectionSet.possibleTypes.includes(type));
fragmentSpread.selectionSet = {
possibleTypes,
selections: fragment.selectionSet.selections
};
}
const typesUsed = compiler.typesUsed;
return { schema, typesUsed, operations, fragments, options };
}
exports.compileToIR = compileToIR;
class Compiler {
constructor(schema, options) {
this.unresolvedFragmentSpreads = [];
this.schema = schema;
this.options = options;
this.typesUsedSet = new Set();
}
addTypeUsed(type) {
if (this.typesUsedSet.has(type))
return;
if (type instanceof graphql_1.GraphQLEnumType ||
type instanceof graphql_1.GraphQLInputObjectType ||
(type instanceof graphql_1.GraphQLScalarType && !graphql_1.isSpecifiedScalarType(type))) {
this.typesUsedSet.add(type);
}
if (type instanceof graphql_1.GraphQLInputObjectType) {
for (const field of Object.values(type.getFields())) {
this.addTypeUsed(graphql_1.getNamedType(field.type));
}
}
}
get typesUsed() {
return Array.from(this.typesUsedSet);
}
compileOperation(operationDefinition) {
if (!operationDefinition.name) {
throw new Error('Operations should be named');
}
const filePath = graphql_2.filePathForNode(operationDefinition);
const operationName = operationDefinition.name.value;
const operationType = operationDefinition.operation;
const variables = (operationDefinition.variableDefinitions || []).map(node => {
const name = node.variable.name.value;
const type = graphql_1.typeFromAST(this.schema, node.type);
this.addTypeUsed(graphql_1.getNamedType(type));
return { name, type };
});
const source = graphql_1.print(operationDefinition);
const rootType = graphql_2.getOperationRootType(this.schema, operationDefinition);
return {
filePath,
operationName,
operationType,
variables,
source,
rootType,
selectionSet: this.compileSelectionSet(operationDefinition.selectionSet, rootType)
};
}
compileFragment(fragmentDefinition) {
const fragmentName = fragmentDefinition.name.value;
const filePath = graphql_2.filePathForNode(fragmentDefinition);
const source = graphql_1.print(fragmentDefinition);
const type = graphql_1.typeFromAST(this.schema, fragmentDefinition.typeCondition);
return {
fragmentName,
filePath,
source,
type,
selectionSet: this.compileSelectionSet(fragmentDefinition.selectionSet, type)
};
}
compileSelectionSet(selectionSetNode, parentType, possibleTypes = this.possibleTypesForType(parentType), visitedFragments = new Set()) {
return {
possibleTypes,
selections: selectionSetNode.selections
.map(selectionNode => wrapInBooleanConditionsIfNeeded(this.compileSelection(selectionNode, parentType, possibleTypes, visitedFragments), selectionNode, possibleTypes))
.filter(x => x)
};
}
compileSelection(selectionNode, parentType, possibleTypes, visitedFragments) {
switch (selectionNode.kind) {
case graphql_1.Kind.FIELD: {
const name = selectionNode.name.value;
const alias = selectionNode.alias ? selectionNode.alias.value : undefined;
const fieldDef = graphql_2.getFieldDef(this.schema, parentType, selectionNode);
if (!fieldDef) {
throw new graphql_1.GraphQLError(`Cannot query field "${name}" on type "${String(parentType)}"`, [
selectionNode
]);
}
const fieldType = fieldDef.type;
const unmodifiedFieldType = graphql_1.getNamedType(fieldType);
this.addTypeUsed(unmodifiedFieldType);
const { description, isDeprecated, deprecationReason } = fieldDef;
const responseKey = alias || name;
const args = selectionNode.arguments && selectionNode.arguments.length > 0
? selectionNode.arguments.map(arg => {
const name = arg.name.value;
const argDef = fieldDef.args.find(argDef => argDef.name === arg.name.value);
return {
name,
value: graphql_2.valueFromValueNode(arg.value),
type: (argDef && argDef.type) || undefined
};
})
: undefined;
let field = {
kind: 'Field',
responseKey,
name,
alias,
args,
type: fieldType,
description: !graphql_2.isMetaFieldName(name) && description ? description : undefined,
isDeprecated,
deprecationReason
};
if (graphql_1.isCompositeType(unmodifiedFieldType)) {
const selectionSetNode = selectionNode.selectionSet;
if (!selectionSetNode) {
throw new graphql_1.GraphQLError(`Composite field "${name}" on type "${String(parentType)}" requires selection set`, [selectionNode]);
}
field.selectionSet = this.compileSelectionSet(selectionNode.selectionSet, unmodifiedFieldType);
}
return field;
}
case graphql_1.Kind.INLINE_FRAGMENT: {
const typeNode = selectionNode.typeCondition;
const type = typeNode ? graphql_1.typeFromAST(this.schema, typeNode) : parentType;
const possibleTypesForTypeCondition = this.possibleTypesForType(type).filter(type => possibleTypes.includes(type));
return {
kind: 'TypeCondition',
type,
selectionSet: this.compileSelectionSet(selectionNode.selectionSet, type, possibleTypesForTypeCondition)
};
}
case graphql_1.Kind.FRAGMENT_SPREAD: {
const fragmentName = selectionNode.name.value;
if (visitedFragments.has(fragmentName))
return null;
visitedFragments.add(fragmentName);
const fragmentSpread = {
kind: 'FragmentSpread',
fragmentName,
selectionSet: {
possibleTypes,
selections: []
}
};
this.unresolvedFragmentSpreads.push(fragmentSpread);
return fragmentSpread;
}
}
}
possibleTypesForType(type) {
if (graphql_1.isAbstractType(type)) {
return this.schema.getPossibleTypes(type) || [];
}
else {
return [type];
}
}
}
function wrapInBooleanConditionsIfNeeded(selection, selectionNode, possibleTypes) {
if (!selection)
return null;
if (!selectionNode.directives)
return selection;
for (const directive of selectionNode.directives) {
const directiveName = directive.name.value;
if (directiveName === 'skip' || directiveName === 'include') {
if (!directive.arguments)
continue;
const value = directive.arguments[0].value;
switch (value.kind) {
case 'BooleanValue':
if (directiveName === 'skip') {
return value.value ? null : selection;
}
else {
return value.value ? selection : null;
}
break;
case 'Variable':
selection = {
kind: 'BooleanCondition',
variableName: value.name.value,
inverted: directiveName === 'skip',
selectionSet: {
possibleTypes,
selections: [selection]
}
};
break;
}
}
}
return selection;
}
//# sourceMappingURL=index.js.map
© 2015 - 2025 Weber Informatics LLC | Privacy Policy