UNPKG

@graphql-codegen/java-apollo-android

Version:

GraphQL Code Generator plugin for generating Java classes for Apollo-Android

111 lines (110 loc) 3.93 kB
import { GraphQLObjectType, isInputObjectType, isListType, isNonNullType, isScalarType, Kind, } from 'graphql'; import { JAVA_SCALARS } from '@graphql-codegen/java-common'; import { getBaseType } from '@graphql-codegen/plugin-helpers'; import { BaseVisitor, buildScalars, getBaseTypeNode } from '@graphql-codegen/visitor-plugin-common'; import { Imports } from './imports.js'; export const SCALAR_TO_WRITER_METHOD = { ID: 'writeString', String: 'writeString', Int: 'writeInt', Boolean: 'writeBoolean', Float: 'writeDouble', }; function isTypeNode(type) { return type && !!type.kind; } export class BaseJavaVisitor extends BaseVisitor { constructor(_schema, rawConfig, additionalConfig) { super(rawConfig, { ...additionalConfig, scalars: buildScalars(_schema, { ID: 'String' }, JAVA_SCALARS), }); this._schema = _schema; this._imports = new Set(); } getPackage() { return ''; } additionalContent() { return ''; } getImports() { return Array.from(this._imports).map(imp => `import ${imp};`); } getImplementingTypes(node) { const allTypesMap = this._schema.getTypeMap(); const implementingTypes = []; for (const graphqlType of Object.values(allTypesMap)) { if (graphqlType instanceof GraphQLObjectType) { const allInterfaces = graphqlType.getInterfaces(); if (allInterfaces.find(int => int.name === node.name)) { implementingTypes.push(graphqlType.name); } } } return implementingTypes; } transformType(type) { let schemaType; let isNonNull; if (isTypeNode(type)) { const baseTypeNode = getBaseTypeNode(type); schemaType = this._schema.getType(baseTypeNode.name.value); isNonNull = type.kind === Kind.NON_NULL_TYPE; } else { schemaType = this._schema.getType(getBaseType(type).name); isNonNull = isNonNullType(type); } const javaType = this.getJavaClass(schemaType); const annotation = isNonNull ? 'Nonnull' : 'Nullable'; const typeToUse = isTypeNode(type) ? this.getListTypeNodeWrapped(javaType, type) : this.getListTypeWrapped(javaType, type); return { baseType: schemaType.name, javaType, isNonNull, annotation, typeToUse, }; } // Replaces a GraphQL type with a Java class getJavaClass(schemaType) { let typeToUse = schemaType.name; if (isScalarType(schemaType)) { const scalar = this.scalars[schemaType.name] || 'Object'; if (Imports[scalar]) { this._imports.add(Imports[scalar]); } typeToUse = scalar; } else if (isInputObjectType(schemaType)) { // Make sure to import it if it's in use this._imports.add(`${this.config.typePackage}.${schemaType.name}`); } return typeToUse; } getListTypeWrapped(toWrap, type) { if (isNonNullType(type)) { return this.getListTypeWrapped(toWrap, type.ofType); } if (isListType(type)) { const child = this.getListTypeWrapped(toWrap, type.ofType); this._imports.add(Imports.List); return `List<${child}>`; } return toWrap; } getListTypeNodeWrapped(toWrap, type) { if (type.kind === Kind.NON_NULL_TYPE) { return this.getListTypeNodeWrapped(toWrap, type.type); } if (type.kind === Kind.LIST_TYPE) { const child = this.getListTypeNodeWrapped(toWrap, type.type); this._imports.add(Imports.List); return `List<${child}>`; } return toWrap; } }